OLD | NEW |
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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 var dart, _js_helper, _js_primitives, dartx; | 5 var dart, dartx; |
6 (function (dart) { | 6 (function (dart) { |
7 'use strict'; | 7 'use strict'; |
8 | 8 |
9 // TODO(vsm): This is referenced (as init.globalState) from | |
10 // isolate_helper.dart. Where should it go? | |
11 // See: https://github.com/dart-lang/dev_compiler/issues/164 | |
12 dart.globalState = null; | |
13 | |
14 const defineProperty = Object.defineProperty; | 9 const defineProperty = Object.defineProperty; |
15 const getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor; | 10 const getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor; |
16 const getOwnPropertyNames = Object.getOwnPropertyNames; | 11 const getOwnPropertyNames = Object.getOwnPropertyNames; |
17 const getOwnPropertySymbols = Object.getOwnPropertySymbols; | 12 const getOwnPropertySymbols = Object.getOwnPropertySymbols; |
18 const hasOwnProperty = Object.prototype.hasOwnProperty; | 13 const hasOwnProperty = Object.prototype.hasOwnProperty; |
19 const slice = [].slice; | 14 const slice = [].slice; |
20 | 15 |
21 let _constructorSig = Symbol('sigCtor'); | 16 let _constructorSig = Symbol('sigCtor'); |
22 let _methodSig = Symbol("sig"); | 17 let _methodSig = Symbol("sig"); |
23 let _staticSig = Symbol("sigStatic"); | 18 let _staticSig = Symbol("sigStatic"); |
24 | 19 |
25 function getOwnNamesAndSymbols(obj) { | 20 function getOwnNamesAndSymbols(obj) { |
26 return getOwnPropertyNames(obj).concat(getOwnPropertySymbols(obj)); | 21 return getOwnPropertyNames(obj).concat(getOwnPropertySymbols(obj)); |
27 } | 22 } |
28 | 23 |
29 function dload(obj, field) { | 24 function dload(obj, field) { |
30 field = _canonicalFieldName(obj, field, [], field); | 25 field = _canonicalFieldName(obj, field, [], field); |
31 if (_getMethodType(obj, field) !== void 0) { | 26 if (_getMethodType(obj, field) !== void 0) { |
32 return dart.bind(obj, field); | 27 return dart.bind(obj, field); |
33 } | 28 } |
34 // TODO(vsm): Implement NSM robustly. An 'in' check breaks on certain | 29 // TODO(vsm): Implement NSM robustly. An 'in' check breaks on certain |
35 // types. hasOwnProperty doesn't chase the proto chain. | 30 // types. hasOwnProperty doesn't chase the proto chain. |
36 // Also, do we want an NSM on regular JS objects? | 31 // Also, do we want an NSM on regular JS objects? |
37 // See: https://github.com/dart-lang/dev_compiler/issues/169 | 32 // See: https://github.com/dart-lang/dev_compiler/issues/169 |
38 var result = obj[field]; | 33 let result = obj[field]; |
39 | 34 |
40 // TODO(vsm): Check this more robustly. | 35 // TODO(vsm): Check this more robustly. |
41 if (typeof result == "function" && !hasOwnProperty.call(obj, field)) { | 36 if (typeof result == "function" && !hasOwnProperty.call(obj, field)) { |
42 // This appears to be a method tearoff. Bind this. | 37 // This appears to be a method tearoff. Bind this. |
43 return result.bind(obj); | 38 return result.bind(obj); |
44 } | 39 } |
45 return result; | 40 return result; |
46 } | 41 } |
47 dart.dload = dload; | 42 dart.dload = dload; |
48 | 43 |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
101 function dcall(f/*, ...args*/) { | 96 function dcall(f/*, ...args*/) { |
102 let args = slice.call(arguments, 1); | 97 let args = slice.call(arguments, 1); |
103 let ftype = _getFunctionType(f); | 98 let ftype = _getFunctionType(f); |
104 return checkAndCall(f, ftype, void 0, args, 'call'); | 99 return checkAndCall(f, ftype, void 0, args, 'call'); |
105 } | 100 } |
106 dart.dcall = dcall; | 101 dart.dcall = dcall; |
107 | 102 |
108 let _extensionType = Symbol('extensionType'); | 103 let _extensionType = Symbol('extensionType'); |
109 function _canonicalFieldName(obj, name, args, displayName) { | 104 function _canonicalFieldName(obj, name, args, displayName) { |
110 if (obj[_extensionType]) { | 105 if (obj[_extensionType]) { |
111 var extension = dartx[name]; | 106 let extension = dartx[name]; |
112 if (extension) return extension; | 107 if (extension) return extension; |
113 // TODO(jmesserly): in the future we might have types that "overlay" Dart | 108 // TODO(jmesserly): in the future we might have types that "overlay" Dart |
114 // methods while also exposing the full native API, e.g. dart:html vs | 109 // methods while also exposing the full native API, e.g. dart:html vs |
115 // dart:dom. To support that we'd need to fall back to the normal name | 110 // dart:dom. To support that we'd need to fall back to the normal name |
116 // if an extension method wasn't found. | 111 // if an extension method wasn't found. |
117 throwNoSuchMethod(obj, displayName, args); | 112 throwNoSuchMethod(obj, displayName, args); |
118 } | 113 } |
119 return name; | 114 return name; |
120 } | 115 } |
121 | 116 |
(...skipping 15 matching lines...) Expand all Loading... |
137 } | 132 } |
138 dart.dindex = dindex; | 133 dart.dindex = dindex; |
139 | 134 |
140 function dsetindex(obj, index, value) { | 135 function dsetindex(obj, index, value) { |
141 return callMethod(obj, 'set', [index, value], '[]='); | 136 return callMethod(obj, 'set', [index, value], '[]='); |
142 } | 137 } |
143 dart.dsetindex = dsetindex; | 138 dart.dsetindex = dsetindex; |
144 | 139 |
145 function typeToString(type) { | 140 function typeToString(type) { |
146 if (typeof(type) == "function") { | 141 if (typeof(type) == "function") { |
147 var name = type.name; | 142 let name = type.name; |
148 var args = type[dart.typeArguments]; | 143 let args = type[dart.typeArguments]; |
149 if (args) { | 144 if (args) { |
150 name += '<'; | 145 name += '<'; |
151 for (var i = 0; i < args.length; ++i) { | 146 for (let i = 0; i < args.length; ++i) { |
152 if (i > 0) name += ', '; | 147 if (i > 0) name += ', '; |
153 name += typeToString(args[i]); | 148 name += typeToString(args[i]); |
154 } | 149 } |
155 name += '>'; | 150 name += '>'; |
156 } | 151 } |
157 return name; | 152 return name; |
158 } else { | 153 } else { |
159 return type.toString(); | 154 return type.toString(); |
160 } | 155 } |
161 } | 156 } |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
202 return null; | 197 return null; |
203 } | 198 } |
204 | 199 |
205 /** | 200 /** |
206 * Returns the runtime type of obj. This is the same as `obj.realRuntimeType` | 201 * Returns the runtime type of obj. This is the same as `obj.realRuntimeType` |
207 * but will not call an overridden getter. | 202 * but will not call an overridden getter. |
208 * | 203 * |
209 * Currently this will return null for non-Dart objects. | 204 * Currently this will return null for non-Dart objects. |
210 */ | 205 */ |
211 function realRuntimeType(obj) { | 206 function realRuntimeType(obj) { |
212 var result = checkPrimitiveType(obj); | 207 let result = checkPrimitiveType(obj); |
213 if (result !== null) return result; | 208 if (result !== null) return result; |
214 // TODO(vsm): Should we treat Dart and JS objects differently here? | 209 // TODO(vsm): Should we treat Dart and JS objects differently here? |
215 // E.g., we can check if obj instanceof core.Object to differentiate. | 210 // E.g., we can check if obj instanceof core.Object to differentiate. |
216 result = obj[_runtimeType]; | 211 result = obj[_runtimeType]; |
217 if (result) return result; | 212 if (result) return result; |
218 result = obj.constructor; | 213 result = obj.constructor; |
219 if (result == Function) { | 214 if (result == Function) { |
220 return getFunctionType(obj); | 215 return getFunctionType(obj); |
221 } | 216 } |
222 return result; | 217 return result; |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
314 // TODO(vsm): Handle Objects with call methods. Those are functions | 309 // TODO(vsm): Handle Objects with call methods. Those are functions |
315 // even if they do not *nominally* subtype core.Function. | 310 // even if they do not *nominally* subtype core.Function. |
316 if (isFunctionType(t1) && | 311 if (isFunctionType(t1) && |
317 isFunctionType(t2)) { | 312 isFunctionType(t2)) { |
318 return isFunctionSubType(t1, t2); | 313 return isFunctionSubType(t1, t2); |
319 } | 314 } |
320 return false; | 315 return false; |
321 } | 316 } |
322 | 317 |
323 function safeGetOwnProperty(obj, name) { | 318 function safeGetOwnProperty(obj, name) { |
324 var desc = getOwnPropertyDescriptor(obj, name); | 319 let desc = getOwnPropertyDescriptor(obj, name); |
325 if (desc) return desc.value; | 320 if (desc) return desc.value; |
326 } | 321 } |
327 | 322 |
328 function isClassSubType(t1, t2) { | 323 function isClassSubType(t1, t2) { |
329 // We support Dart's covariant generics with the caveat that we do not | 324 // We support Dart's covariant generics with the caveat that we do not |
330 // substitute bottom for dynamic in subtyping rules. | 325 // substitute bottom for dynamic in subtyping rules. |
331 // I.e., given T1, ..., Tn where at least one Ti != dynamic we disallow: | 326 // I.e., given T1, ..., Tn where at least one Ti != dynamic we disallow: |
332 // - S !<: S<T1, ..., Tn> | 327 // - S !<: S<T1, ..., Tn> |
333 // - S<dynamic, ..., dynamic> !<: S<T1, ..., Tn> | 328 // - S<dynamic, ..., dynamic> !<: S<T1, ..., Tn> |
334 t1 = canonicalType(t1); | 329 t1 = canonicalType(t1); |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
395 // TODO(vsm): Cache this if we start using it at runtime. | 390 // TODO(vsm): Cache this if we start using it at runtime. |
396 | 391 |
397 if (type instanceof AbstractFunctionType) { | 392 if (type instanceof AbstractFunctionType) { |
398 if (!_isTop(type.returnType, false)) return false; | 393 if (!_isTop(type.returnType, false)) return false; |
399 for (let i = 0; i < type.args.length; ++i) { | 394 for (let i = 0; i < type.args.length; ++i) { |
400 if (!_isBottom(type.args[i], true)) return false; | 395 if (!_isBottom(type.args[i], true)) return false; |
401 } | 396 } |
402 for (let i = 0; i < type.optionals.length; ++i) { | 397 for (let i = 0; i < type.optionals.length; ++i) { |
403 if (!_isBottom(type.optionals[i], true)) return false; | 398 if (!_isBottom(type.optionals[i], true)) return false; |
404 } | 399 } |
405 var names = getOwnPropertyNames(type.named); | 400 let names = getOwnPropertyNames(type.named); |
406 for (let i = 0; i < names.length; ++i) { | 401 for (let i = 0; i < names.length; ++i) { |
407 if (!_isBottom(type.named[names[i]], true)) return false; | 402 if (!_isBottom(type.named[names[i]], true)) return false; |
408 } | 403 } |
409 return true; | 404 return true; |
410 } | 405 } |
411 | 406 |
412 let typeArgs = safeGetOwnProperty(type, dart.typeArguments); | 407 let typeArgs = safeGetOwnProperty(type, dart.typeArguments); |
413 if (!typeArgs) return true; | 408 if (!typeArgs) return true; |
414 for (let t of typeArgs) { | 409 for (let t of typeArgs) { |
415 if (t != core.Object && t != dart.dynamic) return false; | 410 if (t != core.Object && t != dart.dynamic) return false; |
(...skipping 18 matching lines...) Expand all Loading... |
434 | 429 |
435 /** Checks that `x` is not null or undefined. */ | 430 /** Checks that `x` is not null or undefined. */ |
436 function notNull(x) { | 431 function notNull(x) { |
437 if (x == null) throwRuntimeError('expected not-null value'); | 432 if (x == null) throwRuntimeError('expected not-null value'); |
438 return x; | 433 return x; |
439 } | 434 } |
440 dart.notNull = notNull; | 435 dart.notNull = notNull; |
441 | 436 |
442 function _typeName(type) { | 437 function _typeName(type) { |
443 if (type === void 0) throwRuntimeError('Undefined type'); | 438 if (type === void 0) throwRuntimeError('Undefined type'); |
444 var name = type.name; | 439 let name = type.name; |
445 if (!name) throwRuntimeError('Unexpected type: ' + type); | 440 if (!name) throwRuntimeError('Unexpected type: ' + type); |
446 return name; | 441 return name; |
447 } | 442 } |
448 | 443 |
449 class AbstractFunctionType { | 444 class AbstractFunctionType { |
450 constructor() { | 445 constructor() { |
451 this._stringValue = null; | 446 this._stringValue = null; |
452 } | 447 } |
453 | 448 |
454 /// Check that a function of this type can be applied to | 449 /// Check that a function of this type can be applied to |
455 /// actuals. | 450 /// actuals. |
456 checkApply(actuals) { | 451 checkApply(actuals) { |
457 if (actuals.length < this.args.length) return false; | 452 if (actuals.length < this.args.length) return false; |
458 var index = 0; | 453 let index = 0; |
459 for(let i = 0; i < this.args.length; ++i) { | 454 for(let i = 0; i < this.args.length; ++i) { |
460 if (!instanceOfOrNull(actuals[i], this.args[i])) return false; | 455 if (!instanceOfOrNull(actuals[i], this.args[i])) return false; |
461 ++index; | 456 ++index; |
462 } | 457 } |
463 if (actuals.length == this.args.length) return true; | 458 if (actuals.length == this.args.length) return true; |
464 let extras = actuals.length - this.args.length; | 459 let extras = actuals.length - this.args.length; |
465 if (this.optionals.length > 0) { | 460 if (this.optionals.length > 0) { |
466 if (extras > this.optionals.length) return false; | 461 if (extras > this.optionals.length) return false; |
467 for(let i = 0, j=index; i < extras; ++i, ++j) { | 462 for(let i = 0, j=index; i < extras; ++i, ++j) { |
468 if (!instanceOfOrNull(actuals[j], this.optionals[i])) return false; | 463 if (!instanceOfOrNull(actuals[j], this.optionals[i])) return false; |
(...skipping 15 matching lines...) Expand all Loading... |
484 return false; | 479 return false; |
485 } | 480 } |
486 if (!instanceOfOrNull(opts[name], this.named[name])) return false; | 481 if (!instanceOfOrNull(opts[name], this.named[name])) return false; |
487 } | 482 } |
488 return true; | 483 return true; |
489 } | 484 } |
490 | 485 |
491 get name() { | 486 get name() { |
492 if (this._stringValue) return this._stringValue; | 487 if (this._stringValue) return this._stringValue; |
493 | 488 |
494 var buffer = '('; | 489 let buffer = '('; |
495 for (let i = 0; i < this.args.length; ++i) { | 490 for (let i = 0; i < this.args.length; ++i) { |
496 if (i > 0) { | 491 if (i > 0) { |
497 buffer += ', '; | 492 buffer += ', '; |
498 } | 493 } |
499 buffer += _typeName(this.args[i]); | 494 buffer += _typeName(this.args[i]); |
500 } | 495 } |
501 if (this.optionals.length > 0) { | 496 if (this.optionals.length > 0) { |
502 if (this.args.length > 0) buffer += ', '; | 497 if (this.args.length > 0) buffer += ', '; |
503 buffer += '['; | 498 buffer += '['; |
504 for (let i = 0; i < this.optionals.length; ++i) { | 499 for (let i = 0; i < this.optionals.length; ++i) { |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
543 /// dart.fn(cls, func) marks cls with the lazily computed | 538 /// dart.fn(cls, func) marks cls with the lazily computed |
544 /// runtime type as computed by func() | 539 /// runtime type as computed by func() |
545 /// dart.fn(cls, rType, argsT, extras) marks cls as having the | 540 /// dart.fn(cls, rType, argsT, extras) marks cls as having the |
546 /// runtime type dart.functionType(rType, argsT, extras) | 541 /// runtime type dart.functionType(rType, argsT, extras) |
547 function fn(closure/* ...args*/) { | 542 function fn(closure/* ...args*/) { |
548 // Closure and a lazy type constructor | 543 // Closure and a lazy type constructor |
549 if (arguments.length == 2) { | 544 if (arguments.length == 2) { |
550 defineLazyProperty(closure, _runtimeType, {get : arguments[1]}); | 545 defineLazyProperty(closure, _runtimeType, {get : arguments[1]}); |
551 return closure; | 546 return closure; |
552 } | 547 } |
553 var t; | 548 let t; |
554 if (arguments.length == 1) { | 549 if (arguments.length == 1) { |
555 // No type arguments, it's all dynamic | 550 // No type arguments, it's all dynamic |
556 let len = closure.length; | 551 let len = closure.length; |
557 let build = () => { | 552 let build = () => { |
558 let args = Array.apply(null, new Array(len)).map(() => core.Object); | 553 let args = Array.apply(null, new Array(len)).map(() => core.Object); |
559 return functionType(core.Object, args); | 554 return functionType(core.Object, args); |
560 }; | 555 }; |
561 // We could be called before Object is defined. | 556 // We could be called before Object is defined. |
562 if (core.Object === void 0) return fn(closure, build); | 557 if (core.Object === void 0) return fn(closure, build); |
563 t = build(); | 558 t = build(); |
564 } else { | 559 } else { |
565 // We're passed the piecewise components of the function type, | 560 // We're passed the piecewise components of the function type, |
566 // construct it. | 561 // construct it. |
567 let args = slice.call(arguments, 1); | 562 let args = slice.call(arguments, 1); |
568 t = functionType.apply(null, args); | 563 t = functionType.apply(null, args); |
569 } | 564 } |
570 setRuntimeType(closure, t); | 565 setRuntimeType(closure, t); |
571 return closure; | 566 return closure; |
572 } | 567 } |
573 dart.fn = fn; | 568 dart.fn = fn; |
574 | 569 |
575 function functionType(returnType, args, extra) { | 570 function functionType(returnType, args, extra) { |
576 // TODO(vsm): Cache / memomize? | 571 // TODO(vsm): Cache / memomize? |
577 var optionals; | 572 let optionals; |
578 var named; | 573 let named; |
579 if (extra === void 0) { | 574 if (extra === void 0) { |
580 optionals = []; | 575 optionals = []; |
581 named = {}; | 576 named = {}; |
582 } else if (extra instanceof Array) { | 577 } else if (extra instanceof Array) { |
583 optionals = extra; | 578 optionals = extra; |
584 named = {}; | 579 named = {}; |
585 } else { | 580 } else { |
586 optionals = []; | 581 optionals = []; |
587 named = extra; | 582 named = extra; |
588 } | 583 } |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
631 } | 626 } |
632 dart.typedef = typedef; | 627 dart.typedef = typedef; |
633 | 628 |
634 function isFunctionType(type) { | 629 function isFunctionType(type) { |
635 return isClassSubType(type, core.Function) || | 630 return isClassSubType(type, core.Function) || |
636 type instanceof AbstractFunctionType; | 631 type instanceof AbstractFunctionType; |
637 } | 632 } |
638 | 633 |
639 function getFunctionType(obj) { | 634 function getFunctionType(obj) { |
640 // TODO(vsm): Encode this properly on the function for Dart-generated code. | 635 // TODO(vsm): Encode this properly on the function for Dart-generated code. |
641 var args = Array.apply(null, new Array(obj.length)).map(() => core.Object); | 636 let args = Array.apply(null, new Array(obj.length)).map(() => core.Object); |
642 return functionType(dart.bottom, args); | 637 return functionType(dart.bottom, args); |
643 } | 638 } |
644 | 639 |
645 function isFunctionSubType(ft1, ft2) { | 640 function isFunctionSubType(ft1, ft2) { |
646 if (ft2 == core.Function) { | 641 if (ft2 == core.Function) { |
647 return true; | 642 return true; |
648 } | 643 } |
649 | 644 |
650 let ret1 = ft1.returnType; | 645 let ret1 = ft1.returnType; |
651 let ret2 = ft2.returnType; | 646 let ret2 = ft2.returnType; |
(...skipping 23 matching lines...) Expand all Loading... |
675 } | 670 } |
676 } | 671 } |
677 | 672 |
678 let optionals1 = ft1.optionals; | 673 let optionals1 = ft1.optionals; |
679 let optionals2 = ft2.optionals; | 674 let optionals2 = ft2.optionals; |
680 | 675 |
681 if (args1.length + optionals1.length < args2.length + optionals2.length) { | 676 if (args1.length + optionals1.length < args2.length + optionals2.length) { |
682 return false; | 677 return false; |
683 } | 678 } |
684 | 679 |
685 var j = 0; | 680 let j = 0; |
686 for (let i = args1.length; i < args2.length; ++i, ++j) { | 681 for (let i = args1.length; i < args2.length; ++i, ++j) { |
687 if (!isSubtype_(args2[i], optionals1[j], true)) { | 682 if (!isSubtype_(args2[i], optionals1[j], true)) { |
688 return false; | 683 return false; |
689 } | 684 } |
690 } | 685 } |
691 | 686 |
692 for (let i = 0; i < optionals2.length; ++i, ++j) { | 687 for (let i = 0; i < optionals2.length; ++i, ++j) { |
693 if (!isSubtype_(optionals2[i], optionals1[j], true)) { | 688 if (!isSubtype_(optionals2[i], optionals1[j], true)) { |
694 return false; | 689 return false; |
695 } | 690 } |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
832 for (let name of methodNames) { | 827 for (let name of methodNames) { |
833 let method = getOwnPropertyDescriptor(proto, name); | 828 let method = getOwnPropertyDescriptor(proto, name); |
834 defineProperty(proto, getExtensionSymbol(name), method); | 829 defineProperty(proto, getExtensionSymbol(name), method); |
835 } | 830 } |
836 // Ensure the signature is available too. | 831 // Ensure the signature is available too. |
837 // TODO(jmesserly): not sure if we can do this in a cleaner way. Essentially | 832 // TODO(jmesserly): not sure if we can do this in a cleaner way. Essentially |
838 // we need to copy the signature (and in the future, other data like | 833 // we need to copy the signature (and in the future, other data like |
839 // annotations) any time we copy a method as part of our metaprogramming. | 834 // annotations) any time we copy a method as part of our metaprogramming. |
840 // It might be more friendly to JS metaprogramming if we include this info | 835 // It might be more friendly to JS metaprogramming if we include this info |
841 // on the function. | 836 // on the function. |
842 var originalSigFn = getOwnPropertyDescriptor(type, _methodSig).get; | 837 let originalSigFn = getOwnPropertyDescriptor(type, _methodSig).get; |
843 defineMemoizedGetter(type, _methodSig, function() { | 838 defineMemoizedGetter(type, _methodSig, function() { |
844 var sig = originalSigFn(); | 839 let sig = originalSigFn(); |
845 for (let name of methodNames) { | 840 for (let name of methodNames) { |
846 sig[getExtensionSymbol(name)] = sig[name]; | 841 sig[getExtensionSymbol(name)] = sig[name]; |
847 } | 842 } |
848 return sig; | 843 return sig; |
849 }); | 844 }); |
850 } | 845 } |
851 dart.defineExtensionMembers = defineExtensionMembers; | 846 dart.defineExtensionMembers = defineExtensionMembers; |
852 | 847 |
853 function setBaseClass(derived, base) { | 848 function setBaseClass(derived, base) { |
854 // Link the extension to the type it's extending as a base class. | 849 // Link the extension to the type it's extending as a base class. |
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1141 _setStaticTypes(f, names); | 1136 _setStaticTypes(f, names); |
1142 } | 1137 } |
1143 dart.setSignature = setSignature; | 1138 dart.setSignature = setSignature; |
1144 | 1139 |
1145 let _value = Symbol('_value'); | 1140 let _value = Symbol('_value'); |
1146 /** | 1141 /** |
1147 * Looks up a sequence of [keys] in [map], recursively, and | 1142 * Looks up a sequence of [keys] in [map], recursively, and |
1148 * returns the result. If the value is not found, [valueFn] will be called to | 1143 * returns the result. If the value is not found, [valueFn] will be called to |
1149 * add it. For example: | 1144 * add it. For example: |
1150 * | 1145 * |
1151 * var map = new Map(); | 1146 * let map = new Map(); |
1152 * putIfAbsent(map, [1, 2, 'hi ', 'there '], () => 'world'); | 1147 * putIfAbsent(map, [1, 2, 'hi ', 'there '], () => 'world'); |
1153 * | 1148 * |
1154 * ... will create a Map with a structure like: | 1149 * ... will create a Map with a structure like: |
1155 * | 1150 * |
1156 * { 1: { 2: { 'hi ': { 'there ': 'world' } } } } | 1151 * { 1: { 2: { 'hi ': { 'there ': 'world' } } } } |
1157 */ | 1152 */ |
1158 function multiKeyPutIfAbsent(map, keys, valueFn) { | 1153 function multiKeyPutIfAbsent(map, keys, valueFn) { |
1159 for (let k of keys) { | 1154 for (let k of keys) { |
1160 let value = map.get(k); | 1155 let value = map.get(k); |
1161 if (!value) { | 1156 if (!value) { |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1240 return obj & 0x1FFFFFFF; | 1235 return obj & 0x1FFFFFFF; |
1241 case "string": | 1236 case "string": |
1242 // TODO(vsm): Call the JSString hashCode? | 1237 // TODO(vsm): Call the JSString hashCode? |
1243 return obj.length; | 1238 return obj.length; |
1244 } | 1239 } |
1245 return obj.hashCode; | 1240 return obj.hashCode; |
1246 } | 1241 } |
1247 dart.hashCode = hashCode; | 1242 dart.hashCode = hashCode; |
1248 | 1243 |
1249 function runtimeType(obj) { | 1244 function runtimeType(obj) { |
1250 var result = checkPrimitiveType(obj); | 1245 let result = checkPrimitiveType(obj); |
1251 if (result !== null) return result; | 1246 if (result !== null) return result; |
1252 return obj.runtimeType; | 1247 return obj.runtimeType; |
1253 } | 1248 } |
1254 dart.runtimeType = runtimeType; | 1249 dart.runtimeType = runtimeType; |
1255 | 1250 |
1256 function toString(obj) { | 1251 function toString(obj) { |
1257 if (obj == null) { | 1252 if (obj == null) { |
1258 return "null"; | 1253 return "null"; |
1259 } | 1254 } |
1260 return obj.toString(); | 1255 return obj.toString(); |
(...skipping 15 matching lines...) Expand all Loading... |
1276 return obj.noSuchMethod(invocation); | 1271 return obj.noSuchMethod(invocation); |
1277 } | 1272 } |
1278 dart.noSuchMethod = noSuchMethod; | 1273 dart.noSuchMethod = noSuchMethod; |
1279 | 1274 |
1280 class JsIterator { | 1275 class JsIterator { |
1281 constructor(dartIterator) { | 1276 constructor(dartIterator) { |
1282 this.dartIterator = dartIterator; | 1277 this.dartIterator = dartIterator; |
1283 } | 1278 } |
1284 next() { | 1279 next() { |
1285 let i = this.dartIterator; | 1280 let i = this.dartIterator; |
1286 var done = !i.moveNext(); | 1281 let done = !i.moveNext(); |
1287 return { done: done, value: done ? void 0 : i.current }; | 1282 return { done: done, value: done ? void 0 : i.current }; |
1288 } | 1283 } |
1289 } | 1284 } |
1290 dart.JsIterator = JsIterator; | 1285 dart.JsIterator = JsIterator; |
1291 | 1286 |
1292 // TODO(jmesserly): right now this is a sentinel. It should be a type object | 1287 // TODO(jmesserly): right now this is a sentinel. It should be a type object |
1293 // of some sort, assuming we keep around `dynamic` at runtime. | 1288 // of some sort, assuming we keep around `dynamic` at runtime. |
1294 dart.dynamic = { toString() { return 'dynamic'; }, get name() {return toString
();}}; | 1289 dart.dynamic = { toString() { return 'dynamic'; }, get name() {return toString
();}}; |
1295 dart.void = { toString() { return 'void'; }, get name() {return toString();}}; | 1290 dart.void = { toString() { return 'void'; }, get name() {return toString();}}; |
1296 dart.bottom = { toString() { return 'bottom'; }, get name() {return toString()
;}}; | 1291 dart.bottom = { toString() { return 'bottom'; }, get name() {return toString()
;}}; |
1297 | 1292 |
1298 dart.global = window || global; | 1293 dart.global = window || global; |
1299 dart.JsSymbol = Symbol; | 1294 dart.JsSymbol = Symbol; |
1300 | 1295 |
1301 // All libraries, including those that have referenced (lazyImport), | 1296 // Module support. This is a simplified module system for Dart. |
1302 // but not yet loaded. | 1297 // Longer term, we can easily migrate to an existing JS module system: |
1303 var libraries = new Map(); | 1298 // ES6, AMD, RequireJS, .... |
1304 | 1299 |
1305 // Completed libraries. | 1300 class LibraryLoader { |
1306 var loadedLibraries = new Set(); | 1301 constructor(name, defaultValue, imports, lazyImports, loader) { |
| 1302 this._name = name; |
| 1303 this._library = defaultValue ? defaultValue : {}; |
| 1304 this._imports = imports; |
| 1305 this._lazyImports = lazyImports; |
| 1306 this._loader = loader; |
1307 | 1307 |
1308 // Import a library by name. | 1308 // Cyclic import detection |
1309 // This is exported for REPL / JS interop convenience. | 1309 this._state = LibraryLoader.NOT_LOADED; |
1310 function import_(name) { | |
1311 let loaded = loadedLibraries.has(name); | |
1312 let value = libraries[name]; | |
1313 // TODO(vsm): Change this to a hard throw. | |
1314 // For now, we're missing some libraries. E.g., dart:js: | |
1315 // https://github.com/dart-lang/dev_compiler/issues/168 | |
1316 if (!loaded) { | |
1317 console.warn('Missing required module: ' + name); | |
1318 } else if (!value) { | |
1319 throwRuntimeError('Library import error: ' + name) | |
1320 } | 1310 } |
1321 return value; | 1311 |
| 1312 loadImports(pendingSet) { |
| 1313 return this.handleImports(this._imports, (lib) => lib.load(pendingSet)); |
| 1314 } |
| 1315 |
| 1316 deferLazyImports(pendingSet) { |
| 1317 return this.handleImports(this._lazyImports, |
| 1318 (lib) => { |
| 1319 pendingSet.add(lib._name); |
| 1320 return lib.stub(); |
| 1321 }); |
| 1322 } |
| 1323 |
| 1324 loadLazyImports(pendingSet) { |
| 1325 return this.handleImports(pendingSet, (lib) => lib.load()); |
| 1326 } |
| 1327 |
| 1328 handleImports(list, handler) { |
| 1329 let results = []; |
| 1330 for (let name of list) { |
| 1331 let lib = libraries[name]; |
| 1332 if (!lib) { |
| 1333 throwRuntimeError('Library not available: ' + name); |
| 1334 } |
| 1335 results.push(handler(lib)); |
| 1336 } |
| 1337 return results; |
| 1338 } |
| 1339 |
| 1340 load(inheritedPendingSet) { |
| 1341 // Check for cycles |
| 1342 if (this._state == LibraryLoader.LOADING) { |
| 1343 throwRuntimeError('Circular dependence on library: ' + this._name); |
| 1344 } else if (this._state >= LibraryLoader.LOADED) { |
| 1345 return this._library; |
| 1346 } |
| 1347 this._state = LibraryLoader.LOADING; |
| 1348 |
| 1349 // Handle imports and record lazy imports |
| 1350 let pendingSet = inheritedPendingSet ? inheritedPendingSet : new Set(); |
| 1351 let args = this.loadImports(pendingSet); |
| 1352 args = args.concat(this.deferLazyImports(pendingSet)); |
| 1353 |
| 1354 // Load the library |
| 1355 args.unshift(this._library); |
| 1356 this._loader.apply(null, args); |
| 1357 this._state = LibraryLoader.LOADED; |
| 1358 |
| 1359 // Handle lazy imports |
| 1360 if (inheritedPendingSet === void 0) { |
| 1361 // Drain the queue |
| 1362 this.loadLazyImports(pendingSet); |
| 1363 } |
| 1364 this._state = LibraryLoader.READY; |
| 1365 return this._library; |
| 1366 } |
| 1367 |
| 1368 stub() { |
| 1369 return this._library; |
| 1370 } |
| 1371 } |
| 1372 LibraryLoader.NOT_LOADED = 0; |
| 1373 LibraryLoader.LOADING = 1; |
| 1374 LibraryLoader.LOADED = 2; |
| 1375 LibraryLoader.READY = 3; |
| 1376 |
| 1377 // Map from name to LibraryLoader |
| 1378 let libraries = new Map(); |
| 1379 |
| 1380 function library(name, defaultValue, imports, lazyImports, loader) { |
| 1381 libraries[name] = |
| 1382 new LibraryLoader(name, defaultValue, imports, lazyImports, loader); |
| 1383 } |
| 1384 dart.library = library; |
| 1385 |
| 1386 function import_(libraryName) { |
| 1387 bootstrap(); |
| 1388 let loader = libraries[libraryName]; |
| 1389 return loader.load(); |
1322 } | 1390 } |
1323 dart.import = import_; | 1391 dart.import = import_; |
1324 | 1392 |
1325 function initializeLibraryStub(name) { | |
1326 // Create the library object if necessary. | |
1327 if (!libraries[name]) { | |
1328 libraries[name] = {}; | |
1329 } | |
1330 return libraries[name]; | |
1331 } | |
1332 const lazyImport = initializeLibraryStub; | |
1333 | |
1334 function defineLibrary(name, defaultValue) { | |
1335 if (loadedLibraries.has(name)) { | |
1336 throwRuntimeError('Library is already defined: ' + name); | |
1337 } | |
1338 var value; | |
1339 if (defaultValue) { | |
1340 var oldValue = libraries[name]; | |
1341 if (oldValue && oldValue != defaultValue) { | |
1342 throwRuntimeError( | |
1343 `Library ${name} cannot be redefined to ${defaultValue}`); | |
1344 } | |
1345 libraries[name] = value = defaultValue; | |
1346 } else { | |
1347 value = initializeLibraryStub(name); | |
1348 } | |
1349 loadedLibraries.add(name); | |
1350 return value; | |
1351 } | |
1352 | |
1353 function library(name, defaultValue, imports, lazyImports, module) { | |
1354 var args = []; | |
1355 var lib = defineLibrary(name, defaultValue); | |
1356 args.push(lib); | |
1357 for (var i = 0; i < imports.length; ++i) { | |
1358 lib = import_(imports[i]); | |
1359 args.push(lib); | |
1360 } | |
1361 for (var i = 0; i < lazyImports.length; ++i) { | |
1362 lib = lazyImport(lazyImports[i]); | |
1363 args.push(lib); | |
1364 } | |
1365 module.apply(null, args); | |
1366 } | |
1367 dart.library = library; | |
1368 | |
1369 function start(libraryName) { | 1393 function start(libraryName) { |
1370 let lib = import_(libraryName); | 1394 let library = import_(libraryName); |
1371 _isolate_helper.startRootIsolate(lib.main, []); | 1395 _isolate_helper.startRootIsolate(library.main, []); |
1372 } | 1396 } |
1373 dart.start = start; | 1397 dart.start = start; |
1374 | 1398 |
1375 let core = lazyImport('dart/core'); | 1399 // Libraries used in this file. |
1376 let collection = lazyImport('dart/collection'); | 1400 let core; |
1377 let async = lazyImport('dart/async'); | 1401 let collection; |
1378 let _interceptors = lazyImport('dart/_interceptors'); | 1402 let async; |
1379 let _isolate_helper = lazyImport('dart/_isolate_helper'); | 1403 let _interceptors; |
1380 let _js_helper = lazyImport('dart/_js_helper'); | 1404 let _isolate_helper; |
1381 _js_helper.checkNum = notNull; | 1405 let _js_helper; |
1382 let _js_primitives = lazyImport('dart/_js_primitives'); | 1406 let _js_primitives; |
1383 _js_primitives.printString = (s) => console.log(s); | |
1384 | 1407 |
1385 // TODO(vsm): DOM facades? | 1408 function bootstrap() { |
1386 // See: https://github.com/dart-lang/dev_compiler/issues/173 | 1409 if (core) return; |
1387 NodeList.prototype.get = function(i) { return this[i]; }; | |
1388 NamedNodeMap.prototype.get = function(i) { return this[i]; }; | |
1389 DOMTokenList.prototype.get = function(i) { return this[i]; }; | |
1390 | 1410 |
1391 /** Dart extension members. */ | 1411 let lazyImport = (name) => libraries[name].stub(); |
1392 dartx = dartx || {}; | |
1393 | 1412 |
| 1413 core = lazyImport('dart/core'); |
| 1414 collection = lazyImport('dart/collection'); |
| 1415 async = lazyImport('dart/async'); |
| 1416 _interceptors = lazyImport('dart/_interceptors'); |
| 1417 _isolate_helper = lazyImport('dart/_isolate_helper'); |
| 1418 _js_helper = lazyImport('dart/_js_helper'); |
| 1419 _js_helper.checkNum = notNull; |
| 1420 _js_primitives = lazyImport('dart/_js_primitives'); |
| 1421 _js_primitives.printString = (s) => console.log(s); |
| 1422 |
| 1423 // TODO(vsm): DOM facades? |
| 1424 // See: https://github.com/dart-lang/dev_compiler/issues/173 |
| 1425 NodeList.prototype.get = function(i) { return this[i]; }; |
| 1426 NamedNodeMap.prototype.get = function(i) { return this[i]; }; |
| 1427 DOMTokenList.prototype.get = function(i) { return this[i]; }; |
| 1428 |
| 1429 // TODO(vsm): This is referenced (as init.globalState) from |
| 1430 // isolate_helper.dart. Where should it go? |
| 1431 // See: https://github.com/dart-lang/dev_compiler/issues/164 |
| 1432 dart.globalState = null; |
| 1433 |
| 1434 /** Dart extension members. */ |
| 1435 dartx = dartx || {}; |
| 1436 } |
1394 })(dart || (dart = {})); | 1437 })(dart || (dart = {})); |
OLD | NEW |