| 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 |