Chromium Code Reviews| Index: dart/sdk/lib/_internal/compiler/implementation/lib/mirrors_patch.dart |
| diff --git a/dart/sdk/lib/_internal/compiler/implementation/lib/mirrors_patch.dart b/dart/sdk/lib/_internal/compiler/implementation/lib/mirrors_patch.dart |
| index dda7d3db3e087d5075e8c1740cc14e0792194f11..a0db6814ef3c781b6874ced90f22d9b67d6652d2 100644 |
| --- a/dart/sdk/lib/_internal/compiler/implementation/lib/mirrors_patch.dart |
| +++ b/dart/sdk/lib/_internal/compiler/implementation/lib/mirrors_patch.dart |
| @@ -5,60 +5,41 @@ |
| // Patch library for dart:mirrors. |
| import 'dart:_foreign_helper' show JS; |
| -import "dart:_collection-dev" as _symbol_dev; |
| - |
| -// Yeah, seriously: mirrors in dart2js are experimental... |
| -const String _MIRROR_OPT_IN_MESSAGE = """ |
| - |
| -This program is using an experimental feature called \"mirrors\". As |
| -currently implemented, mirrors do not work with minification, and will |
| -cause spurious errors depending on how code was optimized. |
| - |
| -The authors of this program are aware of these problems and have |
| -decided the thrill of using an experimental feature is outweighing the |
| -risks. Furthermore, the authors of this program understand that |
| -long-term, to fix the problems mentioned above, mirrors may have |
| -negative impact on size and performance of Dart programs compiled to |
| -JavaScript. |
| -"""; |
| - |
| -bool _mirrorsEnabled = false; |
| +import 'dart:_collection-dev' as _symbol_dev; |
| +import 'dart:_js_helper' show createInvocationMirror; |
| +import 'dart:_interceptors' show getInterceptor; |
| patch class MirrorSystem { |
| - patch static String getName(Symbol symbol) { |
| - return _symbol_dev.Symbol.getName(symbol); |
| - } |
| + patch static String getName(Symbol symbol) => _n(symbol); |
| } |
| -/** |
| - * Stub class for the mirror system. |
| - */ |
| -patch MirrorSystem currentMirrorSystem() { |
| - _ensureEnabled(); |
| - throw new UnsupportedError("MirrorSystem not implemented"); |
| +class _MirrorSystem implements MirrorSystem { |
| } |
| +String _n(Symbol symbol) => _symbol_dev.Symbol.getName(symbol); |
| + |
| +patch MirrorSystem currentMirrorSystem() => _currentMirrorSystem; |
| + |
| +_MirrorSystem _currentMirrorSystem = new _MirrorSystem(); |
| + |
| patch Future<MirrorSystem> mirrorSystemOf(SendPort port) { |
| - _ensureEnabled(); |
| throw new UnsupportedError("MirrorSystem not implemented"); |
| } |
| patch InstanceMirror reflect(Object reflectee) { |
| - if (!_mirrorsEnabled && (_MIRROR_OPT_IN_MESSAGE == reflectee)) { |
| - // Turn on mirrors and warn that it is an experimental feature. |
| - _mirrorsEnabled = true; |
| - print(reflectee); |
| - } |
| return new _InstanceMirror(reflectee); |
| } |
| +Map<String, ClassMirror> _classMirrors = new Map<String, ClassMirror>(); |
| + |
| patch ClassMirror reflectClass(Type key) { |
| - throw new UnimplementedError('reflectClass is not yet implemented' |
| - 'in dart2js'); |
| + String className = '$key'; |
| + var constructor = Primitives.getConstructor(className); |
| + return _classMirrors.putIfAbsent( |
| + constructor, () => new _ClassMirror(className, constructor)); |
|
ahe
2013/05/07 23:59:12
This isn't right. Restore the expando and figure
|
| } |
| class _InstanceMirror extends InstanceMirror { |
| - static final Expando<ClassMirror> classMirrors = new Expando<ClassMirror>(); |
| final reflectee; |
| @@ -66,43 +47,62 @@ class _InstanceMirror extends InstanceMirror { |
| bool get hasReflectee => true; |
| - ClassMirror get type { |
| - _ensureEnabled(); |
| - String className = Primitives.objectTypeName(reflectee); |
| - var constructor = Primitives.getConstructor(className); |
| - var mirror = classMirrors[constructor]; |
| - if (mirror == null) { |
| - mirror = new _ClassMirror(className, constructor); |
| - classMirrors[constructor] = mirror; |
| - } |
| - return mirror; |
| - } |
| + ClassMirror get type => reflectClass(reflectee.runtimeType); |
| - Future<InstanceMirror> invokeAsync(String memberName, |
| + Future<InstanceMirror> invokeAsync(Symbol memberName, |
| List<Object> positionalArguments, |
| [Map<String,Object> namedArguments]) { |
| - _ensureEnabled(); |
| + if (namedArguments != null && !namedArguments.isEmpty) { |
| + throw new UnsupportedError('Named arguments are not implemented'); |
| + } |
| + return |
| + new Future<InstanceMirror>( |
| + () => invoke(memberName, positionalArguments, namedArguments)); |
| + } |
| + |
| + InstanceMirror invoke(Symbol memberName, |
| + List positionalArguments, |
| + [Map<Symbol,dynamic> namedArguments]) { |
| if (namedArguments != null && !namedArguments.isEmpty) { |
| throw new UnsupportedError('Named arguments are not implemented'); |
| } |
| // Copy the list to ensure that it can safely be passed to |
| // JavaScript. |
| var jsList = new List.from(positionalArguments); |
| - var mangledName = '${memberName}\$${positionalArguments.length}'; |
| - var method = JS('var', '#[#]', reflectee, mangledName); |
| - var completer = new Completer<InstanceMirror>(); |
| - // TODO(ahe): [Completer] or [Future] should have API to create a |
| - // delayed action. Simulating with a [Timer]. |
| - Timer.run(() { |
| - if (JS('String', 'typeof #', method) == 'function') { |
| - var result = |
| - JS('var', '#.apply(#, #)', method, reflectee, jsList); |
| - completer.complete(new _InstanceMirror(result)); |
| - } else { |
| - completer.completeError('not a method $memberName'); |
| - } |
| - }); |
| - return completer.future; |
| + return _invoke( |
| + memberName, JSInvocationMirror.METHOD, |
| + '${_n(memberName)}\$${positionalArguments.length}', jsList); |
| + } |
| + |
| + InstanceMirror _invoke(Symbol name, |
| + int type, |
| + String mangledName, |
| + List arguments) { |
| + // TODO(ahe): Get the argument names. |
| + List<String> argumentNames = []; |
| + Invocation invocation = createInvocationMirror( |
| + _n(name), mangledName, type, arguments, argumentNames); |
| + |
| + return new _InstanceMirror(delegate(invocation)); |
| + } |
| + |
| + Future<InstanceMirror> setFieldAsync(Symbol fieldName, Object value) { |
| + return new Future<InstanceMirror>(() => setField(fieldName, value)); |
| + } |
| + |
| + InstanceMirror setField(Symbol fieldName, Object arg) { |
| + _invoke( |
| + fieldName, JSInvocationMirror.SETTER, 'set\$${_n(fieldName)}', [arg]); |
| + return new _InstanceMirror(arg); |
| + } |
| + |
| + InstanceMirror getField(Symbol fieldName) { |
| + return _invoke( |
| + fieldName, JSInvocationMirror.GETTER, 'get\$${_n(fieldName)}', []); |
| + } |
| + |
| + Future<InstanceMirror> getFieldAsync(Symbol fieldName) { |
| + return new Future<InstanceMirror>(() => getField(fieldName)); |
| } |
| delegate(Invocation invocation) { |
| @@ -117,13 +117,7 @@ class _ClassMirror extends ClassMirror { |
| final _jsConstructor; |
| _ClassMirror(this._name, this._jsConstructor) { |
| - _ensureEnabled(); |
| } |
| String toString() => 'ClassMirror($_name)'; |
| } |
| - |
| -_ensureEnabled() { |
| - if (_mirrorsEnabled) return; |
| - throw new UnsupportedError('dart:mirrors is an experimental feature'); |
| -} |