1 /* 2 * Copyright (C) 2013 Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above 11 * copyright notice, this list of conditions and the following disclaimer 12 * in the documentation and/or other materials provided with the 13 * distribution. 14 * * Neither the name of Google Inc. nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #ifndef ExceptionMessages_h 32 #define ExceptionMessages_h 33 34 #include "wtf/MathExtras.h" 35 #include "wtf/text/StringBuilder.h" 36 #include "wtf/text/WTFString.h" 37 38 namespace blink { 39 40 class Decimal; 41 42 class ExceptionMessages { 43 public: 44 enum BoundType { 45 InclusiveBound, 46 ExclusiveBound, 47 }; 48 49 static String argumentNullOrIncorrectType(int argumentIndex, const String& expectedType); 50 static String constructorNotCallableAsFunction(const char* type); 51 52 static String failedToConstruct(const char* type, const String& detail); 53 static String failedToEnumerate(const char* type, const String& detail); 54 static String failedToExecute(const char* method, const char* type, const String& detail); 55 static String failedToGet(const char* property, const char* type, const String& detail); 56 static String failedToSet(const char* property, const char* type, const String& detail); 57 static String failedToDelete(const char* property, const char* type, const String& detail); 58 static String failedToGetIndexed(const char* type, const String& detail); 59 static String failedToSetIndexed(const char* type, const String& detail); 60 static String failedToDeleteIndexed(const char* type, const String& detail); 61 62 template <typename NumType> formatNumber(NumType number)63 static String formatNumber(NumType number) 64 { 65 return formatFiniteNumber(number); 66 } 67 68 static String incorrectPropertyType(const String& property, const String& detail); 69 70 template <typename NumberType> indexExceedsMaximumBound(const char * name,NumberType given,NumberType bound)71 static String indexExceedsMaximumBound(const char* name, NumberType given, NumberType bound) 72 { 73 bool eq = given == bound; 74 StringBuilder result; 75 result.appendLiteral("The "); 76 result.append(name); 77 result.appendLiteral(" provided ("); 78 result.append(formatNumber(given)); 79 result.appendLiteral(") is greater than "); 80 result.append(eq ? "or equal to " : ""); 81 result.appendLiteral("the maximum bound ("); 82 result.append(formatNumber(bound)); 83 result.appendLiteral(")."); 84 return result.toString(); 85 } 86 87 template <typename NumberType> indexExceedsMinimumBound(const char * name,NumberType given,NumberType bound)88 static String indexExceedsMinimumBound(const char* name, NumberType given, NumberType bound) 89 { 90 bool eq = given == bound; 91 StringBuilder result; 92 result.appendLiteral("The "); 93 result.append(name); 94 result.appendLiteral(" provided ("); 95 result.append(formatNumber(given)); 96 result.appendLiteral(") is less than "); 97 result.append(eq ? "or equal to " : ""); 98 result.appendLiteral("the minimum bound ("); 99 result.append(formatNumber(bound)); 100 result.appendLiteral(")."); 101 return result.toString(); 102 } 103 104 template <typename NumberType> indexOutsideRange(const char * name,NumberType given,NumberType lowerBound,BoundType lowerType,NumberType upperBound,BoundType upperType)105 static String indexOutsideRange(const char* name, NumberType given, NumberType lowerBound, BoundType lowerType, NumberType upperBound, BoundType upperType) 106 { 107 StringBuilder result; 108 result.appendLiteral("The "); 109 result.append(name); 110 result.appendLiteral(" provided ("); 111 result.append(formatNumber(given)); 112 result.appendLiteral(") is outside the range "); 113 result.append(lowerType == ExclusiveBound ? '(' : '['); 114 result.append(formatNumber(lowerBound)); 115 result.appendLiteral(", "); 116 result.append(formatNumber(upperBound)); 117 result.append(upperType == ExclusiveBound ? ')' : ']'); 118 result.append('.'); 119 return result.toString(); 120 } 121 122 static String invalidArity(const char* expected, unsigned provided); 123 124 // If > 0, the argument index that failed type check (1-indexed.) 125 // If == 0, a (non-argument) value (e.g., a setter) failed the same check. 126 static String notAnArrayTypeArgumentOrValue(int argumentIndex); 127 static String notASequenceTypeProperty(const String& propertyName); 128 static String notAFiniteNumber(double value, const char* name = "value provided"); 129 static String notAFiniteNumber(const Decimal& value, const char* name = "value provided"); 130 131 static String notEnoughArguments(unsigned expected, unsigned provided); 132 133 static String readOnly(const char* detail = 0); 134 135 private: 136 template <typename NumType> formatFiniteNumber(NumType number)137 static String formatFiniteNumber(NumType number) 138 { 139 if (number > 1e20 || number < -1e20) 140 return String::format("%e", 1.0*number); 141 return String::number(number); 142 } 143 144 template <typename NumType> formatPotentiallyNonFiniteNumber(NumType number)145 static String formatPotentiallyNonFiniteNumber(NumType number) 146 { 147 if (std::isnan(number)) 148 return "NaN"; 149 if (std::isinf(number)) 150 return number > 0 ? "Infinity" : "-Infinity"; 151 if (number > 1e20 || number < -1e20) 152 return String::format("%e", number); 153 return String::number(number); 154 } 155 156 static String ordinalNumber(int number); 157 }; 158 159 template <> String ExceptionMessages::formatNumber<float>(float number); 160 template <> String ExceptionMessages::formatNumber<double>(double number); 161 162 } // namespace blink 163 164 #endif // ExceptionMessages_h 165