| 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; | 5 var dart, _js_helper; |
| 6 (function (dart) { | 6 (function (dart) { |
| 7 'use strict'; | 7 'use strict'; |
| 8 | 8 |
| 9 let defineProperty = Object.defineProperty; | 9 let defineProperty = Object.defineProperty; |
| 10 let getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor; | 10 let getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor; |
| 11 let getOwnPropertyNames = Object.getOwnPropertyNames; | 11 let getOwnPropertyNames = Object.getOwnPropertyNames; |
| 12 let getOwnPropertySymbols = Object.getOwnPropertySymbols; | 12 let getOwnPropertySymbols = Object.getOwnPropertySymbols; |
| 13 | 13 |
| 14 function getOwnNamesAndSymbols(obj) { |
| 15 return getOwnPropertyNames(obj).concat(getOwnPropertySymbols(obj)); |
| 16 } |
| 17 |
| 14 // Adapted from Angular.js | 18 // Adapted from Angular.js |
| 15 let FN_ARGS = /^function\s*[^\(]*\(\s*([^\)]*)\)/m; | 19 let FN_ARGS = /^function\s*[^\(]*\(\s*([^\)]*)\)/m; |
| 16 let FN_ARG_SPLIT = /,/; | 20 let FN_ARG_SPLIT = /,/; |
| 17 let FN_ARG = /^\s*(_?)(\S+?)\1\s*$/; | 21 let FN_ARG = /^\s*(_?)(\S+?)\1\s*$/; |
| 18 let STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg; | 22 let STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg; |
| 19 | 23 |
| 20 function formalParameterList(fn) { | 24 function formalParameterList(fn) { |
| 21 let fnText,argDecl; | 25 let fnText,argDecl; |
| 22 let args=[]; | 26 let args=[]; |
| 23 fnText = fn.toString().replace(STRIP_COMMENTS, ''); | 27 fnText = fn.toString().replace(STRIP_COMMENTS, ''); |
| 24 argDecl = fnText.match(FN_ARGS); | 28 argDecl = fnText.match(FN_ARGS); |
| 25 | 29 |
| 26 let r = argDecl[1].split(FN_ARG_SPLIT); | 30 let r = argDecl[1].split(FN_ARG_SPLIT); |
| 27 for(let a in r) { | 31 for (let arg of r) { |
| 28 let arg = r[a]; | |
| 29 arg.replace(FN_ARG, function(all, underscore, name){ | 32 arg.replace(FN_ARG, function(all, underscore, name){ |
| 30 args.push(name); | 33 args.push(name); |
| 31 }); | 34 }); |
| 32 } | 35 } |
| 33 return args; | 36 return args; |
| 34 } | 37 } |
| 35 | 38 |
| 36 function dload(obj, field) { | 39 function dload(obj, field) { |
| 37 if (!(field in obj)) { | 40 if (!(field in obj)) { |
| 38 throw new core.NoSuchMethodError(obj, field); | 41 throw new core.NoSuchMethodError(obj, field); |
| (...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 317 } | 320 } |
| 318 | 321 |
| 319 // TODO(jmesserly): this isn't currently used, but it could be if we want | 322 // TODO(jmesserly): this isn't currently used, but it could be if we want |
| 320 // `obj is NonGroundType<T,S>` to be rejected at runtime instead of compile | 323 // `obj is NonGroundType<T,S>` to be rejected at runtime instead of compile |
| 321 // time. | 324 // time. |
| 322 function isGroundType(type) { | 325 function isGroundType(type) { |
| 323 // TODO(vsm): Cache this if we start using it at runtime. | 326 // TODO(vsm): Cache this if we start using it at runtime. |
| 324 | 327 |
| 325 if (type instanceof AbstractFunctionType) { | 328 if (type instanceof AbstractFunctionType) { |
| 326 if (!_isTop(type.returnType, false)) return false; | 329 if (!_isTop(type.returnType, false)) return false; |
| 327 for (var i = 0; i < type.args.length; ++i) { | 330 for (let i = 0; i < type.args.length; ++i) { |
| 328 if (!_isBottom(type.args[i], true)) return false; | 331 if (!_isBottom(type.args[i], true)) return false; |
| 329 } | 332 } |
| 330 for (var i = 0; i < type.optionals.length; ++i) { | 333 for (let i = 0; i < type.optionals.length; ++i) { |
| 331 if (!_isBottom(type.optionals[i], true)) return false; | 334 if (!_isBottom(type.optionals[i], true)) return false; |
| 332 } | 335 } |
| 333 var names = Object.getOwnPropertyNames(type.named); | 336 var names = getOwnPropertyNames(type.named); |
| 334 for (var i = 0; i < names.length; ++i) { | 337 for (let i = 0; i < names.length; ++i) { |
| 335 if (!_isBottom(type.named[names[i]], true)) return false; | 338 if (!_isBottom(type.named[names[i]], true)) return false; |
| 336 } | 339 } |
| 337 return true; | 340 return true; |
| 338 } | 341 } |
| 339 | 342 |
| 340 let typeArgs = safeGetOwnProperty(type, dart.typeArguments); | 343 let typeArgs = safeGetOwnProperty(type, dart.typeArguments); |
| 341 if (!typeArgs) return true; | 344 if (!typeArgs) return true; |
| 342 for (let t of typeArgs) { | 345 for (let t of typeArgs) { |
| 343 if (t != core.Object && t != dart.dynamic) return false; | 346 if (t != core.Object && t != dart.dynamic) return false; |
| 344 } | 347 } |
| (...skipping 30 matching lines...) Expand all Loading... |
| 375 | 378 |
| 376 class AbstractFunctionType { | 379 class AbstractFunctionType { |
| 377 constructor() { | 380 constructor() { |
| 378 this._stringValue = null; | 381 this._stringValue = null; |
| 379 } | 382 } |
| 380 | 383 |
| 381 get name() { | 384 get name() { |
| 382 if (this._stringValue) return this._stringValue; | 385 if (this._stringValue) return this._stringValue; |
| 383 | 386 |
| 384 var buffer = '('; | 387 var buffer = '('; |
| 385 for (var i = 0; i < this.args.length; ++i) { | 388 for (let i = 0; i < this.args.length; ++i) { |
| 386 if (i > 0) { | 389 if (i > 0) { |
| 387 buffer += ', '; | 390 buffer += ', '; |
| 388 } | 391 } |
| 389 buffer += _typeName(this.args[i]); | 392 buffer += _typeName(this.args[i]); |
| 390 } | 393 } |
| 391 if (this.optionals.length > 0) { | 394 if (this.optionals.length > 0) { |
| 392 if (this.args.length > 0) buffer += ', '; | 395 if (this.args.length > 0) buffer += ', '; |
| 393 buffer += '['; | 396 buffer += '['; |
| 394 for (var i = 0; i < this.optionals.length; ++i) { | 397 for (let i = 0; i < this.optionals.length; ++i) { |
| 395 if (i > 0) { | 398 if (i > 0) { |
| 396 buffer += ', '; | 399 buffer += ', '; |
| 397 } | 400 } |
| 398 buffer += _typeName(this.optionals[i]); | 401 buffer += _typeName(this.optionals[i]); |
| 399 } | 402 } |
| 400 buffer += ']'; | 403 buffer += ']'; |
| 401 } else if (this.named.length > 0) { | 404 } else if (this.named.length > 0) { |
| 402 if (this.args.length > 0) buffer += ', '; | 405 if (this.args.length > 0) buffer += ', '; |
| 403 buffer += '{'; | 406 buffer += '{'; |
| 404 let names = Object.getOwnPropertyNames(this.named).sort(); | 407 let names = getOwnPropertyNames(this.named).sort(); |
| 405 for (var i = 0; i < names.length; ++i) { | 408 for (let i = 0; i < names.length; ++i) { |
| 406 if (i > 0) { | 409 if (i > 0) { |
| 407 buffer += ', '; | 410 buffer += ', '; |
| 408 } | 411 } |
| 409 buffer += names[i] + ': ' + _typeName(this.named[names[i]]); | 412 buffer += names[i] + ': ' + _typeName(this.named[names[i]]); |
| 410 } | 413 } |
| 411 buffer += '}'; | 414 buffer += '}'; |
| 412 } | 415 } |
| 413 | 416 |
| 414 buffer += ') -> ' + _typeName(this.returnType); | 417 buffer += ') -> ' + _typeName(this.returnType); |
| 415 this._stringValue = buffer; | 418 this._stringValue = buffer; |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 516 } | 519 } |
| 517 } | 520 } |
| 518 | 521 |
| 519 let args1 = ft1.args; | 522 let args1 = ft1.args; |
| 520 let args2 = ft2.args; | 523 let args2 = ft2.args; |
| 521 | 524 |
| 522 if (args1.length > args2.length) { | 525 if (args1.length > args2.length) { |
| 523 return false; | 526 return false; |
| 524 } | 527 } |
| 525 | 528 |
| 526 for (var i = 0; i < args1.length; ++i) { | 529 for (let i = 0; i < args1.length; ++i) { |
| 527 if (!isSubtype_(args2[i], args1[i], true)) { | 530 if (!isSubtype_(args2[i], args1[i], true)) { |
| 528 return false; | 531 return false; |
| 529 } | 532 } |
| 530 } | 533 } |
| 531 | 534 |
| 532 let optionals1 = ft1.optionals; | 535 let optionals1 = ft1.optionals; |
| 533 let optionals2 = ft2.optionals; | 536 let optionals2 = ft2.optionals; |
| 534 | 537 |
| 535 if (args1.length + optionals1.length < args2.length + optionals2.length) { | 538 if (args1.length + optionals1.length < args2.length + optionals2.length) { |
| 536 return false; | 539 return false; |
| 537 } | 540 } |
| 538 | 541 |
| 539 var j = 0; | 542 var j = 0; |
| 540 for (var i = args1.length; i < args2.length; ++i, ++j) { | 543 for (let i = args1.length; i < args2.length; ++i, ++j) { |
| 541 if (!isSubtype_(args2[i], optionals1[j], true)) { | 544 if (!isSubtype_(args2[i], optionals1[j], true)) { |
| 542 return false; | 545 return false; |
| 543 } | 546 } |
| 544 } | 547 } |
| 545 | 548 |
| 546 for (var i = 0; i < optionals2.length; ++i, ++j) { | 549 for (let i = 0; i < optionals2.length; ++i, ++j) { |
| 547 if (!isSubtype_(optionals2[i], optionals1[j], true)) { | 550 if (!isSubtype_(optionals2[i], optionals1[j], true)) { |
| 548 return false; | 551 return false; |
| 549 } | 552 } |
| 550 } | 553 } |
| 551 | 554 |
| 552 let named1 = ft1.named; | 555 let named1 = ft1.named; |
| 553 let named2 = ft2.named; | 556 let named2 = ft2.named; |
| 554 | 557 |
| 555 let names = Object.getOwnPropertyNames(named2); | 558 let names = getOwnPropertyNames(named2); |
| 556 for (var i = 0; i < names.length; ++i) { | 559 for (let i = 0; i < names.length; ++i) { |
| 557 let name = names[i]; | 560 let name = names[i]; |
| 558 let n1 = named1[name] | 561 let n1 = named1[name]; |
| 559 let n2 = named2[name]; | 562 let n2 = named2[name]; |
| 560 if (n1 === void 0) { | 563 if (n1 === void 0) { |
| 561 return false; | 564 return false; |
| 562 } | 565 } |
| 563 if (!isSubtype_(n2, n1, true)) { | 566 if (!isSubtype_(n2, n1, true)) { |
| 564 return false; | 567 return false; |
| 565 } | 568 } |
| 566 } | 569 } |
| 567 | 570 |
| 568 return true; | 571 return true; |
| (...skipping 23 matching lines...) Expand all Loading... |
| 592 lazySetter(value); | 595 lazySetter(value); |
| 593 return value; | 596 return value; |
| 594 } | 597 } |
| 595 desc.get = lazyGetter; | 598 desc.get = lazyGetter; |
| 596 desc.configurable = true; | 599 desc.configurable = true; |
| 597 if (writable) desc.set = lazySetter; | 600 if (writable) desc.set = lazySetter; |
| 598 defineProperty(to, name, desc); | 601 defineProperty(to, name, desc); |
| 599 } | 602 } |
| 600 | 603 |
| 601 function defineLazy(to, from) { | 604 function defineLazy(to, from) { |
| 602 let names = getOwnPropertyNames(from); | 605 for (let name of getOwnNamesAndSymbols(from)) { |
| 603 for (let i = 0; i < names.length; i++) { | |
| 604 let name = names[i]; | |
| 605 defineLazyProperty(to, name, getOwnPropertyDescriptor(from, name)); | 606 defineLazyProperty(to, name, getOwnPropertyDescriptor(from, name)); |
| 606 } | 607 } |
| 607 } | 608 } |
| 608 // TODO(jmesserly): these are identical, but this makes it easier to grep for. | 609 // TODO(jmesserly): these are identical, but this makes it easier to grep for. |
| 609 dart.defineLazyClass = defineLazy; | 610 dart.defineLazyClass = defineLazy; |
| 610 dart.defineLazyProperties = defineLazy; | 611 dart.defineLazyProperties = defineLazy; |
| 611 dart.defineLazyClassGeneric = defineLazyProperty; | 612 dart.defineLazyClassGeneric = defineLazyProperty; |
| 612 | 613 |
| 613 /** | 614 /** |
| 614 * Copy properties from source to destination object. | 615 * Copy properties from source to destination object. |
| 615 * This operation is commonly called `mixin` in JS. | 616 * This operation is commonly called `mixin` in JS. |
| 616 */ | 617 */ |
| 617 function copyProperties(to, from) { | 618 function copyProperties(to, from) { |
| 618 function copyPropertiesHelper(names) { | 619 for (let name of getOwnNamesAndSymbols(from)) { |
| 619 for (let i = 0; i < names.length; i++) { | 620 defineProperty(to, name, getOwnPropertyDescriptor(from, name)); |
| 620 let name = names[i]; | |
| 621 defineProperty(to, name, getOwnPropertyDescriptor(from, name)); | |
| 622 } | |
| 623 } | 621 } |
| 624 copyPropertiesHelper(getOwnPropertyNames(from)); | |
| 625 copyPropertiesHelper(getOwnPropertySymbols(from)); | |
| 626 return to; | 622 return to; |
| 627 } | 623 } |
| 628 dart.copyProperties = copyProperties; | 624 dart.copyProperties = copyProperties; |
| 629 | 625 |
| 630 /** | 626 /** |
| 631 * This is called whenever a derived class needs to introduce a new field, | 627 * This is called whenever a derived class needs to introduce a new field, |
| 632 * shadowing a field or getter/setter pair on its parent. | 628 * shadowing a field or getter/setter pair on its parent. |
| 633 * | 629 * |
| 634 * This is important because otherwise, trying to read or write the field | 630 * This is important because otherwise, trying to read or write the field |
| 635 * would end up calling the getter or setter, and one of those might not even | 631 * would end up calling the getter or setter, and one of those might not even |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 709 // TODO(jmesserly): this could be faster | 705 // TODO(jmesserly): this could be faster |
| 710 function map(values) { | 706 function map(values) { |
| 711 let map = new collection.LinkedHashMap(); | 707 let map = new collection.LinkedHashMap(); |
| 712 if (Array.isArray(values)) { | 708 if (Array.isArray(values)) { |
| 713 for (let i = 0, end = values.length - 1; i < end; i += 2) { | 709 for (let i = 0, end = values.length - 1; i < end; i += 2) { |
| 714 let key = values[i]; | 710 let key = values[i]; |
| 715 let value = values[i + 1]; | 711 let value = values[i + 1]; |
| 716 map.set(key, value); | 712 map.set(key, value); |
| 717 } | 713 } |
| 718 } else if (typeof values === 'object') { | 714 } else if (typeof values === 'object') { |
| 719 for (let key of Object.getOwnPropertyNames(values)) { | 715 for (let key of getOwnPropertyNames(values)) { |
| 720 map.set(key, values[key]); | 716 map.set(key, values[key]); |
| 721 } | 717 } |
| 722 } | 718 } |
| 723 return map; | 719 return map; |
| 724 } | 720 } |
| 725 dart.map = map; | 721 dart.map = map; |
| 726 | 722 |
| 727 function assert(condition) { | 723 function assert(condition) { |
| 728 // TODO(jmesserly): throw assertion error. | 724 // TODO(jmesserly): throw assertion error. |
| 729 if (!condition) throw 'assertion failed'; | 725 if (!condition) throw 'assertion failed'; |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 789 } | 785 } |
| 790 map.set(arg, value); | 786 map.set(arg, value); |
| 791 } | 787 } |
| 792 } | 788 } |
| 793 return value; | 789 return value; |
| 794 } | 790 } |
| 795 return makeGenericType; | 791 return makeGenericType; |
| 796 } | 792 } |
| 797 dart.generic = generic; | 793 dart.generic = generic; |
| 798 | 794 |
| 795 let _value = Symbol('_value'); |
| 796 /** |
| 797 * Looks up a sequence of [keys] in [map], recursively, and |
| 798 * returns the result. If the value is not found, [valueFn] will be called to |
| 799 * add it. For example: |
| 800 * |
| 801 * var map = new Map(); |
| 802 * putIfAbsent(map, [1, 2, 'hi ', 'there '], () => 'world'); |
| 803 * |
| 804 * ... will create a Map with a structure like: |
| 805 * |
| 806 * { 1: { 2: { 'hi ': { 'there ': 'world' } } } } |
| 807 */ |
| 808 function multiKeyPutIfAbsent(map, keys, valueFn) { |
| 809 for (let k of keys) { |
| 810 let value = map.get(k); |
| 811 if (!value) { |
| 812 // TODO(jmesserly): most of these maps are very small (e.g. 1 item), |
| 813 // so it may be worth optimizing for that. |
| 814 map.set(k, value = new Map()); |
| 815 } |
| 816 map = value; |
| 817 } |
| 818 if (map.has(_value)) return map.get(_value); |
| 819 let value = valueFn(); |
| 820 map.set(_value, value); |
| 821 return value; |
| 822 } |
| 823 |
| 824 /** The global constant table. */ |
| 825 let constants = new Map(); |
| 826 |
| 827 /** |
| 828 * Canonicalize a constant object. |
| 829 * |
| 830 * Preconditions: |
| 831 * - `obj` is an objects or array, not a primitive. |
| 832 * - nested values of the object are themselves already canonicalized. |
| 833 */ |
| 834 function constant(obj) { |
| 835 let objectKey = [getRuntimeType(obj)]; |
| 836 // There's no guarantee in JS that names/symbols are returned in the same |
| 837 // order. We could probably get the same order if we're judicious about |
| 838 // initializing them, but easier to not depend on that. |
| 839 for (let name of getOwnNamesAndSymbols(obj)) { |
| 840 // TODO(jmesserly): we can make this faster if needed. |
| 841 objectKey.push(name); |
| 842 objectKey.push(obj[name]); |
| 843 } |
| 844 return multiKeyPutIfAbsent(constants, objectKey, () => obj); |
| 845 } |
| 846 dart.const = constant; |
| 847 |
| 799 /** Sets the runtime type of `obj` to be `type` */ | 848 /** Sets the runtime type of `obj` to be `type` */ |
| 800 function setType(obj, type) { | 849 function setType(obj, type) { |
| 801 obj[runtimeType] = type; | 850 obj[runtimeType] = type; |
| 802 } | 851 } |
| 803 dart.setType = setType; | 852 dart.setType = setType; |
| 804 | 853 |
| 805 // TODO(jmesserly): right now this is a sentinel. It should be a type object | 854 // TODO(jmesserly): right now this is a sentinel. It should be a type object |
| 806 // of some sort, assuming we keep around `dynamic` at runtime. | 855 // of some sort, assuming we keep around `dynamic` at runtime. |
| 807 dart.dynamic = { toString() { return 'dynamic'; } }; | 856 dart.dynamic = { toString() { return 'dynamic'; } }; |
| 808 dart.void = { toString() { return 'void'; } }; | 857 dart.void = { toString() { return 'void'; } }; |
| 809 dart.bottom = { toString() { return 'bottom'; } }; | 858 dart.bottom = { toString() { return 'bottom'; } }; |
| 810 | 859 |
| 811 dart.global = window || global; | 860 dart.global = window || global; |
| 812 dart.JsSymbol = Symbol; | 861 dart.JsSymbol = Symbol; |
| 813 | 862 |
| 814 // TODO(jmesserly): hack to bootstrap the SDK | 863 // TODO(jmesserly): hack to bootstrap the SDK |
| 815 _js_helper = _js_helper || {}; | 864 _js_helper = _js_helper || {}; |
| 816 _js_helper.checkNum = notNull; | 865 _js_helper.checkNum = notNull; |
| 817 | 866 |
| 818 })(dart || (dart = {})); | 867 })(dart || (dart = {})); |
| OLD | NEW |