From d48b1531937e3331f2d7fd46a41072b5be7585bc Mon Sep 17 00:00:00 2001 From: Vijay Menon Date: Mon, 15 Jun 2015 16:22:54 -0700 Subject: [PATCH] dart:mirrors This is a very bare bones version - just enough to get angular running. See #199 R=jmesserly@google.com Review URL: https://codereview.chromium.org/1186683005. --- pkg/dev_compiler/lib/runtime/_operations.js | 11 +- .../lib/runtime/dart/_js_mirrors.js | 207 +++ pkg/dev_compiler/lib/runtime/dart/mirrors.js | 140 ++ pkg/dev_compiler/lib/runtime/dart_runtime.js | 3 +- pkg/dev_compiler/lib/runtime/dart_utils.js | 6 + .../lib/runtime/harmony_feature_check.js | 6 +- .../lib/src/codegen/js_names.dart | 1 + .../lib/src/dependency_graph.dart | 2 + .../test/codegen/expect/html_input.html | 2 + .../codegen/expect/sunflower/sunflower.html | 2 + pkg/dev_compiler/tool/build_sdk.sh | 2 +- .../tool/input_sdk/lib/mirrors/mirrors.dart | 1235 +++++++++++++++++ .../tool/input_sdk/private/js_mirrors.dart | 174 ++- pkg/dev_compiler/tool/sdk_expected_errors.txt | 147 +- 14 files changed, 1857 insertions(+), 81 deletions(-) create mode 100644 pkg/dev_compiler/lib/runtime/dart/_js_mirrors.js create mode 100644 pkg/dev_compiler/lib/runtime/dart/mirrors.js create mode 100644 pkg/dev_compiler/tool/input_sdk/lib/mirrors/mirrors.dart diff --git a/pkg/dev_compiler/lib/runtime/_operations.js b/pkg/dev_compiler/lib/runtime/_operations.js index b4fa1fa0542a..46d6ccd3cb96 100644 --- a/pkg/dev_compiler/lib/runtime/_operations.js +++ b/pkg/dev_compiler/lib/runtime/_operations.js @@ -8,12 +8,15 @@ dart_library.library('dart_runtime/_operations', null, /* Imports */[ ], /* Lazy Imports */[ 'dart/async', + 'dart/collection', 'dart/core', + 'dart/_js_helper', 'dart_runtime/_classes', 'dart_runtime/_errors', 'dart_runtime/_rtti', 'dart_runtime/_types' -], function(exports, async, core, classes, errors, rtti, types) { +], function(exports, async, collection, core, _js_helper, classes, errors, rtti, + types) { 'use strict'; const getOwnNamesAndSymbols = dart_utils.getOwnNamesAndSymbols; @@ -146,7 +149,6 @@ dart_library.library('dart_runtime/_operations', null, /* Imports */[ } exports.dcall = dcall; - /** Shared code for dsend, dindex, and dsetindex. */ function callMethod(obj, name, args, displayName) { let symbol = _canonicalFieldName(obj, name, args, displayName); @@ -160,6 +162,11 @@ dart_library.library('dart_runtime/_operations', null, /* Imports */[ } exports.dsend = dsend; + function dsendArray(obj, method, args) { + return dsend(obj, method, ...args); + } + exports.dsendArray = dsendArray; + function dindex(obj, index) { return callMethod(obj, 'get', [index], '[]'); } diff --git a/pkg/dev_compiler/lib/runtime/dart/_js_mirrors.js b/pkg/dev_compiler/lib/runtime/dart/_js_mirrors.js new file mode 100644 index 000000000000..0aea04bccf29 --- /dev/null +++ b/pkg/dev_compiler/lib/runtime/dart/_js_mirrors.js @@ -0,0 +1,207 @@ +dart_library.library('dart/_js_mirrors', null, /* Imports */[ + "dart_runtime/dart", + 'dart/_internal', + 'dart/core', + 'dart/mirrors' +], /* Lazy imports */[ +], function(exports, dart, _internal, core, mirrors) { + 'use strict'; + let dartx = dart.dartx; + function getName(symbol) { + return _internal.Symbol.getName(dart.as(symbol, _internal.Symbol)); + } + dart.fn(getName, core.String, [core.Symbol]); + function getSymbol(name, library) { + return dart.throw_(new core.UnimplementedError("MirrorSystem.getSymbol unimplemented")); + } + dart.fn(getSymbol, core.Symbol, [core.Object, core.Object]); + dart.defineLazyProperties(exports, { + get currentJsMirrorSystem() { + return dart.throw_(new core.UnimplementedError("MirrorSystem.currentJsMirrorSystem unimplemented")); + } + }); + function reflect(reflectee) { + return new JsInstanceMirror._(reflectee); + } + dart.fn(reflect, mirrors.InstanceMirror, [core.Object]); + function reflectType(key) { + return new JsClassMirror._(key); + } + dart.fn(reflectType, mirrors.TypeMirror, [core.Type]); + dart.defineLazyProperties(exports, { + get _dart() { + return dart; + }, + get _metadata() { + return exports._dart.metadata; + } + }); + function _dload(obj, name) { + return exports._dart.dload(obj, name); + } + dart.fn(_dload, core.Object, [core.Object, core.String]); + function _dput(obj, name, val) { + exports._dart.dput(obj, name, val); + } + dart.fn(_dput, dart.void, [core.Object, core.String, core.Object]); + function _dsend(obj, name, args) { + return exports._dart.dsendArray(obj, name, args); + } + dart.fn(_dsend, core.Object, [core.Object, core.String, core.List]); + let _toJsMap = Symbol('_toJsMap'); + class JsInstanceMirror extends core.Object { + _(reflectee) { + this.reflectee = reflectee; + } + getField(symbol) { + let name = getName(symbol); + let field = _dload(this.reflectee, name); + return new JsInstanceMirror._(field); + } + setField(symbol, value) { + let name = getName(symbol); + let field = _dput(this.reflectee, name, value); + return new JsInstanceMirror._(field); + } + invoke(symbol, args, namedArgs) { + if (namedArgs === void 0) + namedArgs = null; + let name = getName(symbol); + if (namedArgs != null) { + args = core.List.from(args); + args[dartx.add](this[_toJsMap](namedArgs)); + } + let result = _dsend(this.reflectee, name, args); + return new JsInstanceMirror._(result); + } + [_toJsMap](map) { + let obj = {}; + map.forEach(dart.fn((key, value) => { + obj[getName(key)] = value; + }, core.Object, [core.Symbol, core.Object])); + return obj; + } + } + JsInstanceMirror[dart.implements] = () => [mirrors.InstanceMirror]; + dart.defineNamedConstructor(JsInstanceMirror, '_'); + dart.setSignature(JsInstanceMirror, { + constructors: () => ({_: [JsInstanceMirror, [core.Object]]}), + methods: () => ({ + getField: [mirrors.InstanceMirror, [core.Symbol]], + setField: [mirrors.InstanceMirror, [core.Symbol, core.Object]], + invoke: [mirrors.InstanceMirror, [core.Symbol, core.List], [core.Map$(core.Symbol, core.Object)]], + [_toJsMap]: [core.Object, [core.Map$(core.Symbol, core.Object)]] + }) + }); + let _metadata = Symbol('_metadata'); + let _declarations = Symbol('_declarations'); + let _cls = Symbol('_cls'); + class JsClassMirror extends core.Object { + get metadata() { + return this[_metadata]; + } + get declarations() { + return this[_declarations]; + } + _(cls) { + this[_cls] = cls; + this.simpleName = core.Symbol.new(cls.name); + this[_metadata] = null; + this[_declarations] = null; + let fn = this[_cls][dart.metadata]; + this[_metadata] = fn == null ? dart.list([], mirrors.InstanceMirror) : core.List$(mirrors.InstanceMirror).from(dart.as(dart.dsend(dart.dcall(fn), 'map', dart.fn(i => new JsInstanceMirror._(i), JsInstanceMirror, [core.Object])), core.Iterable)); + this[_declarations] = core.Map$(core.Symbol, mirrors.MethodMirror).new(); + this[_declarations].set(this.simpleName, new JsMethodMirror._(this, this[_cls])); + } + newInstance(constructorName, args, namedArgs) { + if (namedArgs === void 0) + namedArgs = null; + dart.assert(getName(constructorName) == ""); + dart.assert(namedArgs == null || dart.notNull(namedArgs.isEmpty)); + let instance = exports._dart.instantiate(this[_cls], args); + return new JsInstanceMirror._(instance); + } + } + JsClassMirror[dart.implements] = () => [mirrors.ClassMirror]; + dart.defineNamedConstructor(JsClassMirror, '_'); + dart.setSignature(JsClassMirror, { + constructors: () => ({_: [JsClassMirror, [core.Type]]}), + methods: () => ({newInstance: [mirrors.InstanceMirror, [core.Symbol, core.List], [core.Map$(core.Symbol, core.Object)]]}) + }); + class JsTypeMirror extends core.Object { + _(reflectedType) { + this.reflectedType = reflectedType; + } + } + JsTypeMirror[dart.implements] = () => [mirrors.TypeMirror]; + dart.defineNamedConstructor(JsTypeMirror, '_'); + dart.setSignature(JsTypeMirror, { + constructors: () => ({_: [JsTypeMirror, [core.Type]]}) + }); + let _name = Symbol('_name'); + class JsParameterMirror extends core.Object { + _(name, t) { + this.metadata = dart.list([], mirrors.InstanceMirror); + this[_name] = name; + this.type = new JsTypeMirror._(t); + } + } + JsParameterMirror[dart.implements] = () => [mirrors.ParameterMirror]; + dart.defineNamedConstructor(JsParameterMirror, '_'); + dart.setSignature(JsParameterMirror, { + constructors: () => ({_: [JsParameterMirror, [core.String, core.Type]]}) + }); + let _method = Symbol('_method'); + let _params = Symbol('_params'); + let _createParameterMirrorList = Symbol('_createParameterMirrorList'); + class JsMethodMirror extends core.Object { + _(cls, method) { + this[_method] = method; + this[_name] = getName(cls.simpleName); + this[_params] = null; + let ftype = exports._dart.classGetConstructorType(cls[_cls]); + this[_params] = this[_createParameterMirrorList](ftype); + } + get constructorName() { + return core.Symbol.new(''); + } + get parameters() { + return this[_params]; + } + [_createParameterMirrorList](ftype) { + if (ftype == null) { + return dart.list([], mirrors.ParameterMirror); + } + let args = dart.as(dart.dload(ftype, 'args'), core.List); + let opts = dart.as(dart.dload(ftype, 'optionals'), core.List); + let params = core.List$(mirrors.ParameterMirror).new(dart.notNull(args[dartx.length]) + dart.notNull(opts[dartx.length])); + for (let i = 0; dart.notNull(i) < dart.notNull(args[dartx.length]); i = dart.notNull(i) + 1) { + let type = args[dartx.get](i); + let param = new JsParameterMirror._('', dart.as(type, core.Type)); + params[dartx.set](i, param); + } + for (let i = 0; dart.notNull(i) < dart.notNull(opts[dartx.length]); i = dart.notNull(i) + 1) { + let type = opts[dartx.get](i); + let param = new JsParameterMirror._('', dart.as(type, core.Type)); + params[dartx.set](dart.notNull(i) + dart.notNull(args[dartx.length]), param); + } + return params; + } + } + JsMethodMirror[dart.implements] = () => [mirrors.MethodMirror]; + dart.defineNamedConstructor(JsMethodMirror, '_'); + dart.setSignature(JsMethodMirror, { + constructors: () => ({_: [JsMethodMirror, [JsClassMirror, core.Object]]}), + methods: () => ({[_createParameterMirrorList]: [core.List$(mirrors.ParameterMirror), [core.Object]]}) + }); + // Exports: + exports.getName = getName; + exports.getSymbol = getSymbol; + exports.reflect = reflect; + exports.reflectType = reflectType; + exports.JsInstanceMirror = JsInstanceMirror; + exports.JsClassMirror = JsClassMirror; + exports.JsTypeMirror = JsTypeMirror; + exports.JsParameterMirror = JsParameterMirror; + exports.JsMethodMirror = JsMethodMirror; +}); diff --git a/pkg/dev_compiler/lib/runtime/dart/mirrors.js b/pkg/dev_compiler/lib/runtime/dart/mirrors.js new file mode 100644 index 000000000000..56b154ca746b --- /dev/null +++ b/pkg/dev_compiler/lib/runtime/dart/mirrors.js @@ -0,0 +1,140 @@ +dart_library.library('dart/mirrors', null, /* Imports */[ + "dart_runtime/dart", + 'dart/core' +], /* Lazy imports */[ + 'dart/_js_mirrors' +], function(exports, dart, core, _js_mirrors) { + 'use strict'; + let dartx = dart.dartx; + class MirrorSystem extends core.Object { + findLibrary(libraryName) { + return this.libraries.values[dartx.singleWhere](dart.fn(library => dart.equals(dart.dload(library, 'simpleName'), libraryName), core.bool, [core.Object])); + } + static getName(symbol) { + return _js_mirrors.getName(symbol); + } + static getSymbol(name, library) { + if (library === void 0) + library = null; + return _js_mirrors.getSymbol(name, library); + } + } + dart.setSignature(MirrorSystem, { + methods: () => ({findLibrary: [LibraryMirror, [core.Symbol]]}), + statics: () => ({ + getName: [core.String, [core.Symbol]], + getSymbol: [core.Symbol, [core.String], [LibraryMirror]] + }), + names: ['getName', 'getSymbol'] + }); + function currentMirrorSystem() { + return dart.as(_js_mirrors.currentJsMirrorSystem, MirrorSystem); + } + dart.fn(currentMirrorSystem, MirrorSystem, []); + function reflect(reflectee) { + return _js_mirrors.reflect(reflectee); + } + dart.fn(reflect, () => dart.functionType(InstanceMirror, [core.Object])); + function reflectClass(key) { + if (!dart.is(key, core.Type) || dart.equals(key, core.Object)) { + throw new core.ArgumentError(`${key} does not denote a class`); + } + let tm = reflectType(key); + if (!dart.is(tm, ClassMirror)) { + throw new core.ArgumentError(`${key} does not denote a class`); + } + return dart.as(dart.as(tm, ClassMirror).originalDeclaration, ClassMirror); + } + dart.fn(reflectClass, () => dart.functionType(ClassMirror, [core.Type])); + function reflectType(key) { + if (dart.equals(key, core.Object)) { + return currentMirrorSystem().dynamicType; + } + return _js_mirrors.reflectType(key); + } + dart.fn(reflectType, () => dart.functionType(TypeMirror, [core.Type])); + class Mirror extends core.Object {} + class IsolateMirror extends core.Object {} + IsolateMirror[dart.implements] = () => [Mirror]; + class DeclarationMirror extends core.Object {} + DeclarationMirror[dart.implements] = () => [Mirror]; + class ObjectMirror extends core.Object {} + ObjectMirror[dart.implements] = () => [Mirror]; + class InstanceMirror extends core.Object {} + InstanceMirror[dart.implements] = () => [ObjectMirror]; + class ClosureMirror extends core.Object {} + ClosureMirror[dart.implements] = () => [InstanceMirror]; + class LibraryMirror extends core.Object {} + LibraryMirror[dart.implements] = () => [DeclarationMirror, ObjectMirror]; + class LibraryDependencyMirror extends core.Object {} + LibraryDependencyMirror[dart.implements] = () => [Mirror]; + class CombinatorMirror extends core.Object {} + CombinatorMirror[dart.implements] = () => [Mirror]; + class TypeMirror extends core.Object {} + TypeMirror[dart.implements] = () => [DeclarationMirror]; + class ClassMirror extends core.Object {} + ClassMirror[dart.implements] = () => [TypeMirror, ObjectMirror]; + class FunctionTypeMirror extends core.Object {} + FunctionTypeMirror[dart.implements] = () => [ClassMirror]; + class TypeVariableMirror extends TypeMirror {} + class TypedefMirror extends core.Object {} + TypedefMirror[dart.implements] = () => [TypeMirror]; + class MethodMirror extends core.Object {} + MethodMirror[dart.implements] = () => [DeclarationMirror]; + class VariableMirror extends core.Object {} + VariableMirror[dart.implements] = () => [DeclarationMirror]; + class ParameterMirror extends core.Object {} + ParameterMirror[dart.implements] = () => [VariableMirror]; + class SourceLocation extends core.Object {} + class Comment extends core.Object { + Comment(text, trimmedText, isDocComment) { + this.text = text; + this.trimmedText = trimmedText; + this.isDocComment = isDocComment; + } + } + dart.setSignature(Comment, { + constructors: () => ({Comment: [Comment, [core.String, core.String, core.bool]]}) + }); + class MirrorsUsed extends core.Object { + MirrorsUsed(opts) { + let symbols = opts && 'symbols' in opts ? opts.symbols : null; + let targets = opts && 'targets' in opts ? opts.targets : null; + let metaTargets = opts && 'metaTargets' in opts ? opts.metaTargets : null; + let override = opts && 'override' in opts ? opts.override : null; + this.symbols = symbols; + this.targets = targets; + this.metaTargets = metaTargets; + this.override = override; + } + } + dart.setSignature(MirrorsUsed, { + constructors: () => ({MirrorsUsed: [MirrorsUsed, [], {symbols: core.Object, targets: core.Object, metaTargets: core.Object, override: core.Object}]}) + }); + // Exports: + exports.MirrorSystem = MirrorSystem; + exports.currentMirrorSystem = currentMirrorSystem; + exports.reflect = reflect; + exports.reflectClass = reflectClass; + exports.reflectType = reflectType; + exports.Mirror = Mirror; + exports.IsolateMirror = IsolateMirror; + exports.DeclarationMirror = DeclarationMirror; + exports.ObjectMirror = ObjectMirror; + exports.InstanceMirror = InstanceMirror; + exports.ClosureMirror = ClosureMirror; + exports.LibraryMirror = LibraryMirror; + exports.LibraryDependencyMirror = LibraryDependencyMirror; + exports.CombinatorMirror = CombinatorMirror; + exports.TypeMirror = TypeMirror; + exports.ClassMirror = ClassMirror; + exports.FunctionTypeMirror = FunctionTypeMirror; + exports.TypeVariableMirror = TypeVariableMirror; + exports.TypedefMirror = TypedefMirror; + exports.MethodMirror = MethodMirror; + exports.VariableMirror = VariableMirror; + exports.ParameterMirror = ParameterMirror; + exports.SourceLocation = SourceLocation; + exports.Comment = Comment; + exports.MirrorsUsed = MirrorsUsed; +}); diff --git a/pkg/dev_compiler/lib/runtime/dart_runtime.js b/pkg/dev_compiler/lib/runtime/dart_runtime.js index 914636ae8cd9..7e23f52b7f93 100644 --- a/pkg/dev_compiler/lib/runtime/dart_runtime.js +++ b/pkg/dev_compiler/lib/runtime/dart_runtime.js @@ -56,7 +56,7 @@ dart_library.library('dart_runtime/dart', null, /* Imports */[ ]) // From dart_utils - exportFrom(dart_utils, ['copyProperties']); + exportFrom(dart_utils, ['copyProperties', 'instantiate']); // Renames exports.defineLazyClass = _export(dart_utils.defineLazy); exports.defineLazyProperties = _export(dart_utils.defineLazy); @@ -73,6 +73,7 @@ dart_library.library('dart_runtime/dart', null, /* Imports */[ 'dload', 'dput', 'dsend', + 'dsendArray', 'dsetindex', 'equals', 'hashCode', diff --git a/pkg/dev_compiler/lib/runtime/dart_utils.js b/pkg/dev_compiler/lib/runtime/dart_utils.js index 6c97e228da6d..35e3d56ca26c 100644 --- a/pkg/dev_compiler/lib/runtime/dart_utils.js +++ b/pkg/dev_compiler/lib/runtime/dart_utils.js @@ -112,4 +112,10 @@ var dart_utils; } dart_utils.copyProperties = copyProperties; + + function instantiate(type, args) { + return new type(...args); + } + dart_utils.instantiate = instantiate; + })(dart_utils || (dart_utils = {})); diff --git a/pkg/dev_compiler/lib/runtime/harmony_feature_check.js b/pkg/dev_compiler/lib/runtime/harmony_feature_check.js index c2f80e44dd51..33003066a1ad 100644 --- a/pkg/dev_compiler/lib/runtime/harmony_feature_check.js +++ b/pkg/dev_compiler/lib/runtime/harmony_feature_check.js @@ -10,8 +10,9 @@ 'class C {' + 'constructor(x) { this.x = x; };' + '["foo"]() { return x => this.x + x; };' + + 'bar(args) { return this.foo()(...args); };' + '};' + - 'return new C(42).foo()(100);'); + 'return new C(42).bar([100]);'); if (f() == 142) return; // supported! } catch (e) { } @@ -19,7 +20,8 @@ var message = 'This script needs EcmaScript 6 features ' + 'like `class` and `=>`. Please run in a browser with support, ' + 'for example: chrome --js-flags="--harmony-arrow-functions' + - ' --harmony-classes --harmony-computed-property-names"'; + ' --harmony-classes --harmony-computed-property-names' + + ' --harmony-spreadcalls"'; console.error(message); alert(message); diff --git a/pkg/dev_compiler/lib/src/codegen/js_names.dart b/pkg/dev_compiler/lib/src/codegen/js_names.dart index e050532a4a35..38fc7d1e327f 100644 --- a/pkg/dev_compiler/lib/src/codegen/js_names.dart +++ b/pkg/dev_compiler/lib/src/codegen/js_names.dart @@ -241,6 +241,7 @@ bool invalidVariableName(String keyword, {bool strictMode: true}) { case "import": case "in": case "instanceof": + case "interface": case "let": case "new": case "return": diff --git a/pkg/dev_compiler/lib/src/dependency_graph.dart b/pkg/dev_compiler/lib/src/dependency_graph.dart index f808fff2b73b..fc0c01a7f838 100644 --- a/pkg/dev_compiler/lib/src/dependency_graph.dart +++ b/pkg/dev_compiler/lib/src/dependency_graph.dart @@ -532,6 +532,8 @@ const corelibOrder = const [ 'dart._isolate_helper', 'dart._js_primitives', 'dart.convert', + 'dart.mirrors', + 'dart._js_mirrors', // _foreign_helper is not included, as it only defines the JS builtin that // the compiler handles at compile time. ]; diff --git a/pkg/dev_compiler/test/codegen/expect/html_input.html b/pkg/dev_compiler/test/codegen/expect/html_input.html index 6f21c5f1649f..b1ab38df0cec 100644 --- a/pkg/dev_compiler/test/codegen/expect/html_input.html +++ b/pkg/dev_compiler/test/codegen/expect/html_input.html @@ -23,6 +23,8 @@ + + diff --git a/pkg/dev_compiler/test/codegen/expect/sunflower/sunflower.html b/pkg/dev_compiler/test/codegen/expect/sunflower/sunflower.html index c3fccf525213..7ae9c1e67317 100644 --- a/pkg/dev_compiler/test/codegen/expect/sunflower/sunflower.html +++ b/pkg/dev_compiler/test/codegen/expect/sunflower/sunflower.html @@ -47,6 +47,8 @@

