OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 part of _interceptors; | 5 part of _interceptors; |
6 | 6 |
7 /** | 7 /** |
8 * The super interceptor class for [JSInt] and [JSDouble]. The compiler | 8 * The super interceptor class for [JSInt] and [JSDouble]. The compiler |
9 * recognizes this class as an interceptor, and changes references to | 9 * recognizes this class as an interceptor, and changes references to |
10 * [:this:] to actually use the receiver of the method, which is | 10 * [:this:] to actually use the receiver of the method, which is |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
43 | 43 |
44 num remainder(num b) { | 44 num remainder(num b) { |
45 checkNull(b); // TODO(ngeoffray): This is not specified but co19 tests it. | 45 checkNull(b); // TODO(ngeoffray): This is not specified but co19 tests it. |
46 if (b is! num) throw new ArgumentError(b); | 46 if (b is! num) throw new ArgumentError(b); |
47 return JS('num', r'# % #', this, b); | 47 return JS('num', r'# % #', this, b); |
48 } | 48 } |
49 | 49 |
50 num abs() => JS('num', r'Math.abs(#)', this); | 50 num abs() => JS('num', r'Math.abs(#)', this); |
51 | 51 |
52 int toInt() { | 52 int toInt() { |
53 if (isNaN) throw new FormatException('NaN'); | 53 if (isNaN) throw new UnsupportedError('NaN'); |
54 if (isInfinite) throw new FormatException('Infinity'); | 54 if (isInfinite) throw new UnsupportedError('Infinity'); |
55 num truncated = truncate(); | 55 num truncated = truncate(); |
56 return JS('bool', r'# == -0.0', truncated) ? 0 : truncated; | 56 return JS('bool', r'# == -0.0', truncated) ? 0 : truncated; |
57 } | 57 } |
58 | 58 |
59 num ceil() => JS('num', r'Math.ceil(#)', this); | 59 num ceil() => JS('num', r'Math.ceil(#)', this); |
60 | 60 |
61 num floor() => JS('num', r'Math.floor(#)', this); | 61 num floor() => JS('num', r'Math.floor(#)', this); |
62 | 62 |
63 bool get isInfinite { | 63 bool get isInfinite { |
64 return JS('bool', r'# == Infinity', this) | 64 return JS('bool', r'# == Infinity', this) |
65 || JS('bool', r'# == -Infinity', this); | 65 || JS('bool', r'# == -Infinity', this); |
66 } | 66 } |
67 | 67 |
68 num round() { | 68 num round() { |
69 if (this < 0) { | 69 if (this < 0) { |
70 return JS('num', r'-Math.round(-#)', this); | 70 return JS('num', r'-Math.round(-#)', this); |
71 } else { | 71 } else { |
72 return JS('num', r'Math.round(#)', this); | 72 return JS('num', r'Math.round(#)', this); |
73 } | 73 } |
74 } | 74 } |
75 | 75 |
| 76 num clamp(lowerLimit, upperLimit) { |
| 77 if (lowerLimit is! num) throw new ArgumentError(lowerLimit); |
| 78 if (upperLimit is! num) throw new ArgumentError(upperLimit); |
| 79 if (lowerLimit.compareTo(upperLimit) > 0) { |
| 80 throw new ArgumentError(lowerLimit); |
| 81 } |
| 82 if (this.compareTo(lowerLimit) < 0) return lowerLimit; |
| 83 if (this.compareTo(upperLimit) > 0) return upperLimit; |
| 84 return this; |
| 85 } |
| 86 |
76 double toDouble() => this; | 87 double toDouble() => this; |
77 | 88 |
78 num truncate() => this < 0 ? ceil() : floor(); | 89 num truncate() => this < 0 ? ceil() : floor(); |
79 | 90 |
80 String toStringAsFixed(int fractionDigits) { | 91 String toStringAsFixed(int fractionDigits) { |
81 checkNum(fractionDigits); | 92 checkNum(fractionDigits); |
| 93 // TODO(floitsch): fractionDigits must be an integer. |
| 94 if (fractionDigits < 0 || fractionDigits > 20) { |
| 95 throw new RangeError(fractionDigits); |
| 96 } |
82 String result = JS('String', r'#.toFixed(#)', this, fractionDigits); | 97 String result = JS('String', r'#.toFixed(#)', this, fractionDigits); |
83 if (this == 0 && isNegative) return "-$result"; | 98 if (this == 0 && isNegative) return "-$result"; |
84 return result; | 99 return result; |
85 } | 100 } |
86 | 101 |
87 String toStringAsExponential(int fractionDigits) { | 102 String toStringAsExponential([int fractionDigits]) { |
88 String result; | 103 String result; |
89 if (fractionDigits != null) { | 104 if (fractionDigits != null) { |
| 105 // TODO(floitsch): fractionDigits must be an integer. |
90 checkNum(fractionDigits); | 106 checkNum(fractionDigits); |
| 107 if (fractionDigits < 0 || fractionDigits > 20) { |
| 108 throw new RangeError(fractionDigits); |
| 109 } |
91 result = JS('String', r'#.toExponential(#)', this, fractionDigits); | 110 result = JS('String', r'#.toExponential(#)', this, fractionDigits); |
92 } else { | 111 } else { |
93 result = JS('String', r'#.toExponential()', this); | 112 result = JS('String', r'#.toExponential()', this); |
94 } | 113 } |
95 if (this == 0 && isNegative) return "-$result"; | 114 if (this == 0 && isNegative) return "-$result"; |
96 return result; | 115 return result; |
97 } | 116 } |
98 | 117 |
99 String toStringAsPrecision(int fractionDigits) { | 118 String toStringAsPrecision(int precision) { |
100 checkNum(fractionDigits); | 119 // TODO(floitsch): precision must be an integer. |
| 120 checkNum(precision); |
| 121 if (precision < 1 || precision > 21) { |
| 122 throw new RangeError(precision); |
| 123 } |
101 String result = JS('String', r'#.toPrecision(#)', | 124 String result = JS('String', r'#.toPrecision(#)', |
102 this, fractionDigits); | 125 this, precision); |
103 if (this == 0 && isNegative) return "-$result"; | 126 if (this == 0 && isNegative) return "-$result"; |
104 return result; | 127 return result; |
105 } | 128 } |
106 | 129 |
107 String toRadixString(int radix) { | 130 String toRadixString(int radix) { |
108 checkNum(radix); | 131 checkNum(radix); |
109 if (radix < 2 || radix > 36) throw new ArgumentError(radix); | 132 if (radix < 2 || radix > 36) throw new RangeError(radix); |
110 return JS('String', r'#.toString(#)', this, radix); | 133 return JS('String', r'#.toString(#)', this, radix); |
111 } | 134 } |
112 | 135 |
113 String toString() { | 136 String toString() { |
114 if (this == 0 && JS('bool', '(1 / #) < 0', this)) { | 137 if (this == 0 && JS('bool', '(1 / #) < 0', this)) { |
115 return '-0.0'; | 138 return '-0.0'; |
116 } else { | 139 } else { |
117 return JS('String', r'String(#)', this); | 140 return JS('String', r'String(#)', this); |
118 } | 141 } |
119 } | 142 } |
120 | 143 |
121 int get hashCode => this & 0x1FFFFFFF; | 144 int get hashCode => this & 0x1FFFFFFF; |
122 } | 145 } |
123 | 146 |
124 class JSInt extends JSNumber { | 147 class JSInt extends JSNumber { |
125 const JSInt(); | 148 const JSInt(); |
126 | 149 |
127 bool get isEven => (this & 1) == 0; | 150 bool get isEven => (this & 1) == 0; |
128 | 151 |
129 bool get isOdd => (this & 1) == 1; | 152 bool get isOdd => (this & 1) == 1; |
130 | 153 |
131 Type get runtimeType => int; | 154 Type get runtimeType => int; |
132 } | 155 } |
133 | 156 |
134 class JSDouble extends JSNumber { | 157 class JSDouble extends JSNumber { |
135 const JSDouble(); | 158 const JSDouble(); |
136 Type get runtimeType => double; | 159 Type get runtimeType => double; |
137 } | 160 } |
OLD | NEW |