Chromium Code Reviews| 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(var receiver) { |
|
kasperl
2012/02/21 07:16:43
Want to remove var here too?
ahe
2012/02/21 23:03:25
Done.
| |
| 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 iae(argument) { | |
|
kasperl
2012/02/21 07:16:43
Maybe make it clear (through a comment at least) t
ahe
2012/02/21 23:03:25
Done.
| |
| 432 throw new IllegalArgumentException(argument); | |
| 433 } | |
| 434 | |
| 435 ioore(index) { | |
| 436 throw new IndexOutOfRangeException(index); | |
| 437 } | |
| 438 | |
| 439 builtin$addAll$1(receiver, collection) { | |
| 440 checkNull(receiver); | |
| 441 if (!isJSArray(receiver)) return UNINTERCEPTED(receiver.addAll(collection)); | |
| 442 | |
| 443 var iterator = collection.iterator(); | |
|
ngeoffray
2012/02/21 10:41:45
Why not using for in?
ahe
2012/02/21 23:03:25
Because I thought it wasn't implemented and becaus
| |
| 444 while (iterator.hasNext()) { | |
| 445 receiver.add(iterator.next()); | |
| 446 } | |
| 447 } | |
| 448 | |
| 449 // TODO(ahe): Investigate why this method causes a compiler crash. | |
| 450 XXX_builtin$addLast$1(receiver, value) { | |
| 451 checkNull(receiver); | |
| 452 if (!isJSArray(receiver)) return UNINTERCEPTED(receiver.addLast(value)); | |
| 453 | |
| 454 throw @'builtin$addLast$1 is not implemented'; | |
| 455 } | |
| 456 | |
| 457 builtin$clear$0(receiver) { | |
| 458 checkNull(receiver); | |
| 459 if (!isJSArray(receiver)) return UNINTERCEPTED(receiver.clear()); | |
| 460 receiver.length = 0; | |
| 461 } | |
| 462 | |
| 463 // TODO(ahe): Investigate why this method causes a compiler crash. | |
| 464 XXX_builtin$forEach$1(receiver, f) { | |
| 465 checkNull(receiver); | |
| 466 if (!isJSArray(receiver)) return UNINTERCEPTED(receiver.forEach(f)); | |
| 467 | |
| 468 throw @'builtin$forEach$1 is not implemented'; | |
| 469 } | |
| 470 | |
| 471 builtin$getRange$2(receiver, start, length) { | |
| 472 checkNull(receiver); | |
| 473 if (!isJSArray(receiver)) { | |
| 474 return UNINTERCEPTED(receiver.getRange(start, length)); | |
| 475 } | |
| 476 if (0 === length) return []; | |
| 477 checkNull(start); // TODO(ahe): This is not specified but co19 tests it. | |
| 478 checkNull(length); // TODO(ahe): This is not specified but co19 tests it. | |
| 479 if (start is !int) throw new IllegalArgumentException(start); | |
| 480 if (length is !int) throw new IllegalArgumentException(length); | |
| 481 if (start < 0) throw new IndexOutOfRangeException(start); | |
| 482 var end = start + length; | |
| 483 if (end > receiver.length) { | |
| 484 throw new IndexOutOfRangeException(length); | |
| 485 } | |
| 486 if (length < 0) throw new IllegalArgumentException(length); | |
| 487 return JS("Object", @"$0.slice($1, $2)", receiver, start, end); | |
| 488 } | |
| 489 | |
| 490 builtin$indexOf$1(receiver, element) { | |
| 491 checkNull(receiver); | |
| 492 if (isJSArray(receiver) || receiver is String) { | |
| 493 return builtin$indexOf$2(receiver, element, 0); | |
| 494 } | |
| 495 return UNINTERCEPTED(receiver.indexOf(element)); | |
| 496 } | |
| 497 | |
| 498 builtin$indexOf$2(receiver, element, start) { | |
| 499 checkNull(receiver); | |
| 500 if (isJSArray(receiver)) { | |
| 501 if (start is !int) throw new IllegalArgumentException(start); | |
| 502 var length = JS("num", @"$0.length", receiver); | |
| 503 return Arrays.indexOf(receiver, element, start, length); | |
| 504 } else if (receiver is String) { | |
| 505 throw new NotImplementedException(); | |
| 506 } | |
| 507 return UNINTERCEPTED(receiver.indexOf(element, start)); | |
| 508 } | |
| 509 | |
| 510 builtin$insertRange$2(receiver, start, length) { | |
| 511 checkNull(receiver); | |
| 512 if (isJSArray(receiver)) { | |
| 513 return builtin$insertRange$3(receiver, start, length, null); | |
| 514 } | |
| 515 return UNINTERCEPTED(receiver.insertRange(start, length)); | |
| 516 } | |
| 517 | |
| 518 builtin$insertRange$3(receiver, start, length, initialValue) { | |
| 519 checkNull(receiver); | |
| 520 if (!isJSArray(receiver)) { | |
|
ngeoffray
2012/02/21 10:41:45
It would look consistent to have this check invert
ahe
2012/02/21 23:03:25
I'll do this in a follow-up CL. I have 17 CL build
| |
| 521 return UNINTERCEPTED(receiver.insertRange(start, length, initialValue)); | |
| 522 } | |
| 523 return listInsertRange(receiver, start, length, initialValue); | |
| 524 } | |
| 525 | |
| 526 listInsertRange(receiver, start, length, initialValue) { | |
| 527 if (length === 0) { | |
| 528 return; | |
| 529 } | |
| 530 checkNull(start); // TODO(ahe): This is not specified but co19 tests it. | |
| 531 checkNull(length); // TODO(ahe): This is not specified but co19 tests it. | |
| 532 if (length is !int) throw new IllegalArgumentException(length); | |
| 533 if (length < 0) throw new IllegalArgumentException(length); | |
| 534 if (start is !int) throw new IllegalArgumentException(start); | |
| 535 | |
| 536 var receiverLength = JS("num", @"$0.length", receiver); | |
| 537 if (start < 0 || start > receiverLength) { | |
| 538 throw new IndexOutOfRangeException(start); | |
| 539 } | |
| 540 receiver.length = receiverLength + length; | |
| 541 Arrays.copy(receiver, | |
| 542 start, | |
| 543 receiver, | |
| 544 start + length, | |
| 545 receiverLength - start); | |
| 546 if (initialValue !== null) { | |
| 547 for (int i = start; i < start + length; i++) { | |
| 548 receiver[i] = initialValue; | |
| 549 } | |
| 550 } | |
| 551 receiver.length = receiverLength + length; | |
| 552 } | |
| 553 | |
| 554 builtin$last$0(receiver) { | |
| 555 checkNull(receiver); | |
| 556 if (!isJSArray(receiver)) { | |
| 557 return UNINTERCEPTED(receiver.last()); | |
|
ngeoffray
2012/02/21 10:41:45
Ditto for consistency,
| |
| 558 } | |
| 559 return receiver[receiver.length - 1]; | |
| 560 } | |
| 561 | |
| 562 builtin$lastIndexOf$1(receiver, element) { | |
| 563 checkNull(receiver); | |
| 564 if (isJSArray(receiver)) { | |
| 565 var start = JS("num", @"$0.length", receiver); | |
| 566 return Arrays.lastIndexOf(receiver, element, start); | |
| 567 } else if (receiver is String) { | |
| 568 throw new NotImplementedException(); | |
| 569 } | |
| 570 return UNINTERCEPTED(receiver.lastIndexOf(element)); | |
| 571 } | |
| 572 | |
| 573 builtin$lastIndexOf$2(receiver, element, start) { | |
| 574 checkNull(receiver); | |
| 575 if (isJSArray(receiver)) { | |
| 576 return Arrays.lastIndexOf(receiver, element, start); | |
| 577 } else if (receiver is String) { | |
| 578 throw new NotImplementedException(); | |
| 579 } | |
| 580 return UNINTERCEPTED(receiver.lastIndexOf(element, start)); | |
| 581 } | |
| 582 | |
| 583 builtin$removeRange$2(receiver, start, length) { | |
| 584 checkNull(receiver); | |
| 585 if (!isJSArray(receiver)) { | |
| 586 return UNINTERCEPTED(receiver.removeRange(start, length)); | |
|
ngeoffray
2012/02/21 10:41:45
Ditto.
| |
| 587 } | |
| 588 if (length == 0) { | |
| 589 return; | |
| 590 } | |
| 591 checkNull(start); // TODO(ahe): This is not specified but co19 tests it. | |
| 592 checkNull(length); // TODO(ahe): This is not specified but co19 tests it. | |
| 593 if (start is !int) throw new IllegalArgumentException(start); | |
| 594 if (length is !int) throw new IllegalArgumentException(length); | |
| 595 if (length < 0) throw new IllegalArgumentException(length); | |
| 596 var receiverLength = JS("num", @"$0.length", receiver); | |
| 597 if (start < 0 || start >= receiverLength) { | |
| 598 throw new IndexOutOfRangeException(start); | |
| 599 } | |
| 600 if (start + length > receiverLength) { | |
| 601 throw new IndexOutOfRangeException(start + length); | |
| 602 } | |
| 603 Arrays.copy(receiver, | |
| 604 start + length, | |
| 605 receiver, | |
| 606 start, | |
| 607 receiverLength - length - start); | |
| 608 receiver.length = receiverLength - length; | |
| 609 } | |
| 610 | |
| 611 builtin$setRange$3(receiver, start, length, from) { | |
| 612 checkNull(receiver); | |
| 613 if (isJSArray(receiver)) { | |
| 614 return builtin$setRange$4(receiver, start, length, from, 0); | |
| 615 } | |
| 616 return UNINTERCEPTED(receiver.setRange(start, length, from)); | |
| 617 } | |
| 618 | |
| 619 builtin$setRange$4(receiver, start, length, from, startFrom) { | |
| 620 checkNull(receiver); | |
| 621 if (!isJSArray(receiver)) { | |
| 622 return UNINTERCEPTED(receiver.setRange(start, length, from, startFrom)); | |
| 623 } | |
| 624 | |
| 625 if (length === 0) return; | |
| 626 checkNull(start); // TODO(ahe): This is not specified but co19 tests it. | |
| 627 checkNull(length); // TODO(ahe): This is not specified but co19 tests it. | |
| 628 checkNull(from); // TODO(ahe): This is not specified but co19 tests it. | |
| 629 checkNull(startFrom); // TODO(ahe): This is not specified but co19 tests it. | |
| 630 if (start is !int) throw new IllegalArgumentException(start); | |
| 631 if (length is !int) throw new IllegalArgumentException(length); | |
| 632 if (startFrom is !int) throw new IllegalArgumentException(startFrom); | |
| 633 if (length < 0) throw new IllegalArgumentException(length); | |
| 634 if (start < 0) throw new IndexOutOfRangeException(start); | |
| 635 if (start + length > receiver.length) { | |
| 636 throw new IndexOutOfRangeException(start + length); | |
| 637 } | |
| 638 | |
| 639 Arrays.copy(from, startFrom, receiver, start, length); | |
| 640 } | |
| 641 | |
| 642 builtin$some$1(receiver, f) { | |
| 643 checkNull(receiver); | |
| 644 if (!isJSArray(receiver)) return UNINTERCEPTED(receiver.some(f)); | |
| 645 | |
| 646 return Collections.some(receiver, f); | |
| 647 } | |
| 648 | |
| 649 builtin$sort$1(receiver, compare) { | |
| 650 checkNull(receiver); | |
| 651 if (!isJSArray(receiver)) return UNINTERCEPTED(receiver.sort(compare)); | |
| 652 | |
| 653 DualPivotQuicksort.sort(receiver, compare); | |
| 654 } | |
| 655 | |
| 656 checkNull(object) { | |
| 657 if (object === null) throw new NullPointerException(); | |
| 658 } | |
| 659 | |
| 660 builtin$isNegative$0(receiver) { | |
| 661 checkNull(receiver); | |
| 662 if (receiver is num) { | |
| 663 return (receiver === 0) ? (1 / receiver) < 0 : receiver < 0; | |
| 664 } else { | |
| 665 return UNINTERCEPTED(receiver.isNegative()); | |
| 666 } | |
| 667 } | |
| 668 | |
| 669 builtin$isNaN$0(receiver) { | |
| 670 checkNull(receiver); | |
| 671 if (receiver is num) { | |
| 672 return JS("bool", @"isNaN($0)", receiver); | |
| 673 } else { | |
| 674 return UNINTERCEPTED(receiver.isNegative()); | |
| 675 } | |
| 676 } | |
| 677 | |
| 678 builtin$remainder$1(a, b) { | |
| 679 checkNull(a); | |
| 680 if (checkNumbers(a, b, "num.remainder expects a number as second operand.")) { | |
| 681 throw new NotImplementedException(); | |
| 682 } else { | |
| 683 return UNINTERCEPTED(a.remainder(b)); | |
| 684 } | |
| 685 } | |
| 686 | |
| 687 builtin$abs$0(receiver) { | |
| 688 checkNull(receiver); | |
| 689 if (receiver is !num) return UNINTERCEPTED(receiver.abs()); | |
| 690 | |
| 691 throw new NotImplementedException(); | |
| 692 } | |
| 693 | |
| 694 builtin$toInt$0(receiver) { | |
| 695 checkNull(receiver); | |
| 696 if (receiver is !num) return UNINTERCEPTED(receiver.toInt()); | |
| 697 | |
| 698 throw new NotImplementedException(); | |
| 699 } | |
| 700 | |
| 701 builtin$ceil$0(receiver) { | |
| 702 checkNull(receiver); | |
| 703 if (receiver is !num) return UNINTERCEPTED(receiver.ceil()); | |
| 704 | |
| 705 throw new NotImplementedException(); | |
| 706 } | |
| 707 | |
| 708 builtin$floor$0(receiver) { | |
| 709 checkNull(receiver); | |
| 710 if (receiver is !num) return UNINTERCEPTED(receiver.floor()); | |
| 711 | |
| 712 throw new NotImplementedException(); | |
| 713 } | |
| 714 | |
| 715 builtin$isInfinite$0(receiver) { | |
| 716 checkNull(receiver); | |
| 717 if (receiver is !num) return UNINTERCEPTED(receiver.isInfinite()); | |
| 718 | |
| 719 throw new NotImplementedException(); | |
| 720 } | |
| 721 | |
| 722 builtin$negate$0(receiver) { | |
| 723 checkNull(receiver); | |
| 724 if (receiver is !num) return UNINTERCEPTED(receiver.negate()); | |
| 725 | |
| 726 throw new NotImplementedException(); | |
| 727 } | |
| 728 | |
| 729 builtin$round$0(receiver) { | |
| 730 checkNull(receiver); | |
| 731 if (receiver is !num) return UNINTERCEPTED(receiver.round()); | |
| 732 | |
| 733 throw new NotImplementedException(); | |
| 734 } | |
| 735 | |
| 736 builtin$toDouble$0(receiver) { | |
| 737 checkNull(receiver); | |
| 738 if (receiver is !num) return UNINTERCEPTED(receiver.toDouble()); | |
| 739 | |
| 740 throw new NotImplementedException(); | |
| 741 } | |
| 742 | |
| 743 builtin$truncate$0(receiver) { | |
| 744 checkNull(receiver); | |
| 745 if (receiver is !num) return UNINTERCEPTED(receiver.truncate()); | |
| 746 | |
| 747 throw new NotImplementedException(); | |
| 748 } | |
| 749 | |
| 750 | |
| 751 builtin$toStringAsFixed$1(receiver, fractionDigits) { | |
| 752 checkNull(receiver); | |
| 753 if (receiver is !num) { | |
| 754 return UNINTERCEPTED(receiver.toStringAsFixed(fractionDigits)); | |
| 755 } | |
| 756 | |
| 757 throw new NotImplementedException(); | |
| 758 } | |
| 759 | |
| 760 builtin$allMatches$1(receiver, str) { | |
| 761 checkNull(receiver); | |
| 762 if (receiver is !String) return UNINTERCEPTED(receiver.allMatches(str)); | |
| 763 | |
| 764 throw new NotImplementedException(); | |
| 765 } | |
| 766 | |
| 767 builtin$concat$1(receiver, other) { | |
| 768 checkNull(receiver); | |
| 769 if (receiver is !String) return UNINTERCEPTED(receiver.concat(other)); | |
| 770 | |
| 771 throw new NotImplementedException(); | |
| 772 } | |
| 773 | |
| 774 builtin$contains$2(receiver, other, startIndex) { | |
| 775 checkNull(receiver); | |
| 776 if (receiver is !String) { | |
| 777 return UNINTERCEPTED(receiver.contains(other, startIndex)); | |
| 778 } | |
| 779 | |
| 780 throw new NotImplementedException(); | |
| 781 } | |
| 782 | |
| 783 builtin$endsWith$1(receiver, other) { | |
| 784 checkNull(receiver); | |
| 785 if (receiver is !String) return UNINTERCEPTED(receiver.endsWith(other)); | |
| 786 | |
| 787 throw new NotImplementedException(); | |
| 788 } | |
| 789 | |
| 790 builtin$replaceAll$2(receiver, from, to) { | |
| 791 checkNull(receiver); | |
| 792 if (receiver is !String) return UNINTERCEPTED(receiver.replaceAll(from, to)); | |
| 793 | |
| 794 throw new NotImplementedException(); | |
| 795 } | |
| 796 | |
| 797 builtin$replaceFirst$2(receiver, from, to) { | |
| 798 checkNull(receiver); | |
| 799 if (receiver is !String) { | |
| 800 return UNINTERCEPTED(receiver.replaceFirst(from, to)); | |
| 801 } | |
| 802 | |
| 803 throw new NotImplementedException(); | |
| 804 } | |
| 805 | |
| 806 builtin$split$1(receiver, pattern) { | |
| 807 checkNull(receiver); | |
| 808 if (receiver is !String) return UNINTERCEPTED(receiver.split(pattern)); | |
| 809 | |
| 810 throw new NotImplementedException(); | |
| 811 } | |
| 812 | |
| 813 builtin$splitChars$0(receiver) { | |
| 814 checkNull(receiver); | |
| 815 if (receiver is !String) return UNINTERCEPTED(receiver.splitChars()); | |
| 816 | |
| 817 throw new NotImplementedException(); | |
| 818 } | |
| 819 | |
| 820 builtin$startsWith$1(receiver, other) { | |
| 821 checkNull(receiver); | |
| 822 if (receiver is !String) return UNINTERCEPTED(receiver.startsWith(other)); | |
| 823 | |
| 824 throw new NotImplementedException(); | |
| 825 } | |
| 826 | |
| 827 builtin$substring$1(receiver, startIndex) { | |
| 828 checkNull(receiver); | |
| 829 if (receiver is !String) return UNINTERCEPTED(receiver.substring(startIndex)); | |
| 830 | |
| 831 throw new NotImplementedException(); | |
| 832 } | |
| 833 | |
| 834 builtin$substring$2(receiver, startIndex, endIndex) { | |
| 835 checkNull(receiver); | |
| 836 if (receiver is !String) { | |
| 837 return UNINTERCEPTED(receiver.substring(startIndex, endIndex)); | |
| 838 } | |
| 839 | |
| 840 throw new NotImplementedException(); | |
| 841 } | |
| 842 | |
| 843 builtin$toLowerCase$0(receiver) { | |
| 844 checkNull(receiver); | |
| 845 if (receiver is !String) return UNINTERCEPTED(receiver.toLowerCase()); | |
| 846 | |
| 847 throw new NotImplementedException(); | |
| 848 } | |
| 849 | |
| 850 builtin$toUpperCase$0(receiver) { | |
| 851 checkNull(receiver); | |
| 852 if (receiver is !String) return UNINTERCEPTED(receiver.toUpperCase()); | |
| 853 | |
| 854 throw new NotImplementedException(); | |
| 855 } | |
| 856 | |
| 857 builtin$trim$0(receiver) { | |
| 858 checkNull(receiver); | |
| 859 if (receiver is !String) return UNINTERCEPTED(receiver.trim()); | |
| 860 | |
| 861 throw new NotImplementedException(); | |
| 862 } | |
| OLD | NEW |