| 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'); |
| 8 |
| 7 /** | 9 /** |
| 8 * Returns true if both arguments are numbers. | 10 * Returns true if both arguments are numbers. |
| 9 * If only the first argument is a number, throws the given message as | 11 * If only the first argument is a number, throws the given message as |
| 10 * exception. | 12 * exception. |
| 11 */ | 13 */ |
| 12 bool checkNumbers(var a, var b, var message) { | 14 bool checkNumbers(var a, var b, var message) { |
| 13 if (a is num) { | 15 if (a is num) { |
| 14 if (b is num) { | 16 if (b is num) { |
| 15 return true; | 17 return true; |
| 16 } else { | 18 } else { |
| 17 throw message; | 19 throw new IllegalArgumentException(message); |
| 18 } | 20 } |
| 19 } | 21 } |
| 20 return false; | 22 return false; |
| 21 } | 23 } |
| 22 | 24 |
| 23 | 25 |
| 24 bool isJSArray(var value) { | 26 bool isJSArray(var value) { |
| 25 return JS("bool", @"$0.constructor === Array", value); | 27 return JS("bool", @"$0.constructor === Array", value); |
| 26 } | 28 } |
| 27 | 29 |
| (...skipping 29 matching lines...) Expand all Loading... |
| 57 | 59 |
| 58 sub(var a, var b) { | 60 sub(var a, var b) { |
| 59 if (checkNumbers(a, b, "num- expects a number as second operand.")) { | 61 if (checkNumbers(a, b, "num- expects a number as second operand.")) { |
| 60 return JS("num", @"$0 - $1", a, b); | 62 return JS("num", @"$0 - $1", a, b); |
| 61 } | 63 } |
| 62 return UNINTERCEPTED(a - b); | 64 return UNINTERCEPTED(a - b); |
| 63 } | 65 } |
| 64 | 66 |
| 65 mod(var a, var b) { | 67 mod(var a, var b) { |
| 66 if (checkNumbers(a, b, "int% expects an int as second operand.")) { | 68 if (checkNumbers(a, b, "int% expects an int as second operand.")) { |
| 69 if (b === 0) throw new IntegerDivisionByZeroException(); |
| 67 // Euclidean Modulo. | 70 // Euclidean Modulo. |
| 68 int result = JS("num", @"$0 % $1", a, b); | 71 int result = JS("num", @"$0 % $1", a, b); |
| 69 if (result == 0) return 0; // Make sure we don't return -0.0. | 72 if (result == 0) return 0; // Make sure we don't return -0.0. |
| 70 if (result > 0) return result; | 73 if (result > 0) return result; |
| 71 if (b < 0) { | 74 if (b < 0) { |
| 72 return result - b; | 75 return result - b; |
| 73 } else { | 76 } else { |
| 74 return result + b; | 77 return result + b; |
| 75 } | 78 } |
| 76 } | 79 } |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 143 le(var a, var b) { | 146 le(var a, var b) { |
| 144 if (checkNumbers(a, b, "num<= expects a number as second operand.")) { | 147 if (checkNumbers(a, b, "num<= expects a number as second operand.")) { |
| 145 return JS("bool", @"$0 <= $1", a, b); | 148 return JS("bool", @"$0 <= $1", a, b); |
| 146 } | 149 } |
| 147 return UNINTERCEPTED(a <= b); | 150 return UNINTERCEPTED(a <= b); |
| 148 } | 151 } |
| 149 | 152 |
| 150 shl(var a, var b) { | 153 shl(var a, var b) { |
| 151 // TODO(floitsch): inputs must be integers. | 154 // TODO(floitsch): inputs must be integers. |
| 152 if (checkNumbers(a, b, "int<< expects an int as second operand.")) { | 155 if (checkNumbers(a, b, "int<< expects an int as second operand.")) { |
| 156 if (b < 0) throw new IllegalArgumentException(b); |
| 153 return JS("num", @"$0 << $1", a, b); | 157 return JS("num", @"$0 << $1", a, b); |
| 154 } | 158 } |
| 155 return UNINTERCEPTED(a << b); | 159 return UNINTERCEPTED(a << b); |
| 156 } | 160 } |
| 157 | 161 |
| 158 shr(var a, var b) { | 162 shr(var a, var b) { |
| 159 // TODO(floitsch): inputs must be integers. | 163 // TODO(floitsch): inputs must be integers. |
| 160 if (checkNumbers(a, b, "int>> expects an int as second operand.")) { | 164 if (checkNumbers(a, b, "int>> expects an int as second operand.")) { |
| 165 if (b < 0) throw new IllegalArgumentException(b); |
| 161 return JS("num", @"$0 >> $1", a, b); | 166 return JS("num", @"$0 >> $1", a, b); |
| 162 } | 167 } |
| 163 return UNINTERCEPTED(a >> b); | 168 return UNINTERCEPTED(a >> b); |
| 164 } | 169 } |
| 165 | 170 |
| 166 and(var a, var b) { | 171 and(var a, var b) { |
| 167 // TODO(floitsch): inputs must be integers. | 172 // TODO(floitsch): inputs must be integers. |
| 168 if (checkNumbers(a, b, "int& expects an int as second operand.")) { | 173 if (checkNumbers(a, b, "int& expects an int as second operand.")) { |
| 169 return JS("num", @"$0 & $1", a, b); | 174 return JS("num", @"$0 & $1", a, b); |
| 170 } | 175 } |
| (...skipping 20 matching lines...) Expand all Loading... |
| 191 if (JS("bool", @"typeof $0 === 'number'", a)) return JS("num", @"~$0", a); | 196 if (JS("bool", @"typeof $0 === 'number'", a)) return JS("num", @"~$0", a); |
| 192 return UNINTERCEPTED(~a); | 197 return UNINTERCEPTED(~a); |
| 193 } | 198 } |
| 194 | 199 |
| 195 neg(var a) { | 200 neg(var a) { |
| 196 if (JS("bool", @"typeof $0 === 'number'", a)) return JS("num", @"-$0", a); | 201 if (JS("bool", @"typeof $0 === 'number'", a)) return JS("num", @"-$0", a); |
| 197 return UNINTERCEPTED(-a); | 202 return UNINTERCEPTED(-a); |
| 198 } | 203 } |
| 199 | 204 |
| 200 index(var a, var index) { | 205 index(var a, var index) { |
| 206 checkNull(a); |
| 201 if (a is String || isJSArray(a)) { | 207 if (a is String || isJSArray(a)) { |
| 202 if (!(index is int)) { | 208 if (!(index is int)) { |
| 203 throw new IllegalArgumentException(index); | 209 throw new IllegalArgumentException(index); |
| 204 } | 210 } |
| 205 if (index < 0 || index >= a.length) { | 211 if (index < 0 || index >= a.length) { |
| 206 throw new IndexOutOfRangeException(index); | 212 throw new IndexOutOfRangeException(index); |
| 207 } | 213 } |
| 208 return JS("Object", @"$0[$1]", a, index); | 214 return JS("Object", @"$0[$1]", a, index); |
| 209 } | 215 } |
| 210 return UNINTERCEPTED(a[index]); | 216 return UNINTERCEPTED(a[index]); |
| 211 } | 217 } |
| 212 | 218 |
| 213 indexSet(var a, var index, var value) { | 219 indexSet(var a, var index, var value) { |
| 220 checkNull(a); |
| 214 if (isJSArray(a)) { | 221 if (isJSArray(a)) { |
| 215 if (!(index is int)) { | 222 if (!(index is int)) { |
| 216 throw new IllegalArgumentException(index); | 223 throw new IllegalArgumentException(index); |
| 217 } | 224 } |
| 218 if (index < 0 || index >= a.length) { | 225 if (index < 0 || index >= a.length) { |
| 219 throw new IndexOutOfRangeException(index); | 226 throw new IndexOutOfRangeException(index); |
| 220 } | 227 } |
| 221 return JS("Object", @"$0[$1] = $2", a, index, value); | 228 return JS("Object", @"$0[$1] = $2", a, index, value); |
| 222 } | 229 } |
| 223 return UNINTERCEPTED(a[index] = value); | 230 return UNINTERCEPTED(a[index] = value); |
| 224 } | 231 } |
| 225 | 232 |
| 226 builtin$add$1(var receiver, var value) { | 233 builtin$add$1(var receiver, var value) { |
| 234 checkNull(receiver); |
| 227 if (isJSArray(receiver)) { | 235 if (isJSArray(receiver)) { |
| 228 JS("Object", @"$0.push($1)", receiver, value); | 236 JS("Object", @"$0.push($1)", receiver, value); |
| 229 return; | 237 return; |
| 230 } | 238 } |
| 231 return UNINTERCEPTED(receiver.add(value)); | 239 return UNINTERCEPTED(receiver.add(value)); |
| 232 } | 240 } |
| 233 | 241 |
| 234 builtin$removeLast$0(var receiver) { | 242 builtin$removeLast$0(var receiver) { |
| 243 checkNull(receiver); |
| 235 if (isJSArray(receiver)) { | 244 if (isJSArray(receiver)) { |
| 245 if (receiver.length === 0) throw new IndexOutOfRangeException(-1); |
| 236 return JS("Object", @"$0.pop()", receiver); | 246 return JS("Object", @"$0.pop()", receiver); |
| 237 } | 247 } |
| 238 return UNINTERCEPTED(receiver.removeLast()); | 248 return UNINTERCEPTED(receiver.removeLast()); |
| 239 } | 249 } |
| 240 | 250 |
| 241 builtin$filter$1(var receiver, var predicate) { | 251 builtin$filter$1(var receiver, var predicate) { |
| 252 checkNull(receiver); |
| 242 if (isJSArray(receiver)) { | 253 if (isJSArray(receiver)) { |
| 243 return JS("Object", @"$0.filter(function(v) { return $1(v) === true; })", | 254 return JS("Object", @"$0.filter(function(v) { return $1(v) === true; })", |
| 244 receiver, predicate); | 255 receiver, predicate); |
| 245 } | 256 } |
| 246 return UNINTERCEPTED(receiver.filter(predicate)); | 257 return UNINTERCEPTED(receiver.filter(predicate)); |
| 247 } | 258 } |
| 248 | 259 |
| 249 | 260 |
| 250 builtin$get$length(var receiver) { | 261 builtin$get$length(var receiver) { |
| 262 checkNull(receiver); |
| 251 if (receiver is String || isJSArray(receiver)) { | 263 if (receiver is String || isJSArray(receiver)) { |
| 252 return JS("num", @"$0.length", receiver); | 264 return JS("num", @"$0.length", receiver); |
| 253 } | 265 } |
| 254 return UNINTERCEPTED(receiver.length); | 266 return UNINTERCEPTED(receiver.length); |
| 255 } | 267 } |
| 256 | 268 |
| 269 builtin$set$length(receiver, newLength) { |
| 270 checkNull(receiver); |
| 271 if (isJSArray(receiver)) { |
| 272 checkNull(newLength); // TODO(ahe): This is not specified but co19 tests it. |
| 273 if (newLength is !int) throw new IllegalArgumentException(newLength); |
| 274 if (newLength < 0) throw new IndexOutOfRangeException(newLength); |
| 275 JS('void', @"$0.length = $1", receiver, newLength); |
| 276 } else { |
| 277 UNINTERCEPTED(receiver.length = newLength); |
| 278 } |
| 279 } |
| 257 | 280 |
| 258 builtin$toString$0(var value) { | 281 builtin$toString$0(var value) { |
| 259 if (JS("bool", @"typeof $0 == 'object'", value)) { | 282 if (JS("bool", @"typeof $0 == 'object'", value)) { |
| 260 if (isJSArray(value)) { | 283 if (isJSArray(value)) { |
| 261 return "Instance of 'List'"; | 284 return "Instance of 'List'"; |
| 262 } | 285 } |
| 263 return UNINTERCEPTED(value.toString()); | 286 return UNINTERCEPTED(value.toString()); |
| 264 } | 287 } |
| 265 if (JS("bool", @"$0 === 0 && (1 / $0) < 0", value)) { | 288 if (JS("bool", @"$0 === 0 && (1 / $0) < 0", value)) { |
| 266 return "-0.0"; | 289 return "-0.0"; |
| 267 } | 290 } |
| 268 if (value === null) return "null"; | 291 if (value === null) return "null"; |
| 269 if (JS("bool", @"typeof $0 == 'function'", value)) { | 292 if (JS("bool", @"typeof $0 == 'function'", value)) { |
| 270 return "Closure"; | 293 return "Closure"; |
| 271 } | 294 } |
| 272 return JS("string", @"String($0)", value); | 295 return JS("string", @"String($0)", value); |
| 273 } | 296 } |
| 274 | 297 |
| 275 | 298 |
| 276 builtin$iterator$0(var receiver) { | 299 builtin$iterator$0(receiver) { |
| 300 checkNull(receiver); |
| 277 if (isJSArray(receiver)) { | 301 if (isJSArray(receiver)) { |
| 278 return new ListIterator(receiver); | 302 return new ListIterator(receiver); |
| 279 } | 303 } |
| 280 return UNINTERCEPTED(receiver.iterator()); | 304 return UNINTERCEPTED(receiver.iterator()); |
| 281 } | 305 } |
| 282 | 306 |
| 283 class ListIterator<T> implements Iterator<T> { | 307 class ListIterator<T> implements Iterator<T> { |
| 284 int i; | 308 int i; |
| 285 List<T> list; | 309 List<T> list; |
| 286 ListIterator(List<T> this.list) : i = 0; | 310 ListIterator(List<T> this.list) : i = 0; |
| 287 bool hasNext() => i < JS("int", @"$0.length", list); | 311 bool hasNext() => i < JS("int", @"$0.length", list); |
| 288 T next() { | 312 T next() { |
| 313 if (!hasNext()) throw new NoMoreElementsException(); |
| 289 var value = JS("Object", @"$0[$1]", list, i); | 314 var value = JS("Object", @"$0[$1]", list, i); |
| 290 i += 1; | 315 i += 1; |
| 291 return value; | 316 return value; |
| 292 } | 317 } |
| 293 } | 318 } |
| 294 | 319 |
| 295 builtin$charCodeAt$1(var receiver, int index) { | 320 builtin$charCodeAt$1(var receiver, int index) { |
| 296 if (receiver is String) { | 321 if (receiver is String) { |
| 297 return JS("string", @"$0.charCodeAt($1)", receiver, index); | 322 return JS("string", @"$0.charCodeAt($1)", receiver, index); |
| 298 } else { | 323 } else { |
| 299 return UNINTERCEPTED(receiver.charCodeAt(index)); | 324 return UNINTERCEPTED(receiver.charCodeAt(index)); |
| 300 } | 325 } |
| 301 } | 326 } |
| 302 | 327 |
| 303 builtin$isEmpty$0(var receiver) { | 328 builtin$isEmpty$0(receiver) { |
| 329 checkNull(receiver); |
| 304 if (receiver is String || isJSArray(receiver)) { | 330 if (receiver is String || isJSArray(receiver)) { |
| 305 return JS("bool", @"$0.length === 0", receiver); | 331 return JS("bool", @"$0.length === 0", receiver); |
| 306 } | 332 } |
| 307 return UNINTERCEPTED(receiver.isEmpty()); | 333 return UNINTERCEPTED(receiver.isEmpty()); |
| 308 } | 334 } |
| 309 | 335 |
| 310 class Primitives { | 336 class Primitives { |
| 311 static void printString(String string) { | 337 static void printString(String string) { |
| 312 var hasConsole = JS("bool", @"typeof console == 'object'"); | 338 var hasConsole = JS("bool", @"typeof console == 'object'"); |
| 313 if (hasConsole) { | 339 if (hasConsole) { |
| 314 JS("void", @"console.log($0)", string); | 340 JS("void", @"console.log($0)", string); |
| 315 } else { | 341 } else { |
| 316 JS("void", @"write($0)", string); | 342 JS("void", @"write($0)", string); |
| 317 JS("void", @"write('\n')"); | 343 JS("void", @"write('\n')"); |
| 318 } | 344 } |
| 319 } | 345 } |
| 320 | 346 |
| 321 static String objectToString(Object object) { | 347 static String objectToString(Object object) { |
| 322 String name = JS('String', @'$0.constructor.name', object); | 348 String name = JS('String', @'$0.constructor.name', object); |
| 323 if (name === null) { | 349 if (name === null) { |
| 324 name = JS('String', @'$0.match(/^\s*function\s*(\S*)\s*\(/)[1]', | 350 name = JS('String', @'$0.match(/^\s*function\s*(\S*)\s*\(/)[1]', |
| 325 JS('String', @'$0.constructor.toString()', object)); | 351 JS('String', @'$0.constructor.toString()', object)); |
| 326 } | 352 } |
| 327 return "Instance of '$name'"; | 353 return "Instance of '$name'"; |
| 328 } | 354 } |
| 329 | 355 |
| 330 static List newList(int length) { | 356 static List newList(length) { |
| 331 if (length == null) return JS("Object", @"new Array()"); | 357 if (length == null) return JS("Object", @"new Array()"); |
| 332 if (!(length is int)) throw "Invalid argument"; | 358 if ((length is !int) || (length < 0)) { |
| 333 if (length < 0) throw "Negative size"; | 359 throw new IllegalArgumentException(length); |
| 360 } |
| 334 return JS("Object", @"new Array($0)", length); | 361 return JS("Object", @"new Array($0)", length); |
| 335 } | 362 } |
| 336 | 363 |
| 337 static num dateNow() => JS("num", @"Date.now()"); | 364 static num dateNow() => JS("num", @"Date.now()"); |
| 338 | 365 |
| 339 static num mathFloor(num value) => JS("num", @"Math.floor($0)", value); | 366 static num mathFloor(num value) => JS("num", @"Math.floor($0)", value); |
| 340 | 367 |
| 341 static brokenDownDateToSecondsSinceEpoch( | 368 static brokenDownDateToSecondsSinceEpoch( |
| 342 int years, int month, int day, int hours, int minutes, int seconds, | 369 int years, int month, int day, int hours, int minutes, int seconds, |
| 343 bool isUtc) { | 370 bool isUtc) { |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 393 return 1; | 420 return 1; |
| 394 } else { | 421 } else { |
| 395 return -1; | 422 return -1; |
| 396 } | 423 } |
| 397 } else if (a is String) { | 424 } else if (a is String) { |
| 398 throw 'String.compareTo is not implemented'; | 425 throw 'String.compareTo is not implemented'; |
| 399 } else { | 426 } else { |
| 400 return UNINTERCEPTED(a.compareTo(b)); | 427 return UNINTERCEPTED(a.compareTo(b)); |
| 401 } | 428 } |
| 402 } | 429 } |
| 430 |
| 431 /** |
| 432 * Called by generated code to throw an illegal-argument exception, |
| 433 * for example, if a non-integer index is given to an optimized |
| 434 * indexed access. |
| 435 */ |
| 436 iae(argument) { |
| 437 throw new IllegalArgumentException(argument); |
| 438 } |
| 439 |
| 440 /** |
| 441 * Called by generated code to throw an index-out-of-range exception, |
| 442 * for example, if a bounds check fails in an optimized indexed |
| 443 * access. |
| 444 */ |
| 445 ioore(index) { |
| 446 throw new IndexOutOfRangeException(index); |
| 447 } |
| 448 |
| 449 builtin$addAll$1(receiver, collection) { |
| 450 checkNull(receiver); |
| 451 if (!isJSArray(receiver)) return UNINTERCEPTED(receiver.addAll(collection)); |
| 452 |
| 453 // TODO(ahe): Use for-in when it is implemented correctly. |
| 454 var iterator = collection.iterator(); |
| 455 while (iterator.hasNext()) { |
| 456 receiver.add(iterator.next()); |
| 457 } |
| 458 } |
| 459 |
| 460 // TODO(ahe): Investigate why this method causes a compiler crash. |
| 461 XXX_builtin$addLast$1(receiver, value) { |
| 462 checkNull(receiver); |
| 463 if (!isJSArray(receiver)) return UNINTERCEPTED(receiver.addLast(value)); |
| 464 |
| 465 throw @'builtin$addLast$1 is not implemented'; |
| 466 } |
| 467 |
| 468 builtin$clear$0(receiver) { |
| 469 checkNull(receiver); |
| 470 if (!isJSArray(receiver)) return UNINTERCEPTED(receiver.clear()); |
| 471 receiver.length = 0; |
| 472 } |
| 473 |
| 474 // TODO(ahe): Investigate why this method causes a compiler crash. |
| 475 XXX_builtin$forEach$1(receiver, f) { |
| 476 checkNull(receiver); |
| 477 if (!isJSArray(receiver)) return UNINTERCEPTED(receiver.forEach(f)); |
| 478 |
| 479 throw @'builtin$forEach$1 is not implemented'; |
| 480 } |
| 481 |
| 482 builtin$getRange$2(receiver, start, length) { |
| 483 checkNull(receiver); |
| 484 if (!isJSArray(receiver)) { |
| 485 return UNINTERCEPTED(receiver.getRange(start, length)); |
| 486 } |
| 487 if (0 === length) return []; |
| 488 checkNull(start); // TODO(ahe): This is not specified but co19 tests it. |
| 489 checkNull(length); // TODO(ahe): This is not specified but co19 tests it. |
| 490 if (start is !int) throw new IllegalArgumentException(start); |
| 491 if (length is !int) throw new IllegalArgumentException(length); |
| 492 if (start < 0) throw new IndexOutOfRangeException(start); |
| 493 var end = start + length; |
| 494 if (end > receiver.length) { |
| 495 throw new IndexOutOfRangeException(length); |
| 496 } |
| 497 if (length < 0) throw new IllegalArgumentException(length); |
| 498 return JS("Object", @"$0.slice($1, $2)", receiver, start, end); |
| 499 } |
| 500 |
| 501 builtin$indexOf$1(receiver, element) { |
| 502 checkNull(receiver); |
| 503 if (isJSArray(receiver) || receiver is String) { |
| 504 return builtin$indexOf$2(receiver, element, 0); |
| 505 } |
| 506 return UNINTERCEPTED(receiver.indexOf(element)); |
| 507 } |
| 508 |
| 509 builtin$indexOf$2(receiver, element, start) { |
| 510 checkNull(receiver); |
| 511 if (isJSArray(receiver)) { |
| 512 if (start is !int) throw new IllegalArgumentException(start); |
| 513 var length = JS("num", @"$0.length", receiver); |
| 514 return Arrays.indexOf(receiver, element, start, length); |
| 515 } else if (receiver is String) { |
| 516 throw new NotImplementedException(); |
| 517 } |
| 518 return UNINTERCEPTED(receiver.indexOf(element, start)); |
| 519 } |
| 520 |
| 521 builtin$insertRange$2(receiver, start, length) { |
| 522 checkNull(receiver); |
| 523 if (isJSArray(receiver)) { |
| 524 return builtin$insertRange$3(receiver, start, length, null); |
| 525 } |
| 526 return UNINTERCEPTED(receiver.insertRange(start, length)); |
| 527 } |
| 528 |
| 529 builtin$insertRange$3(receiver, start, length, initialValue) { |
| 530 checkNull(receiver); |
| 531 if (!isJSArray(receiver)) { |
| 532 return UNINTERCEPTED(receiver.insertRange(start, length, initialValue)); |
| 533 } |
| 534 return listInsertRange(receiver, start, length, initialValue); |
| 535 } |
| 536 |
| 537 listInsertRange(receiver, start, length, initialValue) { |
| 538 if (length === 0) { |
| 539 return; |
| 540 } |
| 541 checkNull(start); // TODO(ahe): This is not specified but co19 tests it. |
| 542 checkNull(length); // TODO(ahe): This is not specified but co19 tests it. |
| 543 if (length is !int) throw new IllegalArgumentException(length); |
| 544 if (length < 0) throw new IllegalArgumentException(length); |
| 545 if (start is !int) throw new IllegalArgumentException(start); |
| 546 |
| 547 var receiverLength = JS("num", @"$0.length", receiver); |
| 548 if (start < 0 || start > receiverLength) { |
| 549 throw new IndexOutOfRangeException(start); |
| 550 } |
| 551 receiver.length = receiverLength + length; |
| 552 Arrays.copy(receiver, |
| 553 start, |
| 554 receiver, |
| 555 start + length, |
| 556 receiverLength - start); |
| 557 if (initialValue !== null) { |
| 558 for (int i = start; i < start + length; i++) { |
| 559 receiver[i] = initialValue; |
| 560 } |
| 561 } |
| 562 receiver.length = receiverLength + length; |
| 563 } |
| 564 |
| 565 builtin$last$0(receiver) { |
| 566 checkNull(receiver); |
| 567 if (!isJSArray(receiver)) { |
| 568 return UNINTERCEPTED(receiver.last()); |
| 569 } |
| 570 return receiver[receiver.length - 1]; |
| 571 } |
| 572 |
| 573 builtin$lastIndexOf$1(receiver, element) { |
| 574 checkNull(receiver); |
| 575 if (isJSArray(receiver)) { |
| 576 var start = JS("num", @"$0.length", receiver); |
| 577 return Arrays.lastIndexOf(receiver, element, start); |
| 578 } else if (receiver is String) { |
| 579 throw new NotImplementedException(); |
| 580 } |
| 581 return UNINTERCEPTED(receiver.lastIndexOf(element)); |
| 582 } |
| 583 |
| 584 builtin$lastIndexOf$2(receiver, element, start) { |
| 585 checkNull(receiver); |
| 586 if (isJSArray(receiver)) { |
| 587 return Arrays.lastIndexOf(receiver, element, start); |
| 588 } else if (receiver is String) { |
| 589 throw new NotImplementedException(); |
| 590 } |
| 591 return UNINTERCEPTED(receiver.lastIndexOf(element, start)); |
| 592 } |
| 593 |
| 594 builtin$removeRange$2(receiver, start, length) { |
| 595 checkNull(receiver); |
| 596 if (!isJSArray(receiver)) { |
| 597 return UNINTERCEPTED(receiver.removeRange(start, length)); |
| 598 } |
| 599 if (length == 0) { |
| 600 return; |
| 601 } |
| 602 checkNull(start); // TODO(ahe): This is not specified but co19 tests it. |
| 603 checkNull(length); // TODO(ahe): This is not specified but co19 tests it. |
| 604 if (start is !int) throw new IllegalArgumentException(start); |
| 605 if (length is !int) throw new IllegalArgumentException(length); |
| 606 if (length < 0) throw new IllegalArgumentException(length); |
| 607 var receiverLength = JS("num", @"$0.length", receiver); |
| 608 if (start < 0 || start >= receiverLength) { |
| 609 throw new IndexOutOfRangeException(start); |
| 610 } |
| 611 if (start + length > receiverLength) { |
| 612 throw new IndexOutOfRangeException(start + length); |
| 613 } |
| 614 Arrays.copy(receiver, |
| 615 start + length, |
| 616 receiver, |
| 617 start, |
| 618 receiverLength - length - start); |
| 619 receiver.length = receiverLength - length; |
| 620 } |
| 621 |
| 622 builtin$setRange$3(receiver, start, length, from) { |
| 623 checkNull(receiver); |
| 624 if (isJSArray(receiver)) { |
| 625 return builtin$setRange$4(receiver, start, length, from, 0); |
| 626 } |
| 627 return UNINTERCEPTED(receiver.setRange(start, length, from)); |
| 628 } |
| 629 |
| 630 builtin$setRange$4(receiver, start, length, from, startFrom) { |
| 631 checkNull(receiver); |
| 632 if (!isJSArray(receiver)) { |
| 633 return UNINTERCEPTED(receiver.setRange(start, length, from, startFrom)); |
| 634 } |
| 635 |
| 636 if (length === 0) return; |
| 637 checkNull(start); // TODO(ahe): This is not specified but co19 tests it. |
| 638 checkNull(length); // TODO(ahe): This is not specified but co19 tests it. |
| 639 checkNull(from); // TODO(ahe): This is not specified but co19 tests it. |
| 640 checkNull(startFrom); // TODO(ahe): This is not specified but co19 tests it. |
| 641 if (start is !int) throw new IllegalArgumentException(start); |
| 642 if (length is !int) throw new IllegalArgumentException(length); |
| 643 if (startFrom is !int) throw new IllegalArgumentException(startFrom); |
| 644 if (length < 0) throw new IllegalArgumentException(length); |
| 645 if (start < 0) throw new IndexOutOfRangeException(start); |
| 646 if (start + length > receiver.length) { |
| 647 throw new IndexOutOfRangeException(start + length); |
| 648 } |
| 649 |
| 650 Arrays.copy(from, startFrom, receiver, start, length); |
| 651 } |
| 652 |
| 653 builtin$some$1(receiver, f) { |
| 654 checkNull(receiver); |
| 655 if (!isJSArray(receiver)) return UNINTERCEPTED(receiver.some(f)); |
| 656 |
| 657 return Collections.some(receiver, f); |
| 658 } |
| 659 |
| 660 builtin$sort$1(receiver, compare) { |
| 661 checkNull(receiver); |
| 662 if (!isJSArray(receiver)) return UNINTERCEPTED(receiver.sort(compare)); |
| 663 |
| 664 DualPivotQuicksort.sort(receiver, compare); |
| 665 } |
| 666 |
| 667 checkNull(object) { |
| 668 if (object === null) throw new NullPointerException(); |
| 669 } |
| 670 |
| 671 builtin$isNegative$0(receiver) { |
| 672 checkNull(receiver); |
| 673 if (receiver is num) { |
| 674 return (receiver === 0) ? (1 / receiver) < 0 : receiver < 0; |
| 675 } else { |
| 676 return UNINTERCEPTED(receiver.isNegative()); |
| 677 } |
| 678 } |
| 679 |
| 680 builtin$isNaN$0(receiver) { |
| 681 checkNull(receiver); |
| 682 if (receiver is num) { |
| 683 return JS("bool", @"isNaN($0)", receiver); |
| 684 } else { |
| 685 return UNINTERCEPTED(receiver.isNegative()); |
| 686 } |
| 687 } |
| 688 |
| 689 builtin$remainder$1(a, b) { |
| 690 checkNull(a); |
| 691 if (checkNumbers(a, b, "num.remainder expects a number as second operand.")) { |
| 692 throw new NotImplementedException(); |
| 693 } else { |
| 694 return UNINTERCEPTED(a.remainder(b)); |
| 695 } |
| 696 } |
| 697 |
| 698 builtin$abs$0(receiver) { |
| 699 checkNull(receiver); |
| 700 if (receiver is !num) return UNINTERCEPTED(receiver.abs()); |
| 701 |
| 702 throw new NotImplementedException(); |
| 703 } |
| 704 |
| 705 builtin$toInt$0(receiver) { |
| 706 checkNull(receiver); |
| 707 if (receiver is !num) return UNINTERCEPTED(receiver.toInt()); |
| 708 |
| 709 throw new NotImplementedException(); |
| 710 } |
| 711 |
| 712 builtin$ceil$0(receiver) { |
| 713 checkNull(receiver); |
| 714 if (receiver is !num) return UNINTERCEPTED(receiver.ceil()); |
| 715 |
| 716 throw new NotImplementedException(); |
| 717 } |
| 718 |
| 719 builtin$floor$0(receiver) { |
| 720 checkNull(receiver); |
| 721 if (receiver is !num) return UNINTERCEPTED(receiver.floor()); |
| 722 |
| 723 throw new NotImplementedException(); |
| 724 } |
| 725 |
| 726 builtin$isInfinite$0(receiver) { |
| 727 checkNull(receiver); |
| 728 if (receiver is !num) return UNINTERCEPTED(receiver.isInfinite()); |
| 729 |
| 730 throw new NotImplementedException(); |
| 731 } |
| 732 |
| 733 builtin$negate$0(receiver) { |
| 734 checkNull(receiver); |
| 735 if (receiver is !num) return UNINTERCEPTED(receiver.negate()); |
| 736 |
| 737 throw new NotImplementedException(); |
| 738 } |
| 739 |
| 740 builtin$round$0(receiver) { |
| 741 checkNull(receiver); |
| 742 if (receiver is !num) return UNINTERCEPTED(receiver.round()); |
| 743 |
| 744 throw new NotImplementedException(); |
| 745 } |
| 746 |
| 747 builtin$toDouble$0(receiver) { |
| 748 checkNull(receiver); |
| 749 if (receiver is !num) return UNINTERCEPTED(receiver.toDouble()); |
| 750 |
| 751 throw new NotImplementedException(); |
| 752 } |
| 753 |
| 754 builtin$truncate$0(receiver) { |
| 755 checkNull(receiver); |
| 756 if (receiver is !num) return UNINTERCEPTED(receiver.truncate()); |
| 757 |
| 758 throw new NotImplementedException(); |
| 759 } |
| 760 |
| 761 |
| 762 builtin$toStringAsFixed$1(receiver, fractionDigits) { |
| 763 checkNull(receiver); |
| 764 if (receiver is !num) { |
| 765 return UNINTERCEPTED(receiver.toStringAsFixed(fractionDigits)); |
| 766 } |
| 767 |
| 768 throw new NotImplementedException(); |
| 769 } |
| 770 |
| 771 builtin$allMatches$1(receiver, str) { |
| 772 checkNull(receiver); |
| 773 if (receiver is !String) return UNINTERCEPTED(receiver.allMatches(str)); |
| 774 |
| 775 throw new NotImplementedException(); |
| 776 } |
| 777 |
| 778 builtin$concat$1(receiver, other) { |
| 779 checkNull(receiver); |
| 780 if (receiver is !String) return UNINTERCEPTED(receiver.concat(other)); |
| 781 |
| 782 throw new NotImplementedException(); |
| 783 } |
| 784 |
| 785 builtin$contains$2(receiver, other, startIndex) { |
| 786 checkNull(receiver); |
| 787 if (receiver is !String) { |
| 788 return UNINTERCEPTED(receiver.contains(other, startIndex)); |
| 789 } |
| 790 |
| 791 throw new NotImplementedException(); |
| 792 } |
| 793 |
| 794 builtin$endsWith$1(receiver, other) { |
| 795 checkNull(receiver); |
| 796 if (receiver is !String) return UNINTERCEPTED(receiver.endsWith(other)); |
| 797 |
| 798 throw new NotImplementedException(); |
| 799 } |
| 800 |
| 801 builtin$replaceAll$2(receiver, from, to) { |
| 802 checkNull(receiver); |
| 803 if (receiver is !String) return UNINTERCEPTED(receiver.replaceAll(from, to)); |
| 804 |
| 805 throw new NotImplementedException(); |
| 806 } |
| 807 |
| 808 builtin$replaceFirst$2(receiver, from, to) { |
| 809 checkNull(receiver); |
| 810 if (receiver is !String) { |
| 811 return UNINTERCEPTED(receiver.replaceFirst(from, to)); |
| 812 } |
| 813 |
| 814 throw new NotImplementedException(); |
| 815 } |
| 816 |
| 817 builtin$split$1(receiver, pattern) { |
| 818 checkNull(receiver); |
| 819 if (receiver is !String) return UNINTERCEPTED(receiver.split(pattern)); |
| 820 |
| 821 throw new NotImplementedException(); |
| 822 } |
| 823 |
| 824 builtin$splitChars$0(receiver) { |
| 825 checkNull(receiver); |
| 826 if (receiver is !String) return UNINTERCEPTED(receiver.splitChars()); |
| 827 |
| 828 throw new NotImplementedException(); |
| 829 } |
| 830 |
| 831 builtin$startsWith$1(receiver, other) { |
| 832 checkNull(receiver); |
| 833 if (receiver is !String) return UNINTERCEPTED(receiver.startsWith(other)); |
| 834 |
| 835 throw new NotImplementedException(); |
| 836 } |
| 837 |
| 838 builtin$substring$1(receiver, startIndex) { |
| 839 checkNull(receiver); |
| 840 if (receiver is !String) return UNINTERCEPTED(receiver.substring(startIndex)); |
| 841 |
| 842 throw new NotImplementedException(); |
| 843 } |
| 844 |
| 845 builtin$substring$2(receiver, startIndex, endIndex) { |
| 846 checkNull(receiver); |
| 847 if (receiver is !String) { |
| 848 return UNINTERCEPTED(receiver.substring(startIndex, endIndex)); |
| 849 } |
| 850 |
| 851 throw new NotImplementedException(); |
| 852 } |
| 853 |
| 854 builtin$toLowerCase$0(receiver) { |
| 855 checkNull(receiver); |
| 856 if (receiver is !String) return UNINTERCEPTED(receiver.toLowerCase()); |
| 857 |
| 858 throw new NotImplementedException(); |
| 859 } |
| 860 |
| 861 builtin$toUpperCase$0(receiver) { |
| 862 checkNull(receiver); |
| 863 if (receiver is !String) return UNINTERCEPTED(receiver.toUpperCase()); |
| 864 |
| 865 throw new NotImplementedException(); |
| 866 } |
| 867 |
| 868 builtin$trim$0(receiver) { |
| 869 checkNull(receiver); |
| 870 if (receiver is !String) return UNINTERCEPTED(receiver.trim()); |
| 871 |
| 872 throw new NotImplementedException(); |
| 873 } |
| OLD | NEW |