| 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; | 5 var dart, _js_helper, _js_primitives; |
| 6 (function (dart) { | 6 (function (dart) { |
| 7 'use strict'; | 7 'use strict'; |
| 8 | 8 |
| 9 // TODO(vsm): This is referenced (as init.globalState) from | 9 // TODO(vsm): This is referenced (as init.globalState) from |
| 10 // isolate_helper.dart. Where should it go? | 10 // isolate_helper.dart. Where should it go? |
| (...skipping 24 matching lines...) Expand all Loading... |
| 35 let r = argDecl[1].split(FN_ARG_SPLIT); | 35 let r = argDecl[1].split(FN_ARG_SPLIT); |
| 36 for (let arg of r) { | 36 for (let arg of r) { |
| 37 arg.replace(FN_ARG, function(all, underscore, name){ | 37 arg.replace(FN_ARG, function(all, underscore, name){ |
| 38 args.push(name); | 38 args.push(name); |
| 39 }); | 39 }); |
| 40 } | 40 } |
| 41 return args; | 41 return args; |
| 42 } | 42 } |
| 43 | 43 |
| 44 function dload(obj, field) { | 44 function dload(obj, field) { |
| 45 field = _canonicalFieldName(obj, field); |
| 46 if (_getMethodType(obj, field) !== void 0) { |
| 47 return dart.tearoff(obj, field); |
| 48 } |
| 45 // TODO(vsm): Implement NSM robustly. An 'in' check breaks on certain | 49 // TODO(vsm): Implement NSM robustly. An 'in' check breaks on certain |
| 46 // types. hasOwnProperty doesn't chase the proto chain. | 50 // types. hasOwnProperty doesn't chase the proto chain. |
| 47 // Also, do we want an NSM on regular JS objects? | 51 // Also, do we want an NSM on regular JS objects? |
| 48 // See: https://github.com/dart-lang/dev_compiler/issues/169 | 52 // See: https://github.com/dart-lang/dev_compiler/issues/169 |
| 49 var result = obj[field]; | 53 var result = obj[field]; |
| 50 | 54 |
| 51 // TODO(vsm): Check this more robustly. | 55 // TODO(leafp): Decide whether to keep this for javascript |
| 56 // objects, or just use the javascript semantics. |
| 52 if (typeof result == "function" && | 57 if (typeof result == "function" && |
| 53 !Object.prototype.hasOwnProperty.call(obj, field)) { | 58 !Object.prototype.hasOwnProperty.call(obj, field)) { |
| 54 // This appears to be a method tearoff. Bind this. | 59 // This appears to be a method tearoff. Bind this. |
| 55 return result.bind(obj); | 60 return result.bind(obj); |
| 56 } | 61 } |
| 57 return result; | 62 return result; |
| 58 } | 63 } |
| 59 dart.dload = dload; | 64 dart.dload = dload; |
| 60 | 65 |
| 61 function dput(obj, field, value) { | 66 function dput(obj, field, value) { |
| 67 field = _canonicalFieldName(obj, field); |
| 62 // TODO(vsm): Implement NSM and type checks. | 68 // TODO(vsm): Implement NSM and type checks. |
| 63 // See: https://github.com/dart-lang/dev_compiler/issues/170 | 69 // See: https://github.com/dart-lang/dev_compiler/issues/170 |
| 64 obj[field] = value; | 70 obj[field] = value; |
| 65 } | 71 } |
| 66 dart.dput = dput; | 72 dart.dput = dput; |
| 67 | 73 |
| 68 // TODO(jmesserly): this should call noSuchMethod, not throw. | 74 // TODO(jmesserly): this should call noSuchMethod, not throw. |
| 69 function throwNoSuchMethod(obj, name, args, opt_func) { | 75 function throwNoSuchMethod(obj, name, args, opt_func) { |
| 70 if (obj === void 0) obj = opt_func; | 76 if (obj === void 0) obj = opt_func; |
| 71 throw new core.NoSuchMethodError(obj, name, args); | 77 throw new core.NoSuchMethodError(obj, name, args); |
| 72 } | 78 } |
| 73 | 79 |
| 74 function checkAndCall(f, obj, args, name) { | 80 function checkAndCall(f, ftype, obj, args, name) { |
| 75 if (!(f instanceof Function)) { | 81 if (!(f instanceof Function)) { |
| 82 // We're not a function (and hence not a method either) |
| 76 // Grab the `call` method if it's not a function. | 83 // Grab the `call` method if it's not a function. |
| 77 if (f !== null) f = f.call; | 84 if (f !== null) { |
| 85 ftype = _getMethodType(f, 'call'); |
| 86 f = f.call; |
| 87 } |
| 78 if (!(f instanceof Function)) { | 88 if (!(f instanceof Function)) { |
| 79 throwNoSuchMethod(obj, name, args); | 89 throwNoSuchMethod(obj, name, args); |
| 80 } | 90 } |
| 81 } | 91 } |
| 82 // TODO(jmesserly): enable this when we can fix => and methods. | 92 // If f is a function, but not a method (no method type) |
| 83 /* | 93 // then it should have been a function valued field, so |
| 84 let formals = formalParameterList(f); | 94 // get the type from the function. |
| 85 // TODO(vsm): Type check args! We need to encode sufficient type info on f. | 95 if (ftype === void 0) { |
| 86 if (formals.length < args.length) { | 96 ftype = _getFunctionType(f); |
| 87 throwNoSuchMethod(obj, name, args, f); | |
| 88 } else if (formals.length > args.length) { | |
| 89 for (let i = args.length; i < formals.length; ++i) { | |
| 90 if (formals[i].indexOf("opt$") != 0) { | |
| 91 throwNoSuchMethod(obj, name, args, f); | |
| 92 } | |
| 93 } | |
| 94 } | 97 } |
| 95 */ | 98 |
| 96 return f.apply(obj, args); | 99 // TODO(leafp): Allow JS objects to go through? |
| 100 if (!ftype) throw "Unable to find a type for applicand"; |
| 101 |
| 102 if (ftype.checkApply(args)) return f.apply(obj, args); |
| 103 // TODO(leafp): throw a type error (rather than NSM) |
| 104 // if the arity matches but the types are wrong. |
| 105 throwNoSuchMethod(obj, name, args, f); |
| 97 } | 106 } |
| 98 | 107 |
| 99 function dcall(f/*, ...args*/) { | 108 function dcall(f/*, ...args*/) { |
| 100 let args = Array.prototype.slice.call(arguments, 1); | 109 let args = Array.prototype.slice.call(arguments, 1); |
| 101 return checkAndCall(f, void 0, args, 'call'); | 110 let ftype = _getFunctionType(f); |
| 111 return checkAndCall(f, ftype, void 0, args, 'call'); |
| 102 } | 112 } |
| 103 dart.dcall = dcall; | 113 dart.dcall = dcall; |
| 104 | 114 |
| 105 // TODO(vsm): Automatically build this. | 115 // TODO(vsm): Automatically build this. |
| 106 // All dynamic methods should check for these. | 116 // All dynamic methods should check for these. |
| 107 // See: https://github.com/dart-lang/dev_compiler/issues/142 | 117 // See: https://github.com/dart-lang/dev_compiler/issues/142 |
| 108 var _extensionMethods = { | 118 var _extensionMethods = { |
| 109 // Lazy - as these symbols may not be loaded yet. | 119 // Lazy - as these symbols may not be loaded yet. |
| 110 // TODO(vsm): This should record / check the receiver type | 120 // TODO(vsm): This should record / check the receiver type |
| 111 // as well. E.g., only look for core.$map if the receiver | 121 // as well. E.g., only look for core.$map if the receiver |
| 112 // is an Iterable. | 122 // is an Iterable. |
| 113 'map': () => core.$map, | 123 'map': () => core.$map, |
| 114 }; | 124 }; |
| 115 | 125 |
| 126 // TODO(leafp): Integrate this with the eventual proper extension |
| 127 // method system. |
| 128 function _canonicalFieldName(obj, name) { |
| 129 if (obj[name] === void 0) return _extensionMethods[name](); |
| 130 return name; |
| 131 } |
| 132 |
| 116 function dsend(obj, method/*, ...args*/) { | 133 function dsend(obj, method/*, ...args*/) { |
| 117 let args = Array.prototype.slice.call(arguments, 2); | 134 let args = Array.prototype.slice.call(arguments, 2); |
| 118 var f = obj[method]; | 135 let symbol = _canonicalFieldName(obj, method); |
| 119 if (f === void 0) { | 136 let f = obj[symbol]; |
| 120 var symbol = _extensionMethods[method](); | 137 let ftype = _getMethodType(obj, symbol); |
| 121 f = obj[symbol]; | 138 return checkAndCall(f, ftype, obj, args, method); |
| 122 } | |
| 123 return checkAndCall(f, obj, args, method); | |
| 124 } | 139 } |
| 125 dart.dsend = dsend; | 140 dart.dsend = dsend; |
| 126 | 141 |
| 127 function dindex(obj, index) { | 142 function dindex(obj, index) { |
| 128 // TODO(jmesserly): remove this special case once Array extensions are | 143 // TODO(jmesserly): remove this special case once Array extensions are |
| 129 // hooked up. | 144 // hooked up. |
| 130 if (obj instanceof Array && realRuntimeType(index) == core.int) { | 145 if (obj instanceof Array && realRuntimeType(index) == core.int) { |
| 131 return obj[index]; | 146 return obj[index]; |
| 132 } | 147 } |
| 133 return checkAndCall(obj.get, obj, [index], '[]'); | 148 return checkAndCall(obj.get, obj, [index], '[]'); |
| (...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 437 dart.equals = equals; | 452 dart.equals = equals; |
| 438 | 453 |
| 439 /** Checks that `x` is not null or undefined. */ | 454 /** Checks that `x` is not null or undefined. */ |
| 440 function notNull(x) { | 455 function notNull(x) { |
| 441 if (x == null) throw 'expected not-null value'; | 456 if (x == null) throw 'expected not-null value'; |
| 442 return x; | 457 return x; |
| 443 } | 458 } |
| 444 dart.notNull = notNull; | 459 dart.notNull = notNull; |
| 445 | 460 |
| 446 function _typeName(type) { | 461 function _typeName(type) { |
| 462 if (type === void 0) throw "Undefined type"; |
| 447 var name = type.name; | 463 var name = type.name; |
| 448 if (!name) throw 'Unexpected type: ' + type; | 464 if (!name) throw 'Unexpected type: ' + type; |
| 449 return name; | 465 return name; |
| 450 } | 466 } |
| 451 | 467 |
| 452 class AbstractFunctionType { | 468 class AbstractFunctionType { |
| 453 constructor() { | 469 constructor() { |
| 454 this._stringValue = null; | 470 this._stringValue = null; |
| 455 } | 471 } |
| 456 | 472 |
| 473 /// Check that a function of this type can be applied to |
| 474 /// actuals. |
| 475 checkApply(actuals) { |
| 476 if (actuals.length < this.args.length) return false; |
| 477 var index = 0; |
| 478 for(let i = 0; i < this.args.length; ++i) { |
| 479 let t = realRuntimeType(actuals[i]); |
| 480 if (!isSubtype(t, this.args[i])) return false; |
| 481 ++index; |
| 482 } |
| 483 if (actuals.length == this.args.length) return true; |
| 484 let extras = actuals.length - this.args.length; |
| 485 if (this.optionals.length > 0) { |
| 486 if (extras > this.optionals.length) return false; |
| 487 for(let i = 0; i < extras; ++i) { |
| 488 let t = realRuntimeType(actuals[index + i]); |
| 489 if (!isSubtype(t, this.optionals[i])) return false; |
| 490 } |
| 491 return true; |
| 492 } |
| 493 // TODO(leafp): We can't tell when someone might be calling |
| 494 // something expecting an optional argument with named arguments |
| 495 |
| 496 if (extras != 1) return false; |
| 497 // An empty named list means no named arguments |
| 498 if (getOwnPropertyNames(this.named).length == 0) return false; |
| 499 let opts = actuals[index]; |
| 500 let names = getOwnPropertyNames(opts); |
| 501 // This is something other than a map |
| 502 if (names.length == 0) return false; |
| 503 for (name of names) { |
| 504 if (!(Object.prototype.hasOwnProperty.call(this.named, name))) { |
| 505 return false; |
| 506 } |
| 507 let t = realRuntimeType(opts[name]); |
| 508 if (!isSubtype(t, this.named[name])) return false; |
| 509 } |
| 510 return true; |
| 511 } |
| 512 |
| 457 get name() { | 513 get name() { |
| 458 if (this._stringValue) return this._stringValue; | 514 if (this._stringValue) return this._stringValue; |
| 459 | 515 |
| 460 var buffer = '('; | 516 var buffer = '('; |
| 461 for (let i = 0; i < this.args.length; ++i) { | 517 for (let i = 0; i < this.args.length; ++i) { |
| 462 if (i > 0) { | 518 if (i > 0) { |
| 463 buffer += ', '; | 519 buffer += ', '; |
| 464 } | 520 } |
| 465 buffer += _typeName(this.args[i]); | 521 buffer += _typeName(this.args[i]); |
| 466 } | 522 } |
| 467 if (this.optionals.length > 0) { | 523 if (this.optionals.length > 0) { |
| 468 if (this.args.length > 0) buffer += ', '; | 524 if (this.args.length > 0) buffer += ', '; |
| 469 buffer += '['; | 525 buffer += '['; |
| 470 for (let i = 0; i < this.optionals.length; ++i) { | 526 for (let i = 0; i < this.optionals.length; ++i) { |
| 471 if (i > 0) { | 527 if (i > 0) { |
| 472 buffer += ', '; | 528 buffer += ', '; |
| 473 } | 529 } |
| 474 buffer += _typeName(this.optionals[i]); | 530 buffer += _typeName(this.optionals[i]); |
| 475 } | 531 } |
| 476 buffer += ']'; | 532 buffer += ']'; |
| 477 } else if (this.named.length > 0) { | 533 } else if (Object.keys(this.named).length > 0) { |
| 478 if (this.args.length > 0) buffer += ', '; | 534 if (this.args.length > 0) buffer += ', '; |
| 479 buffer += '{'; | 535 buffer += '{'; |
| 480 let names = getOwnPropertyNames(this.named).sort(); | 536 let names = getOwnPropertyNames(this.named).sort(); |
| 481 for (let i = 0; i < names.length; ++i) { | 537 for (let i = 0; i < names.length; ++i) { |
| 482 if (i > 0) { | 538 if (i > 0) { |
| 483 buffer += ', '; | 539 buffer += ', '; |
| 484 } | 540 } |
| 485 buffer += names[i] + ': ' + _typeName(this.named[names[i]]); | 541 buffer += names[i] + ': ' + _typeName(this.named[names[i]]); |
| 486 } | 542 } |
| 487 buffer += '}'; | 543 buffer += '}'; |
| 488 } | 544 } |
| 489 | 545 |
| 490 buffer += ') -> ' + _typeName(this.returnType); | 546 buffer += ') -> ' + _typeName(this.returnType); |
| 491 this._stringValue = buffer; | 547 this._stringValue = buffer; |
| 492 return buffer; | 548 return buffer; |
| 493 } | 549 } |
| 494 } | 550 } |
| 495 | 551 |
| 496 class FunctionType extends AbstractFunctionType { | 552 class FunctionType extends AbstractFunctionType { |
| 497 constructor(returnType, args, optionals, named) { | 553 constructor(returnType, args, optionals, named) { |
| 498 super(); | 554 super(); |
| 499 this.returnType = returnType; | 555 this.returnType = returnType; |
| 500 this.args = args; | 556 this.args = args; |
| 501 this.optionals = optionals; | 557 this.optionals = optionals; |
| 502 this.named = named; | 558 this.named = named; |
| 503 } | 559 } |
| 504 } | 560 } |
| 505 | 561 |
| 562 /// Tag a closure with a type, using one of three forms: |
| 563 /// dart.fn(cls) marks cls has having no optional or named |
| 564 /// parameters, with all argument and return types as dynamic |
| 565 /// dart.fn(cls, func) marks cls with the lazily computed |
| 566 /// runtime type as computed by func() |
| 567 /// dart.fn(cls, rType, argsT, extras) marks cls as having the |
| 568 /// runtime type dart.functionType(rType, argsT, extras) |
| 569 function fn(closure/* ...args*/) { |
| 570 // Closure and a lazy type constructor |
| 571 if (arguments.length == 2) { |
| 572 defineLazyProperty(closure, _runtimeType, {get : arguments[1]}); |
| 573 return closure; |
| 574 } |
| 575 var t; |
| 576 if (arguments.length == 1) { |
| 577 // No type arguments, it's all dynamic |
| 578 let len = closure.length; |
| 579 let args = Array.apply(null, new Array(len)).map(() => dart.dynamic); |
| 580 t = functionType(dart.dynamic, args); |
| 581 } else { |
| 582 // We're passed the piecewise components of the function type, |
| 583 // construct it. |
| 584 let args = Array.prototype.slice.call(arguments, 1); |
| 585 t = functionType.apply(functionType, args); |
| 586 } |
| 587 setRuntimeType(closure, t); |
| 588 return closure; |
| 589 } |
| 590 dart.fn = fn; |
| 591 |
| 506 function functionType(returnType, args, extra) { | 592 function functionType(returnType, args, extra) { |
| 507 // TODO(vsm): Cache / memomize? | 593 // TODO(vsm): Cache / memomize? |
| 508 var optionals; | 594 var optionals; |
| 509 var named; | 595 var named; |
| 510 if (extra === void 0) { | 596 if (extra === void 0) { |
| 511 optionals = []; | 597 optionals = []; |
| 512 named = {}; | 598 named = {}; |
| 513 } else if (extra instanceof Array) { | 599 } else if (extra instanceof Array) { |
| 514 optionals = extra; | 600 optionals = extra; |
| 515 named = {}; | 601 named = {}; |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 678 function defineLazy(to, from) { | 764 function defineLazy(to, from) { |
| 679 for (let name of getOwnNamesAndSymbols(from)) { | 765 for (let name of getOwnNamesAndSymbols(from)) { |
| 680 defineLazyProperty(to, name, getOwnPropertyDescriptor(from, name)); | 766 defineLazyProperty(to, name, getOwnPropertyDescriptor(from, name)); |
| 681 } | 767 } |
| 682 } | 768 } |
| 683 // TODO(jmesserly): these are identical, but this makes it easier to grep for. | 769 // TODO(jmesserly): these are identical, but this makes it easier to grep for. |
| 684 dart.defineLazyClass = defineLazy; | 770 dart.defineLazyClass = defineLazy; |
| 685 dart.defineLazyProperties = defineLazy; | 771 dart.defineLazyProperties = defineLazy; |
| 686 dart.defineLazyClassGeneric = defineLazyProperty; | 772 dart.defineLazyClassGeneric = defineLazyProperty; |
| 687 | 773 |
| 774 function defineMemoizedGetter(obj, name, get) { |
| 775 let cache = null; |
| 776 function getter() { |
| 777 if (cache != null) return cache; |
| 778 cache = get(); |
| 779 get = null; |
| 780 return cache; |
| 781 } |
| 782 defineProperty(obj, name, {get : getter}); |
| 783 } |
| 784 |
| 688 function copyPropertiesHelper(to, from, names) { | 785 function copyPropertiesHelper(to, from, names) { |
| 689 for (let name of names) { | 786 for (let name of names) { |
| 690 defineProperty(to, name, getOwnPropertyDescriptor(from, name)); | 787 defineProperty(to, name, getOwnPropertyDescriptor(from, name)); |
| 691 } | 788 } |
| 692 return to; | 789 return to; |
| 693 } | 790 } |
| 694 | 791 |
| 695 /** | 792 /** |
| 696 * Copy properties from source to destination object. | 793 * Copy properties from source to destination object. |
| 697 * This operation is commonly called `mixin` in JS. | 794 * This operation is commonly called `mixin` in JS. |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 771 } | 868 } |
| 772 // Run base initializer. | 869 // Run base initializer. |
| 773 let init = base.prototype[base.name]; | 870 let init = base.prototype[base.name]; |
| 774 if (init) init.apply(this, arguments); | 871 if (init) init.apply(this, arguments); |
| 775 } | 872 } |
| 776 } | 873 } |
| 777 // Copy each mixin's methods, with later ones overwriting earlier entries. | 874 // Copy each mixin's methods, with later ones overwriting earlier entries. |
| 778 for (let m of mixins) { | 875 for (let m of mixins) { |
| 779 copyProperties(Mixin.prototype, m.prototype); | 876 copyProperties(Mixin.prototype, m.prototype); |
| 780 } | 877 } |
| 878 |
| 879 // Set the signature of the Mixin class to be the composition |
| 880 // of the signatures of the mixins. |
| 881 dart.setSignature(Mixin, { |
| 882 methods : () => { |
| 883 let s = {}; |
| 884 for (let m of mixins) { |
| 885 copyProperties(s, m[_methodSig]); |
| 886 } |
| 887 return s; |
| 888 } |
| 889 }); |
| 890 |
| 781 // Save mixins for reflection | 891 // Save mixins for reflection |
| 782 Mixin[dart.mixins] = mixins; | 892 Mixin[dart.mixins] = mixins; |
| 783 return Mixin; | 893 return Mixin; |
| 784 } | 894 } |
| 785 dart.mixin = mixin; | 895 dart.mixin = mixin; |
| 786 | 896 |
| 787 /** | 897 /** |
| 788 * Creates a dart:collection LinkedHashMap. | 898 * Creates a dart:collection LinkedHashMap. |
| 789 * | 899 * |
| 790 * For a map with string keys an object literal can be used, for example | 900 * For a map with string keys an object literal can be used, for example |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 882 } | 992 } |
| 883 map.set(arg, value); | 993 map.set(arg, value); |
| 884 } | 994 } |
| 885 } | 995 } |
| 886 return value; | 996 return value; |
| 887 } | 997 } |
| 888 return makeGenericType; | 998 return makeGenericType; |
| 889 } | 999 } |
| 890 dart.generic = generic; | 1000 dart.generic = generic; |
| 891 | 1001 |
| 1002 let _methodSig = Symbol("sig"); |
| 1003 let _staticSig = Symbol("sigStatic"); |
| 1004 |
| 1005 /// Get the type of a function using the store runtime type |
| 1006 function _getFunctionType(f) { |
| 1007 return f[_runtimeType]; |
| 1008 } |
| 1009 |
| 1010 /// Get the type of a method using the stored signature |
| 1011 function _getMethodType(obj, name) { |
| 1012 if (obj === void 0) return void 0; |
| 1013 if (obj == null) return void 0; |
| 1014 let sigObj = obj.__proto__.constructor[_methodSig]; |
| 1015 if (sigObj === void 0) return void 0; |
| 1016 let sig = sigObj[name]; |
| 1017 return sig; |
| 1018 } |
| 1019 |
| 1020 /// Given an object and a method name, tear off the method. |
| 1021 /// Sets the runtime type of the torn off method appropriately, |
| 1022 /// and also binds the object. |
| 1023 /// TODO(leafp): Consider caching the tearoff on the object? |
| 1024 function tearoff(obj, name) { |
| 1025 let f = obj[name].bind(obj); |
| 1026 let sig = _getMethodType(obj, name) |
| 1027 assert(sig); |
| 1028 setRuntimeType(f, sig); |
| 1029 return f; |
| 1030 } |
| 1031 dart.tearoff = tearoff; |
| 1032 |
| 1033 // Set up the method signature field on the constructor |
| 1034 function _setMethodSignature(f, sigF) { |
| 1035 defineMemoizedGetter(f, _methodSig, () => { |
| 1036 let sigObj = sigF(); |
| 1037 sigObj.__proto__ = f.__proto__[_methodSig]; |
| 1038 return sigObj; |
| 1039 }); |
| 1040 } |
| 1041 |
| 1042 // Set up the static signature field on the constructor |
| 1043 function _setStaticSignature(f, sigF) { |
| 1044 defineMemoizedGetter(f, _staticSig, sigF); |
| 1045 } |
| 1046 |
| 1047 // Set the lazily computed runtime type field on static methods |
| 1048 function _setStaticTypes(f, names) { |
| 1049 for (let name of names) { |
| 1050 function getT() { return f[_staticSig][name];}; |
| 1051 defineProperty(f[name], _runtimeType, {get : getT}); |
| 1052 } |
| 1053 } |
| 1054 |
| 1055 /// Set up the type signature of a class (constructor object) |
| 1056 /// f is a constructor object |
| 1057 /// signature is an object containing optional properties as follows: |
| 1058 /// methods: A function returning an object mapping method names |
| 1059 /// to method types. The function is evaluated lazily and cached. |
| 1060 /// statics: A function returning an object mapping static method |
| 1061 /// names to types. The function is evalutated lazily and cached. |
| 1062 /// names: An array of the names of the static methods. Used to |
| 1063 /// permit eagerly setting the runtimeType field on the methods |
| 1064 /// while still lazily computing the type descriptor object. |
| 1065 function setSignature(f, signature) { |
| 1066 let methods = |
| 1067 ('methods' in signature) ? signature.methods : () => ({}); |
| 1068 let statics = |
| 1069 ('statics' in signature) ? signature.statics : () => ({}); |
| 1070 let names = |
| 1071 ('names' in signature) ? signature.names : []; |
| 1072 _setMethodSignature(f, methods); |
| 1073 _setStaticSignature(f, statics); |
| 1074 _setStaticTypes(f, names); |
| 1075 }; |
| 1076 dart.setSignature = setSignature; |
| 1077 |
| 892 let _value = Symbol('_value'); | 1078 let _value = Symbol('_value'); |
| 893 /** | 1079 /** |
| 894 * Looks up a sequence of [keys] in [map], recursively, and | 1080 * Looks up a sequence of [keys] in [map], recursively, and |
| 895 * returns the result. If the value is not found, [valueFn] will be called to | 1081 * returns the result. If the value is not found, [valueFn] will be called to |
| 896 * add it. For example: | 1082 * add it. For example: |
| 897 * | 1083 * |
| 898 * var map = new Map(); | 1084 * var map = new Map(); |
| 899 * putIfAbsent(map, [1, 2, 'hi ', 'there '], () => 'world'); | 1085 * putIfAbsent(map, [1, 2, 'hi ', 'there '], () => 'world'); |
| 900 * | 1086 * |
| 901 * ... will create a Map with a structure like: | 1087 * ... will create a Map with a structure like: |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1019 next() { | 1205 next() { |
| 1020 let i = this.dartIterator; | 1206 let i = this.dartIterator; |
| 1021 var done = !i.moveNext(); | 1207 var done = !i.moveNext(); |
| 1022 return { done: done, value: done ? void 0 : i.current }; | 1208 return { done: done, value: done ? void 0 : i.current }; |
| 1023 } | 1209 } |
| 1024 } | 1210 } |
| 1025 dart.JsIterator = JsIterator; | 1211 dart.JsIterator = JsIterator; |
| 1026 | 1212 |
| 1027 // TODO(jmesserly): right now this is a sentinel. It should be a type object | 1213 // TODO(jmesserly): right now this is a sentinel. It should be a type object |
| 1028 // of some sort, assuming we keep around `dynamic` at runtime. | 1214 // of some sort, assuming we keep around `dynamic` at runtime. |
| 1029 dart.dynamic = { toString() { return 'dynamic'; } }; | 1215 dart.dynamic = { toString() { return 'dynamic'; }, get name() {return toString
();}}; |
| 1030 dart.void = { toString() { return 'void'; } }; | 1216 dart.void = { toString() { return 'void'; }, get name() {return toString();}}; |
| 1031 dart.bottom = { toString() { return 'bottom'; } }; | 1217 dart.bottom = { toString() { return 'bottom'; }, get name() {return toString()
;}}; |
| 1032 | 1218 |
| 1033 dart.global = window || global; | 1219 dart.global = window || global; |
| 1034 dart.JsSymbol = Symbol; | 1220 dart.JsSymbol = Symbol; |
| 1035 | 1221 |
| 1036 function import_(value) { | 1222 function import_(value) { |
| 1037 // TODO(vsm): Change this to a hard throw. | 1223 // TODO(vsm): Change this to a hard throw. |
| 1038 // For now, we're missing some libraries. E.g., dart:js: | 1224 // For now, we're missing some libraries. E.g., dart:js: |
| 1039 // https://github.com/dart-lang/dev_compiler/issues/168 | 1225 // https://github.com/dart-lang/dev_compiler/issues/168 |
| 1040 if (!value) { | 1226 if (!value) { |
| 1041 console.log('missing required module'); | 1227 console.log('missing required module'); |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1095 Number.prototype['>'] = function(arg) { return this.valueOf() > arg; }; | 1281 Number.prototype['>'] = function(arg) { return this.valueOf() > arg; }; |
| 1096 Number.prototype['+'] = function(arg) { return this.valueOf() + arg; }; | 1282 Number.prototype['+'] = function(arg) { return this.valueOf() + arg; }; |
| 1097 | 1283 |
| 1098 // TODO(vsm): DOM facades? | 1284 // TODO(vsm): DOM facades? |
| 1099 // See: https://github.com/dart-lang/dev_compiler/issues/173 | 1285 // See: https://github.com/dart-lang/dev_compiler/issues/173 |
| 1100 NodeList.prototype.get = function(i) { return this[i]; }; | 1286 NodeList.prototype.get = function(i) { return this[i]; }; |
| 1101 NamedNodeMap.prototype.get = function(i) { return this[i]; }; | 1287 NamedNodeMap.prototype.get = function(i) { return this[i]; }; |
| 1102 DOMTokenList.prototype.get = function(i) { return this[i]; }; | 1288 DOMTokenList.prototype.get = function(i) { return this[i]; }; |
| 1103 | 1289 |
| 1104 })(dart || (dart = {})); | 1290 })(dart || (dart = {})); |
| OLD | NEW |