OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 dart._js_helper; | 5 library dart._js_helper; |
6 | 6 |
7 import 'dart:collection'; | 7 import 'dart:collection'; |
8 | 8 |
9 import 'dart:_foreign_helper' show | 9 import 'dart:_foreign_helper' show |
10 JS, | 10 JS, |
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
236 } | 236 } |
237 result = JS('String', '# + String.fromCharCode.apply(#, #)', | 237 result = JS('String', '# + String.fromCharCode.apply(#, #)', |
238 result, null, subarray); | 238 result, null, subarray); |
239 } | 239 } |
240 return result; | 240 return result; |
241 } | 241 } |
242 | 242 |
243 static String stringFromCodePoints(codePoints) { | 243 static String stringFromCodePoints(codePoints) { |
244 List<int> a = <int>[]; | 244 List<int> a = <int>[]; |
245 for (var i in codePoints) { | 245 for (var i in codePoints) { |
246 if (i is !int) throw new ArgumentError(i); | 246 if (i is !int) throw argumentErrorValue(i); |
247 if (i <= 0xffff) { | 247 if (i <= 0xffff) { |
248 a.add(i); | 248 a.add(i); |
249 } else if (i <= 0x10ffff) { | 249 } else if (i <= 0x10ffff) { |
250 a.add(0xd800 + ((((i - 0x10000) >> 10) & 0x3ff))); | 250 a.add(0xd800 + ((((i - 0x10000) >> 10) & 0x3ff))); |
251 a.add(0xdc00 + (i & 0x3ff)); | 251 a.add(0xdc00 + (i & 0x3ff)); |
252 } else { | 252 } else { |
253 throw new ArgumentError(i); | 253 throw argumentErrorValue(i); |
254 } | 254 } |
255 } | 255 } |
256 return _fromCharCodeApply(a); | 256 return _fromCharCodeApply(a); |
257 } | 257 } |
258 | 258 |
259 static String stringFromCharCodes(charCodes) { | 259 static String stringFromCharCodes(charCodes) { |
260 for (var i in charCodes) { | 260 for (var i in charCodes) { |
261 if (i is !int) throw new ArgumentError(i); | 261 if (i is !int) throw argumentErrorValue(i); |
262 if (i < 0) throw new ArgumentError(i); | 262 if (i < 0) throw argumentErrorValue(i); |
263 if (i > 0xffff) return stringFromCodePoints(charCodes); | 263 if (i > 0xffff) return stringFromCodePoints(charCodes); |
264 } | 264 } |
265 return _fromCharCodeApply(charCodes); | 265 return _fromCharCodeApply(charCodes); |
266 } | 266 } |
267 | 267 |
268 static String stringFromCharCode(charCode) { | 268 static String stringFromCharCode(int charCode) { |
269 if (0 <= charCode) { | 269 if (0 <= charCode) { |
270 if (charCode <= 0xffff) { | 270 if (charCode <= 0xffff) { |
271 return JS('String', 'String.fromCharCode(#)', charCode); | 271 return JS('String', 'String.fromCharCode(#)', charCode); |
272 } | 272 } |
273 if (charCode <= 0x10ffff) { | 273 if (charCode <= 0x10ffff) { |
274 var bits = charCode - 0x10000; | 274 var bits = charCode - 0x10000; |
275 var low = 0xDC00 | (bits & 0x3ff); | 275 var low = 0xDC00 | (bits & 0x3ff); |
276 var high = 0xD800 | (bits >> 10); | 276 var high = 0xD800 | (bits >> 10); |
277 return JS('String', 'String.fromCharCode(#, #)', high, low); | 277 return JS('String', 'String.fromCharCode(#, #)', high, low); |
278 } | 278 } |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
423 | 423 |
424 static getWeekday(receiver) { | 424 static getWeekday(receiver) { |
425 int weekday = (receiver.isUtc) | 425 int weekday = (receiver.isUtc) |
426 ? JS('int', r'#.getUTCDay() + 0', lazyAsJsDate(receiver)) | 426 ? JS('int', r'#.getUTCDay() + 0', lazyAsJsDate(receiver)) |
427 : JS('int', r'#.getDay() + 0', lazyAsJsDate(receiver)); | 427 : JS('int', r'#.getDay() + 0', lazyAsJsDate(receiver)); |
428 // Adjust by one because JS weeks start on Sunday. | 428 // Adjust by one because JS weeks start on Sunday. |
429 return (weekday + 6) % 7 + 1; | 429 return (weekday + 6) % 7 + 1; |
430 } | 430 } |
431 | 431 |
432 static valueFromDateString(str) { | 432 static valueFromDateString(str) { |
433 if (str is !String) throw new ArgumentError(str); | 433 if (str is !String) throw argumentErrorValue(str); |
434 var value = JS('num', r'Date.parse(#)', str); | 434 var value = JS('num', r'Date.parse(#)', str); |
435 if (value.isNaN) throw new ArgumentError(str); | 435 if (value.isNaN) throw argumentErrorValue(str); |
436 return value; | 436 return value; |
437 } | 437 } |
438 | 438 |
439 static getProperty(object, key) { | 439 static getProperty(object, key) { |
440 if (object == null || object is bool || object is num || object is String) { | 440 if (object == null || object is bool || object is num || object is String) { |
441 throw new ArgumentError(object); | 441 throw argumentErrorValue(object); |
442 } | 442 } |
443 return JS('var', '#[#]', object, key); | 443 return JS('var', '#[#]', object, key); |
444 } | 444 } |
445 | 445 |
446 static void setProperty(object, key, value) { | 446 static void setProperty(object, key, value) { |
447 if (object == null || object is bool || object is num || object is String) { | 447 if (object == null || object is bool || object is num || object is String) { |
448 throw new ArgumentError(object); | 448 throw argumentErrorValue(object); |
449 } | 449 } |
450 JS('void', '#[#] = #', object, key, value); | 450 JS('void', '#[#] = #', object, key, value); |
451 } | 451 } |
452 | 452 |
453 static bool identicalImplementation(a, b) { | 453 static bool identicalImplementation(a, b) { |
454 return JS('bool', '# == null', a) | 454 return JS('bool', '# == null', a) |
455 ? JS('bool', '# == null', b) | 455 ? JS('bool', '# == null', b) |
456 : JS('bool', '# === #', a, b); | 456 : JS('bool', '# === #', a, b); |
457 } | 457 } |
458 | 458 |
459 static StackTrace extractStackTrace(Error error) { | 459 static StackTrace extractStackTrace(Error error) { |
460 return getTraceFromException(JS('', r'#.$thrownJsError', error)); | 460 return getTraceFromException(JS('', r'#.$thrownJsError', error)); |
461 } | 461 } |
462 } | 462 } |
| 463 /** |
| 464 * Diagnoses an indexing error. Returns the ArgumentError or RangeError that |
| 465 * describes the problem. |
| 466 */ |
| 467 @NoInline() |
| 468 Error diagnoseIndexError(indexable, index) { |
| 469 if (index is !int) return new ArgumentError.value(index, 'index'); |
| 470 int length = indexable.length; |
| 471 // The following returns the same error that would be thrown by calling |
| 472 // [RangeError.checkValidIndex] with no optional parameters provided. |
| 473 if (index < 0 || index >= length) { |
| 474 return new RangeError.index(index, indexable, 'index', null, length); |
| 475 } |
| 476 // The above should always match, but if it does not, use the following. |
| 477 return new RangeError.value(index, 'index'); |
| 478 } |
| 479 |
| 480 /** |
| 481 * Diagnoses a range error. Returns the ArgumentError or RangeError that |
| 482 * describes the problem. |
| 483 */ |
| 484 @NoInline() |
| 485 Error diagnoseRangeError(start, end, length) { |
| 486 if (start is! int) { |
| 487 return new ArgumentError.value(start, 'start'); |
| 488 } |
| 489 if (start < 0 || start > length) { |
| 490 return new RangeError.range(start, 0, length, 'start'); |
| 491 } |
| 492 if (end != null) { |
| 493 if (end is! int) { |
| 494 return new ArgumentError.value(end, 'end'); |
| 495 } |
| 496 if (end < start || end > length) { |
| 497 return new RangeError.range(end, start, length, 'end'); |
| 498 } |
| 499 } |
| 500 // The above should always match, but if it does not, use the following. |
| 501 return new ArgumentError.value(end, "end"); |
| 502 } |
463 | 503 |
464 stringLastIndexOfUnchecked(receiver, element, start) | 504 stringLastIndexOfUnchecked(receiver, element, start) |
465 => JS('int', r'#.lastIndexOf(#, #)', receiver, element, start); | 505 => JS('int', r'#.lastIndexOf(#, #)', receiver, element, start); |
466 | 506 |
467 | 507 |
| 508 /// 'factory' for constructing ArgumentError.value to keep the call sites small. |
| 509 @NoInline() |
| 510 ArgumentError argumentErrorValue(object) { |
| 511 return new ArgumentError.value(object); |
| 512 } |
| 513 |
468 checkNull(object) { | 514 checkNull(object) { |
469 if (object == null) throw new ArgumentError(null); | 515 if (object == null) throw argumentErrorValue(object); |
470 return object; | 516 return object; |
471 } | 517 } |
472 | 518 |
473 checkNum(value) { | 519 checkNum(value) { |
474 if (value is !num) { | 520 if (value is !num) throw argumentErrorValue(value); |
475 throw new ArgumentError(value); | |
476 } | |
477 return value; | 521 return value; |
478 } | 522 } |
479 | 523 |
480 checkInt(value) { | 524 checkInt(value) { |
481 if (value is !int) { | 525 if (value is !int) throw argumentErrorValue(value); |
482 throw new ArgumentError(value); | |
483 } | |
484 return value; | 526 return value; |
485 } | 527 } |
486 | 528 |
487 checkBool(value) { | 529 checkBool(value) { |
488 if (value is !bool) { | 530 if (value is !bool) throw argumentErrorValue(value); |
489 throw new ArgumentError(value); | |
490 } | |
491 return value; | 531 return value; |
492 } | 532 } |
493 | 533 |
494 checkString(value) { | 534 checkString(value) { |
495 if (value is !String) { | 535 if (value is !String) throw argumentErrorValue(value); |
496 throw new ArgumentError(value); | |
497 } | |
498 return value; | 536 return value; |
499 } | 537 } |
500 | 538 |
501 throwRuntimeError(message) { | 539 throwRuntimeError(message) { |
502 throw new RuntimeError(message); | 540 throw new RuntimeError(message); |
503 } | 541 } |
504 | 542 |
505 throwAbstractClassInstantiationError(className) { | 543 throwAbstractClassInstantiationError(className) { |
506 throw new AbstractClassInstantiationError(className); | 544 throw new AbstractClassInstantiationError(className); |
507 } | 545 } |
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
788 | 826 |
789 SyncIterable(this._generator, this._args); | 827 SyncIterable(this._generator, this._args); |
790 | 828 |
791 // TODO(jmesserly): this should be [Symbol.iterator]() method. Unfortunately | 829 // TODO(jmesserly): this should be [Symbol.iterator]() method. Unfortunately |
792 // we have no way of telling the compiler yet, so it will generate an extra | 830 // we have no way of telling the compiler yet, so it will generate an extra |
793 // layer of indirection that wraps the SyncIterator. | 831 // layer of indirection that wraps the SyncIterator. |
794 _jsIterator() => JS('', '#(...#)', _generator, _args); | 832 _jsIterator() => JS('', '#(...#)', _generator, _args); |
795 | 833 |
796 Iterator<E> get iterator => new SyncIterator<E>(_jsIterator()); | 834 Iterator<E> get iterator => new SyncIterator<E>(_jsIterator()); |
797 } | 835 } |
OLD | NEW |