| 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 #library('js_helper'); | 5 #library('js_helper'); |
| 6 | 6 |
| 7 #import('coreimpl.dart'); | 7 #import('coreimpl.dart'); |
| 8 | 8 |
| 9 #source('date_helper.dart'); | 9 #source('date_helper.dart'); |
| 10 #source('regexp_helper.dart'); | 10 #source('regexp_helper.dart'); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 22 } else { | 22 } else { |
| 23 checkNull(b); | 23 checkNull(b); |
| 24 throw new IllegalArgumentException(message); | 24 throw new IllegalArgumentException(message); |
| 25 } | 25 } |
| 26 } | 26 } |
| 27 return false; | 27 return false; |
| 28 } | 28 } |
| 29 | 29 |
| 30 | 30 |
| 31 bool isJsArray(var value) { | 31 bool isJsArray(var value) { |
| 32 return value !== null && JS("bool", @"$0.constructor === Array", value); | 32 return value !== null && JS('bool', @'$0.constructor === Array', value); |
| 33 } | 33 } |
| 34 | 34 |
| 35 | 35 |
| 36 add(var a, var b) { | 36 add(var a, var b) { |
| 37 if (checkNumbers(a, b, "num+ expects a number as second operand.")) { | 37 if (checkNumbers(a, b, 'num+ expects a number as second operand.')) { |
| 38 return JS("num", @"$0 + $1", a, b); | 38 return JS('num', @'$0 + $1', a, b); |
| 39 } else if (a is String) { | 39 } else if (a is String) { |
| 40 b = b.toString(); | 40 b = b.toString(); |
| 41 if (b is String) { | 41 if (b is String) { |
| 42 return JS("String", @"$0 + $1", a, b); | 42 return JS('String', @'$0 + $1', a, b); |
| 43 } | 43 } |
| 44 checkNull(b); | 44 checkNull(b); |
| 45 throw new IllegalArgumentException(b); | 45 throw new IllegalArgumentException(b); |
| 46 } | 46 } |
| 47 checkNull(a); | 47 checkNull(a); |
| 48 return UNINTERCEPTED(a + b); | 48 return UNINTERCEPTED(a + b); |
| 49 } | 49 } |
| 50 | 50 |
| 51 div(var a, var b) { | 51 div(var a, var b) { |
| 52 if (checkNumbers(a, b, "num/ expects a number as second operand.")) { | 52 if (checkNumbers(a, b, 'num/ expects a number as second operand.')) { |
| 53 return JS("num", @"$0 / $1", a, b); | 53 return JS('num', @'$0 / $1', a, b); |
| 54 } | 54 } |
| 55 checkNull(a); | 55 checkNull(a); |
| 56 return UNINTERCEPTED(a / b); | 56 return UNINTERCEPTED(a / b); |
| 57 } | 57 } |
| 58 | 58 |
| 59 mul(var a, var b) { | 59 mul(var a, var b) { |
| 60 if (checkNumbers(a, b, "num* expects a number as second operand.")) { | 60 if (checkNumbers(a, b, 'num* expects a number as second operand.')) { |
| 61 return JS("num", @"$0 * $1", a, b); | 61 return JS('num', @'$0 * $1', a, b); |
| 62 } | 62 } |
| 63 checkNull(a); | 63 checkNull(a); |
| 64 return UNINTERCEPTED(a * b); | 64 return UNINTERCEPTED(a * b); |
| 65 } | 65 } |
| 66 | 66 |
| 67 sub(var a, var b) { | 67 sub(var a, var b) { |
| 68 if (checkNumbers(a, b, "num- expects a number as second operand.")) { | 68 if (checkNumbers(a, b, 'num- expects a number as second operand.')) { |
| 69 return JS("num", @"$0 - $1", a, b); | 69 return JS('num', @'$0 - $1', a, b); |
| 70 } | 70 } |
| 71 checkNull(a); | 71 checkNull(a); |
| 72 return UNINTERCEPTED(a - b); | 72 return UNINTERCEPTED(a - b); |
| 73 } | 73 } |
| 74 | 74 |
| 75 mod(var a, var b) { | 75 mod(var a, var b) { |
| 76 if (checkNumbers(a, b, "int% expects an int as second operand.")) { | 76 if (checkNumbers(a, b, 'int% expects an int as second operand.')) { |
| 77 if (b === 0) throw new IntegerDivisionByZeroException(); | 77 if (b === 0) throw new IntegerDivisionByZeroException(); |
| 78 // Euclidean Modulo. | 78 // Euclidean Modulo. |
| 79 int result = JS("num", @"$0 % $1", a, b); | 79 int result = JS('num', @'$0 % $1', a, b); |
| 80 if (result == 0) return 0; // Make sure we don't return -0.0. | 80 if (result == 0) return 0; // Make sure we don't return -0.0. |
| 81 if (result > 0) return result; | 81 if (result > 0) return result; |
| 82 if (b < 0) { | 82 if (b < 0) { |
| 83 return result - b; | 83 return result - b; |
| 84 } else { | 84 } else { |
| 85 return result + b; | 85 return result + b; |
| 86 } | 86 } |
| 87 } | 87 } |
| 88 checkNull(a); | 88 checkNull(a); |
| 89 return UNINTERCEPTED(a % b); | 89 return UNINTERCEPTED(a % b); |
| 90 } | 90 } |
| 91 | 91 |
| 92 tdiv(var a, var b) { | 92 tdiv(var a, var b) { |
| 93 if (checkNumbers(a, b, "num~/ expects a number as second operand.")) { | 93 if (checkNumbers(a, b, 'num~/ expects a number as second operand.')) { |
| 94 if (b === 0) throw new IntegerDivisionByZeroException(); | 94 if (b === 0) throw new IntegerDivisionByZeroException(); |
| 95 return (a / b).truncate(); | 95 return (a / b).truncate(); |
| 96 } | 96 } |
| 97 checkNull(a); | 97 checkNull(a); |
| 98 return UNINTERCEPTED(a ~/ b); | 98 return UNINTERCEPTED(a ~/ b); |
| 99 } | 99 } |
| 100 | 100 |
| 101 eq(var a, var b) { | 101 eq(var a, var b) { |
| 102 if (JS("bool", @"typeof $0 === 'object'", a)) { | 102 if (JS('bool', @'typeof $0 === "object"', a)) { |
| 103 if (JS_HAS_EQUALS(a)) { | 103 if (JS_HAS_EQUALS(a)) { |
| 104 return UNINTERCEPTED(a == b) === true; | 104 return UNINTERCEPTED(a == b) === true; |
| 105 } else { | 105 } else { |
| 106 return JS("bool", @"$0 === $1", a, b); | 106 return JS('bool', @'$0 === $1', a, b); |
| 107 } | 107 } |
| 108 } | 108 } |
| 109 // TODO(lrn): is NaN === NaN ? Is -0.0 === 0.0 ? | 109 // TODO(lrn): is NaN === NaN ? Is -0.0 === 0.0 ? |
| 110 return JS("bool", @"$0 === $1", a, b); | 110 return JS('bool', @'$0 === $1', a, b); |
| 111 } | 111 } |
| 112 | 112 |
| 113 eqq(var a, var b) { | 113 eqq(var a, var b) { |
| 114 return JS("bool", @"$0 === $1", a, b); | 114 return JS('bool', @'$0 === $1', a, b); |
| 115 } | 115 } |
| 116 | 116 |
| 117 eqNull(var a) { | 117 eqNull(var a) { |
| 118 if (JS("bool", @"typeof $0 === 'object'", a)) { | 118 if (JS('bool', @'typeof $0 === "object"', a)) { |
| 119 if (JS_HAS_EQUALS(a)) { | 119 if (JS_HAS_EQUALS(a)) { |
| 120 return UNINTERCEPTED(a == null) === true; | 120 return UNINTERCEPTED(a == null) === true; |
| 121 } else { | 121 } else { |
| 122 return false; | 122 return false; |
| 123 } | 123 } |
| 124 } else { | 124 } else { |
| 125 return JS("bool", @"typeof $0 === 'undefined'", a); | 125 return JS('bool', @'typeof $0 === "undefined"', a); |
| 126 } | 126 } |
| 127 } | 127 } |
| 128 | 128 |
| 129 gt(var a, var b) { | 129 gt(var a, var b) { |
| 130 if (checkNumbers(a, b, "num> expects a number as second operand.")) { | 130 if (checkNumbers(a, b, 'num> expects a number as second operand.')) { |
| 131 return JS("bool", @"$0 > $1", a, b); | 131 return JS('bool', @'$0 > $1', a, b); |
| 132 } | 132 } |
| 133 checkNull(a); | 133 checkNull(a); |
| 134 return UNINTERCEPTED(a > b); | 134 return UNINTERCEPTED(a > b); |
| 135 } | 135 } |
| 136 | 136 |
| 137 ge(var a, var b) { | 137 ge(var a, var b) { |
| 138 if (checkNumbers(a, b, "num>= expects a number as second operand.")) { | 138 if (checkNumbers(a, b, 'num>= expects a number as second operand.')) { |
| 139 return JS("bool", @"$0 >= $1", a, b); | 139 return JS('bool', @'$0 >= $1', a, b); |
| 140 } | 140 } |
| 141 checkNull(a); | 141 checkNull(a); |
| 142 return UNINTERCEPTED(a >= b); | 142 return UNINTERCEPTED(a >= b); |
| 143 } | 143 } |
| 144 | 144 |
| 145 lt(var a, var b) { | 145 lt(var a, var b) { |
| 146 if (checkNumbers(a, b, "num< expects a number as second operand.")) { | 146 if (checkNumbers(a, b, 'num< expects a number as second operand.')) { |
| 147 return JS("bool", @"$0 < $1", a, b); | 147 return JS('bool', @'$0 < $1', a, b); |
| 148 } | 148 } |
| 149 checkNull(a); | 149 checkNull(a); |
| 150 return UNINTERCEPTED(a < b); | 150 return UNINTERCEPTED(a < b); |
| 151 } | 151 } |
| 152 | 152 |
| 153 le(var a, var b) { | 153 le(var a, var b) { |
| 154 if (checkNumbers(a, b, "num<= expects a number as second operand.")) { | 154 if (checkNumbers(a, b, 'num<= expects a number as second operand.')) { |
| 155 return JS("bool", @"$0 <= $1", a, b); | 155 return JS('bool', @'$0 <= $1', a, b); |
| 156 } | 156 } |
| 157 checkNull(a); | 157 checkNull(a); |
| 158 return UNINTERCEPTED(a <= b); | 158 return UNINTERCEPTED(a <= b); |
| 159 } | 159 } |
| 160 | 160 |
| 161 shl(var a, var b) { | 161 shl(var a, var b) { |
| 162 // TODO(floitsch): inputs must be integers. | 162 // TODO(floitsch): inputs must be integers. |
| 163 if (checkNumbers(a, b, "int<< expects an int as second operand.")) { | 163 if (checkNumbers(a, b, 'int<< expects an int as second operand.')) { |
| 164 if (b < 0) throw new IllegalArgumentException(b); | 164 if (b < 0) throw new IllegalArgumentException(b); |
| 165 return JS("num", @"$0 << $1", a, b); | 165 return JS('num', @'$0 << $1', a, b); |
| 166 } | 166 } |
| 167 checkNull(a); | 167 checkNull(a); |
| 168 return UNINTERCEPTED(a << b); | 168 return UNINTERCEPTED(a << b); |
| 169 } | 169 } |
| 170 | 170 |
| 171 shr(var a, var b) { | 171 shr(var a, var b) { |
| 172 // TODO(floitsch): inputs must be integers. | 172 // TODO(floitsch): inputs must be integers. |
| 173 if (checkNumbers(a, b, "int>> expects an int as second operand.")) { | 173 if (checkNumbers(a, b, 'int>> expects an int as second operand.')) { |
| 174 if (b < 0) throw new IllegalArgumentException(b); | 174 if (b < 0) throw new IllegalArgumentException(b); |
| 175 return JS("num", @"$0 >> $1", a, b); | 175 return JS('num', @'$0 >> $1', a, b); |
| 176 } | 176 } |
| 177 checkNull(a); | 177 checkNull(a); |
| 178 return UNINTERCEPTED(a >> b); | 178 return UNINTERCEPTED(a >> b); |
| 179 } | 179 } |
| 180 | 180 |
| 181 and(var a, var b) { | 181 and(var a, var b) { |
| 182 // TODO(floitsch): inputs must be integers. | 182 // TODO(floitsch): inputs must be integers. |
| 183 if (checkNumbers(a, b, "int& expects an int as second operand.")) { | 183 if (checkNumbers(a, b, 'int& expects an int as second operand.')) { |
| 184 return JS("num", @"$0 & $1", a, b); | 184 return JS('num', @'$0 & $1', a, b); |
| 185 } | 185 } |
| 186 checkNull(a); | 186 checkNull(a); |
| 187 return UNINTERCEPTED(a & b); | 187 return UNINTERCEPTED(a & b); |
| 188 } | 188 } |
| 189 | 189 |
| 190 or(var a, var b) { | 190 or(var a, var b) { |
| 191 // TODO(floitsch): inputs must be integers. | 191 // TODO(floitsch): inputs must be integers. |
| 192 if (checkNumbers(a, b, "int| expects an int as second operand.")) { | 192 if (checkNumbers(a, b, 'int| expects an int as second operand.')) { |
| 193 return JS("num", @"$0 | $1", a, b); | 193 return JS('num', @'$0 | $1', a, b); |
| 194 } | 194 } |
| 195 checkNull(a); | 195 checkNull(a); |
| 196 return UNINTERCEPTED(a | b); | 196 return UNINTERCEPTED(a | b); |
| 197 } | 197 } |
| 198 | 198 |
| 199 xor(var a, var b) { | 199 xor(var a, var b) { |
| 200 // TODO(floitsch): inputs must be integers. | 200 // TODO(floitsch): inputs must be integers. |
| 201 if (checkNumbers(a, b, "int^ expects an int as second operand.")) { | 201 if (checkNumbers(a, b, 'int^ expects an int as second operand.')) { |
| 202 return JS("num", @"$0 ^ $1", a, b); | 202 return JS('num', @'$0 ^ $1', a, b); |
| 203 } | 203 } |
| 204 checkNull(a); | 204 checkNull(a); |
| 205 return UNINTERCEPTED(a ^ b); | 205 return UNINTERCEPTED(a ^ b); |
| 206 } | 206 } |
| 207 | 207 |
| 208 not(var a) { | 208 not(var a) { |
| 209 if (JS("bool", @"typeof $0 === 'number'", a)) return JS("num", @"~$0", a); | 209 if (JS('bool', @'typeof $0 === "number"', a)) return JS('num', @'~$0', a); |
| 210 checkNull(a); | 210 checkNull(a); |
| 211 return UNINTERCEPTED(~a); | 211 return UNINTERCEPTED(~a); |
| 212 } | 212 } |
| 213 | 213 |
| 214 neg(var a) { | 214 neg(var a) { |
| 215 if (JS("bool", @"typeof $0 === 'number'", a)) return JS("num", @"-$0", a); | 215 if (JS('bool', @'typeof $0 === "number"', a)) return JS('num', @'-$0', a); |
| 216 checkNull(a); | 216 checkNull(a); |
| 217 return UNINTERCEPTED(-a); | 217 return UNINTERCEPTED(-a); |
| 218 } | 218 } |
| 219 | 219 |
| 220 index(var a, var index) { | 220 index(var a, var index) { |
| 221 checkNull(a); | 221 checkNull(a); |
| 222 if (a is String || isJsArray(a)) { | 222 if (a is String || isJsArray(a)) { |
| 223 if (index is !int) { | 223 if (index is !int) { |
| 224 if (index is !num) throw new IllegalArgumentException(index); | 224 if (index is !num) throw new IllegalArgumentException(index); |
| 225 if (index.truncate() !== index) throw new IllegalArgumentException(index); | 225 if (index.truncate() !== index) throw new IllegalArgumentException(index); |
| 226 } | 226 } |
| 227 if (index < 0 || index >= a.length) { | 227 if (index < 0 || index >= a.length) { |
| 228 throw new IndexOutOfRangeException(index); | 228 throw new IndexOutOfRangeException(index); |
| 229 } | 229 } |
| 230 return JS("Object", @"$0[$1]", a, index); | 230 return JS('Object', @'$0[$1]', a, index); |
| 231 } | 231 } |
| 232 checkNull(a); | 232 checkNull(a); |
| 233 return UNINTERCEPTED(a[index]); | 233 return UNINTERCEPTED(a[index]); |
| 234 } | 234 } |
| 235 | 235 |
| 236 indexSet(var a, var index, var value) { | 236 indexSet(var a, var index, var value) { |
| 237 checkNull(a); | 237 checkNull(a); |
| 238 if (isJsArray(a)) { | 238 if (isJsArray(a)) { |
| 239 if (!(index is int)) { | 239 if (!(index is int)) { |
| 240 throw new IllegalArgumentException(index); | 240 throw new IllegalArgumentException(index); |
| 241 } | 241 } |
| 242 if (index < 0 || index >= a.length) { | 242 if (index < 0 || index >= a.length) { |
| 243 throw new IndexOutOfRangeException(index); | 243 throw new IndexOutOfRangeException(index); |
| 244 } | 244 } |
| 245 checkMutable(a, 'indexed set'); | 245 checkMutable(a, 'indexed set'); |
| 246 return JS("Object", @"$0[$1] = $2", a, index, value); | 246 return JS('Object', @'$0[$1] = $2', a, index, value); |
| 247 } | 247 } |
| 248 checkNull(a); | 248 checkNull(a); |
| 249 UNINTERCEPTED(a[index] = value); | 249 UNINTERCEPTED(a[index] = value); |
| 250 return value; | 250 return value; |
| 251 } | 251 } |
| 252 | 252 |
| 253 checkMutable(list, reason) { | 253 checkMutable(list, reason) { |
| 254 if (JS('bool', @'!!($0.immutable$list)', list)) { | 254 if (JS('bool', @'!!($0.immutable$list)', list)) { |
| 255 throw new UnsupportedOperationException(reason); | 255 throw new UnsupportedOperationException(reason); |
| 256 } | 256 } |
| 257 } | 257 } |
| 258 | 258 |
| 259 builtin$add$1(var receiver, var value) { | 259 builtin$add$1(var receiver, var value) { |
| 260 checkNull(receiver); | 260 checkNull(receiver); |
| 261 if (isJsArray(receiver)) { | 261 if (isJsArray(receiver)) { |
| 262 checkGrowable(receiver, 'add'); | 262 checkGrowable(receiver, 'add'); |
| 263 JS("Object", @"$0.push($1)", receiver, value); | 263 JS('Object', @'$0.push($1)', receiver, value); |
| 264 return; | 264 return; |
| 265 } | 265 } |
| 266 return UNINTERCEPTED(receiver.add(value)); | 266 return UNINTERCEPTED(receiver.add(value)); |
| 267 } | 267 } |
| 268 | 268 |
| 269 builtin$removeLast$0(var receiver) { | 269 builtin$removeLast$0(var receiver) { |
| 270 checkNull(receiver); | 270 checkNull(receiver); |
| 271 if (isJsArray(receiver)) { | 271 if (isJsArray(receiver)) { |
| 272 checkGrowable(receiver, 'removeLast'); | 272 checkGrowable(receiver, 'removeLast'); |
| 273 if (receiver.length === 0) throw new IndexOutOfRangeException(-1); | 273 if (receiver.length === 0) throw new IndexOutOfRangeException(-1); |
| 274 return JS("Object", @"$0.pop()", receiver); | 274 return JS('Object', @'$0.pop()', receiver); |
| 275 } | 275 } |
| 276 return UNINTERCEPTED(receiver.removeLast()); | 276 return UNINTERCEPTED(receiver.removeLast()); |
| 277 } | 277 } |
| 278 | 278 |
| 279 builtin$filter$1(var receiver, var predicate) { | 279 builtin$filter$1(var receiver, var predicate) { |
| 280 checkNull(receiver); | 280 checkNull(receiver); |
| 281 if (isJsArray(receiver)) { | 281 if (isJsArray(receiver)) { |
| 282 return JS("Object", @"$0.filter(function(v) { return $1(v) === true; })", | 282 return JS('Object', @'$0.filter(function(v) { return $1(v) === true; })', |
| 283 receiver, predicate); | 283 receiver, predicate); |
| 284 } | 284 } |
| 285 return UNINTERCEPTED(receiver.filter(predicate)); | 285 return UNINTERCEPTED(receiver.filter(predicate)); |
| 286 } | 286 } |
| 287 | 287 |
| 288 | 288 |
| 289 builtin$get$length(var receiver) { | 289 builtin$get$length(var receiver) { |
| 290 checkNull(receiver); | 290 checkNull(receiver); |
| 291 if (receiver is String || isJsArray(receiver)) { | 291 if (receiver is String || isJsArray(receiver)) { |
| 292 return JS("num", @"$0.length", receiver); | 292 return JS('num', @'$0.length', receiver); |
| 293 } | 293 } |
| 294 return UNINTERCEPTED(receiver.length); | 294 return UNINTERCEPTED(receiver.length); |
| 295 } | 295 } |
| 296 | 296 |
| 297 builtin$set$length(receiver, newLength) { | 297 builtin$set$length(receiver, newLength) { |
| 298 checkNull(receiver); | 298 checkNull(receiver); |
| 299 if (isJsArray(receiver)) { | 299 if (isJsArray(receiver)) { |
| 300 checkNull(newLength); // TODO(ahe): This is not specified but co19 tests it. | 300 checkNull(newLength); // TODO(ahe): This is not specified but co19 tests it. |
| 301 if (newLength is !int) throw new IllegalArgumentException(newLength); | 301 if (newLength is !int) throw new IllegalArgumentException(newLength); |
| 302 if (newLength < 0) throw new IndexOutOfRangeException(newLength); | 302 if (newLength < 0) throw new IndexOutOfRangeException(newLength); |
| 303 checkGrowable(receiver, 'set length'); | 303 checkGrowable(receiver, 'set length'); |
| 304 JS('void', @"$0.length = $1", receiver, newLength); | 304 JS('void', @'$0.length = $1', receiver, newLength); |
| 305 } else { | 305 } else { |
| 306 UNINTERCEPTED(receiver.length = newLength); | 306 UNINTERCEPTED(receiver.length = newLength); |
| 307 } | 307 } |
| 308 return newLength; | 308 return newLength; |
| 309 } | 309 } |
| 310 | 310 |
| 311 checkGrowable(list, reason) { | 311 checkGrowable(list, reason) { |
| 312 if (JS('bool', @'!!($0.fixed$length)', list)) { | 312 if (JS('bool', @'!!($0.fixed$length)', list)) { |
| 313 throw new UnsupportedOperationException(reason); | 313 throw new UnsupportedOperationException(reason); |
| 314 } | 314 } |
| 315 } | 315 } |
| 316 | 316 |
| 317 builtin$toString$0(var value) { | 317 builtin$toString$0(var value) { |
| 318 if (JS("bool", @"typeof $0 == 'object'", value)) { | 318 if (JS('bool', @'typeof $0 == "object"', value)) { |
| 319 if (isJsArray(value)) { | 319 if (isJsArray(value)) { |
| 320 return "Instance of 'List'"; | 320 return "Instance of 'List'"; |
| 321 } | 321 } |
| 322 return UNINTERCEPTED(value.toString()); | 322 return UNINTERCEPTED(value.toString()); |
| 323 } | 323 } |
| 324 if (JS("bool", @"$0 === 0 && (1 / $0) < 0", value)) { | 324 if (JS('bool', @'$0 === 0 && (1 / $0) < 0', value)) { |
| 325 return "-0.0"; | 325 return '-0.0'; |
| 326 } | 326 } |
| 327 if (value === null) return "null"; | 327 if (value === null) return 'null'; |
| 328 if (JS("bool", @"typeof $0 == 'function'", value)) { | 328 if (JS('bool', @'typeof $0 == "function"', value)) { |
| 329 return "Closure"; | 329 return 'Closure'; |
| 330 } | 330 } |
| 331 return JS("string", @"String($0)", value); | 331 return JS('string', @'String($0)', value); |
| 332 } | 332 } |
| 333 | 333 |
| 334 | 334 |
| 335 builtin$iterator$0(receiver) { | 335 builtin$iterator$0(receiver) { |
| 336 checkNull(receiver); | 336 checkNull(receiver); |
| 337 if (isJsArray(receiver)) { | 337 if (isJsArray(receiver)) { |
| 338 return new ListIterator(receiver); | 338 return new ListIterator(receiver); |
| 339 } | 339 } |
| 340 return UNINTERCEPTED(receiver.iterator()); | 340 return UNINTERCEPTED(receiver.iterator()); |
| 341 } | 341 } |
| 342 | 342 |
| 343 class ListIterator<T> implements Iterator<T> { | 343 class ListIterator<T> implements Iterator<T> { |
| 344 int i; | 344 int i; |
| 345 List<T> list; | 345 List<T> list; |
| 346 ListIterator(List<T> this.list) : i = 0; | 346 ListIterator(List<T> this.list) : i = 0; |
| 347 bool hasNext() => i < JS("int", @"$0.length", list); | 347 bool hasNext() => i < JS('int', @'$0.length', list); |
| 348 T next() { | 348 T next() { |
| 349 if (!hasNext()) throw new NoMoreElementsException(); | 349 if (!hasNext()) throw new NoMoreElementsException(); |
| 350 var value = JS("Object", @"$0[$1]", list, i); | 350 var value = JS('Object', @'$0[$1]', list, i); |
| 351 i += 1; | 351 i += 1; |
| 352 return value; | 352 return value; |
| 353 } | 353 } |
| 354 } | 354 } |
| 355 | 355 |
| 356 builtin$charCodeAt$1(var receiver, int index) { | 356 builtin$charCodeAt$1(var receiver, int index) { |
| 357 checkNull(receiver); | 357 checkNull(receiver); |
| 358 if (receiver is String) { | 358 if (receiver is String) { |
| 359 if (index is !num) throw new IllegalArgumentException(index); | 359 if (index is !num) throw new IllegalArgumentException(index); |
| 360 if (index < 0) throw new IndexOutOfRangeException(index); | 360 if (index < 0) throw new IndexOutOfRangeException(index); |
| 361 if (index >= receiver.length) throw new IndexOutOfRangeException(index); | 361 if (index >= receiver.length) throw new IndexOutOfRangeException(index); |
| 362 return JS("string", @"$0.charCodeAt($1)", receiver, index); | 362 return JS('int', @'$0.charCodeAt($1)', receiver, index); |
| 363 } else { | 363 } else { |
| 364 return UNINTERCEPTED(receiver.charCodeAt(index)); | 364 return UNINTERCEPTED(receiver.charCodeAt(index)); |
| 365 } | 365 } |
| 366 } | 366 } |
| 367 | 367 |
| 368 builtin$isEmpty$0(receiver) { | 368 builtin$isEmpty$0(receiver) { |
| 369 checkNull(receiver); | 369 checkNull(receiver); |
| 370 if (receiver is String || isJsArray(receiver)) { | 370 if (receiver is String || isJsArray(receiver)) { |
| 371 return JS("bool", @"$0.length === 0", receiver); | 371 return JS('bool', @'$0.length === 0', receiver); |
| 372 } | 372 } |
| 373 return UNINTERCEPTED(receiver.isEmpty()); | 373 return UNINTERCEPTED(receiver.isEmpty()); |
| 374 } | 374 } |
| 375 | 375 |
| 376 class Primitives { | 376 class Primitives { |
| 377 static void printString(String string) { | 377 static void printString(String string) { |
| 378 var hasConsole = JS("bool", @"typeof console == 'object'"); | 378 var hasConsole = JS('bool', @'typeof console == "object"'); |
| 379 if (hasConsole) { | 379 if (hasConsole) { |
| 380 JS("void", @"console.log($0)", string); | 380 JS('void', @'console.log($0)', string); |
| 381 } else { | 381 } else { |
| 382 JS("void", @"write($0)", string); | 382 JS('void', @'write($0)', string); |
| 383 JS("void", @"write('\n')"); | 383 JS('void', @'write("\n")'); |
| 384 } | 384 } |
| 385 } | 385 } |
| 386 | 386 |
| 387 static String objectToString(Object object) { | 387 static String objectToString(Object object) { |
| 388 String name = JS('String', @'$0.constructor.name', object); | 388 String name = JS('String', @'$0.constructor.name', object); |
| 389 if (name === null) { | 389 if (name === null) { |
| 390 name = JS('String', @'$0.match(/^\s*function\s*(\S*)\s*\(/)[1]', | 390 name = JS('String', @'$0.match(/^\s*function\s*(\S*)\s*\(/)[1]', |
| 391 JS('String', @'$0.constructor.toString()', object)); | 391 JS('String', @'$0.constructor.toString()', object)); |
| 392 } | 392 } |
| 393 return "Instance of '$name'"; | 393 return "Instance of '$name'"; |
| 394 } | 394 } |
| 395 | 395 |
| 396 static List newList(length) { | 396 static List newList(length) { |
| 397 if (length === null) return JS("Object", @"new Array()"); | 397 if (length === null) return JS('Object', @'new Array()'); |
| 398 if ((length is !int) || (length < 0)) { | 398 if ((length is !int) || (length < 0)) { |
| 399 throw new IllegalArgumentException(length); | 399 throw new IllegalArgumentException(length); |
| 400 } | 400 } |
| 401 var result = JS("Object", @"new Array($0)", length); | 401 var result = JS('Object', @'new Array($0)', length); |
| 402 JS('void', @'$0.fixed$length = $1', result, true); | 402 JS('void', @'$0.fixed$length = $1', result, true); |
| 403 return result; | 403 return result; |
| 404 } | 404 } |
| 405 | 405 |
| 406 static num dateNow() => JS("num", @"Date.now()"); | 406 static num dateNow() => JS('num', @'Date.now()'); |
| 407 | 407 |
| 408 static String stringFromCharCodes(charCodes) { | 408 static String stringFromCharCodes(charCodes) { |
| 409 for (var i in charCodes) { | 409 for (var i in charCodes) { |
| 410 if (i is !int) throw new IllegalArgumentException(i); | 410 if (i is !int) throw new IllegalArgumentException(i); |
| 411 } | 411 } |
| 412 return JS('String', @'String.fromCharCode.apply($0, $1)', null, charCodes); | 412 return JS('String', @'String.fromCharCode.apply($0, $1)', null, charCodes); |
| 413 } | 413 } |
| 414 | 414 |
| 415 static valueFromDecomposedDate(years, month, day, hours, minutes, seconds, | 415 static valueFromDecomposedDate(years, month, day, hours, minutes, seconds, |
| 416 milliseconds, isUtc) { | 416 milliseconds, isUtc) { |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 584 while (iterator.hasNext()) { | 584 while (iterator.hasNext()) { |
| 585 receiver.add(iterator.next()); | 585 receiver.add(iterator.next()); |
| 586 } | 586 } |
| 587 } | 587 } |
| 588 | 588 |
| 589 builtin$addLast$1(receiver, value) { | 589 builtin$addLast$1(receiver, value) { |
| 590 checkNull(receiver); | 590 checkNull(receiver); |
| 591 if (!isJsArray(receiver)) return UNINTERCEPTED(receiver.addLast(value)); | 591 if (!isJsArray(receiver)) return UNINTERCEPTED(receiver.addLast(value)); |
| 592 | 592 |
| 593 checkGrowable(receiver, 'addLast'); | 593 checkGrowable(receiver, 'addLast'); |
| 594 JS("Object", @"$0.push($1)", receiver, value); | 594 JS('Object', @'$0.push($1)', receiver, value); |
| 595 } | 595 } |
| 596 | 596 |
| 597 builtin$clear$0(receiver) { | 597 builtin$clear$0(receiver) { |
| 598 checkNull(receiver); | 598 checkNull(receiver); |
| 599 if (!isJsArray(receiver)) return UNINTERCEPTED(receiver.clear()); | 599 if (!isJsArray(receiver)) return UNINTERCEPTED(receiver.clear()); |
| 600 receiver.length = 0; | 600 receiver.length = 0; |
| 601 } | 601 } |
| 602 | 602 |
| 603 builtin$forEach$1(receiver, f) { | 603 builtin$forEach$1(receiver, f) { |
| 604 checkNull(receiver); | 604 checkNull(receiver); |
| 605 if (!isJsArray(receiver)) return UNINTERCEPTED(receiver.forEach(f)); | 605 if (!isJsArray(receiver)) return UNINTERCEPTED(receiver.forEach(f)); |
| 606 | 606 |
| 607 | 607 |
| 608 var length = JS("num", @"$0.length", receiver); | 608 var length = JS('num', @'$0.length', receiver); |
| 609 if (length > 0 && f === null) throw new ObjectNotClosureException(); // Sigh. | 609 if (length > 0 && f === null) throw new ObjectNotClosureException(); // Sigh. |
| 610 for (var i = 0; i < length; i++) { | 610 for (var i = 0; i < length; i++) { |
| 611 f(JS("Object", @"$0[$1]", receiver, i)); | 611 f(JS('Object', @'$0[$1]', receiver, i)); |
| 612 } | 612 } |
| 613 } | 613 } |
| 614 | 614 |
| 615 builtin$getRange$2(receiver, start, length) { | 615 builtin$getRange$2(receiver, start, length) { |
| 616 checkNull(receiver); | 616 checkNull(receiver); |
| 617 if (!isJsArray(receiver)) { | 617 if (!isJsArray(receiver)) { |
| 618 return UNINTERCEPTED(receiver.getRange(start, length)); | 618 return UNINTERCEPTED(receiver.getRange(start, length)); |
| 619 } | 619 } |
| 620 if (0 === length) return []; | 620 if (0 === length) return []; |
| 621 checkNull(start); // TODO(ahe): This is not specified but co19 tests it. | 621 checkNull(start); // TODO(ahe): This is not specified but co19 tests it. |
| 622 checkNull(length); // TODO(ahe): This is not specified but co19 tests it. | 622 checkNull(length); // TODO(ahe): This is not specified but co19 tests it. |
| 623 if (start is !int) throw new IllegalArgumentException(start); | 623 if (start is !int) throw new IllegalArgumentException(start); |
| 624 if (length is !int) throw new IllegalArgumentException(length); | 624 if (length is !int) throw new IllegalArgumentException(length); |
| 625 if (start < 0) throw new IndexOutOfRangeException(start); | 625 if (start < 0) throw new IndexOutOfRangeException(start); |
| 626 if (length < 0) throw new IllegalArgumentException(length); | 626 if (length < 0) throw new IllegalArgumentException(length); |
| 627 var end = start + length; | 627 var end = start + length; |
| 628 if (end > receiver.length) { | 628 if (end > receiver.length) { |
| 629 throw new IndexOutOfRangeException(length); | 629 throw new IndexOutOfRangeException(length); |
| 630 } | 630 } |
| 631 if (length < 0) throw new IllegalArgumentException(length); | 631 if (length < 0) throw new IllegalArgumentException(length); |
| 632 return JS("Object", @"$0.slice($1, $2)", receiver, start, end); | 632 return JS('Object', @'$0.slice($1, $2)', receiver, start, end); |
| 633 } | 633 } |
| 634 | 634 |
| 635 builtin$indexOf$1(receiver, element) { | 635 builtin$indexOf$1(receiver, element) { |
| 636 checkNull(receiver); | 636 checkNull(receiver); |
| 637 if (isJsArray(receiver) || receiver is String) { | 637 if (isJsArray(receiver) || receiver is String) { |
| 638 return builtin$indexOf$2(receiver, element, 0); | 638 return builtin$indexOf$2(receiver, element, 0); |
| 639 } | 639 } |
| 640 return UNINTERCEPTED(receiver.indexOf(element)); | 640 return UNINTERCEPTED(receiver.indexOf(element)); |
| 641 } | 641 } |
| 642 | 642 |
| 643 builtin$indexOf$2(receiver, element, start) { | 643 builtin$indexOf$2(receiver, element, start) { |
| 644 checkNull(receiver); | 644 checkNull(receiver); |
| 645 if (isJsArray(receiver)) { | 645 if (isJsArray(receiver)) { |
| 646 if (start is !int) throw new IllegalArgumentException(start); | 646 if (start is !int) throw new IllegalArgumentException(start); |
| 647 var length = JS("num", @"$0.length", receiver); | 647 var length = JS('num', @'$0.length', receiver); |
| 648 return Arrays.indexOf(receiver, element, start, length); | 648 return Arrays.indexOf(receiver, element, start, length); |
| 649 } else if (receiver is String) { | 649 } else if (receiver is String) { |
| 650 checkNull(element); | 650 checkNull(element); |
| 651 if (start is !int) throw new IllegalArgumentException(start); | 651 if (start is !int) throw new IllegalArgumentException(start); |
| 652 if (element is !String) throw new IllegalArgumentException(element); | 652 if (element is !String) throw new IllegalArgumentException(element); |
| 653 if (start < 0) return -1; // TODO(ahe): Is this correct? | 653 if (start < 0) return -1; // TODO(ahe): Is this correct? |
| 654 return JS('int', @'$0.indexOf($1, $2)', receiver, element, start); | 654 return JS('int', @'$0.indexOf($1, $2)', receiver, element, start); |
| 655 } | 655 } |
| 656 return UNINTERCEPTED(receiver.indexOf(element, start)); | 656 return UNINTERCEPTED(receiver.indexOf(element, start)); |
| 657 } | 657 } |
| (...skipping 17 matching lines...) Expand all Loading... |
| 675 listInsertRange(receiver, start, length, initialValue) { | 675 listInsertRange(receiver, start, length, initialValue) { |
| 676 if (length === 0) { | 676 if (length === 0) { |
| 677 return; | 677 return; |
| 678 } | 678 } |
| 679 checkNull(start); // TODO(ahe): This is not specified but co19 tests it. | 679 checkNull(start); // TODO(ahe): This is not specified but co19 tests it. |
| 680 checkNull(length); // TODO(ahe): This is not specified but co19 tests it. | 680 checkNull(length); // TODO(ahe): This is not specified but co19 tests it. |
| 681 if (length is !int) throw new IllegalArgumentException(length); | 681 if (length is !int) throw new IllegalArgumentException(length); |
| 682 if (length < 0) throw new IllegalArgumentException(length); | 682 if (length < 0) throw new IllegalArgumentException(length); |
| 683 if (start is !int) throw new IllegalArgumentException(start); | 683 if (start is !int) throw new IllegalArgumentException(start); |
| 684 | 684 |
| 685 var receiverLength = JS("num", @"$0.length", receiver); | 685 var receiverLength = JS('num', @'$0.length', receiver); |
| 686 if (start < 0 || start > receiverLength) { | 686 if (start < 0 || start > receiverLength) { |
| 687 throw new IndexOutOfRangeException(start); | 687 throw new IndexOutOfRangeException(start); |
| 688 } | 688 } |
| 689 receiver.length = receiverLength + length; | 689 receiver.length = receiverLength + length; |
| 690 Arrays.copy(receiver, | 690 Arrays.copy(receiver, |
| 691 start, | 691 start, |
| 692 receiver, | 692 receiver, |
| 693 start + length, | 693 start + length, |
| 694 receiverLength - start); | 694 receiverLength - start); |
| 695 if (initialValue !== null) { | 695 if (initialValue !== null) { |
| 696 for (int i = start; i < start + length; i++) { | 696 for (int i = start; i < start + length; i++) { |
| 697 receiver[i] = initialValue; | 697 receiver[i] = initialValue; |
| 698 } | 698 } |
| 699 } | 699 } |
| 700 receiver.length = receiverLength + length; | 700 receiver.length = receiverLength + length; |
| 701 } | 701 } |
| 702 | 702 |
| 703 builtin$last$0(receiver) { | 703 builtin$last$0(receiver) { |
| 704 checkNull(receiver); | 704 checkNull(receiver); |
| 705 if (!isJsArray(receiver)) { | 705 if (!isJsArray(receiver)) { |
| 706 return UNINTERCEPTED(receiver.last()); | 706 return UNINTERCEPTED(receiver.last()); |
| 707 } | 707 } |
| 708 return receiver[receiver.length - 1]; | 708 return receiver[receiver.length - 1]; |
| 709 } | 709 } |
| 710 | 710 |
| 711 builtin$lastIndexOf$1(receiver, element) { | 711 builtin$lastIndexOf$1(receiver, element) { |
| 712 checkNull(receiver); | 712 checkNull(receiver); |
| 713 if (isJsArray(receiver)) { | 713 if (isJsArray(receiver)) { |
| 714 var start = JS("num", @"$0.length", receiver); | 714 var start = JS('num', @'$0.length', receiver); |
| 715 return Arrays.lastIndexOf(receiver, element, start); | 715 return Arrays.lastIndexOf(receiver, element, start); |
| 716 } else if (receiver is String) { | 716 } else if (receiver is String) { |
| 717 checkNull(element); | 717 checkNull(element); |
| 718 if (element is !String) throw new IllegalArgumentException(element); | 718 if (element is !String) throw new IllegalArgumentException(element); |
| 719 return JS('int', @'$0.lastIndexOf($1)', receiver, element); | 719 return JS('int', @'$0.lastIndexOf($1)', receiver, element); |
| 720 } | 720 } |
| 721 return UNINTERCEPTED(receiver.lastIndexOf(element)); | 721 return UNINTERCEPTED(receiver.lastIndexOf(element)); |
| 722 } | 722 } |
| 723 | 723 |
| 724 builtin$lastIndexOf$2(receiver, element, start) { | 724 builtin$lastIndexOf$2(receiver, element, start) { |
| (...skipping 23 matching lines...) Expand all Loading... |
| 748 } | 748 } |
| 749 checkGrowable(receiver, 'removeRange'); | 749 checkGrowable(receiver, 'removeRange'); |
| 750 if (length == 0) { | 750 if (length == 0) { |
| 751 return; | 751 return; |
| 752 } | 752 } |
| 753 checkNull(start); // TODO(ahe): This is not specified but co19 tests it. | 753 checkNull(start); // TODO(ahe): This is not specified but co19 tests it. |
| 754 checkNull(length); // TODO(ahe): This is not specified but co19 tests it. | 754 checkNull(length); // TODO(ahe): This is not specified but co19 tests it. |
| 755 if (start is !int) throw new IllegalArgumentException(start); | 755 if (start is !int) throw new IllegalArgumentException(start); |
| 756 if (length is !int) throw new IllegalArgumentException(length); | 756 if (length is !int) throw new IllegalArgumentException(length); |
| 757 if (length < 0) throw new IllegalArgumentException(length); | 757 if (length < 0) throw new IllegalArgumentException(length); |
| 758 var receiverLength = JS("num", @"$0.length", receiver); | 758 var receiverLength = JS('num', @'$0.length', receiver); |
| 759 if (start < 0 || start >= receiverLength) { | 759 if (start < 0 || start >= receiverLength) { |
| 760 throw new IndexOutOfRangeException(start); | 760 throw new IndexOutOfRangeException(start); |
| 761 } | 761 } |
| 762 if (start + length > receiverLength) { | 762 if (start + length > receiverLength) { |
| 763 throw new IndexOutOfRangeException(start + length); | 763 throw new IndexOutOfRangeException(start + length); |
| 764 } | 764 } |
| 765 Arrays.copy(receiver, | 765 Arrays.copy(receiver, |
| 766 start + length, | 766 start + length, |
| 767 receiver, | 767 receiver, |
| 768 start, | 768 start, |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 850 if (receiver is num) { | 850 if (receiver is num) { |
| 851 return (receiver === 0) ? (1 / receiver) < 0 : receiver < 0; | 851 return (receiver === 0) ? (1 / receiver) < 0 : receiver < 0; |
| 852 } else { | 852 } else { |
| 853 return UNINTERCEPTED(receiver.isNegative()); | 853 return UNINTERCEPTED(receiver.isNegative()); |
| 854 } | 854 } |
| 855 } | 855 } |
| 856 | 856 |
| 857 builtin$isNaN$0(receiver) { | 857 builtin$isNaN$0(receiver) { |
| 858 checkNull(receiver); | 858 checkNull(receiver); |
| 859 if (receiver is num) { | 859 if (receiver is num) { |
| 860 return JS("bool", @"isNaN($0)", receiver); | 860 return JS('bool', @'isNaN($0)', receiver); |
| 861 } else { | 861 } else { |
| 862 return UNINTERCEPTED(receiver.isNegative()); | 862 return UNINTERCEPTED(receiver.isNegative()); |
| 863 } | 863 } |
| 864 } | 864 } |
| 865 | 865 |
| 866 builtin$remainder$1(a, b) { | 866 builtin$remainder$1(a, b) { |
| 867 checkNull(a); | 867 checkNull(a); |
| 868 if (checkNumbers(a, b, "num.remainder expects a number as second operand.")) { | 868 if (checkNumbers(a, b, 'num.remainder expects a number as second operand.')) { |
| 869 if (b === 0) throw new IntegerDivisionByZeroException(); | 869 if (b === 0) throw new IntegerDivisionByZeroException(); |
| 870 return JS("num", @"$0 % $1", a, b); | 870 return JS('num', @'$0 % $1', a, b); |
| 871 } else { | 871 } else { |
| 872 return UNINTERCEPTED(a.remainder(b)); | 872 return UNINTERCEPTED(a.remainder(b)); |
| 873 } | 873 } |
| 874 } | 874 } |
| 875 | 875 |
| 876 builtin$abs$0(receiver) { | 876 builtin$abs$0(receiver) { |
| 877 checkNull(receiver); | 877 checkNull(receiver); |
| 878 if (receiver is !num) return UNINTERCEPTED(receiver.abs()); | 878 if (receiver is !num) return UNINTERCEPTED(receiver.abs()); |
| 879 | 879 |
| 880 return JS("num", @"Math.abs($0)", receiver); | 880 return JS('num', @'Math.abs($0)', receiver); |
| 881 } | 881 } |
| 882 | 882 |
| 883 builtin$toInt$0(receiver) { | 883 builtin$toInt$0(receiver) { |
| 884 checkNull(receiver); | 884 checkNull(receiver); |
| 885 if (receiver is !num) return UNINTERCEPTED(receiver.toInt()); | 885 if (receiver is !num) return UNINTERCEPTED(receiver.toInt()); |
| 886 | 886 |
| 887 if (receiver.isNaN()) throw new BadNumberFormatException("NaN"); | 887 if (receiver.isNaN()) throw new BadNumberFormatException('NaN'); |
| 888 | 888 |
| 889 if (receiver.isInfinite()) throw new BadNumberFormatException("Infinity"); | 889 if (receiver.isInfinite()) throw new BadNumberFormatException('Infinity'); |
| 890 | 890 |
| 891 var truncated = receiver.truncate(); | 891 var truncated = receiver.truncate(); |
| 892 return JS("bool", @"$0 == -0.0", truncated) ? 0 : truncated; | 892 return JS('bool', @'$0 == -0.0', truncated) ? 0 : truncated; |
| 893 } | 893 } |
| 894 | 894 |
| 895 builtin$ceil$0(receiver) { | 895 builtin$ceil$0(receiver) { |
| 896 checkNull(receiver); | 896 checkNull(receiver); |
| 897 if (receiver is !num) return UNINTERCEPTED(receiver.ceil()); | 897 if (receiver is !num) return UNINTERCEPTED(receiver.ceil()); |
| 898 | 898 |
| 899 return JS("num", @"Math.ceil($0)", receiver); | 899 return JS('num', @'Math.ceil($0)', receiver); |
| 900 } | 900 } |
| 901 | 901 |
| 902 builtin$floor$0(receiver) { | 902 builtin$floor$0(receiver) { |
| 903 checkNull(receiver); | 903 checkNull(receiver); |
| 904 if (receiver is !num) return UNINTERCEPTED(receiver.floor()); | 904 if (receiver is !num) return UNINTERCEPTED(receiver.floor()); |
| 905 | 905 |
| 906 return JS("num", @"Math.floor($0)", receiver); | 906 return JS('num', @'Math.floor($0)', receiver); |
| 907 } | 907 } |
| 908 | 908 |
| 909 builtin$isInfinite$0(receiver) { | 909 builtin$isInfinite$0(receiver) { |
| 910 checkNull(receiver); | 910 checkNull(receiver); |
| 911 if (receiver is !num) return UNINTERCEPTED(receiver.isInfinite()); | 911 if (receiver is !num) return UNINTERCEPTED(receiver.isInfinite()); |
| 912 | 912 |
| 913 return JS("bool", @"$0 == Infinity", receiver) | 913 return JS('bool', @'$0 == Infinity', receiver) |
| 914 || JS("bool", @"$0 == -Infinity", receiver); | 914 || JS('bool', @'$0 == -Infinity', receiver); |
| 915 } | 915 } |
| 916 | 916 |
| 917 builtin$negate$0(receiver) { | 917 builtin$negate$0(receiver) { |
| 918 checkNull(receiver); | 918 checkNull(receiver); |
| 919 if (receiver is !num) return UNINTERCEPTED(receiver.negate()); | 919 if (receiver is !num) return UNINTERCEPTED(receiver.negate()); |
| 920 | 920 |
| 921 return JS("num", @"-$0", receiver); | 921 return JS('num', @'-$0', receiver); |
| 922 } | 922 } |
| 923 | 923 |
| 924 builtin$round$0(receiver) { | 924 builtin$round$0(receiver) { |
| 925 checkNull(receiver); | 925 checkNull(receiver); |
| 926 if (receiver is !num) return UNINTERCEPTED(receiver.round()); | 926 if (receiver is !num) return UNINTERCEPTED(receiver.round()); |
| 927 | 927 |
| 928 return JS("num", @"Math.round($0)", receiver); | 928 return JS('num', @'Math.round($0)', receiver); |
| 929 } | 929 } |
| 930 | 930 |
| 931 builtin$toDouble$0(receiver) { | 931 builtin$toDouble$0(receiver) { |
| 932 checkNull(receiver); | 932 checkNull(receiver); |
| 933 if (receiver is !num) return UNINTERCEPTED(receiver.toDouble()); | 933 if (receiver is !num) return UNINTERCEPTED(receiver.toDouble()); |
| 934 | 934 |
| 935 // TODO(ahe): Just return receiver? | 935 // TODO(ahe): Just return receiver? |
| 936 return JS("double", @"$0 + 0", receiver); | 936 return JS('double', @'$0 + 0', receiver); |
| 937 } | 937 } |
| 938 | 938 |
| 939 builtin$truncate$0(receiver) { | 939 builtin$truncate$0(receiver) { |
| 940 checkNull(receiver); | 940 checkNull(receiver); |
| 941 if (receiver is !num) return UNINTERCEPTED(receiver.truncate()); | 941 if (receiver is !num) return UNINTERCEPTED(receiver.truncate()); |
| 942 | 942 |
| 943 return receiver < 0 ? receiver.ceil() : receiver.floor(); | 943 return receiver < 0 ? receiver.ceil() : receiver.floor(); |
| 944 } | 944 } |
| 945 | 945 |
| 946 builtin$toStringAsFixed$1(receiver, fractionDigits) { | 946 builtin$toStringAsFixed$1(receiver, fractionDigits) { |
| 947 checkNull(receiver); | 947 checkNull(receiver); |
| 948 if (receiver is !num) { | 948 if (receiver is !num) { |
| 949 return UNINTERCEPTED(receiver.toStringAsFixed(fractionDigits)); | 949 return UNINTERCEPTED(receiver.toStringAsFixed(fractionDigits)); |
| 950 } | 950 } |
| 951 checkNum(fractionDigits); | 951 checkNum(fractionDigits); |
| 952 | 952 |
| 953 return JS("String", @"$0.toFixed($1)", receiver, fractionDigits); | 953 return JS('String', @'$0.toFixed($1)', receiver, fractionDigits); |
| 954 } | 954 } |
| 955 | 955 |
| 956 builtin$toStringAsExponential$1(receiver, fractionDigits) { | 956 builtin$toStringAsExponential$1(receiver, fractionDigits) { |
| 957 checkNull(receiver); | 957 checkNull(receiver); |
| 958 if (receiver is !num) { | 958 if (receiver is !num) { |
| 959 return UNINTERCEPTED(receiver.toStringAsExponential(fractionDigits)); | 959 return UNINTERCEPTED(receiver.toStringAsExponential(fractionDigits)); |
| 960 } | 960 } |
| 961 checkNum(fractionDigits); | 961 checkNum(fractionDigits); |
| 962 | 962 |
| 963 return JS("String", @"$0.toExponential($1)", receiver, fractionDigits); | 963 return JS('String', @'$0.toExponential($1)', receiver, fractionDigits); |
| 964 } | 964 } |
| 965 | 965 |
| 966 builtin$toStringAsPrecision$1(receiver, fractionDigits) { | 966 builtin$toStringAsPrecision$1(receiver, fractionDigits) { |
| 967 checkNull(receiver); | 967 checkNull(receiver); |
| 968 if (receiver is !num) { | 968 if (receiver is !num) { |
| 969 return UNINTERCEPTED(receiver.toStringAsPrecision(fractionDigits)); | 969 return UNINTERCEPTED(receiver.toStringAsPrecision(fractionDigits)); |
| 970 } | 970 } |
| 971 checkNum(fractionDigits); | 971 checkNum(fractionDigits); |
| 972 | 972 |
| 973 return JS("String", @"$0.toPrecision($1)", receiver, fractionDigits); | 973 return JS('String', @'$0.toPrecision($1)', receiver, fractionDigits); |
| 974 } | 974 } |
| 975 | 975 |
| 976 builtin$toRadixString$1(receiver, radix) { | 976 builtin$toRadixString$1(receiver, radix) { |
| 977 checkNull(receiver); | 977 checkNull(receiver); |
| 978 if (receiver is !num) { | 978 if (receiver is !num) { |
| 979 return UNINTERCEPTED(receiver.toRadixString(radix)); | 979 return UNINTERCEPTED(receiver.toRadixString(radix)); |
| 980 } | 980 } |
| 981 checkNum(radix); | 981 checkNum(radix); |
| 982 | 982 |
| 983 return JS("String", @"$0.toString($1)", receiver, radix); | 983 return JS('String', @'$0.toString($1)', receiver, radix); |
| 984 } | 984 } |
| 985 | 985 |
| 986 builtin$allMatches$1(receiver, str) { | 986 builtin$allMatches$1(receiver, str) { |
| 987 checkNull(receiver); | 987 checkNull(receiver); |
| 988 if (receiver is !String) return UNINTERCEPTED(receiver.allMatches(str)); | 988 if (receiver is !String) return UNINTERCEPTED(receiver.allMatches(str)); |
| 989 checkString(str); | 989 checkString(str); |
| 990 return allMatchesInStringUnchecked(receiver, str); | 990 return allMatchesInStringUnchecked(receiver, str); |
| 991 } | 991 } |
| 992 | 992 |
| 993 builtin$concat$1(receiver, other) { | 993 builtin$concat$1(receiver, other) { |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1121 } | 1121 } |
| 1122 | 1122 |
| 1123 class MathNatives { | 1123 class MathNatives { |
| 1124 static int parseInt(str) { | 1124 static int parseInt(str) { |
| 1125 checkNull(str); | 1125 checkNull(str); |
| 1126 if (str is !String) throw new IllegalArgumentException(str); | 1126 if (str is !String) throw new IllegalArgumentException(str); |
| 1127 var trimmed = str.trim(); | 1127 var trimmed = str.trim(); |
| 1128 if (!JS('bool', @'/^(0[xX])?[+-]?[0-9]+$/.test($0)', trimmed)) { | 1128 if (!JS('bool', @'/^(0[xX])?[+-]?[0-9]+$/.test($0)', trimmed)) { |
| 1129 throw new BadNumberFormatException(str); | 1129 throw new BadNumberFormatException(str); |
| 1130 } | 1130 } |
| 1131 var ret = JS("num", @"parseInt($0, 10)", str); | 1131 var ret = JS('num', @'parseInt($0, 10)', str); |
| 1132 if (ret.isNaN()) throw new BadNumberFormatException(str); | 1132 if (ret.isNaN()) throw new BadNumberFormatException(str); |
| 1133 return ret; | 1133 return ret; |
| 1134 } | 1134 } |
| 1135 | 1135 |
| 1136 static double parseDouble(String str) { | 1136 static double parseDouble(String str) { |
| 1137 checkNull(str); | 1137 checkNull(str); |
| 1138 if (str is !String) throw new IllegalArgumentException(); | 1138 if (str is !String) throw new IllegalArgumentException(); |
| 1139 var ret = JS("num", @"parseFloat($0)", str); | 1139 var ret = JS('num', @'parseFloat($0)', str); |
| 1140 if (ret.isNaN() && str != 'NaN') throw new BadNumberFormatException(str); | 1140 if (ret.isNaN() && str != 'NaN') throw new BadNumberFormatException(str); |
| 1141 return ret; | 1141 return ret; |
| 1142 } | 1142 } |
| 1143 | 1143 |
| 1144 static double sqrt(num value) | 1144 static double sqrt(num value) |
| 1145 => JS("double", @"Math.sqrt($0)", checkNum(value)); | 1145 => JS('double', @'Math.sqrt($0)', checkNum(value)); |
| 1146 | 1146 |
| 1147 static double sin(num value) | 1147 static double sin(num value) |
| 1148 => JS("double", @"Math.sin($0)", checkNum(value)); | 1148 => JS('double', @'Math.sin($0)', checkNum(value)); |
| 1149 | 1149 |
| 1150 static double cos(num value) | 1150 static double cos(num value) |
| 1151 => JS("double", @"Math.cos($0)", checkNum(value)); | 1151 => JS('double', @'Math.cos($0)', checkNum(value)); |
| 1152 | 1152 |
| 1153 static double tan(num value) | 1153 static double tan(num value) |
| 1154 => JS("double", @"Math.tan($0)", checkNum(value)); | 1154 => JS('double', @'Math.tan($0)', checkNum(value)); |
| 1155 | 1155 |
| 1156 static double acos(num value) | 1156 static double acos(num value) |
| 1157 => JS("double", @"Math.acos($0)", checkNum(value)); | 1157 => JS('double', @'Math.acos($0)', checkNum(value)); |
| 1158 | 1158 |
| 1159 static double asin(num value) | 1159 static double asin(num value) |
| 1160 => JS("double", @"Math.asin($0)", checkNum(value)); | 1160 => JS('double', @'Math.asin($0)', checkNum(value)); |
| 1161 | 1161 |
| 1162 static double atan(num value) | 1162 static double atan(num value) |
| 1163 => JS("double", @"Math.atan($0)", checkNum(value)); | 1163 => JS('double', @'Math.atan($0)', checkNum(value)); |
| 1164 | 1164 |
| 1165 static double atan2(num a, num b) | 1165 static double atan2(num a, num b) |
| 1166 => JS("double", @"Math.atan2($0, $1)", checkNum(a), checkNum(b)); | 1166 => JS('double', @'Math.atan2($0, $1)', checkNum(a), checkNum(b)); |
| 1167 | 1167 |
| 1168 static double exp(num value) | 1168 static double exp(num value) |
| 1169 => JS("double", @"Math.exp($0)", checkNum(value)); | 1169 => JS('double', @'Math.exp($0)', checkNum(value)); |
| 1170 | 1170 |
| 1171 static double log(num value) | 1171 static double log(num value) |
| 1172 => JS("double", @"Math.log($0)", checkNum(value)); | 1172 => JS('double', @'Math.log($0)', checkNum(value)); |
| 1173 | 1173 |
| 1174 static num pow(num value, num exponent) { | 1174 static num pow(num value, num exponent) { |
| 1175 checkNum(value); | 1175 checkNum(value); |
| 1176 checkNum(exponent); | 1176 checkNum(exponent); |
| 1177 return JS("num", @"Math.pow($0, $1)", value, exponent); | 1177 return JS('num', @'Math.pow($0, $1)', value, exponent); |
| 1178 } | 1178 } |
| 1179 | 1179 |
| 1180 static double random() => JS("double", @"Math.random()"); | 1180 static double random() => JS('double', @'Math.random()'); |
| 1181 } | 1181 } |
| 1182 | 1182 |
| 1183 /** |
| 1184 * This is the [Jenkins hash function][1] but using masking to keep |
| 1185 * values in SMI range. This was inspired by jmesserly's work in |
| 1186 * Frog. |
| 1187 * |
| 1188 * [1]: http://en.wikipedia.org/wiki/Jenkins_hash_function |
| 1189 */ |
| 1183 builtin$hashCode$0(receiver) { | 1190 builtin$hashCode$0(receiver) { |
| 1184 if (receiver is num) return receiver & 0x1FFFFFFF; | 1191 // TODO(ahe): This method shouldn't have to use JS. Update when our |
| 1185 if (receiver is String) { | 1192 // optimizations are smarter. |
| 1186 throw 'String.hashCode is not implemented'; | 1193 if (receiver is num) return JS('int', @'$0 & 0x1FFFFFFF', receiver); |
| 1194 if (receiver is !String) return UNINTERCEPTED(receiver.hashCode()); |
| 1195 int hash = 0; |
| 1196 int length = JS('int', @'$0.length', receiver); |
| 1197 for (int i = 0; i < length; i++) { |
| 1198 hash = 0x1fffffff & (hash + JS('int', @'$0.charCodeAt($1)', receiver, i)); |
| 1199 hash = 0x1fffffff & (hash + JS('int', @'$0 << $1', 0x0007ffff & hash, 10)); |
| 1200 hash ^= hash >> 6; |
| 1187 } | 1201 } |
| 1188 if (isJsArray(receiver)) { | 1202 hash = 0x1fffffff & (hash + JS('int', @'$0 << $1', 0x03ffffff & hash, 3)); |
| 1189 throw 'List.hashCode is not implemented'; | 1203 hash ^= hash >> 11; |
| 1190 } | 1204 return 0x1fffffff & (hash + JS('int', @'$0 << $1', 0x00003fff & hash, 15)); |
| 1191 return UNINTERCEPTED(receiver.hashCode()); | |
| 1192 } | 1205 } |
| 1193 | 1206 |
| 1194 // TODO(ahe): Dynamic may be overridden. | 1207 // TODO(ahe): Dynamic may be overridden. |
| 1195 builtin$get$dynamic(receiver) => receiver; | 1208 builtin$get$dynamic(receiver) => receiver; |
| 1196 | 1209 |
| 1197 /** | 1210 /** |
| 1198 * Called by generated code to capture the stacktrace before throwing | 1211 * Called by generated code to capture the stacktrace before throwing |
| 1199 * an exception. | 1212 * an exception. |
| 1200 */ | 1213 */ |
| 1201 captureStackTrace(ex) { | 1214 captureStackTrace(ex) { |
| 1202 var jsError = JS('Object', @'new Error()'); | 1215 var jsError = JS('Object', @'new Error()'); |
| 1203 JS('void', @'$0.dartException = $1', jsError, ex); | 1216 JS('void', @'$0.dartException = $1', jsError, ex); |
| 1204 JS('void', @'''$0.toString = $1''', jsError, toStringWrapper); | 1217 JS('void', @'''$0.toString = $1''', jsError, toStringWrapper); |
| 1205 return jsError; | 1218 return jsError; |
| 1206 } | 1219 } |
| 1207 | 1220 |
| 1208 /** | 1221 /** |
| 1209 * This method is installed as JavaScript toString method on exception | 1222 * This method is installed as JavaScript toString method on exception |
| 1210 * objects in [captureStackTrace]. So JavaScript 'this' binds to an | 1223 * objects in [captureStackTrace]. So JavaScript 'this' binds to an |
| 1211 * instance of JavaScript Error to which we have added a property | 1224 * instance of JavaScript Error to which we have added a property |
| 1212 * "dartException" which holds a Dart object. | 1225 * 'dartException' which holds a Dart object. |
| 1213 */ | 1226 */ |
| 1214 toStringWrapper() => JS('Object', @'this.dartException').toString(); | 1227 toStringWrapper() => JS('Object', @'this.dartException').toString(); |
| 1215 | 1228 |
| 1216 builtin$charCodes$0(receiver) { | 1229 builtin$charCodes$0(receiver) { |
| 1217 checkNull(receiver); | 1230 checkNull(receiver); |
| 1218 if (receiver is !String) return UNINTERCEPTED(receiver.charCodes()); | 1231 if (receiver is !String) return UNINTERCEPTED(receiver.charCodes()); |
| 1219 int len = receiver.length; | 1232 int len = receiver.length; |
| 1220 List<int> result = new List<int>(len); | 1233 List<int> result = new List<int>(len); |
| 1221 for (int i = 0; i < len; i++) { | 1234 for (int i = 0; i < len; i++) { |
| 1222 result[i] = receiver.charCodeAt(i); | 1235 result[i] = receiver.charCodeAt(i); |
| 1223 } | 1236 } |
| 1224 return result; | 1237 return result; |
| 1225 } | 1238 } |
| 1226 | 1239 |
| 1227 makeLiteralListConst(list) { | 1240 makeLiteralListConst(list) { |
| 1228 JS('bool', @'$0.immutable$list = $1', list, true); | 1241 JS('bool', @'$0.immutable$list = $1', list, true); |
| 1229 JS('bool', @'$0.fixed$length = $1', list, true); | 1242 JS('bool', @'$0.fixed$length = $1', list, true); |
| 1230 return list; | 1243 return list; |
| 1231 } | 1244 } |
| 1232 | 1245 |
| 1233 /** | 1246 /** |
| 1234 * Called from catch blocks in generated code to extract the Dart | 1247 * Called from catch blocks in generated code to extract the Dart |
| 1235 * exception from the thrown value. The thrown value may have been | 1248 * exception from the thrown value. The thrown value may have been |
| 1236 * created by [captureStackTrace] or it may be a "native" JS | 1249 * created by [captureStackTrace] or it may be a 'native' JS |
| 1237 * exception. | 1250 * exception. |
| 1238 * | 1251 * |
| 1239 * Some native exceptions are mapped to new Dart instances, others are | 1252 * Some native exceptions are mapped to new Dart instances, others are |
| 1240 * returned unmodified. | 1253 * returned unmodified. |
| 1241 */ | 1254 */ |
| 1242 unwrapException(ex) { | 1255 unwrapException(ex) { |
| 1243 if (JS('bool', @'"dartException" in $0', ex)) { | 1256 if (JS('bool', @'"dartException" in $0', ex)) { |
| 1244 return JS('Object', @'$0.dartException', ex); | 1257 return JS('Object', @'$0.dartException', ex); |
| 1245 } else if (JS('bool', @'$0 instanceof TypeError', ex)) { | 1258 } else if (JS('bool', @'$0 instanceof TypeError', ex)) { |
| 1246 var type = JS('String', @'$0.type', ex); | 1259 var type = JS('String', @'$0.type', ex); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1263 } | 1276 } |
| 1264 } | 1277 } |
| 1265 } else if (JS('bool', @'$0 instanceof RangeError', ex)) { | 1278 } else if (JS('bool', @'$0 instanceof RangeError', ex)) { |
| 1266 var message = JS('String', @'$0.message', ex); | 1279 var message = JS('String', @'$0.message', ex); |
| 1267 if (message.contains('call stack')) { | 1280 if (message.contains('call stack')) { |
| 1268 return new StackOverflowException(); | 1281 return new StackOverflowException(); |
| 1269 } | 1282 } |
| 1270 } | 1283 } |
| 1271 return ex; | 1284 return ex; |
| 1272 } | 1285 } |
| OLD | NEW |