drfibonacci's Sunflower Spectacular

+ + diff --git a/pkg/dev_compiler/tool/build_sdk.sh b/pkg/dev_compiler/tool/build_sdk.sh index b473350bc957..a665c8c1db42 100755 --- a/pkg/dev_compiler/tool/build_sdk.sh +++ b/pkg/dev_compiler/tool/build_sdk.sh @@ -16,7 +16,7 @@ fi # transitively. Ideally we could pass them explicitly, though: # https://github.com/dart-lang/dev_compiler/issues/219 dart -c bin/devc.dart --no-source-maps --sdk-check --force-compile -l warning \ - --dart-sdk tool/generated_sdk -o lib/runtime/ dart:js \ + --dart-sdk tool/generated_sdk -o lib/runtime/ dart:mirrors \ > tool/generated_sdk/sdk_errors.txt || true if [[ ! -f lib/runtime/dart/core.js ]] ; then diff --git a/pkg/dev_compiler/tool/input_sdk/lib/mirrors/mirrors.dart b/pkg/dev_compiler/tool/input_sdk/lib/mirrors/mirrors.dart new file mode 100644 index 000000000000..d16e62eecb7f --- /dev/null +++ b/pkg/dev_compiler/tool/input_sdk/lib/mirrors/mirrors.dart @@ -0,0 +1,1235 @@ +// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file +// 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. + +// For the purposes of the mirrors library, we adopt a naming +// convention with respect to getters and setters. Specifically, for +// some variable or field... +// +// var myField; +// +// ...the getter is named 'myField' and the setter is named +// 'myField='. This allows us to assign unique names to getters and +// setters for the purposes of member lookup. + +/** + * Basic reflection in Dart, + * with support for introspection and dynamic evaluation. + * + * *Introspection* is that subset of reflection by which a running + * program can examine its own structure. For example, a function + * that prints out the names of all the members of an arbitrary object. + * + * *Dynamic evaluation* refers the ability to evaluate code that + * has not been literally specified at compile time, such as calling a method + * whose name is provided as an argument (because it is looked up + * in a database, or provided interactively by the user). + * + * ## How to interpret this library's documentation + * + * As a rule, the names of Dart declarations are represented using + * instances of class [Symbol]. Whenever the doc speaks of an object *s* + * of class [Symbol] denoting a name, it means the string that + * was used to construct *s*. + * + * The documentation frequently abuses notation with + * Dart pseudo-code such as [:o.x(a):], where + * o and a are defined to be objects; what is actually meant in these + * cases is [:o'.x(a'):] where *o'* and *a'* are Dart variables + * bound to *o* and *a* respectively. Furthermore, *o'* and *a'* + * are assumed to be fresh variables (meaning that they are + * distinct from any other variables in the program). + * + * Sometimes the documentation refers to *serializable* objects. + * An object is serializable across isolates if and only if it is an instance of + * num, bool, String, a list of objects that are serializable + * across isolates, or a map with keys and values that are all serializable across + * isolates. + * + * ## Status: Unstable + * + * The dart:mirrors library is unstable and its API might change slightly as a + * result of user feedback. This library is platform dependent and therefore it + * has implementations for both dart2js and the Dart VM. Both are under + * development and may not support all operations yet. + */ +library dart.mirrors; + +/** + * A [MirrorSystem] is the main interface used to reflect on a set of + * associated libraries. + * + * At runtime each running isolate has a distinct [MirrorSystem]. + * + * It is also possible to have a [MirrorSystem] which represents a set + * of libraries which are not running -- perhaps at compile-time. In + * this case, all available reflective functionality would be + * supported, but runtime functionality (such as invoking a function + * or inspecting the contents of a variable) would fail dynamically. + */ +abstract class MirrorSystem { + /** + * Returns an immutable map from URIs to mirrors for all + * libraries known to this mirror system. + */ + Map get libraries; + + /** + * Returns the unique library named [libraryName] if it exists. + * + * If no unique library exists, an error is thrown. + */ + LibraryMirror findLibrary(Symbol libraryName) { + return libraries.values.singleWhere( + (library) => library.simpleName == libraryName); + } + + /** + * A mirror on the isolate associated with this [MirrorSystem]. + * This may be null if this mirror system is not running. + */ + IsolateMirror get isolate; + + /** + * A mirror on the [:dynamic:] type. + */ + TypeMirror get dynamicType; + + /** + * A mirror on the [:void:] type. + */ + TypeMirror get voidType; + + /** + * Returns the name of [symbol]. + * + * The following text is non-normative: + * + * Using this method may result in larger output. If possible, use + * [MirrorsUsed] to specify which symbols must be retained in clear text. + */ + external static String getName(Symbol symbol); + + /** + * Returns a symbol for [name]. If [library] is not a [LibraryMirror] or if + * [name] is a private identifier and [library] is [:null:], throws an + * [ArgumentError]. If [name] is a private identifier, the symbol returned is + * with respect to [library]. + * + * The following text is non-normative: + * + * Using this method may result in larger output. If possible, use + * the const constructor of Symbol or symbol literals. + */ + external static Symbol getSymbol(String name, [LibraryMirror library]); +} + +/** + * Returns a [MirrorSystem] for the current isolate. + */ +external MirrorSystem currentMirrorSystem(); + +/** + * Reflects an instance. + * Returns an [InstanceMirror] reflecting [reflectee]. + * If [reflectee] is a function or an instance of a class + * that has a [:call:] method, the returned instance mirror + * will be a [ClosureMirror]. + * + * Note that since one cannot obtain an object from + * another isolate, this function can only be used to + * obtain mirrors on objects of the current isolate. + */ +external InstanceMirror reflect(Object reflectee); + +/** + * Reflects a class declaration. + * Let *C* be the original class declaration of the class + * represented by [key]. + * This function returns a [ClassMirror] reflecting *C*. + * + * If [key] is not an instance of [Type] then this function + * throws an [ArgumentError]. If [key] is the Type for dynamic + * or a function typedef, throws an [ArgumentError]. + * + * Note that since one cannot obtain a [Type] object from + * another isolate, this function can only be used to + * obtain class mirrors on classes of the current isolate. + */ +external ClassMirror reflectClass(Type key); + +/** + * This function returns a [TypeMirror] reflecting the type + * represented by [key]. + * + * If [key] is not an instance of [Type] then this function + * throws an [ArgumentError]. + * + * Note that since one cannot obtain a [Type] object from + * another isolate, this function can only be used to + * obtain type mirrors on types of the current isolate. + */ +external TypeMirror reflectType(Type key); + +/** + * A [Mirror] reflects some Dart language entity. + * + * Every [Mirror] originates from some [MirrorSystem]. + */ +abstract class Mirror {} + +/** + * An [IsolateMirror] reflects an isolate. + */ +abstract class IsolateMirror implements Mirror { + /** + * Returns a unique name used to refer to an isolate + * in debugging messages. + */ + String get debugName; + + /** + * Returns [:true:] if and only if this mirror reflects + * the currently running isolate. Otherwise returns + * [:false:]. + */ + bool get isCurrent; + + /** + * Returns a [LibraryMirror] on the root library for this + * isolate. + */ + LibraryMirror get rootLibrary; + + /** + * Returns [:true:] if this mirror is equal to [other]. + * Otherwise returns [:false:]. + * The equality holds if and only if + * (1) [other] is a mirror of the same kind + * and + * (2) the isolate being reflected by this mirror is the same + * isolate being reflected by [other]. + */ + bool operator == (other); +} + +/** + * A [DeclarationMirror] reflects some entity declared in a Dart program. + */ +abstract class DeclarationMirror implements Mirror { + /** + * The simple name for this Dart language entity. + * + * The simple name is in most cases the the identifier name of the + * entity, such as 'method' for a method [:void method() {...}:] or + * 'mylibrary' for a [:library 'mylibrary';:] declaration. + */ + Symbol get simpleName; + + /** + * The fully-qualified name for this Dart language entity. + * + * This name is qualified by the name of the owner. For instance, + * the qualified name of a method 'method' in class 'Class' in + * library 'library' is 'library.Class.method'. + * + * Returns a [Symbol] constructed from a string representing the + * fully qualified name of the reflectee. + * Let *o* be the [owner] of this mirror, let *r* be the reflectee of + * this mirror, let *p* be the fully qualified + * name of the reflectee of *o*, and let *s* be the simple name of *r* + * computed by [simpleName]. + * The fully qualified name of *r* is the + * concatenation of *p*, '.', and *s*. + * + * Because an isolate can contain more than one library with the same name (at + * different URIs), a fully-qualified name does not uniquely identify any + * language entity. + */ + Symbol get qualifiedName; + + /** + * A mirror on the owner of this Dart language entity. This is the declaration + * immediately surrounding the reflectee. + * + * For a library, the owner is [:null:]. + * For a class declaration, typedef or top level function + * or variable, the owner is the enclosing library. + * For a mixin application *S with M*, the owner is the owner + * of *M*. + * For a constructor, the owner is the immediately enclosing class. + * For a method, instance variable or + * a static variable, the owner is the immediately enclosing class, + * unless the class is a mixin application *S with M*, in which case + * the owner is *M*. Note that *M* may be an invocation of a generic. + * For a parameter, local variable or local function the owner is the + * immediately enclosing function. + */ + DeclarationMirror get owner; + + /** + * Returns [:true:] if this declaration is considered private + * according to the Dart language specification. + * Always returns [: false :] if this declaration + * is a library. + * Otherwise return [:false:]. + * + */ + bool get isPrivate; + + /** + * Is this declaration top-level? + * + * This is defined to be equivalent to: + * [:mirror.owner != null && mirror.owner is LibraryMirror:] + */ + bool get isTopLevel; + + /** + * The source location of this Dart language entity. + * + * This operation is optional and may return [:null:]. + */ + SourceLocation get location; + + /** + * A list of the metadata associated with this declaration. + * + * Let *D* be the declaration this mirror reflects. + * If *D* is decorated with annotations *A1, ..., An* + * where *n > 0*, then for each annotation *Ai* associated + * with *D, 1 <= i <= n*, let *ci* be the constant object + * specified by *Ai*. Then this method returns a list whose + * members are instance mirrors on *c1, ..., cn*. + * If no annotations are associated with *D*, then + * an empty list is returned. + * + * If evaluating any of *c1, ..., cn* would cause a + * compilation error + * the effect is the same as if a non-reflective compilation error + * had been encountered. + */ + List get metadata; +} + +/** + * An [ObjectMirror] is a common superinterface of [InstanceMirror], + * [ClassMirror], and [LibraryMirror] that represents their shared + * functionality. + * + * For the purposes of the mirrors library, these types are all + * object-like, in that they support method invocation and field + * access. Real Dart objects are represented by the [InstanceMirror] + * type. + * + * See [InstanceMirror], [ClassMirror], and [LibraryMirror]. + */ +abstract class ObjectMirror implements Mirror { + + /** + * Invokes the named function and returns a mirror on the result. + * + * Let *o* be the object reflected by this mirror, let + * *f* be the simple name of the member denoted by [memberName], + * let *a1, ..., an* be the elements of [positionalArguments] + * let *k1, ..., km* be the identifiers denoted by the elements of + * [namedArguments.keys] + * and let *v1, ..., vm* be the elements of [namedArguments.values]. + * Then this method will perform the method invocation + * *o.f(a1, ..., an, k1: v1, ..., km: vm)* + * in a scope that has access to the private members + * of *o* (if *o* is a class or library) or the private members of the + * class of *o* (otherwise). + * If the invocation returns a result *r*, this method returns + * the result of calling [reflect](*r*). + * If the invocation causes a compilation error + * the effect is the same as if a non-reflective compilation error + * had been encountered. + * If the invocation throws an exception *e* (that it does not catch) + * this method throws *e*. + */ + /* + * TODO(turnidge): Handle ambiguous names. + * TODO(turnidge): Handle optional & named arguments. + */ + InstanceMirror invoke(Symbol memberName, + List positionalArguments, + [Map namedArguments]); + + /** + * Invokes a getter and returns a mirror on the result. The getter + * can be the implicit getter for a field or a user-defined getter + * method. + * + * Let *o* be the object reflected by this mirror, let + * *f* be the simple name of the getter denoted by [fieldName], + * Then this method will perform the getter invocation + * *o.f* + * in a scope that has access to the private members + * of *o* (if *o* is a class or library) or the private members of the + * class of *o* (otherwise). + * + * If this mirror is an [InstanceMirror], and [fieldName] denotes an instance + * method on its reflectee, the result of the invocation is an instance + * mirror on a closure corresponding to that method. + * + * If this mirror is a [LibraryMirror], and [fieldName] denotes a top-level + * method in the corresponding library, the result of the invocation is an + * instance mirror on a closure corresponding to that method. + * + * If this mirror is a [ClassMirror], and [fieldName] denotes a static method + * in the corresponding class, the result of the invocation is an instance + * mirror on a closure corresponding to that method. + * + * If the invocation returns a result *r*, this method returns + * the result of calling [reflect](*r*). + * If the invocation causes a compilation error + * the effect is the same as if a non-reflective compilation error + * had been encountered. + * If the invocation throws an exception *e* (that it does not catch) + * this method throws *e*. + */ + // TODO(ahe): Remove stuff about scope and private members. [fieldName] is a + // capability giving access to private members. + InstanceMirror getField(Symbol fieldName); + + /** + * Invokes a setter and returns a mirror on the result. The setter + * may be either the implicit setter for a non-final field or a + * user-defined setter method. + * + * Let *o* be the object reflected by this mirror, let + * *f* be the simple name of the getter denoted by [fieldName], + * and let *a* be the object bound to [value]. + * Then this method will perform the setter invocation + * *o.f = a* + * in a scope that has access to the private members + * of *o* (if *o* is a class or library) or the private members of the + * class of *o* (otherwise). + * If the invocation returns a result *r*, this method returns + * the result of calling [reflect]([value]). + * If the invocation causes a compilation error + * the effect is the same as if a non-reflective compilation error + * had been encountered. + * If the invocation throws an exception *e* (that it does not catch) + * this method throws *e*. + */ + /* TODO(turnidge): Handle ambiguous names.*/ + InstanceMirror setField(Symbol fieldName, Object value); +} + +/** + * An [InstanceMirror] reflects an instance of a Dart language object. + */ +abstract class InstanceMirror implements ObjectMirror { + /** + * A mirror on the type of the reflectee. + * + * Returns a mirror on the actual class of the reflectee. + * The class of the reflectee may differ from + * the object returned by invoking [runtimeType] on + * the reflectee. + */ + ClassMirror get type; + + /** + * Does [reflectee] contain the instance reflected by this mirror? + * This will always be true in the local case (reflecting instances + * in the same isolate), but only true in the remote case if this + * mirror reflects a simple value. + * + * A value is simple if one of the following holds: + * - the value is [:null:] + * - the value is of type [num] + * - the value is of type [bool] + * - the value is of type [String] + */ + bool get hasReflectee; + + /** + * If the [InstanceMirror] reflects an instance it is meaningful to + * have a local reference to, we provide access to the actual + * instance here. + * + * If you access [reflectee] when [hasReflectee] is false, an + * exception is thrown. + */ + get reflectee; + + /** + * Returns true if this mirror is equal to [other]. + * The equality holds if and only if + * (1) [other] is a mirror of the same kind + * and + * (2) either + * (a) [hasReflectee] is true and so is + * [:identical(reflectee, other.reflectee):] + * or + * (b) the remote objects reflected by this mirror and + * by [other] are identical. + */ + bool operator == (other); + + /** + * Perform [invocation] on [reflectee]. + * Equivalent to + * + * this.invoke(invocation.memberName, + * invocation.positionalArguments, + * invocation.namedArguments); + */ + delegate(Invocation invocation); +} + +/** + * A [ClosureMirror] reflects a closure. + * + * A [ClosureMirror] provides access to its captured variables and + * provides the ability to execute its reflectee. + */ +abstract class ClosureMirror implements InstanceMirror { + /** + * A mirror on the function associated with this closure. + * + * The function associated with an implicit closure of a function is that + * function. + * + * The function associated with an instance of a class that has a [:call:] + * method is that [:call:] method. + * + * A Dart implementation might choose to create a class for each closure + * expression, in which case [:function:] would be the same as + * [:type.declarations[#call]:]. But the Dart language model does not require + * this. A more typical implementation involves a single closure class for + * each type signature, where the call method dispatches to a function held + * in the closure rather the call method + * directly implementing the closure body. So one cannot rely on closures from + * distinct closure expressions having distinct classes ([:type:]), but one + * can rely on them having distinct functions ([:function:]). + */ + MethodMirror get function; + + /** + * Executes the closure and returns a mirror on the result. + * Let *f* be the closure reflected by this mirror, + * let *a1, ..., an* be the elements of [positionalArguments] + * let *k1, ..., km* be the identifiers denoted by the elements of + * [namedArguments.keys] + * and let *v1, ..., vm* be the elements of [namedArguments.values]. + * Then this method will perform the method invocation + * *f(a1, ..., an, k1: v1, ..., km: vm)* + * If the invocation returns a result *r*, this method returns + * the result of calling [reflect](*r*). + * If the invocation causes a compilation error + * the effect is the same as if a non-reflective compilation error + * had been encountered. + * If the invocation throws an exception *e* (that it does not catch) + * this method throws *e*. + */ + InstanceMirror apply(List positionalArguments, + [Map namedArguments]); +} + +/** + * A [LibraryMirror] reflects a Dart language library, providing + * access to the variables, functions, and classes of the + * library. + */ +abstract class LibraryMirror implements DeclarationMirror, ObjectMirror { + /** + * The absolute uri of the library. + */ + Uri get uri; + + /** + * Returns an immutable map of the declarations actually given in the library. + * + * This map includes all regular methods, getters, setters, fields, classes + * and typedefs actually declared in the library. The map is keyed by the + * simple names of the declarations. + */ + Map get declarations; + + /** + * Returns [:true:] if this mirror is equal to [other]. + * Otherwise returns [:false:]. + * + * The equality holds if and only if + * (1) [other] is a mirror of the same kind + * and + * (2) The library being reflected by this mirror + * and the library being reflected by [other] + * are + * the same library in the same isolate. + */ + bool operator ==(other); + + /** + * Returns a list of the imports and exports in this library; + */ + List get libraryDependencies; +} + +/// A mirror on an import or export declaration. +abstract class LibraryDependencyMirror implements Mirror { + /// Is `true` if this dependency is an import. + bool get isImport; + + /// Is `true` if this dependency is an export. + bool get isExport; + + /// Returns the library mirror of the library that imports or exports the + /// [targetLibrary]. + LibraryMirror get sourceLibrary; + + /// Returns the library mirror of the library that is imported or exported. + LibraryMirror get targetLibrary; + + /// Returns the prefix if this is a prefixed import and `null` otherwise. + Symbol get prefix; + + /// Returns the list of show/hide combinators on the import/export + /// declaration. + List get combinators; + + /// Returns the source location for this import/export declaration. + SourceLocation get location; + + List get metadata; +} + +/// A mirror on a show/hide combinator declared on a library dependency. +abstract class CombinatorMirror implements Mirror { + /// The list of identifiers on the combinator. + List get identifiers; + + /// Is `true` if this is a 'show' combinator. + bool get isShow; + + /// Is `true` if this is a 'hide' combinator. + bool get isHide; +} + +/** + * A [TypeMirror] reflects a Dart language class, typedef, + * function type or type variable. + */ +abstract class TypeMirror implements DeclarationMirror { + /** + * Returns true if this mirror reflects dynamic, a non-generic class or + * typedef, or an instantiated generic class or typedef in the current + * isolate. Otherwise, returns false. + */ + bool get hasReflectedType; + + /** + * If [:hasReflectedType:] returns true, returns the corresponding [Type]. + * Otherwise, an [UnsupportedError] is thrown. + */ + Type get reflectedType; + + /** + * An immutable list with mirrors for all type variables for this type. + * + * If this type is a generic declaration or an invocation of a generic + * declaration, the returned list contains mirrors on the type variables + * declared in the original declaration. + * Otherwise, the returned list is empty. + * + * This list preserves the order of declaration of the type variables. + */ + List get typeVariables; + + /** + * An immutable list with mirrors for all type arguments for + * this type. + * + * If the reflectee is an invocation of a generic class, + * the type arguments are the bindings of its type parameters. + * If the reflectee is the original declaration of a generic, + * it has no type arguments and this method returns an empty list. + * If the reflectee is not generic, then + * it has no type arguments and this method returns an empty list. + * + * This list preserves the order of declaration of the type variables. + */ + List get typeArguments; + + /** + * Is this the original declaration of this type? + * + * For most classes, they are their own original declaration. For + * generic classes, however, there is a distinction between the + * original class declaration, which has unbound type variables, and + * the instantiations of generic classes, which have bound type + * variables. + */ + bool get isOriginalDeclaration; + + /** + * A mirror on the original declaration of this type. + * + * For most classes, they are their own original declaration. For + * generic classes, however, there is a distinction between the + * original class declaration, which has unbound type variables, and + * the instantiations of generic classes, which have bound type + * variables. + */ + TypeMirror get originalDeclaration; + + + /** + * Checks the subtype relationship, denoted by [:<::] in the language + * specification. This is the type relationship used in [:is:] test checks. + */ + bool isSubtypeOf(TypeMirror other); + + /** + * Checks the assignability relationship, denoted by [:<=>:] in the language + * specification. This is the type relationship tested on assignment in + * checked mode. + */ + bool isAssignableTo(TypeMirror other); +} + +/** + * A [ClassMirror] reflects a Dart language class. + */ +abstract class ClassMirror implements TypeMirror, ObjectMirror { + /** + * A mirror on the superclass on the reflectee. + * + * If this type is [:Object:], the superclass will be null. + */ + ClassMirror get superclass; + + /** + * A list of mirrors on the superinterfaces of the reflectee. + */ + List get superinterfaces; + + /** + * Is the reflectee abstract? + */ + bool get isAbstract; + + /** + * Returns an immutable map of the declarations actually given in the class + * declaration. + * + * This map includes all regular methods, getters, setters, fields, + * constructors and type variables actually declared in the class. Both + * static and instance members are included, but no inherited members are + * included. The map is keyed by the simple names of the declarations. + * + * This does not include inherited members. + */ + Map get declarations; + + /** + * Returns a map of the methods, getters and setters of an instance of the + * class. + * + * The intent is to capture those members that constitute the API of an + * instance. Hence fields are not included, but the getters and setters + * implicitly introduced by fields are included. The map includes methods, + * getters and setters that are inherited as well as those introduced by the + * class itself. + * + * The map is keyed by the simple names of the members. + */ + Map get instanceMembers; + + /** + * Returns a map of the static methods, getters and setters of the class. + * + * The intent is to capture those members that constitute the API of a class. + * Hence fields are not included, but the getters and setters implicitly + * introduced by fields are included. + * + * The map is keyed by the simple names of the members. + */ + Map get staticMembers; + + + /** + * The mixin of this class. + * If this class is the result of a mixin application of the + * form S with M, returns a class mirror on M. + * Otherwise returns a class mirror on [reflectee]. + */ + ClassMirror get mixin; + + // TODO(ahe): What about: + // /// Finds the instance member named [name] declared or inherited in the + // /// reflected class. + // DeclarationMirror instanceLookup(Symbol name); + + /** + * Invokes the named constructor and returns a mirror on the result. + * + * Let *c* be the class reflected by this mirror + * let *a1, ..., an* be the elements of [positionalArguments] + * let *k1, ..., km* be the identifiers denoted by the elements of + * [namedArguments.keys] + * and let *v1, ..., vm* be the elements of [namedArguments.values]. + * If [constructorName] was created from the empty string + * Then this method will execute the instance creation expression + * *new c(a1, ..., an, k1: v1, ..., km: vm)* + * in a scope that has access to the private members + * of *c*. Otherwise, let + * *f* be the simple name of the constructor denoted by [constructorName] + * Then this method will execute the instance creation expression + * *new c.f(a1, ..., an, k1: v1, ..., km: vm)* + * in a scope that has access to the private members + * of *c*. + * In either case: + * If the expression evaluates to a result *r*, this method returns + * the result of calling [reflect](*r*). + * If evaluating the expression causes a compilation error + * the effect is the same as if a non-reflective compilation error + * had been encountered. + * If evaluating the expression throws an exception *e* + * (that it does not catch) + * this method throws *e*. + */ + InstanceMirror newInstance(Symbol constructorName, + List positionalArguments, + [Map namedArguments]); + + /** + * Returns [:true:] if this mirror is equal to [other]. + * Otherwise returns [:false:]. + * + * The equality holds if and only if + * (1) [other] is a mirror of the same kind + * and + * (2) This mirror and [other] reflect the same class. + * + * Note that if the reflected class is an invocation of + * a generic class,(2) implies that the reflected class + * and [other] have equal type arguments. + */ + bool operator == (other); + + /** + * Returns whether the class denoted by the receiver is a subclass of the + * class denoted by the argument. + * + * Note that the subclass relationship is reflexive. + */ + bool isSubclassOf(ClassMirror other); +} + +/** + * A [FunctionTypeMirror] represents the type of a function in the + * Dart language. + */ +abstract class FunctionTypeMirror implements ClassMirror { + /** + * Returns the return type of the reflectee. + */ + TypeMirror get returnType; + + /** + * Returns a list of the parameter types of the reflectee. + */ + List get parameters; + + /** + * A mirror on the [:call:] method for the reflectee. + */ + // This is only here because in the past the VM did not implement a call + // method on closures. + MethodMirror get callMethod; +} + +/** + * A [TypeVariableMirror] represents a type parameter of a generic + * type. + */ +abstract class TypeVariableMirror extends TypeMirror { + /** + * A mirror on the type that is the upper bound of this type variable. + */ + TypeMirror get upperBound; + + /** + * Is the reflectee static? + * + * For the purposes of the mirrors library, type variables are considered + * non-static. + */ + bool get isStatic; + + /** + * Returns [:true:] if this mirror is equal to [other]. + * Otherwise returns [:false:]. + * + * The equality holds if and only if + * (1) [other] is a mirror of the same kind + * and + * (2) [:simpleName == other.simpleName:] and + * [:owner == other.owner:]. + */ + bool operator == (other); +} + +/** + * A [TypedefMirror] represents a typedef in a Dart language program. + */ +abstract class TypedefMirror implements TypeMirror { + /** + * The defining type for this typedef. + * If the the type referred to by the reflectee is a function type + * *F*, the result will be [:FunctionTypeMirror:] reflecting *F* + * which is abstract and has an abstract method [:call:] whose + * signature corresponds to *F*. + * + * For instance [:void f(int):] is the referent for [:typedef void f(int):]. + */ + FunctionTypeMirror get referent; +} + +/** + * A [MethodMirror] reflects a Dart language function, method, + * constructor, getter, or setter. + */ +abstract class MethodMirror implements DeclarationMirror { + /** + * A mirror on the return type for the reflectee. + */ + TypeMirror get returnType; + + /** + * The source code for the reflectee, if available. Otherwise null. + */ + String get source; + + /** + * A list of mirrors on the parameters for the reflectee. + */ + List get parameters; + + /** + * A function is considered non-static iff it is permited to refer to 'this'. + * + * Note that generative constructors are considered non-static, whereas + * factory constructors are considered static. + */ + bool get isStatic; + + /** + * Is the reflectee abstract? + */ + bool get isAbstract; + + /** + * Returns true if the reflectee is synthetic, and returns false otherwise. + * + * A reflectee is synthetic if it is a getter or setter implicitly introduced + * for a field or Type, or if it is a constructor that was implicitly + * introduced as a default constructor or as part of a mixin application. + */ + bool get isSynthetic; + + /** + * Is the reflectee a regular function or method? + * + * A function or method is regular if it is not a getter, setter, or + * constructor. Note that operators, by this definition, are + * regular methods. + */ + bool get isRegularMethod; + + /** + * Is the reflectee an operator? + */ + bool get isOperator; + + /** + * Is the reflectee a getter? + */ + bool get isGetter; + + /** + * Is the reflectee a setter? + */ + bool get isSetter; + + /** + * Is the reflectee a constructor? + */ + bool get isConstructor; + + /** + * The constructor name for named constructors and factory methods. + * + * For unnamed constructors, this is the empty string. For + * non-constructors, this is the empty string. + * + * For example, [:'bar':] is the constructor name for constructor + * [:Foo.bar:] of type [:Foo:]. + */ + Symbol get constructorName; + + /** + * Is the reflectee a const constructor? + */ + bool get isConstConstructor; + + /** + * Is the reflectee a generative constructor? + */ + bool get isGenerativeConstructor; + + /** + * Is the reflectee a redirecting constructor? + */ + bool get isRedirectingConstructor; + + /** + * Is the reflectee a factory constructor? + */ + bool get isFactoryConstructor; + + /** + * Returns true if this mirror is equal to [other]. + * + * The equality holds if and only if + * (1) [other] is a mirror of the same kind + * and + * (2) [:simpleName == other.simpleName:] and + * [:owner == other.owner:]. + */ + bool operator == (other); +} + +/** + * A [VariableMirror] reflects a Dart language variable declaration. + */ +abstract class VariableMirror implements DeclarationMirror { + /** + * Returns a mirror on the type of the reflectee. + */ + TypeMirror get type; + + /** + * Returns [:true:] if the reflectee is a static variable. + * Otherwise returns [:false:]. + * + * For the purposes of the mirror library, top-level variables are + * implicitly declared static. + */ + bool get isStatic; + + /** + * Returns [:true:] if the reflectee is a final variable. + * Otherwise returns [:false:]. + */ + bool get isFinal; + + /** + * Returns [:true:] if the reflectee is declared [:const:]. + * Otherwise returns [:false:]. + */ + bool get isConst; + + /** + * Returns true if this mirror is equal to [other]. + * + * The equality holds if and only if + * (1) [other] is a mirror of the same kind + * and + * (2) [:simpleName == other.simpleName:] and + * [:owner == other.owner:]. + */ + bool operator == (other); +} + +/** + * A [ParameterMirror] reflects a Dart formal parameter declaration. + */ +abstract class ParameterMirror implements VariableMirror { + /** + * A mirror on the type of this parameter. + */ + TypeMirror get type; + + /** + * Returns [:true:] if the reflectee is an optional parameter. + * Otherwise returns [:false:]. + */ + bool get isOptional; + + /** + * Returns [:true:] if the reflectee is a named parameter. + * Otherwise returns [:false:]. + */ + bool get isNamed; + + /** + * Returns [:true:] if the reflectee has explicitly declared a default value. + * Otherwise returns [:false:]. + */ + bool get hasDefaultValue; + + /** + * If this is a required parameter, returns [:null:]. Otherwise returns a + * mirror on the default value for this parameter. If no default is declared + * for an optional parameter, the default is [:null:] and a mirror on [:null:] + * is returned. + */ + InstanceMirror get defaultValue; +} + +/** + * A [SourceLocation] describes the span of an entity in Dart source code. + */ +abstract class SourceLocation { + /** + * The 1-based line number for this source location. + * + * A value of 0 means that the line number is unknown. + */ + int get line; + + /** + * The 1-based column number for this source location. + * + * A value of 0 means that the column number is unknown. + */ + int get column; + + /** + * Returns the URI where the source originated. + */ + Uri get sourceUri; +} + +/** + * Class used for encoding comments as metadata annotations. + */ +class Comment { + /** + * The comment text as written in the source text. + */ + final String text; + + /** + * The comment text without the start, end, and padding text. + * + * For example, if [text] is [: /** Comment text. */ :] then the [trimmedText] + * is [: Comment text. :]. + */ + final String trimmedText; + + /** + * Is [:true:] if this comment is a documentation comment. + * + * That is, that the comment is either enclosed in [: /** ... */ :] or starts + * with [: /// :]. + */ + final bool isDocComment; + + const Comment(this.text, this.trimmedText, this.isDocComment); +} + +/** + * Annotation describing how "dart:mirrors" is used (EXPERIMENTAL). + * + * When used as metadata on an import of "dart:mirrors" in library *L*, this + * class describes how "dart:mirrors" is used by library *L* unless overridden. + * See [override]. + * + * The following text is non-normative: + * + * In some scenarios, for example, when minifying Dart code, or when generating + * JavaScript code from a Dart program, the size and performance of the output + * can suffer from use of reflection. In those cases, telling the compiler + * what is used, can have a significant impact. + * + * Example usage: + * + * @MirrorsUsed(symbols: 'foo', override: '*') + * import 'dart:mirrors'; + * + * class Foo { + * noSuchMethod(Invocation invocation) { + * print(MirrorSystem.getName(invocation.memberName)); + * } + * } + * + * main() { + * new Foo().foo(); // Prints "foo". + * new Foo().bar(); // Might print an arbitrary (mangled) name, "bar". + * } + */ +// TODO(ahe): Remove ", override: '*'" when it isn't necessary anymore. +class MirrorsUsed { + // Note: the fields of this class are untyped. This is because the most + // convenient way to specify to specify symbols today is using a single + // string. In some cases, a const list of classes might be convenient. Some + // might prefer to use a const list of symbols. + + /** + * The list of strings passed to new [Symbol], and symbols that might be + * passed to [MirrorSystem.getName]. + * + * Combined with the names of [targets], [metaTargets] and their members, + * this forms the complete list of strings passed to new [Symbol], and + * symbols that might be passed to [MirrorSystem.getName] by the library to + * which this metadata applies. + * + * The following text is non-normative: + * + * Specifying this option turns off the following warnings emitted by + * dart2js: + * + * * Using "MirrorSystem.getName" may result in larger output. + * * Using "new #{name}" may result in larger output. + * + * Use symbols = "*" to turn off the warnings mentioned above. + * + * For example, if using [noSuchMethod] to interact with a database, extract + * all the possible column names and include them in this list. Similarly, + * if using [noSuchMethod] to interact with another language (JavaScript, for + * example) extract all the identifiers from API used and include them in + * this list. + */ + final symbols; + + /** + * A list of reflective targets. + * + * Combined with [metaTargets], this provides the complete list of reflective + * targets used by the library to which this metadata applies. + * + * The following text is non-normative: + * + * For now, there is no formal description of what a reflective target is. + * Informally, it is a list of things that are expected to have fully + * functional mirrors. + */ + final targets; + + /** + * A list of classes that when used as metadata indicates a reflective + * target. + * + * See [targets]. + */ + final metaTargets; + + /** + * A list of library names or "*". + * + * When used as metadata on an import of "dart:mirrors", this metadata does + * not apply to the library in which the annotation is used, but instead + * applies to the other libraries (all libraries if "*" is used). + */ + final override; + + const MirrorsUsed( + {this.symbols, this.targets, this.metaTargets, this.override}); +} diff --git a/pkg/dev_compiler/tool/input_sdk/private/js_mirrors.dart b/pkg/dev_compiler/tool/input_sdk/private/js_mirrors.dart index b39ebd865b2f..d55e623bd2ea 100644 --- a/pkg/dev_compiler/tool/input_sdk/private/js_mirrors.dart +++ b/pkg/dev_compiler/tool/input_sdk/private/js_mirrors.dart @@ -1,26 +1,176 @@ -// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file +// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file // 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. library dart._js_mirrors; -getName(symbol) { - throw new UnimplementedError("MirrorSystem.getName unimplemented"); +import 'dart:collection'; +import 'dart:mirrors'; +import 'dart:_foreign_helper' show JS; +import 'dart:_internal' as _internal; + +// TODO(vsm): This a workaround for: +// https://github.com/dart-lang/dev_compiler/issues/219 +import 'dart:js'; + +String getName(Symbol symbol) => + _internal.Symbol.getName(symbol as _internal.Symbol); + +Symbol getSymbol(name, library) => + throw new UnimplementedError("MirrorSystem.getSymbol unimplemented"); + +final currentJsMirrorSystem = throw new UnimplementedError( + "MirrorSystem.currentJsMirrorSystem unimplemented"); + +InstanceMirror reflect(reflectee) => new JsInstanceMirror._(reflectee); + +TypeMirror reflectType(Type key) { + // TODO(vsm): Might not be a class. + return new JsClassMirror._(key); +} + +final dynamic _dart = JS('', 'dart'); +final _metadata = JS('', '#.metadata', _dart); + +dynamic _dload(obj, String name) { + return JS('', '#.dload(#, #)', _dart, obj, name); +} + +void _dput(obj, String name, val) { + JS('', '#.dput(#, #, #)', _dart, obj, name, val); +} + +dynamic _dsend(obj, String name, List args) { + return JS('', '#.dsendArray(#, #, #)', _dart, obj, name, args); +} + +class JsInstanceMirror implements InstanceMirror { + final Object reflectee; + + JsInstanceMirror._(this.reflectee); + + InstanceMirror getField(Symbol symbol) { + var name = getName(symbol); + var field = _dload(reflectee, name); + return new JsInstanceMirror._(field); + } + + InstanceMirror setField(Symbol symbol, Object value) { + var name = getName(symbol); + var field = _dput(reflectee, name, value); + return new JsInstanceMirror._(field); + } + + InstanceMirror invoke(Symbol symbol, List args, + [Map namedArgs]) { + var name = getName(symbol); + if (namedArgs != null) { + args = new List.from(args); + args.add(_toJsMap(namedArgs)); + } + var result = _dsend(reflectee, name, args); + return new JsInstanceMirror._(result); + } + + dynamic _toJsMap(Map map) { + var obj = JS('', '{}'); + map.forEach((Symbol key, value) { + JS('', '#[#] = #', obj, getName(key), value); + }); + return obj; + } } -getSymbol(name, library) { - throw new UnimplementedError("MirrorSystem.getSymbol unimplemented"); +class JsClassMirror implements ClassMirror { + final Type _cls; + final Symbol simpleName; + + List _metadata; + Map _declarations; + + // TODO(vsm):These need to be immutable when escaping from this class. + List get metadata => _metadata; + Map get declarations => _declarations; + + JsClassMirror._(Type cls) + : _cls = cls, + simpleName = new Symbol(JS('String', '#.name', cls)) { + // Load metadata. + var fn = JS('List', '#[dart.metadata]', _cls); + _metadata = (fn == null) + ? [] + : new List.from(fn().map((i) => new JsInstanceMirror._(i))); + + // Load declarations. + // TODO(vsm): This is only populating the default constructor right now. + _declarations = new Map(); + _declarations[simpleName] = new JsMethodMirror._(this, _cls); + } + + InstanceMirror newInstance(Symbol constructorName, List args, + [Map namedArgs]) { + // TODO(vsm): Support named constructors and named arguments. + assert(getName(constructorName) == ""); + assert(namedArgs == null || namedArgs.isEmpty); + var instance = JS('', '#.instantiate(#, #)', _dart, _cls, args); + return new JsInstanceMirror._(instance); + } } -final currentJsMirrorSystem = - throw new UnimplementedError( - "MirrorSystem.currentJsMirrorSystem unimplemented"); +class JsTypeMirror implements TypeMirror { + final Type reflectedType; + JsTypeMirror._(this.reflectedType); +} -reflect(reflectee) { - throw new UnimplementedError("MirrorSystem.reflect unimplemented"); +class JsParameterMirror implements ParameterMirror { + final String _name; + final TypeMirror type; + final List metadata = []; + + JsParameterMirror._(this._name, Type t) : type = new JsTypeMirror._(t); } -reflectType(Type key) { - throw new UnimplementedError("MirrorSystem.reflectType unimplemented"); +class JsMethodMirror implements MethodMirror { + final String _name; + final dynamic _method; + List _params; + + JsMethodMirror._(JsClassMirror cls, this._method) + : _name = getName(cls.simpleName) { + var ftype = JS('', '#.classGetConstructorType(#)', _dart, cls._cls); + _params = _createParameterMirrorList(ftype); + } + + // TODO(vsm): Support named constructors. + Symbol get constructorName => new Symbol(''); + List get parameters => _params; + + List _createParameterMirrorList(ftype) { + if (ftype == null) { + // TODO(vsm): No explicit constructor. Verify this. + return []; + } + + // TODO(vsm): Add named args. + List args = ftype.args; + List opts = ftype.optionals; + var params = new List(args.length + opts.length); + + for (var i = 0; i < args.length; ++i) { + var type = args[i]; + // TODO(vsm): Recover the param name. + var param = new JsParameterMirror._('', type); + params[i] = param; + } + + for (var i = 0; i < opts.length; ++i) { + var type = opts[i]; + // TODO(vsm): Recover the param name. + var param = new JsParameterMirror._('', type); + params[i + args.length] = param; + } + + return params; + } } diff --git a/pkg/dev_compiler/tool/sdk_expected_errors.txt b/pkg/dev_compiler/tool/sdk_expected_errors.txt index cd814a025738..d69ac29b1170 100644 --- a/pkg/dev_compiler/tool/sdk_expected_errors.txt +++ b/pkg/dev_compiler/tool/sdk_expected_errors.txt @@ -4,6 +4,12 @@ import 'dart:html' show Blob, Event, ImageData, Node, Window; severe: line 92, column 1 of dart:js: [Message] File dart:indexed_db not found import 'dart:indexed_db' show KeyRange; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +warning: line 168, column 14 of dart:isolate: [DownCastComposite] IsolateNatives.spawnFunction(entryPoint, message, paused).then((msg) => new Isolate(msg[1], pauseCapability: msg[2], terminateCapability: msg[3])) (Future) will need runtime check to cast to type Future + return IsolateNatives.spawnFunction(entryPoint, message, paused) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +warning: line 234, column 14 of dart:isolate: [DownCastComposite] IsolateNatives.spawnUri(uri, args, message, paused).then((msg) => new Isolate(msg[1], pauseCapability: msg[2], terminateCapability: msg[3])) (Future) will need runtime check to cast to type Future + return IsolateNatives.spawnUri(uri, args, message, paused) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: line 426, column 16 of dart:math: [DownCastImplicit] rnd32.remainder(max) (num) will need runtime check to cast to type int result = rnd32.remainder(max); // % max; ^^^^^^^^^^^^^^^^^^^^ @@ -136,21 +142,21 @@ warning: line 177, column 12 of dart:_interceptors/js_array.dart: [DownCastCompo warning: line 313, column 12 of dart:_interceptors/js_array.dart: [DownCastComposite] JS('var', '#[#]', this, index) (dynamic) will need runtime check to cast to type E return JS('var', '#[#]', this, index); ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: line 349, column 46 of dart:_interceptors/js_number.dart: [AnalyzerMessage] Classes cannot implement 'double' -class JSInt extends JSNumber implements int, double { - ^^^^^^ -severe: line 110, column 17 of dart:_interceptors/js_number.dart: [AnalyzerMessage] The return type 'JSNumber' is not a 'double', as defined by the method 'toDouble' - toDouble() => this; - ^^^^ +warning: line 420, column 44 of dart:_interceptors/js_number.dart: [AnalyzerMessage] Classes cannot implement 'double' +class JSDouble extends JSNumber implements double { + ^^^^^^ warning: line 349, column 41 of dart:_interceptors/js_number.dart: [AnalyzerMessage] Classes cannot implement 'int' class JSInt extends JSNumber implements int, double { ^^^ warning: line 16, column 47 of dart:_interceptors/js_number.dart: [AnalyzerMessage] Classes cannot implement 'num' class JSNumber extends Interceptor implements num { ^^^ -warning: line 420, column 44 of dart:_interceptors/js_number.dart: [AnalyzerMessage] Classes cannot implement 'double' -class JSDouble extends JSNumber implements double { - ^^^^^^ +warning: line 349, column 46 of dart:_interceptors/js_number.dart: [AnalyzerMessage] Classes cannot implement 'double' +class JSInt extends JSNumber implements int, double { + ^^^^^^ +severe: line 110, column 17 of dart:_interceptors/js_number.dart: [AnalyzerMessage] The return type 'JSNumber' is not a 'double', as defined by the method 'toDouble' + toDouble() => this; + ^^^^ warning: line 83, column 28 of dart:_interceptors/js_number.dart: [DownCastImplicit] JS('num', r'Math.ceil(#)', this) (num) will need runtime check to cast to type double double ceilToDouble() => JS('num', r'Math.ceil(#)', this); ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -232,51 +238,6 @@ warning: line 89, column 14 of dart:_interceptors/js_string.dart: [DownCastCompo severe: line 346, column 7 of dart:_interceptors/js_string.dart: [StaticTypeError] Type check failed: s += s (String) is not of type JSString s += s; ^^^^^^ -warning: line 87, column 18 of dart:_js_helper: [DownCastImplicit] JS('num', r'parseInt(#, 16)', source) (num) will need runtime check to cast to type int - return JS('num', r'parseInt(#, 16)', source); - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: line 91, column 18 of dart:_js_helper: [DownCastImplicit] JS('num', r'parseInt(#, 10)', source) (num) will need runtime check to cast to type int - return JS('num', r'parseInt(#, 10)', source); - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: line 103, column 18 of dart:_js_helper: [DownCastImplicit] JS('num', r'parseInt(#, 10)', source) (num) will need runtime check to cast to type int - return JS('num', r'parseInt(#, 10)', source); - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: line 135, column 12 of dart:_js_helper: [DownCastImplicit] JS('num', r'parseInt(#, #)', source, radix) (num) will need runtime check to cast to type int - return JS('num', r'parseInt(#, #)', source, radix); - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: line 159, column 16 of dart:_js_helper: [DownCastImplicit] result (num) will need runtime check to cast to type double - return result; - ^^^^^^ -warning: line 163, column 12 of dart:_js_helper: [DownCastImplicit] result (num) will need runtime check to cast to type double - return result; - ^^^^^^ -warning: line 250, column 15 of dart:_js_helper: [DownCastImplicit] 0xd800 + ((((i - 0x10000) >> 10) & 0x3ff)) (num) will need runtime check to cast to type int - a.add(0xd800 + ((((i - 0x10000) >> 10) & 0x3ff))); - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: line 251, column 15 of dart:_js_helper: [DownCastImplicit] 0xdc00 + (i & 0x3ff) (num) will need runtime check to cast to type int - a.add(0xdc00 + (i & 0x3ff)); - ^^^^^^^^^^^^^^^^^^^^ -warning: line 265, column 31 of dart:_js_helper: [DownCastComposite] charCodes (dynamic) will need runtime check to cast to type List - return _fromCharCodeApply(charCodes); - ^^^^^^^^^ -warning: line 108, column 22 of dart:_js_helper/regexp_helper.dart: [DownCastComposite] JS('JSExtendableArray|Null', r'#.exec(#)', _nativeRegExp, checkString(string)) (dynamic) will need runtime check to cast to type List - List m = JS('JSExtendableArray|Null', - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: line 140, column 43 of dart:_js_helper/regexp_helper.dart: [DownCastComposite] match (List) will need runtime check to cast to type List - return new _MatchImplementation(this, match); - ^^^^^ -warning: line 152, column 43 of dart:_js_helper/regexp_helper.dart: [DownCastComposite] match (List) will need runtime check to cast to type List - return new _MatchImplementation(this, match); - ^^^^^ -warning: line 137, column 23 of dart:_js_helper/string_helper.dart: [DownCastComposite] pattern.allMatches(receiver) (dynamic) will need runtime check to cast to type Iterable - for (Match match in pattern.allMatches(receiver)) { - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: line 168, column 14 of dart:isolate: [DownCastComposite] IsolateNatives.spawnFunction(entryPoint, message, paused).then((msg) => new Isolate(msg[1], pauseCapability: msg[2], terminateCapability: msg[3])) (Future) will need runtime check to cast to type Future - return IsolateNatives.spawnFunction(entryPoint, message, paused) - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: line 234, column 14 of dart:isolate: [DownCastComposite] IsolateNatives.spawnUri(uri, args, message, paused).then((msg) => new Isolate(msg[1], pauseCapability: msg[2], terminateCapability: msg[3])) (Future) will need runtime check to cast to type Future - return IsolateNatives.spawnUri(uri, args, message, paused) - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ severe: line 452, column 28 of dart:_native_typed_data: [AnalyzerMessage] The getter 'length' is not defined for the class 'NativeTypedData' if (length == list.length) { ^^^^^^ @@ -346,21 +307,21 @@ warning: line 357, column 29 of dart:_isolate_helper/isolate_serialization.dart: warning: line 20, column 39 of dart:async/async_error.dart: [DownCastImplicit] errorHandler (Function) will need runtime check to cast to type (dynamic) → dynamic return zone.registerUnaryCallback(errorHandler); ^^^^^^^^^^^^ -severe: line 211, column 38 of dart:async/broadcast_stream_controller.dart: [AnalyzerMessage] The getter '_next' is not defined for the class 'StreamSubscription' - assert(!identical(subscription._next, subscription)); - ^^^^^ -severe: line 209, column 20 of dart:async/broadcast_stream_controller.dart: [AnalyzerMessage] The method '_setRemoveAfterFiring' is not defined for the class 'StreamSubscription' - subscription._setRemoveAfterFiring(); - ^^^^^^^^^^^^^^^^^^^^^ -severe: line 207, column 36 of dart:async/broadcast_stream_controller.dart: [AnalyzerMessage] The getter '_next' is not defined for the class 'StreamSubscription' - assert(!identical(subscription._next, subscription)); - ^^^^^ severe: line 208, column 22 of dart:async/broadcast_stream_controller.dart: [AnalyzerMessage] The getter '_isFiring' is not defined for the class 'StreamSubscription' if (subscription._isFiring) { ^^^^^^^^^ severe: line 206, column 32 of dart:async/broadcast_stream_controller.dart: [AnalyzerMessage] The getter '_next' is not defined for the class 'StreamSubscription' if (identical(subscription._next, subscription)) return null; ^^^^^ +severe: line 209, column 20 of dart:async/broadcast_stream_controller.dart: [AnalyzerMessage] The method '_setRemoveAfterFiring' is not defined for the class 'StreamSubscription' + subscription._setRemoveAfterFiring(); + ^^^^^^^^^^^^^^^^^^^^^ +severe: line 207, column 36 of dart:async/broadcast_stream_controller.dart: [AnalyzerMessage] The getter '_next' is not defined for the class 'StreamSubscription' + assert(!identical(subscription._next, subscription)); + ^^^^^ +severe: line 211, column 38 of dart:async/broadcast_stream_controller.dart: [AnalyzerMessage] The getter '_next' is not defined for the class 'StreamSubscription' + assert(!identical(subscription._next, subscription)); + ^^^^^ warning: line 8, column 67 of dart:async/broadcast_stream_controller.dart: [DownCastComposite] controller (_StreamControllerLifecycle) will need runtime check to cast to type _StreamControllerLifecycle _BroadcastStream(_StreamControllerLifecycle controller) : super(controller); ^^^^^^^^^^ @@ -1117,6 +1078,45 @@ warning: line 779, column 39 of dart:collection/splay_tree.dart: [DownCastCompos warning: line 791, column 23 of dart:collection/splay_tree.dart: [DownCastComposite] object (Object) will need runtime check to cast to type E int comp = _splay(object); ^^^^^^ +warning: line 87, column 18 of dart:_js_helper: [DownCastImplicit] JS('num', r'parseInt(#, 16)', source) (num) will need runtime check to cast to type int + return JS('num', r'parseInt(#, 16)', source); + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +warning: line 91, column 18 of dart:_js_helper: [DownCastImplicit] JS('num', r'parseInt(#, 10)', source) (num) will need runtime check to cast to type int + return JS('num', r'parseInt(#, 10)', source); + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +warning: line 103, column 18 of dart:_js_helper: [DownCastImplicit] JS('num', r'parseInt(#, 10)', source) (num) will need runtime check to cast to type int + return JS('num', r'parseInt(#, 10)', source); + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +warning: line 135, column 12 of dart:_js_helper: [DownCastImplicit] JS('num', r'parseInt(#, #)', source, radix) (num) will need runtime check to cast to type int + return JS('num', r'parseInt(#, #)', source, radix); + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +warning: line 159, column 16 of dart:_js_helper: [DownCastImplicit] result (num) will need runtime check to cast to type double + return result; + ^^^^^^ +warning: line 163, column 12 of dart:_js_helper: [DownCastImplicit] result (num) will need runtime check to cast to type double + return result; + ^^^^^^ +warning: line 250, column 15 of dart:_js_helper: [DownCastImplicit] 0xd800 + ((((i - 0x10000) >> 10) & 0x3ff)) (num) will need runtime check to cast to type int + a.add(0xd800 + ((((i - 0x10000) >> 10) & 0x3ff))); + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +warning: line 251, column 15 of dart:_js_helper: [DownCastImplicit] 0xdc00 + (i & 0x3ff) (num) will need runtime check to cast to type int + a.add(0xdc00 + (i & 0x3ff)); + ^^^^^^^^^^^^^^^^^^^^ +warning: line 265, column 31 of dart:_js_helper: [DownCastComposite] charCodes (dynamic) will need runtime check to cast to type List + return _fromCharCodeApply(charCodes); + ^^^^^^^^^ +warning: line 108, column 22 of dart:_js_helper/regexp_helper.dart: [DownCastComposite] JS('JSExtendableArray|Null', r'#.exec(#)', _nativeRegExp, checkString(string)) (dynamic) will need runtime check to cast to type List + List m = JS('JSExtendableArray|Null', + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +warning: line 140, column 43 of dart:_js_helper/regexp_helper.dart: [DownCastComposite] match (List) will need runtime check to cast to type List + return new _MatchImplementation(this, match); + ^^^^^ +warning: line 152, column 43 of dart:_js_helper/regexp_helper.dart: [DownCastComposite] match (List) will need runtime check to cast to type List + return new _MatchImplementation(this, match); + ^^^^^ +warning: line 137, column 23 of dart:_js_helper/string_helper.dart: [DownCastComposite] pattern.allMatches(receiver) (dynamic) will need runtime check to cast to type Iterable + for (Match match in pattern.allMatches(receiver)) { + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ severe: line 514, column 46 of dart:js: [AnalyzerMessage] The name 'Window' is not defined and cannot be used in an 'is' expression || o is Node || o is TypedData || o is Window) { ^^^^^^ @@ -1201,3 +1201,24 @@ warning: line 571, column 12 of dart:js: [DownCastImplicit] _getDartProxy(o, _DA warning: line 574, column 12 of dart:js: [DownCastImplicit] _getDartProxy(o, _DART_OBJECT_PROPERTY_NAME, (o) => new JsObject._fromJs(o)) (Object) will need runtime check to cast to type JsObject return _getDartProxy(o, _DART_OBJECT_PROPERTY_NAME, ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +severe: line 47, column 7 of dart:_js_mirrors: [AnalyzerMessage] Missing concrete implementation of getter 'InstanceMirror.type', getter 'InstanceMirror.hasReflectee' and 'InstanceMirror.delegate' +class JsInstanceMirror implements InstanceMirror { + ^^^^^^^^^^^^^^^^ +severe: line 126, column 7 of dart:_js_mirrors: [AnalyzerMessage] Missing concrete implementation of getter 'VariableMirror.isStatic', getter 'VariableMirror.isFinal', getter 'DeclarationMirror.owner', getter 'ParameterMirror.isOptional' and 9 more +class JsParameterMirror implements ParameterMirror { + ^^^^^^^^^^^^^^^^^ +severe: line 84, column 7 of dart:_js_mirrors: [AnalyzerMessage] Missing concrete implementation of getter 'TypeMirror.typeArguments', getter 'ClassMirror.superinterfaces', getter 'TypeMirror.isOriginalDeclaration', getter 'ClassMirror.staticMembers' and 19 more +class JsClassMirror implements ClassMirror { + ^^^^^^^^^^^^^ +severe: line 134, column 7 of dart:_js_mirrors: [AnalyzerMessage] Missing concrete implementation of getter 'MethodMirror.isSetter', getter 'MethodMirror.isConstructor', getter 'MethodMirror.isConstConstructor', getter 'MethodMirror.isAbstract' and 17 more +class JsMethodMirror implements MethodMirror { + ^^^^^^^^^^^^^^ +severe: line 120, column 7 of dart:_js_mirrors: [AnalyzerMessage] Missing concrete implementation of getter 'TypeMirror.typeArguments', getter 'TypeMirror.isOriginalDeclaration', getter 'DeclarationMirror.owner', getter 'DeclarationMirror.location' and 10 more +class JsTypeMirror implements TypeMirror { + ^^^^^^^^^^^^ +severe: line 61, column 35 of dart:_js_mirrors: [AnalyzerMessage] The argument type 'void' cannot be assigned to the parameter type 'Object' + return new JsInstanceMirror._(field); + ^^^^^ +warning: line 171, column 10 of dart:mirrors: [DownCastImplicit] (tm as ClassMirror).originalDeclaration (TypeMirror) will need runtime check to cast to type ClassMirror + return (tm as ClassMirror).originalDeclaration; + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^