| Index: lib/runtime/dart_runtime.js
|
| diff --git a/lib/runtime/dart_runtime.js b/lib/runtime/dart_runtime.js
|
| index 0c1df96582a0ec8ae04602a9d2ffbe98f39fe3d7..914636ae8cd900771054820bbc86879cfea34510 100644
|
| --- a/lib/runtime/dart_runtime.js
|
| +++ b/lib/runtime/dart_runtime.js
|
| @@ -2,1461 +2,106 @@
|
| // for details. All rights reserved. Use of this source code is governed by a
|
| // BSD-style license that can be found in the LICENSE file.
|
|
|
| -var dart, dartx;
|
| -(function (dart) {
|
| +dart_library.library('dart_runtime/dart', null, /* Imports */[
|
| + 'dart_runtime/_classes',
|
| + 'dart_runtime/_errors',
|
| + 'dart_runtime/_operations',
|
| + 'dart_runtime/_rtti',
|
| + 'dart_runtime/_types',
|
| +], /* Lazy Imports */[
|
| + 'dart/_js_helper'
|
| +], function(exports, classes, errors, operations, rtti, types, _js_helper) {
|
| 'use strict';
|
|
|
| - const defineProperty = Object.defineProperty;
|
| - const getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
|
| - const getOwnPropertyNames = Object.getOwnPropertyNames;
|
| - const getOwnPropertySymbols = Object.getOwnPropertySymbols;
|
| - const hasOwnProperty = Object.prototype.hasOwnProperty;
|
| - const slice = [].slice;
|
| -
|
| - let _constructorSig = Symbol('sigCtor');
|
| - let _methodSig = Symbol("sig");
|
| - let _staticSig = Symbol("sigStatic");
|
| -
|
| - function getOwnNamesAndSymbols(obj) {
|
| - return getOwnPropertyNames(obj).concat(getOwnPropertySymbols(obj));
|
| - }
|
| -
|
| - function dload(obj, field) {
|
| - field = _canonicalFieldName(obj, field, [], field);
|
| - if (_getMethodType(obj, field) !== void 0) {
|
| - return dart.bind(obj, field);
|
| - }
|
| - // TODO(vsm): Implement NSM robustly. An 'in' check breaks on certain
|
| - // types. hasOwnProperty doesn't chase the proto chain.
|
| - // Also, do we want an NSM on regular JS objects?
|
| - // See: https://github.com/dart-lang/dev_compiler/issues/169
|
| - let result = obj[field];
|
| -
|
| - // TODO(vsm): Check this more robustly.
|
| - if (typeof result == "function" && !hasOwnProperty.call(obj, field)) {
|
| - // This appears to be a method tearoff. Bind this.
|
| - return result.bind(obj);
|
| - }
|
| - return result;
|
| - }
|
| - dart.dload = dload;
|
| -
|
| - function dput(obj, field, value) {
|
| - field = _canonicalFieldName(obj, field, [value], field);
|
| - // TODO(vsm): Implement NSM and type checks.
|
| - // See: https://github.com/dart-lang/dev_compiler/issues/170
|
| - obj[field] = value;
|
| - }
|
| - dart.dput = dput;
|
| -
|
| - function throwRuntimeError(message) {
|
| - throw Error(message);
|
| - }
|
| -
|
| - // TODO(jmesserly): this should call noSuchMethod, not throw.
|
| - function throwNoSuchMethod(obj, name, args, opt_func) {
|
| - if (obj === void 0) obj = opt_func;
|
| - throw new core.NoSuchMethodError(obj, name, args);
|
| - }
|
| -
|
| - function checkAndCall(f, ftype, obj, args, name) {
|
| - if (!(f instanceof Function)) {
|
| - // We're not a function (and hence not a method either)
|
| - // Grab the `call` method if it's not a function.
|
| - if (f !== null) {
|
| - ftype = _getMethodType(f, 'call');
|
| - f = f.call;
|
| - }
|
| - if (!(f instanceof Function)) {
|
| - throwNoSuchMethod(obj, name, args);
|
| - }
|
| - }
|
| - // If f is a function, but not a method (no method type)
|
| - // then it should have been a function valued field, so
|
| - // get the type from the function.
|
| - if (ftype === void 0) {
|
| - ftype = _getFunctionType(f);
|
| - }
|
| -
|
| - if (!ftype) {
|
| - // TODO(leafp): Allow JS objects to go through?
|
| - // This includes the DOM.
|
| - return f.apply(obj, args);
|
| - }
|
| -
|
| - if (ftype.checkApply(args)) {
|
| - return f.apply(obj, args);
|
| - }
|
| -
|
| - // TODO(leafp): throw a type error (rather than NSM)
|
| - // if the arity matches but the types are wrong.
|
| - throwNoSuchMethod(obj, name, args, f);
|
| - }
|
| -
|
| - function dcall(f/*, ...args*/) {
|
| - let args = slice.call(arguments, 1);
|
| - let ftype = _getFunctionType(f);
|
| - return checkAndCall(f, ftype, void 0, args, 'call');
|
| - }
|
| - dart.dcall = dcall;
|
| -
|
| - let _extensionType = Symbol('extensionType');
|
| - function _canonicalFieldName(obj, name, args, displayName) {
|
| - if (obj[_extensionType]) {
|
| - let extension = dartx[name];
|
| - if (extension) return extension;
|
| - // TODO(jmesserly): in the future we might have types that "overlay" Dart
|
| - // methods while also exposing the full native API, e.g. dart:html vs
|
| - // dart:dom. To support that we'd need to fall back to the normal name
|
| - // if an extension method wasn't found.
|
| - throwNoSuchMethod(obj, displayName, args);
|
| - }
|
| - return name;
|
| - }
|
| -
|
| - /** Shared code for dsend, dindex, and dsetindex. */
|
| - function callMethod(obj, name, args, displayName) {
|
| - let symbol = _canonicalFieldName(obj, name, args, displayName);
|
| - let f = obj[symbol];
|
| - let ftype = _getMethodType(obj, name);
|
| - return checkAndCall(f, ftype, obj, args, displayName);
|
| - }
|
| -
|
| - function dsend(obj, method/*, ...args*/) {
|
| - return callMethod(obj, method, slice.call(arguments, 2));
|
| - }
|
| - dart.dsend = dsend;
|
| -
|
| - function dindex(obj, index) {
|
| - return callMethod(obj, 'get', [index], '[]');
|
| - }
|
| - dart.dindex = dindex;
|
| -
|
| - function dsetindex(obj, index, value) {
|
| - return callMethod(obj, 'set', [index, value], '[]=');
|
| + function _export(value) {
|
| + if (value) return value;
|
| + console.log("Re-exporting null field: " + name);
|
| + throw "Bad export";
|
| }
|
| - dart.dsetindex = dsetindex;
|
| -
|
| - function _typeName(type) {
|
| - if (typeof(type) == "function") {
|
| - let name = type.name;
|
| - let args = type[dart.typeArguments];
|
| - if (args) {
|
| - name += '<';
|
| - for (let i = 0; i < args.length; ++i) {
|
| - if (i > 0) name += ', ';
|
| - name += _typeName(args[i]);
|
| - }
|
| - name += '>';
|
| - }
|
| - return name;
|
| - } else {
|
| - return type.toString();
|
| - }
|
| - }
|
| - dart.typeName = _typeName;
|
| -
|
| - function _ignoreTypeFailure(actual, type) {
|
| - // TODO(vsm): Remove this hack ...
|
| - // This is primarily due to the lack of generic methods,
|
| - // but we need to triage all the errors.
|
| - if (isSubtype(type, core.Iterable) && isSubtype(actual, core.Iterable) ||
|
| - isSubtype(type, async.Future) && isSubtype(actual, async.Future) ||
|
| - isSubtype(type, core.Map) && isSubtype(actual, core.Map) ||
|
| - isSubtype(type, core.Function) && isSubtype(actual, core.Function)) {
|
| - console.error('Ignoring cast fail from ' + _typeName(actual) +
|
| - ' to ' + _typeName(type));
|
| - return true;
|
| - }
|
| - return false;
|
| - }
|
| -
|
| - function cast(obj, type) {
|
| - // TODO(vsm): handle non-nullable types
|
| - if (obj == null) return obj;
|
| - let actual = realRuntimeType(obj);
|
| - if (isSubtype(actual, type)) return obj;
|
| - if (_ignoreTypeFailure(actual, type)) return obj;
|
| - throw new _js_helper.CastErrorImplementation(actual, type);
|
| - }
|
| - dart.as = cast;
|
| -
|
| -
|
| - // TODO(vsm): How should we encode the runtime type?
|
| - const _runtimeType = Symbol('_runtimeType');
|
| -
|
| - function checkPrimitiveType(obj) {
|
| - switch (typeof obj) {
|
| - case "undefined":
|
| - return core.Null;
|
| - case "number":
|
| - return Math.floor(obj) == obj ? core.int : core.double;
|
| - case "boolean":
|
| - return core.bool;
|
| - case "string":
|
| - return core.String;
|
| - case "symbol":
|
| - return Symbol;
|
| - }
|
| - // Undefined is handled above. For historical reasons,
|
| - // typeof null == "object" in JS.
|
| - if (obj === null) return core.Null;
|
| - return null;
|
| - }
|
| -
|
| - /**
|
| - * Returns the runtime type of obj. This is the same as `obj.realRuntimeType`
|
| - * but will not call an overridden getter.
|
| - *
|
| - * Currently this will return null for non-Dart objects.
|
| - */
|
| - function realRuntimeType(obj) {
|
| - let result = checkPrimitiveType(obj);
|
| - if (result !== null) return result;
|
| - // TODO(vsm): Should we treat Dart and JS objects differently here?
|
| - // E.g., we can check if obj instanceof core.Object to differentiate.
|
| - result = obj[_runtimeType];
|
| - if (result) return result;
|
| - result = obj.constructor;
|
| - if (result == Function) {
|
| - return getFunctionType(obj);
|
| - }
|
| - return result;
|
| - }
|
| - dart.realRuntimeType = realRuntimeType;
|
| -
|
| - function instanceOf(obj, type) {
|
| - return isSubtype(realRuntimeType(obj), type);
|
| - }
|
| - dart.is = instanceOf;
|
| -
|
| - function instanceOfOrNull(obj, type) {
|
| - // FIXME(vsm): This is used only in checkApply.
|
| - // Just log failures due to generics for now.
|
| - if ((obj == null) || instanceOf(obj, type)) return true;
|
| - let actual = realRuntimeType(obj);
|
| - if (_ignoreTypeFailure(actual, type)) return true;
|
| - return false;
|
| - }
|
| -
|
| - /**
|
| - * Computes the canonical type.
|
| - * This maps JS types onto their corresponding Dart Type.
|
| - */
|
| - // TODO(jmesserly): lots more needs to be done here.
|
| - function canonicalType(t) {
|
| - if (t === Object) return core.Object;
|
| - if (t === Function) return core.Function;
|
| - if (t === Array) return core.List;
|
| -
|
| - // We shouldn't normally get here with these types, unless something strange
|
| - // happens like subclassing Number in JS and passing it to Dart.
|
| - if (t === String) return core.String;
|
| - if (t === Number) return core.double;
|
| - if (t === Boolean) return core.bool;
|
| - return t;
|
| - }
|
| -
|
| - const subtypeMap = new Map();
|
| - function isSubtype(t1, t2) {
|
| - // See if we already know the answer
|
| - // TODO(jmesserly): general purpose memoize function?
|
| - let map = subtypeMap.get(t1);
|
| - let result;
|
| - if (map) {
|
| - result = map.get(t2);
|
| - if (result !== void 0) return result;
|
| - } else {
|
| - subtypeMap.set(t1, map = new Map());
|
| - }
|
| - if (t2 == core.Type) {
|
| - // Special case Types.
|
| - result = t1.prototype instanceof core.Type ||
|
| - t1 instanceof AbstractFunctionType ||
|
| - isSubtype_(t1, t2);
|
| - } else {
|
| - result = isSubtype_(t1, t2)
|
| - }
|
| - map.set(t2, result);
|
| - return result;
|
| - }
|
| - dart.isSubtype = isSubtype;
|
| -
|
| - function _isBottom(type, dynamicIsBottom) {
|
| - return (type == dart.dynamic && dynamicIsBottom) || type == dart.bottom;
|
| - }
|
| -
|
| - function _isTop(type, dynamicIsBottom) {
|
| - return type == core.Object || (type == dart.dynamic && !dynamicIsBottom);
|
| - }
|
| -
|
| - function isSubtype_(t1, t2, opt_dynamicIsBottom) {
|
| - let dynamicIsBottom =
|
| - opt_dynamicIsBottom === void 0 ? false : opt_dynamicIsBottom;
|
| -
|
| - t1 = canonicalType(t1);
|
| - t2 = canonicalType(t2);
|
| - if (t1 == t2) return true;
|
| -
|
| - // In Dart, dynamic is effectively both top and bottom.
|
| - // Here, we treat dynamic as one or the other depending on context,
|
| - // but not both.
|
| -
|
| - // Trivially true.
|
| - if (_isTop(t2, dynamicIsBottom) || _isBottom(t1, dynamicIsBottom)) {
|
| - return true;
|
| - }
|
| -
|
| - // Trivially false.
|
| - if (_isTop(t1, dynamicIsBottom) || _isBottom(t2, dynamicIsBottom)) {
|
| - return false;
|
| - }
|
| -
|
| - // "Traditional" name-based subtype check.
|
| - if (isClassSubType(t1, t2)) {
|
| - return true;
|
| - }
|
| -
|
| - // Function subtyping.
|
| - // TODO(vsm): Handle Objects with call methods. Those are functions
|
| - // even if they do not *nominally* subtype core.Function.
|
| - if (isFunctionType(t1) &&
|
| - isFunctionType(t2)) {
|
| - return isFunctionSubType(t1, t2);
|
| - }
|
| - return false;
|
| - }
|
| -
|
| - function safeGetOwnProperty(obj, name) {
|
| - let desc = getOwnPropertyDescriptor(obj, name);
|
| - if (desc) return desc.value;
|
| - }
|
| -
|
| - function isClassSubType(t1, t2) {
|
| - // We support Dart's covariant generics with the caveat that we do not
|
| - // substitute bottom for dynamic in subtyping rules.
|
| - // I.e., given T1, ..., Tn where at least one Ti != dynamic we disallow:
|
| - // - S !<: S<T1, ..., Tn>
|
| - // - S<dynamic, ..., dynamic> !<: S<T1, ..., Tn>
|
| - t1 = canonicalType(t1);
|
| - assert(t2 == canonicalType(t2));
|
| - if (t1 == t2) return true;
|
| -
|
| - if (t1 == core.Object) return false;
|
| -
|
| - // If t1 is a JS Object, we may not hit core.Object.
|
| - if (t1 == null) return t2 == core.Object || t2 == dart.dynamic;
|
| -
|
| - // Check if t1 and t2 have the same raw type. If so, check covariance on
|
| - // type parameters.
|
| - let raw1 = safeGetOwnProperty(t1, dart.originalDeclaration);
|
| - let raw2 = safeGetOwnProperty(t2, dart.originalDeclaration);
|
| - if (raw1 != null && raw1 == raw2) {
|
| - let typeArguments1 = safeGetOwnProperty(t1, dart.typeArguments);
|
| - let typeArguments2 = safeGetOwnProperty(t2, dart.typeArguments);
|
| - let length = typeArguments1.length;
|
| - if (typeArguments2.length == 0) {
|
| - // t2 is the raw form of t1
|
| - return true;
|
| - } else if (length == 0) {
|
| - // t1 is raw, but t2 is not
|
| - return false;
|
| - }
|
| - assert(length == typeArguments2.length);
|
| - for (let i = 0; i < length; ++i) {
|
| - if (!isSubtype(typeArguments1[i], typeArguments2[i])) {
|
| - return false;
|
| - }
|
| - }
|
| - return true;
|
| - }
|
| -
|
| - // Check superclass.
|
| - if (isClassSubType(t1.__proto__, t2)) return true;
|
| -
|
| - // Check mixins.
|
| - let mixins = safeGetOwnProperty(t1, dart.mixins);
|
| - if (mixins) {
|
| - for (let m1 of mixins) {
|
| - // TODO(jmesserly): remove the != null check once we can load core libs.
|
| - if (m1 != null && isClassSubType(m1, t2)) return true;
|
| - }
|
| - }
|
| -
|
| - // Check interfaces.
|
| - let getInterfaces = safeGetOwnProperty(t1, dart.implements);
|
| - if (getInterfaces) {
|
| - for (let i1 of getInterfaces()) {
|
| - // TODO(jmesserly): remove the != null check once we can load core libs.
|
| - if (i1 != null && isClassSubType(i1, t2)) return true;
|
| - }
|
| - }
|
| -
|
| - return false;
|
| - }
|
| -
|
| - // TODO(jmesserly): this isn't currently used, but it could be if we want
|
| - // `obj is NonGroundType<T,S>` to be rejected at runtime instead of compile
|
| - // time.
|
| - function isGroundType(type) {
|
| - // TODO(vsm): Cache this if we start using it at runtime.
|
| -
|
| - if (type instanceof AbstractFunctionType) {
|
| - if (!_isTop(type.returnType, false)) return false;
|
| - for (let i = 0; i < type.args.length; ++i) {
|
| - if (!_isBottom(type.args[i], true)) return false;
|
| - }
|
| - for (let i = 0; i < type.optionals.length; ++i) {
|
| - if (!_isBottom(type.optionals[i], true)) return false;
|
| - }
|
| - let names = getOwnPropertyNames(type.named);
|
| - for (let i = 0; i < names.length; ++i) {
|
| - if (!_isBottom(type.named[names[i]], true)) return false;
|
| - }
|
| - return true;
|
| - }
|
| -
|
| - let typeArgs = safeGetOwnProperty(type, dart.typeArguments);
|
| - if (!typeArgs) return true;
|
| - for (let t of typeArgs) {
|
| - if (t != core.Object && t != dart.dynamic) return false;
|
| - }
|
| - return true;
|
| - }
|
| - dart.isGroundType = isGroundType;
|
| -
|
| - function arity(f) {
|
| - // TODO(jmesserly): need to parse optional params.
|
| - // In ES6, length is the number of required arguments.
|
| - return { min: f.length, max: f.length };
|
| - }
|
| - dart.arity = arity;
|
| -
|
| - function equals(x, y) {
|
| - if (x == null || y == null) return x == y;
|
| - let eq = x['=='];
|
| - return eq ? eq.call(x, y) : x === y;
|
| - }
|
| - dart.equals = equals;
|
| -
|
| - /** Checks that `x` is not null or undefined. */
|
| - function notNull(x) {
|
| - if (x == null) throwRuntimeError('expected not-null value');
|
| - return x;
|
| - }
|
| - dart.notNull = notNull;
|
| -
|
| - class AbstractFunctionType {
|
| - constructor() {
|
| - this._stringValue = null;
|
| - }
|
| -
|
| - /// Check that a function of this type can be applied to
|
| - /// actuals.
|
| - checkApply(actuals) {
|
| - if (actuals.length < this.args.length) return false;
|
| - let index = 0;
|
| - for(let i = 0; i < this.args.length; ++i) {
|
| - if (!instanceOfOrNull(actuals[i], this.args[i])) return false;
|
| - ++index;
|
| - }
|
| - if (actuals.length == this.args.length) return true;
|
| - let extras = actuals.length - this.args.length;
|
| - if (this.optionals.length > 0) {
|
| - if (extras > this.optionals.length) return false;
|
| - for(let i = 0, j=index; i < extras; ++i, ++j) {
|
| - if (!instanceOfOrNull(actuals[j], this.optionals[i])) return false;
|
| - }
|
| - return true;
|
| - }
|
| - // TODO(leafp): We can't tell when someone might be calling
|
| - // something expecting an optional argument with named arguments
|
| -
|
| - if (extras != 1) return false;
|
| - // An empty named list means no named arguments
|
| - if (getOwnPropertyNames(this.named).length == 0) return false;
|
| - let opts = actuals[index];
|
| - let names = getOwnPropertyNames(opts);
|
| - // This is something other than a map
|
| - if (names.length == 0) return false;
|
| - for (name of names) {
|
| - if (!(Object.prototype.hasOwnProperty.call(this.named, name))) {
|
| - return false;
|
| - }
|
| - if (!instanceOfOrNull(opts[name], this.named[name])) return false;
|
| - }
|
| - return true;
|
| - }
|
| -
|
| - toString() { return this.name; }
|
| -
|
| - get name() {
|
| - if (this._stringValue) return this._stringValue;
|
| -
|
| - let buffer = '(';
|
| - for (let i = 0; i < this.args.length; ++i) {
|
| - if (i > 0) {
|
| - buffer += ', ';
|
| - }
|
| - buffer += _typeName(this.args[i]);
|
| - }
|
| - if (this.optionals.length > 0) {
|
| - if (this.args.length > 0) buffer += ', ';
|
| - buffer += '[';
|
| - for (let i = 0; i < this.optionals.length; ++i) {
|
| - if (i > 0) {
|
| - buffer += ', ';
|
| - }
|
| - buffer += _typeName(this.optionals[i]);
|
| - }
|
| - buffer += ']';
|
| - } else if (Object.keys(this.named).length > 0) {
|
| - if (this.args.length > 0) buffer += ', ';
|
| - buffer += '{';
|
| - let names = getOwnPropertyNames(this.named).sort();
|
| - for (let i = 0; i < names.length; ++i) {
|
| - if (i > 0) {
|
| - buffer += ', ';
|
| - }
|
| - buffer += names[i] + ': ' + _typeName(this.named[names[i]]);
|
| - }
|
| - buffer += '}';
|
| - }
|
| -
|
| - buffer += ') -> ' + _typeName(this.returnType);
|
| - this._stringValue = buffer;
|
| - return buffer;
|
| - }
|
| - }
|
| -
|
| - class FunctionType extends AbstractFunctionType {
|
| - constructor(returnType, args, optionals, named) {
|
| - super();
|
| - this.returnType = returnType;
|
| - this.args = args;
|
| - this.optionals = optionals;
|
| - this.named = named;
|
| - }
|
| - }
|
| -
|
| - /// Tag a closure with a type, using one of three forms:
|
| - /// dart.fn(cls) marks cls has having no optional or named
|
| - /// parameters, with all argument and return types as dynamic
|
| - /// dart.fn(cls, func) marks cls with the lazily computed
|
| - /// runtime type as computed by func()
|
| - /// dart.fn(cls, rType, argsT, extras) marks cls as having the
|
| - /// runtime type dart.functionType(rType, argsT, extras)
|
| - function fn(closure/* ...args*/) {
|
| - // Closure and a lazy type constructor
|
| - if (arguments.length == 2) {
|
| - defineLazyProperty(closure, _runtimeType, {get : arguments[1]});
|
| - return closure;
|
| - }
|
| - let t;
|
| - if (arguments.length == 1) {
|
| - // No type arguments, it's all dynamic
|
| - let len = closure.length;
|
| - let build = () => {
|
| - let args = Array.apply(null, new Array(len)).map(() => core.Object);
|
| - return functionType(core.Object, args);
|
| - };
|
| - // We could be called before Object is defined.
|
| - if (core.Object === void 0) return fn(closure, build);
|
| - t = build();
|
| - } else {
|
| - // We're passed the piecewise components of the function type,
|
| - // construct it.
|
| - let args = slice.call(arguments, 1);
|
| - t = functionType.apply(null, args);
|
| - }
|
| - setRuntimeType(closure, t);
|
| - return closure;
|
| - }
|
| - dart.fn = fn;
|
| -
|
| - function functionType(returnType, args, extra) {
|
| - // TODO(vsm): Cache / memomize?
|
| - let optionals;
|
| - let named;
|
| - if (extra === void 0) {
|
| - optionals = [];
|
| - named = {};
|
| - } else if (extra instanceof Array) {
|
| - optionals = extra;
|
| - named = {};
|
| - } else {
|
| - optionals = [];
|
| - named = extra;
|
| - }
|
| - return new FunctionType(returnType, args, optionals, named);
|
| - }
|
| - dart.functionType = functionType;
|
| -
|
| - class Typedef extends AbstractFunctionType {
|
| - constructor(name, closure) {
|
| - super();
|
| - this._name = name;
|
| - this._closure = closure;
|
| - this._functionType = null;
|
| - }
|
| -
|
| - get name() {
|
| - return this._name;
|
| - }
|
| -
|
| - get functionType() {
|
| - if (!this._functionType) {
|
| - this._functionType = this._closure();
|
| - }
|
| - return this._functionType;
|
| - }
|
| -
|
| - get returnType() {
|
| - return this.functionType.returnType;
|
| - }
|
| -
|
| - get args() {
|
| - return this.functionType.args;
|
| - }
|
| -
|
| - get optionals() {
|
| - return this.functionType.optionals;
|
| - }
|
| -
|
| - get named() {
|
| - return this.functionType.named;
|
| - }
|
| - }
|
| -
|
| - function typedef(name, closure) {
|
| - return new Typedef(name, closure);
|
| - }
|
| - dart.typedef = typedef;
|
| -
|
| - function isFunctionType(type) {
|
| - return isClassSubType(type, core.Function) ||
|
| - type instanceof AbstractFunctionType;
|
| - }
|
| -
|
| - function getFunctionType(obj) {
|
| - // TODO(vsm): Encode this properly on the function for Dart-generated code.
|
| - let args = Array.apply(null, new Array(obj.length)).map(() => core.Object);
|
| - return functionType(dart.bottom, args);
|
| - }
|
| -
|
| - function isFunctionSubType(ft1, ft2) {
|
| - if (ft2 == core.Function) {
|
| - return true;
|
| - }
|
| -
|
| - let ret1 = ft1.returnType;
|
| - let ret2 = ft2.returnType;
|
| -
|
| - if (!isSubtype_(ret1, ret2)) {
|
| - // Covariant return types
|
| - // Note, void (which can only appear as a return type) is effectively
|
| - // treated as dynamic. If the base return type is void, we allow any
|
| - // subtype return type.
|
| - // E.g., we allow:
|
| - // () -> int <: () -> void
|
| - if (ret2 != dart.void) {
|
| - return false;
|
| - }
|
| - }
|
| -
|
| - let args1 = ft1.args;
|
| - let args2 = ft2.args;
|
| -
|
| - if (args1.length > args2.length) {
|
| - return false;
|
| - }
|
| -
|
| - for (let i = 0; i < args1.length; ++i) {
|
| - if (!isSubtype_(args2[i], args1[i], true)) {
|
| - return false;
|
| - }
|
| - }
|
| -
|
| - let optionals1 = ft1.optionals;
|
| - let optionals2 = ft2.optionals;
|
|
|
| - if (args1.length + optionals1.length < args2.length + optionals2.length) {
|
| - return false;
|
| - }
|
| -
|
| - let j = 0;
|
| - for (let i = args1.length; i < args2.length; ++i, ++j) {
|
| - if (!isSubtype_(args2[i], optionals1[j], true)) {
|
| - return false;
|
| - }
|
| - }
|
| -
|
| - for (let i = 0; i < optionals2.length; ++i, ++j) {
|
| - if (!isSubtype_(optionals2[i], optionals1[j], true)) {
|
| - return false;
|
| - }
|
| - }
|
| -
|
| - let named1 = ft1.named;
|
| - let named2 = ft2.named;
|
| -
|
| - let names = getOwnPropertyNames(named2);
|
| - for (let i = 0; i < names.length; ++i) {
|
| - let name = names[i];
|
| - let n1 = named1[name];
|
| - let n2 = named2[name];
|
| - if (n1 === void 0) {
|
| - return false;
|
| - }
|
| - if (!isSubtype_(n2, n1, true)) {
|
| - return false;
|
| - }
|
| - }
|
| -
|
| - return true;
|
| - }
|
| -
|
| - /**
|
| - * Defines a lazy property.
|
| - * After initial get or set, it will replace itself with a value property.
|
| - */
|
| - // TODO(jmesserly): is this the best implementation for JS engines?
|
| - // TODO(jmesserly): reusing descriptor objects has been shown to improve
|
| - // performance in other projects (e.g. webcomponents.js ShadowDOM polyfill).
|
| - function defineLazyProperty(to, name, desc) {
|
| - let init = desc.get;
|
| - let writable = !!desc.set;
|
| - function lazySetter(value) {
|
| - defineProperty(to, name, { value: value, writable: writable });
|
| - }
|
| - function lazyGetter() {
|
| - // Clear the init function to detect circular initialization.
|
| - let f = init;
|
| - if (f === null) throwRuntimeError('circular initialization for field ' + name);
|
| - init = null;
|
| -
|
| - // Compute and store the value.
|
| - let value = f();
|
| - lazySetter(value);
|
| - return value;
|
| - }
|
| - desc.get = lazyGetter;
|
| - desc.configurable = true;
|
| - if (writable) desc.set = lazySetter;
|
| - defineProperty(to, name, desc);
|
| - }
|
| -
|
| - function defineLazy(to, from) {
|
| - for (let name of getOwnNamesAndSymbols(from)) {
|
| - defineLazyProperty(to, name, getOwnPropertyDescriptor(from, name));
|
| - }
|
| - }
|
| - // TODO(jmesserly): these are identical, but this makes it easier to grep for.
|
| - dart.defineLazyClass = defineLazy;
|
| - dart.defineLazyProperties = defineLazy;
|
| - dart.defineLazyClassGeneric = defineLazyProperty;
|
| -
|
| - function defineMemoizedGetter(obj, name, get) {
|
| - let cache = null;
|
| - function getter() {
|
| - if (cache != null) return cache;
|
| - cache = get();
|
| - get = null;
|
| - return cache;
|
| - }
|
| - defineProperty(obj, name, {get: getter, configurable: true});
|
| - }
|
| -
|
| - function copyPropertiesHelper(to, from, names) {
|
| - for (let name of names) {
|
| - defineProperty(to, name, getOwnPropertyDescriptor(from, name));
|
| - }
|
| - return to;
|
| - }
|
| -
|
| - /**
|
| - * Copy properties from source to destination object.
|
| - * This operation is commonly called `mixin` in JS.
|
| - */
|
| - function copyProperties(to, from) {
|
| - return copyPropertiesHelper(to, from, getOwnNamesAndSymbols(from));
|
| - }
|
| - dart.copyProperties = copyProperties;
|
| -
|
| - function getExtensionSymbol(name) {
|
| - let sym = dartx[name];
|
| - if (!sym) dartx[name] = sym = Symbol('dartx.' + name);
|
| - return sym;
|
| - }
|
| -
|
| - function defineExtensionNames(names) {
|
| - names.forEach(getExtensionSymbol);
|
| - }
|
| - dart.defineExtensionNames = defineExtensionNames;
|
| -
|
| - /**
|
| - * Copy symbols from the prototype of the source to destination.
|
| - * These are the only properties safe to copy onto an existing public
|
| - * JavaScript class.
|
| - */
|
| - function registerExtension(jsType, dartExtType) {
|
| - let extProto = dartExtType.prototype;
|
| - let jsProto = jsType.prototype;
|
| -
|
| - // Mark the JS type's instances so we can easily check for extensions.
|
| - assert(jsProto[_extensionType] === void 0);
|
| - jsProto[_extensionType] = extProto;
|
| -
|
| - let dartObjProto = core.Object.prototype;
|
| - while (extProto !== dartObjProto && extProto !== jsProto) {
|
| - copyPropertiesHelper(jsProto, extProto, getOwnPropertySymbols(extProto));
|
| - extProto = extProto.__proto__;
|
| - }
|
| - }
|
| - dart.registerExtension = registerExtension;
|
| -
|
| - /**
|
| - * Mark a concrete type as implementing extension methods.
|
| - * For example: `class MyIter implements Iterable`.
|
| - *
|
| - * This takes a list of names, which are the extension methods implemented.
|
| - * It will add a forwarder, so the extension method name redirects to the
|
| - * normal Dart method name. For example:
|
| - *
|
| - * defineExtensionMembers(MyType, ['add', 'remove']);
|
| - *
|
| - * Results in:
|
| - *
|
| - * MyType.prototype[dartx.add] = MyType.prototype.add;
|
| - * MyType.prototype[dartx.remove] = MyType.prototype.remove;
|
| - */
|
| - // TODO(jmesserly): essentially this gives two names to the same method.
|
| - // This benefit is roughly equivalent call performance either way, but the
|
| - // cost is we need to call defineExtensionMEmbers any time a subclass overrides
|
| - // one of these methods.
|
| - function defineExtensionMembers(type, methodNames) {
|
| - let proto = type.prototype;
|
| - for (let name of methodNames) {
|
| - let method = getOwnPropertyDescriptor(proto, name);
|
| - defineProperty(proto, getExtensionSymbol(name), method);
|
| - }
|
| - // Ensure the signature is available too.
|
| - // TODO(jmesserly): not sure if we can do this in a cleaner way. Essentially
|
| - // we need to copy the signature (and in the future, other data like
|
| - // annotations) any time we copy a method as part of our metaprogramming.
|
| - // It might be more friendly to JS metaprogramming if we include this info
|
| - // on the function.
|
| - let originalSigFn = getOwnPropertyDescriptor(type, _methodSig).get;
|
| - defineMemoizedGetter(type, _methodSig, function() {
|
| - let sig = originalSigFn();
|
| - for (let name of methodNames) {
|
| - sig[getExtensionSymbol(name)] = sig[name];
|
| - }
|
| - return sig;
|
| - });
|
| - }
|
| - dart.defineExtensionMembers = defineExtensionMembers;
|
| -
|
| - function setBaseClass(derived, base) {
|
| - // Link the extension to the type it's extending as a base class.
|
| - derived.prototype.__proto__ = base.prototype;
|
| - }
|
| - dart.setBaseClass = setBaseClass;
|
| -
|
| - /**
|
| - * This is called whenever a derived class needs to introduce a new field,
|
| - * shadowing a field or getter/setter pair on its parent.
|
| - *
|
| - * This is important because otherwise, trying to read or write the field
|
| - * would end up calling the getter or setter, and one of those might not even
|
| - * exist, resulting in a runtime error. Even if they did exist, that's the
|
| - * wrong behavior if a new field was declared.
|
| - */
|
| - function virtualField(subclass, fieldName) {
|
| - // If the field is already overridden, do nothing.
|
| - let prop = getOwnPropertyDescriptor(subclass.prototype, fieldName);
|
| - if (prop) return;
|
| -
|
| - let symbol = Symbol(subclass.name + '.' + fieldName);
|
| - defineProperty(subclass.prototype, fieldName, {
|
| - get: function() { return this[symbol]; },
|
| - set: function(x) { this[symbol] = x; }
|
| - });
|
| - }
|
| - dart.virtualField = virtualField;
|
| -
|
| - /** The Symbol for storing type arguments on a specialized generic type. */
|
| - dart.mixins = Symbol('mixins');
|
| - dart.implements = Symbol('implements');
|
| - dart.metadata = Symbol('metadata');
|
| -
|
| - /**
|
| - * Returns a new type that mixes members from base and all mixins.
|
| - *
|
| - * Each mixin applies in sequence, with further to the right ones overriding
|
| - * previous entries.
|
| - *
|
| - * For each mixin, we only take its own properties, not anything from its
|
| - * superclass (prototype).
|
| - */
|
| - function mixin(base/*, ...mixins*/) {
|
| - // Create an initializer for the mixin, so when derived constructor calls
|
| - // super, we can correctly initialize base and mixins.
|
| - let mixins = slice.call(arguments, 1);
|
| -
|
| - // Create a class that will hold all of the mixin methods.
|
| - class Mixin extends base {
|
| - // Initializer method: run mixin initializers, then the base.
|
| - [base.name](/*...args*/) {
|
| - // Run mixin initializers. They cannot have arguments.
|
| - // Run them backwards so most-derived mixin is initialized first.
|
| - for (let i = mixins.length - 1; i >= 0; i--) {
|
| - let mixin = mixins[i];
|
| - let init = mixin.prototype[mixin.name];
|
| - if (init) init.call(this);
|
| - }
|
| - // Run base initializer.
|
| - let init = base.prototype[base.name];
|
| - if (init) init.apply(this, arguments);
|
| - }
|
| - }
|
| - // Copy each mixin's methods, with later ones overwriting earlier entries.
|
| - for (let m of mixins) {
|
| - copyProperties(Mixin.prototype, m.prototype);
|
| - }
|
| -
|
| - // Set the signature of the Mixin class to be the composition
|
| - // of the signatures of the mixins.
|
| - dart.setSignature(Mixin, {
|
| - methods: () => {
|
| - let s = {};
|
| - for (let m of mixins) {
|
| - copyProperties(s, m[_methodSig]);
|
| - }
|
| - return s;
|
| - }
|
| - });
|
| -
|
| - // Save mixins for reflection
|
| - Mixin[dart.mixins] = mixins;
|
| - return Mixin;
|
| - }
|
| - dart.mixin = mixin;
|
| -
|
| - /**
|
| - * Creates a dart:collection LinkedHashMap.
|
| - *
|
| - * For a map with string keys an object literal can be used, for example
|
| - * `map({'hi': 1, 'there': 2})`.
|
| - *
|
| - * Otherwise an array should be used, for example `map([1, 2, 3, 4])` will
|
| - * create a map with keys [1, 3] and values [2, 4]. Each key-value pair
|
| - * should be adjacent entries in the array.
|
| - *
|
| - * For a map with no keys the function can be called with no arguments, for
|
| - * example `map()`.
|
| - */
|
| - // TODO(jmesserly): this could be faster
|
| - function map(values) {
|
| - let map = collection.LinkedHashMap.new();
|
| - if (Array.isArray(values)) {
|
| - for (let i = 0, end = values.length - 1; i < end; i += 2) {
|
| - let key = values[i];
|
| - let value = values[i + 1];
|
| - map.set(key, value);
|
| - }
|
| - } else if (typeof values === 'object') {
|
| - for (let key of getOwnPropertyNames(values)) {
|
| - map.set(key, values[key]);
|
| - }
|
| - }
|
| - return map;
|
| - }
|
| - dart.map = map;
|
| -
|
| - function assert(condition) {
|
| - if (!condition) throw new core.AssertionError();
|
| - }
|
| - dart.assert = assert;
|
| -
|
| - function throw_(obj) { throw obj; }
|
| - dart.throw_ = throw_;
|
| -
|
| - /**
|
| - * Given a class and an initializer method name, creates a constructor
|
| - * function with the same name. For example `new SomeClass.name(args)`.
|
| - */
|
| - function defineNamedConstructor(clazz, name) {
|
| - let proto = clazz.prototype;
|
| - let initMethod = proto[name];
|
| - let ctor = function() { return initMethod.apply(this, arguments); };
|
| - ctor.prototype = proto;
|
| - // Use defineProperty so we don't hit a property defined on Function,
|
| - // like `caller` and `arguments`.
|
| - defineProperty(clazz, name, { value: ctor, configurable: true });
|
| - }
|
| - dart.defineNamedConstructor = defineNamedConstructor;
|
| -
|
| - function stackTrace(exception) {
|
| - return _js_helper.getTraceFromException(exception);
|
| - }
|
| - dart.stackTrace = stackTrace;
|
| -
|
| - /** The Symbol for storing type arguments on a specialized generic type. */
|
| - dart.typeArguments = Symbol('typeArguments');
|
| - dart.originalDeclaration = Symbol('originalDeclaration');
|
| -
|
| - /** Memoize a generic type constructor function. */
|
| - function generic(typeConstructor) {
|
| - let length = typeConstructor.length;
|
| - if (length < 1) throwRuntimeError('must have at least one generic type argument');
|
| -
|
| - let resultMap = new Map();
|
| - function makeGenericType(/*...arguments*/) {
|
| - if (arguments.length != length && arguments.length != 0) {
|
| - throwRuntimeError('requires ' + length + ' or 0 type arguments');
|
| - }
|
| - let args = slice.call(arguments);
|
| - // TODO(leafp): This should really be core.Object for
|
| - // consistency, but Object is not attached to core
|
| - // until the entire core library has been processed,
|
| - // which is too late.
|
| - while (args.length < length) args.push(dart.dynamic);
|
| -
|
| - let value = resultMap;
|
| - for (let i = 0; i < length; i++) {
|
| - let arg = args[i];
|
| - if (arg == null) {
|
| - throwRuntimeError('type arguments should not be null: ' + typeConstructor);
|
| - }
|
| - let map = value;
|
| - value = map.get(arg);
|
| - if (value === void 0) {
|
| - if (i + 1 == length) {
|
| - value = typeConstructor.apply(null, args);
|
| - // Save the type constructor and arguments for reflection.
|
| - if (value) {
|
| - value[dart.typeArguments] = args;
|
| - value[dart.originalDeclaration] = makeGenericType;
|
| - }
|
| - } else {
|
| - value = new Map();
|
| - }
|
| - map.set(arg, value);
|
| - }
|
| - }
|
| - return value;
|
| - }
|
| - return makeGenericType;
|
| - }
|
| - dart.generic = generic;
|
| -
|
| - /// Get the type of a function using the store runtime type
|
| - function _getFunctionType(f) {
|
| - return f[_runtimeType];
|
| - }
|
| -
|
| - /// Get the type of a method using the stored signature
|
| - function _getMethodType(obj, name) {
|
| - if (obj === void 0) return void 0;
|
| - if (obj == null) return void 0;
|
| - let sigObj = obj.__proto__.constructor[_methodSig];
|
| - if (sigObj === void 0) return void 0;
|
| - let parts = sigObj[name];
|
| - if (parts === void 0) return void 0;
|
| - return functionType.apply(null, parts);
|
| - }
|
| -
|
| - /// Get the type of a constructor from a class using the stored signature
|
| - /// If name is undefined, returns the type of the default constructor
|
| - /// Returns undefined if the constructor is not found.
|
| - function _getConstructorType(cls, name) {
|
| - if(!name) name = cls.name;
|
| - if (cls === void 0) return void 0;
|
| - if (cls == null) return void 0;
|
| - let sigCtor = cls[_constructorSig];
|
| - if (sigCtor === void 0) return void 0;
|
| - let parts = sigCtor[name];
|
| - if (parts === void 0) return void 0;
|
| - return functionType.apply(null, parts);
|
| - }
|
| - dart.classGetConstructorType = _getConstructorType;
|
| -
|
| - /// Given an object and a method name, tear off the method.
|
| - /// Sets the runtime type of the torn off method appropriately,
|
| - /// and also binds the object.
|
| - /// TODO(leafp): Consider caching the tearoff on the object?
|
| - function bind(obj, name) {
|
| - let f = obj[name].bind(obj);
|
| - let sig = _getMethodType(obj, name);
|
| - assert(sig);
|
| - setRuntimeType(f, sig);
|
| - return f;
|
| - }
|
| - dart.bind = bind;
|
| -
|
| - // Set up the method signature field on the constructor
|
| - function _setMethodSignature(f, sigF) {
|
| - defineMemoizedGetter(f, _methodSig, () => {
|
| - let sigObj = sigF();
|
| - sigObj.__proto__ = f.__proto__[_methodSig];
|
| - return sigObj;
|
| - });
|
| - }
|
| -
|
| - // Set up the constructor signature field on the constructor
|
| - function _setConstructorSignature(f, sigF) {
|
| - defineMemoizedGetter(f, _constructorSig, sigF);
|
| - }
|
| -
|
| - // Set up the static signature field on the constructor
|
| - function _setStaticSignature(f, sigF) {
|
| - defineMemoizedGetter(f, _staticSig, sigF);
|
| - }
|
| -
|
| - // Set the lazily computed runtime type field on static methods
|
| - function _setStaticTypes(f, names) {
|
| + function exportFrom(value, names) {
|
| for (let name of names) {
|
| - defineProperty(f[name], _runtimeType, { get: function() {
|
| - let parts = f[_staticSig][name];
|
| - return functionType.apply(null, parts);
|
| - }});
|
| - }
|
| - }
|
| -
|
| - /// Set up the type signature of a class (constructor object)
|
| - /// f is a constructor object
|
| - /// signature is an object containing optional properties as follows:
|
| - /// methods: A function returning an object mapping method names
|
| - /// to method types. The function is evaluated lazily and cached.
|
| - /// statics: A function returning an object mapping static method
|
| - /// names to types. The function is evalutated lazily and cached.
|
| - /// names: An array of the names of the static methods. Used to
|
| - /// permit eagerly setting the runtimeType field on the methods
|
| - /// while still lazily computing the type descriptor object.
|
| - function setSignature(f, signature) {
|
| - let constructors =
|
| - ('constructors' in signature) ? signature.constructors : () => ({});
|
| - let methods =
|
| - ('methods' in signature) ? signature.methods : () => ({});
|
| - let statics =
|
| - ('statics' in signature) ? signature.statics : () => ({});
|
| - let names =
|
| - ('names' in signature) ? signature.names : [];
|
| - _setConstructorSignature(f, constructors);
|
| - _setMethodSignature(f, methods);
|
| - _setStaticSignature(f, statics);
|
| - _setStaticTypes(f, names);
|
| - }
|
| - dart.setSignature = setSignature;
|
| -
|
| - let _value = Symbol('_value');
|
| - /**
|
| - * Looks up a sequence of [keys] in [map], recursively, and
|
| - * returns the result. If the value is not found, [valueFn] will be called to
|
| - * add it. For example:
|
| - *
|
| - * let map = new Map();
|
| - * putIfAbsent(map, [1, 2, 'hi ', 'there '], () => 'world');
|
| - *
|
| - * ... will create a Map with a structure like:
|
| - *
|
| - * { 1: { 2: { 'hi ': { 'there ': 'world' } } } }
|
| - */
|
| - function multiKeyPutIfAbsent(map, keys, valueFn) {
|
| - for (let k of keys) {
|
| - let value = map.get(k);
|
| - if (!value) {
|
| - // TODO(jmesserly): most of these maps are very small (e.g. 1 item),
|
| - // so it may be worth optimizing for that.
|
| - map.set(k, value = new Map());
|
| - }
|
| - map = value;
|
| - }
|
| - if (map.has(_value)) return map.get(_value);
|
| - let value = valueFn();
|
| - map.set(_value, value);
|
| - return value;
|
| - }
|
| -
|
| - /** The global constant table. */
|
| - const constants = new Map();
|
| -
|
| - /**
|
| - * Canonicalize a constant object.
|
| - *
|
| - * Preconditions:
|
| - * - `obj` is an objects or array, not a primitive.
|
| - * - nested values of the object are themselves already canonicalized.
|
| - */
|
| - function constant(obj) {
|
| - let objectKey = [realRuntimeType(obj)];
|
| - // TODO(jmesserly): there's no guarantee in JS that names/symbols are
|
| - // returned in the same order.
|
| - //
|
| - // We could probably get the same order if we're judicious about
|
| - // initializing fields in a consistent order across all const constructors.
|
| - // Alternatively we need a way to sort them to make consistent.
|
| - //
|
| - // Right now we use the (name,value) pairs in sequence, which prevents
|
| - // an object with incorrect field values being returned, but won't
|
| - // canonicalize correctly if key order is different.
|
| - for (let name of getOwnNamesAndSymbols(obj)) {
|
| - objectKey.push(name);
|
| - objectKey.push(obj[name]);
|
| - }
|
| - return multiKeyPutIfAbsent(constants, objectKey, () => obj);
|
| - }
|
| - dart.const = constant;
|
| -
|
| - // TODO(vsm): Rationalize these type methods. We're currently using the
|
| - // setType / proto scheme for nominal types (e.g., classes) and the
|
| - // setRuntimeType / field scheme for structural types (e.g., functions
|
| - // - and only in tests for now).
|
| - // See: https://github.com/dart-lang/dev_compiler/issues/172
|
| -
|
| - /** Sets the type of `obj` to be `type` */
|
| - function setType(obj, type) {
|
| - obj.__proto__ = type.prototype;
|
| - return obj;
|
| - }
|
| - dart.setType = setType;
|
| -
|
| - /** Sets the element type of a list literal. */
|
| - function list(obj, elementType) {
|
| - return setType(obj, _interceptors.JSArray$(elementType));
|
| - }
|
| - dart.list = list;
|
| -
|
| - /** Sets the internal runtime type of `obj` to be `type` */
|
| - function setRuntimeType(obj, type) {
|
| - obj[_runtimeType] = type;
|
| - }
|
| - dart.setRuntimeType = setRuntimeType;
|
| -
|
| - // The following are helpers for Object methods when the receiver
|
| - // may be null or primitive. These should only be generated by
|
| - // the compiler.
|
| - function hashCode(obj) {
|
| - if (obj == null) {
|
| - return 0;
|
| - }
|
| - // TODO(vsm): What should we do for primitives and non-Dart objects?
|
| - switch (typeof obj) {
|
| - case "number":
|
| - case "boolean":
|
| - return obj & 0x1FFFFFFF;
|
| - case "string":
|
| - // TODO(vsm): Call the JSString hashCode?
|
| - return obj.length;
|
| - }
|
| - return obj.hashCode;
|
| - }
|
| - dart.hashCode = hashCode;
|
| -
|
| - function runtimeType(obj) {
|
| - let result = checkPrimitiveType(obj);
|
| - if (result !== null) return result;
|
| - return obj.runtimeType;
|
| - }
|
| - dart.runtimeType = runtimeType;
|
| -
|
| - function toString(obj) {
|
| - if (obj == null) {
|
| - return "null";
|
| - }
|
| - return obj.toString();
|
| - }
|
| - dart.toString = toString;
|
| -
|
| - function noSuchMethod(obj, invocation) {
|
| - if (obj == null) {
|
| - throw new core.NoSuchMethodError(obj, invocation.memberName,
|
| - invocation.positionalArguments, invocation.namedArguments);
|
| - }
|
| - switch (typeof obj) {
|
| - case "number":
|
| - case "boolean":
|
| - case "string":
|
| - throw new core.NoSuchMethodError(obj, invocation.memberName,
|
| - invocation.positionalArguments, invocation.namedArguments);
|
| - }
|
| - return obj.noSuchMethod(invocation);
|
| - }
|
| - dart.noSuchMethod = noSuchMethod;
|
| -
|
| - class JsIterator {
|
| - constructor(dartIterator) {
|
| - this.dartIterator = dartIterator;
|
| - }
|
| - next() {
|
| - let i = this.dartIterator;
|
| - let done = !i.moveNext();
|
| - return { done: done, value: done ? void 0 : i.current };
|
| - }
|
| - }
|
| - dart.JsIterator = JsIterator;
|
| -
|
| - // TODO(jmesserly/vsm): Right now these are sentinels. They should be type
|
| - // objects of some sort, assuming we keep them at runtime.
|
| - function _sentinel(_name) {
|
| - return {
|
| - toString() { return _name; },
|
| - get name() { return this.toString(); }
|
| - };
|
| - }
|
| - dart.dynamic = _sentinel('dynamic');
|
| - dart.void = _sentinel('void');
|
| - dart.bottom = _sentinel('bottom');
|
| -
|
| - dart.global = window || global;
|
| - dart.JsSymbol = Symbol;
|
| -
|
| - // Module support. This is a simplified module system for Dart.
|
| - // Longer term, we can easily migrate to an existing JS module system:
|
| - // ES6, AMD, RequireJS, ....
|
| -
|
| - class LibraryLoader {
|
| - constructor(name, defaultValue, imports, lazyImports, loader) {
|
| - this._name = name;
|
| - this._library = defaultValue ? defaultValue : {};
|
| - this._imports = imports;
|
| - this._lazyImports = lazyImports;
|
| - this._loader = loader;
|
| -
|
| - // Cyclic import detection
|
| - this._state = LibraryLoader.NOT_LOADED;
|
| - }
|
| -
|
| - loadImports(pendingSet) {
|
| - return this.handleImports(this._imports, (lib) => lib.load(pendingSet));
|
| - }
|
| -
|
| - deferLazyImports(pendingSet) {
|
| - return this.handleImports(this._lazyImports,
|
| - (lib) => {
|
| - pendingSet.add(lib._name);
|
| - return lib.stub();
|
| - });
|
| - }
|
| -
|
| - loadLazyImports(pendingSet) {
|
| - return this.handleImports(pendingSet, (lib) => lib.load());
|
| - }
|
| -
|
| - handleImports(list, handler) {
|
| - let results = [];
|
| - for (let name of list) {
|
| - let lib = libraries[name];
|
| - if (!lib) {
|
| - throwRuntimeError('Library not available: ' + name);
|
| - }
|
| - results.push(handler(lib));
|
| - }
|
| - return results;
|
| - }
|
| -
|
| - load(inheritedPendingSet) {
|
| - // Check for cycles
|
| - if (this._state == LibraryLoader.LOADING) {
|
| - throwRuntimeError('Circular dependence on library: ' + this._name);
|
| - } else if (this._state >= LibraryLoader.LOADED) {
|
| - return this._library;
|
| - }
|
| - this._state = LibraryLoader.LOADING;
|
| -
|
| - // Handle imports and record lazy imports
|
| - let pendingSet = inheritedPendingSet ? inheritedPendingSet : new Set();
|
| - let args = this.loadImports(pendingSet);
|
| - args = args.concat(this.deferLazyImports(pendingSet));
|
| -
|
| - // Load the library
|
| - args.unshift(this._library);
|
| - this._loader.apply(null, args);
|
| - this._state = LibraryLoader.LOADED;
|
| -
|
| - // Handle lazy imports
|
| - if (inheritedPendingSet === void 0) {
|
| - // Drain the queue
|
| - this.loadLazyImports(pendingSet);
|
| - }
|
| - this._state = LibraryLoader.READY;
|
| - return this._library;
|
| - }
|
| -
|
| - stub() {
|
| - return this._library;
|
| - }
|
| - }
|
| - LibraryLoader.NOT_LOADED = 0;
|
| - LibraryLoader.LOADING = 1;
|
| - LibraryLoader.LOADED = 2;
|
| - LibraryLoader.READY = 3;
|
| -
|
| - // Map from name to LibraryLoader
|
| - let libraries = new Map();
|
| -
|
| - function library(name, defaultValue, imports, lazyImports, loader) {
|
| - return libraries[name] =
|
| - new LibraryLoader(name, defaultValue, imports, lazyImports, loader);
|
| - }
|
| - dart.library = library;
|
| -
|
| - function import_(libraryName) {
|
| - bootstrap();
|
| - let loader = libraries[libraryName];
|
| - return loader.load();
|
| - }
|
| - dart.import = import_;
|
| -
|
| - function start(libraryName) {
|
| - let library = import_(libraryName);
|
| - _isolate_helper.startRootIsolate(library.main, []);
|
| - }
|
| - dart.start = start;
|
| -
|
| - // Libraries used in this file.
|
| - let core;
|
| - let collection;
|
| - let async;
|
| - let _interceptors;
|
| - let _isolate_helper;
|
| - let _js_helper;
|
| - let _js_primitives;
|
| -
|
| - let _bootstrapped = false;
|
| - function bootstrap() {
|
| - if (_bootstrapped) return;
|
| - _bootstrapped = true;
|
| -
|
| - // Setup stubs for top-level symbols.
|
| - let lazyImport = (name) => libraries[name].stub();
|
| - core = lazyImport('dart/core');
|
| - collection = lazyImport('dart/collection');
|
| - async = lazyImport('dart/async');
|
| - _interceptors = lazyImport('dart/_interceptors');
|
| - _isolate_helper = lazyImport('dart/_isolate_helper');
|
| - _js_helper = lazyImport('dart/_js_helper');
|
| - _js_helper.checkNum = notNull;
|
| - _js_primitives = lazyImport('dart/_js_primitives');
|
| - _js_primitives.printString = (s) => console.log(s);
|
| -
|
| - // Create namespace for dart extension members.
|
| - dartx = dartx || {};
|
| -
|
| - // Force import of core.
|
| - import_('dart/core');
|
| -
|
| - // TODO(vsm): DOM facades?
|
| - // See: https://github.com/dart-lang/dev_compiler/issues/173
|
| - NodeList.prototype.get = function(i) { return this[i]; };
|
| - NamedNodeMap.prototype.get = function(i) { return this[i]; };
|
| - DOMTokenList.prototype.get = function(i) { return this[i]; };
|
| - HTMLCollection.prototype.get = function(i) { return this[i]; };
|
| -
|
| - // TODO(vsm): This is referenced (as init.globalState) from
|
| - // isolate_helper.dart. Where should it go?
|
| - // See: https://github.com/dart-lang/dev_compiler/issues/164
|
| - dart.globalState = null;
|
| - }
|
| -})(dart || (dart = {}));
|
| + exports[name] = _export(value[name]);
|
| + }
|
| + }
|
| +
|
| + exports.global = window || global;
|
| + exports.JsSymbol = _export(Symbol);
|
| +
|
| + // TODO(vsm): This is referenced (as init.globalState) from
|
| + // isolate_helper.dart. Where should it go?
|
| + // See: https://github.com/dart-lang/dev_compiler/issues/164
|
| + exports.globalState = null;
|
| + _js_helper.checkNum = operations.notNull;
|
| +
|
| + // Re-exports
|
| +
|
| + // From classes
|
| + exportFrom(classes, [
|
| + 'bind',
|
| + 'classGetConstructorType',
|
| + 'dartx',
|
| + 'defineNamedConstructor',
|
| + 'defineExtensionNames',
|
| + 'defineExtensionMembers',
|
| + 'generic',
|
| + 'implements',
|
| + 'list',
|
| + 'metadata',
|
| + 'mixin',
|
| + 'registerExtension',
|
| + 'setBaseClass',
|
| + 'setSignature',
|
| + 'virtualField',
|
| + ])
|
| +
|
| + // From dart_utils
|
| + exportFrom(dart_utils, ['copyProperties']);
|
| + // Renames
|
| + exports.defineLazyClass = _export(dart_utils.defineLazy);
|
| + exports.defineLazyProperties = _export(dart_utils.defineLazy);
|
| + exports.defineLazyClassGeneric = _export(dart_utils.defineLazyProperty);
|
| +
|
| + // From operations
|
| + exportFrom(operations, [
|
| + 'JsIterator',
|
| + 'arity',
|
| + 'assert',
|
| + 'const',
|
| + 'dcall',
|
| + 'dindex',
|
| + 'dload',
|
| + 'dput',
|
| + 'dsend',
|
| + 'dsetindex',
|
| + 'equals',
|
| + 'hashCode',
|
| + 'map',
|
| + 'noSuchMethod',
|
| + 'notNull',
|
| + 'stackTrace',
|
| + 'throw_',
|
| + 'toString',
|
| + ])
|
| + // Renames
|
| + exports.as = _export(operations.cast);
|
| + exports.is = _export(operations.instanceOf);
|
| +
|
| + // From types
|
| + exportFrom(types, [
|
| + 'bottom',
|
| + 'dynamic',
|
| + 'functionType',
|
| + 'typedef',
|
| + 'typeName',
|
| + 'void',
|
| + ]);
|
| +
|
| + // From rtti
|
| + exportFrom(rtti, [
|
| + 'fn',
|
| + 'realRuntimeType',
|
| + 'runtimeType',
|
| + ]);
|
| +
|
| +});
|
|
|