Index: sdk/lib/_internal/compiler/implementation/lib/mirrors_patch.dart |
diff --git a/sdk/lib/_internal/compiler/implementation/lib/mirrors_patch.dart b/sdk/lib/_internal/compiler/implementation/lib/mirrors_patch.dart |
index 8a2f57c1c571ff786de8d8f67c8c65aa67085e69..eee378fc00c3957233f90ecc0c37c29157775a5f 100644 |
--- a/sdk/lib/_internal/compiler/implementation/lib/mirrors_patch.dart |
+++ b/sdk/lib/_internal/compiler/implementation/lib/mirrors_patch.dart |
@@ -9,41 +9,324 @@ |
/** |
* Stub class for the mirror system. |
*/ |
+ |
+MirrorSystem _currentMirrorSystem = null; |
patch MirrorSystem currentMirrorSystem() { |
_ensureEnabled(); |
- throw new UnsupportedError("MirrorSystem not implemented"); |
+ if (_currentMirrorSystem == null) { |
+ _currentMirrorSystem = |
+ new _LocalMirrorSystem(Primitives.getCurrentIsolate()); |
+ } |
+ return _currentMirrorSystem; |
} |
patch Future<MirrorSystem> mirrorSystemOf(SendPort port) { |
_ensureEnabled(); |
- throw new UnsupportedError("MirrorSystem not implemented"); |
+ throw new UnsupportedError("mirrorSystemOf not implemented"); |
} |
patch InstanceMirror reflect(Object reflectee) { |
_ensureEnabled(); |
- return new _InstanceMirror(reflectee); |
+ if (reflectee is Closure) { |
+ return new _LocalClosureMirror(reflectee); |
+ } else { |
+ return new _LocalInstanceMirror(reflectee); |
+ } |
+} |
+ |
+// [_createMirrorSystem] below creates mirror system for currently executed |
+// program. It is done during program initialization. Mirror system s stored |
+// in [_libraries] global variable. Call to method below as well as array |
+// parameter [libraries] are synthesized by the emitter. [libraries] holds |
+// string representation of the mirror system. |
+final List<LibraryMirror> _libraries = new List<LibraryMirror>(); |
+ |
+_createMirrorSystem(libraries) { |
+ for (var library in libraries) { |
+ var libraryName = library[0]; |
+ var libraryClasses = library[1]; |
+ var libraryFunctions = library[2]; |
+ var libraryGetters = library[3]; |
+ var librarySetters = library[4]; |
+ var libraryVariables = library[5]; |
+ var libraryClosures = library[6]; |
+ |
+ _libraries.add(new _LocalLibraryMirror.createLibraryMirror( |
+ libraryName, |
+ libraryClasses, |
+ libraryFunctions, |
+ libraryGetters, |
+ librarySetters, |
+ libraryVariables, |
+ libraryClosures)); |
+ } |
} |
-class _InstanceMirror extends InstanceMirror { |
- static final Expando<ClassMirror> classMirrors = new Expando<ClassMirror>(); |
+class _LocalMirrorSystem implements MirrorSystem { |
+ final isolateContext; |
+ |
+ _LocalMirrorSystem(this.isolateContext); |
+ |
+ _LocalIsolateMirror isolateMirror; |
+ |
+ IsolateMirror get isolate { |
+ if (isolateMirror == null) { |
+ isolateMirror = new _LocalIsolateMirror(isolateContext); |
+ } |
+ return isolateMirror; |
+ } |
+ |
+ TypeMirror _dynamicType; |
+ TypeMirror get dynamicType { |
+ if (_dynamicType == null) { |
+ _dynamicType = new _LocalClassMirror("dynamic", []); |
+ } |
+ return _dynamicType; |
+ } |
+ |
+ TypeMirror _voidType; |
+ TypeMirror get voidType { |
+ if (_voidType == null) { |
+ _voidType = new _LocalClassMirror("void", []); |
+ } |
+ return _voidType; |
+ } |
+ |
+ Map<String, LibraryMirror> _librariesMap; |
+ |
+ Map<String, LibraryMirror> get libraries { |
+ if (_librariesMap == null) { |
+ _librariesMap = new Map<String, LibraryMirror>(); |
+ _libraries.forEach( |
+ (library) => _librariesMap[library.simpleName] = library); |
+ } |
+ return _librariesMap; |
+ } |
+} |
+ |
+class _LocalMirror { |
+ MirrorSystem get mirrors => currentMirrorSystem(); |
+} |
+ |
+class _LocalLibraryMirror extends _LocalMirror implements LibraryMirror { |
+ String simpleName; |
+ |
+ Map<String, Mirror> _members; |
+ Map<String, Mirror> get members => _members; |
+ |
+ Map<String, ClassMirror> _classes; |
+ Map<String, Mirror> get classes => _classes; |
+ |
+ Map<String, MethodMirror> _functions; |
+ Map<String, Mirror> get functions => _functions; |
+ |
+ Map<String, MethodMirror> _getters; |
+ Map<String, MethodMirror> get getters => _getters; |
+ |
+ Map<String, MethodMirror> _setters; |
+ Map<String, MethodMirror> get setters => _setters; |
+ |
+ Map<String, VariableMirror> _variables; |
+ Map<String, VariableMirror> get variables => _variables; |
+ |
+ Map<String, _LocalClosureClassMirror> _closureClasses; |
+ Map<String, _LocalClosureClassMirror> get closureClasses => _closureClasses; |
+ |
+ _LocalLibraryMirror(this.simpleName); |
+ |
+ addMember(String name, Mirror mirror) { |
+ if (_members == null) { |
+ _members = new Map<String, Mirror>(); |
+ } |
+ members[name] = mirror; |
+ } |
+ |
+ addClass(String name, ClassMirror classMirror) { |
+ if (_classes == null) { |
+ _classes = new Map<String, ClassMirror>(); |
+ } |
+ _classes[name] = classMirror; |
+ addMember(name, classMirror); |
+ } |
+ |
+ addFunction(String name, MethodMirror methodMirror) { |
+ if (_functions == null) { |
+ _functions = new Map<String, MethodMirror>(); |
+ } |
+ _functions[name] = methodMirror; |
+ addMember(name, methodMirror); |
+ } |
+ |
+ addVariable(String name, VariableMirror variableMirror) { |
+ if (_variables == null) { |
+ _variables = new Map<String, VariableMirror>(); |
+ } |
+ variables[name] = variableMirror; |
+ addMember(name, variableMirror); |
+ } |
+ |
+ addClosureClass(String name, _LocalClosureClassMirror closureClassMirror) { |
+ if (_closureClasses == null) { |
+ _closureClasses = new Map<String, _LocalClosureClassMirror>(); |
+ } |
+ _closureClasses[name] = closureClassMirror; |
+ } |
+ |
+ factory _LocalLibraryMirror.createLibraryMirror( |
+ String libraryName, |
+ var classes, |
+ var functions, |
+ var getters, |
+ var setters, |
+ var variables, |
+ var closures) { |
+ _LocalLibraryMirror libraryMirror = new _LocalLibraryMirror(libraryName); |
+ if (classes != null) { |
+ for (var classDescription in classes) { |
+ var className = classDescription[0]; |
+ var classMembers = classDescription[1]; |
+ libraryMirror.addClass( |
+ className, |
+ new _LocalClassMirror(className, |
+ classMembers)); |
+ } |
+ } |
+ if (functions != null) { |
+ for (String functionName in functions) { |
+ var functionMirror = |
+ new _LocalMethodMirror.fromQualifiedString(functionName); |
+ libraryMirror.addFunction(functionMirror.simpleName, functionMirror); |
+ } |
+ } |
+ if (getters != null) { |
+ for (String getterName in getters) { |
+ var getterMirror = |
+ new _LocalMethodMirror.fromQualifiedString(getterName); |
+ libraryMirror.addFunction(getterMirror.simpleName, getterMirror); |
+ } |
+ } |
+ if (setters != null) { |
+ for (String setterName in setters) { |
+ var setterMirror = |
+ new _LocalMethodMirror.fromQualifiedString(setterName); |
+ libraryMirror.addFunction(setterMirror.simpleName, setterMirror); |
+ } |
+ } |
+ if (variables != null) { |
+ for (String qualifiedName in variables) { |
+ var variableMirror = |
+ new _LocalVariableMirror.fromQualifiedString(qualifiedName); |
+ libraryMirror.addVariable(variableMirror.simpleName, variableMirror); |
+ } |
+ } |
+ if (closures != null) { |
+ for (String qualifiedName in closures) { |
+ var closureMirror = |
+ new _LocalClosureClassMirror.fromQualifiedString(qualifiedName); |
+ libraryMirror.addClosureClass(closureMirror.simpleName, closureMirror); |
+ } |
+ } |
+ return libraryMirror; |
+ } |
+ |
+ Future<InstanceMirror> invoke(String memberName, |
+ List<Object> positionalArguments, |
+ [Map<String,Object> namedArguments]) { |
+ throw new UnsupportedError("Not implemented yet."); |
+ } |
+ |
+ Future<InstanceMirror> getField(String fieldName) { |
+ var name; |
+ if (variables != null && variables.containsKey(fieldName)) { |
+ name = variables[fieldName].internalName; |
+ } else if (getters != nulll && getters.containsKey(fieldName)) { |
+ name = getters[fieldName].internalName; |
+ } else { |
+ throw new MirroredCompilationError('$fieldName field not found.'); |
+ } |
+ var completer = new Completer<InstanceMirror>(); |
+ // TODO(ahe): [Completer] or [Future] should have API to create a |
+ // delayed action. Simulating with a [Timer]. |
+ new Timer(0, (timer) { |
+ var statics = Primitives.getGlobalStatics(); |
+ var result = Primitives.getProperty(statics, name); |
+ completer.complete(new _LocalInstanceMirror(result)); |
+ }); |
+ return completer.future; |
+ } |
+ |
+ Future<InstanceMirror> setField(String fieldName, Object value) { |
+ var name; |
+ if (variables != null && variables.containsKey(fieldName)) { |
+ name = variables[fieldName].internalName; |
+ } else if (getters != null && getters.containsKey(fieldName)) { |
+ name = getters[fieldName].internalName; |
+ } else { |
+ throw new MirroredCompilationError('$fieldName field not found.'); |
+ } |
+ var completer = new Completer<InstanceMirror>(); |
+ // TODO(ahe): [Completer] or [Future] should have API to create a |
+ // delayed action. Simulating with a [Timer]. |
+ new Timer(0, (timer) { |
+ var statics = Primitives.getGlobalStatics(); |
+ completer.complete( |
+ Primitives.setProperty(statics, name, value)); |
+ }); |
+ return completer.future; |
+ } |
+ |
+ String toString() => "LocalLibraryMirror for '$simpleName'"; |
+} |
+ |
+class _LocalIsolateMirror extends _LocalMirror implements IsolateMirror { |
+ var isolateContext; |
+ |
+ _LocalIsolateMirror(this.isolateContext); |
+ |
+ String get debugName { |
+ var isolateid = Primitives.getIsolateID(isolateContext); |
+ if (isolateid == null) { |
+ return "The Isolate"; |
+ } else { |
+ return "Isolate $isolateid"; |
+ } |
+ } |
+ |
+ bool get isCurrent => Primitives.getCurrentIsolate() == isolateContext; |
+ |
+ LibraryMirror get rootLibrary { |
+ throw new UnsupportedError("rootLibrary not implemented"); |
+ } |
+ |
+ String toString() => "LocalIsolateMirror on '$isolateContext'"; |
+} |
+ |
+class _LocalEmptyInstanceMirror extends _LocalMirror implements InstanceMirror { |
+ final ClassMirror type; |
+ |
+ final bool get hasReflectee => false; |
+ |
+ final get reflectee => null; |
+ |
+ _LocalEmptyInstanceMirror(this.type); |
+ |
+ String toString() => "EmptyInstanceMirror on '$type'"; |
+} |
+ |
+class _LocalInstanceMirror extends _LocalMirror implements InstanceMirror { |
+ final bool hasReflectee = true; |
final reflectee; |
- _InstanceMirror(this.reflectee) { |
+ _LocalInstanceMirror(this.reflectee) { |
_ensureEnabled(); |
} |
- bool get hasReflectee => true; |
- |
ClassMirror get type { |
- 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; |
+ // We need library so we can find class mirror in there. |
+ var library = JS('var', '#.builtin\$library', reflectee); |
+ LibraryMirror lib = _libraries[library]; |
+ return lib.members[Primitives.objectTypeName(reflectee)]; |
} |
Future<InstanceMirror> invoke(String memberName, |
@@ -64,7 +347,7 @@ class _InstanceMirror extends InstanceMirror { |
if (JS('String', 'typeof #', method) == 'function') { |
var result = |
JS('var', '#.apply(#, #)', method, reflectee, jsList); |
- completer.complete(new _InstanceMirror(result)); |
+ completer.complete(new _LocalInstanceMirror(result)); |
} else { |
completer.completeException('not a method $memberName'); |
} |
@@ -72,18 +355,503 @@ class _InstanceMirror extends InstanceMirror { |
return completer.future; |
} |
- String toString() => 'InstanceMirror($reflectee)'; |
+ Future<InstanceMirror> getField(String fieldName) { |
+ var name; |
+ var classType = type; |
+ if (classType.variables != null && |
+ classType.variables.containsKey(fieldName)) { |
+ name = classType.variables[fieldName].internalName; |
+ } else if (classType.getters != nulll && |
+ classType.getters.containsKey(fieldName)) { |
+ name = classType.getters[fieldName].internalName; |
+ } else { |
+ throw new MirroredCompilationError('$fieldName field not found.'); |
+ } |
+ var completer = new Completer<InstanceMirror>(); |
+ // TODO(ahe): [Completer] or [Future] should have API to create a |
+ // delayed action. Simulating with a [Timer]. |
+ new Timer(0, (timer) { |
+ var result = Primitives.getProperty(reflectee, name); |
+ completer.complete(new _LocalInstanceMirror(result)); |
+ }); |
+ return completer.future; |
+ } |
+ |
+ Future<InstanceMirror> setField(String fieldName, Object value) { |
+ var name; |
+ var classType = type; |
+ if (classType.variables != null && |
+ classType.variables.containsKey(fieldName)) { |
+ name = classType.variables[fieldName].internalName; |
+ } else if (classType.getters != null && |
+ classType.getters.containsKey(fieldName)) { |
+ name = classType.getters[fieldName].internalName; |
+ } else { |
+ throw new MirroredCompilationError('$fieldName field not found.'); |
+ } |
+ var completer = new Completer<InstanceMirror>(); |
+ // TODO(ahe): [Completer] or [Future] should have API to create a |
+ // delayed action. Simulating with a [Timer]. |
+ new Timer(0, (timer) { |
+ completer.complete( |
+ Primitives.setProperty(reflectee, name, value)); |
+ }); |
+ return completer.future; |
+ } |
+ |
+ String toString() => "InstanceMirror on '$reflectee'"; |
} |
-class _ClassMirror extends ClassMirror { |
- final String _name; |
- final _jsConstructor; |
+class _LocalClosureMirror extends _LocalMirror implements ClosureMirror { |
+ MethodMirror get function { |
+ var library = JS('var', '#.builtin\$library', reflectee); |
+ LibraryMirror lib = _libraries[library]; |
+ _LocalClosureClassMirror closureClass = |
+ lib.closureClasses[Primitives.objectTypeName(reflectee)]; |
+ return closureClass.callMethod; |
+ } |
+ |
+ String get source { |
+ throw new UnsupportedError("Not implemented yet."); |
+ } |
+ |
+ Future<InstanceMirror> apply(List<Object> positionalArguments, |
+ [Map<String,Object> 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 method = JS('var', '#[#]', reflectee, function.internalName); |
+ var completer = new Completer<InstanceMirror>(); |
+ // TODO(ahe): [Completer] or [Future] should have API to create a |
+ // delayed action. Simulating with a [Timer]. |
+ new Timer(0, (timer) { |
+ if (JS('String', 'typeof #', method) == 'function') { |
+ var result = |
+ JS('var', '#.apply(#, #)', method, reflectee, jsList); |
+ completer.complete(new _LocalInstanceMirror(result)); |
+ } else { |
+ completer.completeException('not a method $memberName'); |
+ } |
+ }); |
+ return completer.future; |
+ } |
+ |
+ Future<InstanceMirror> findInContext(String name) { |
+ throw new UnsupportedError("Not implemented yet."); |
+ } |
- _ClassMirror(this._name, this._jsConstructor) { |
+ final bool hasReflectee = true; |
+ |
+ final reflectee; |
+ |
+ _LocalClosureMirror(this.reflectee) { |
_ensureEnabled(); |
} |
+} |
+ |
+class _LocalClassMirror extends _LocalMirror implements ClassMirror { |
+ ClassMirror get superclass { |
+ throw new UnsupportedError("Not implemented yet."); |
+ } |
+ List<ClassMirror> get superinterfaces { |
+ throw new UnsupportedError("Not implemented yet."); |
+ } |
+ |
+ final String _name; |
+ String get simpleName => _name; |
+ |
+ Map<String, Mirror> _members; |
+ void addMember(String name, MethodMirror member) { |
+ if (_members == null) { |
+ _members = new Map<String, Mirror>(); |
+ } |
+ } |
+ Map<String, Mirror> get members => _members; |
+ |
+ Map<String, MethodMirror> _methods; |
+ void addMethod(String name, MethodMirror mirror) { |
+ if (_methods == null) { |
+ _methods = new Map<String, MethodMirror>(); |
+ } |
+ _methods[name] = mirror; |
+ addMember(name, mirror); |
+ } |
+ Map<String, MethodMirror> get methods => _methods; |
+ |
+ Map<String, MethodMirror> _getters; |
+ void addGetter(String name, MethodMirror mirror) { |
+ if (_getters == null) { |
+ _getters = new Map<String, MethodMirror>(); |
+ } |
+ _getters[name] = mirror; |
+ addMember(name, mirror); |
+ } |
+ Map<String, MethodMirror> get getters => _getters; |
+ |
+ Map<String, MethodMirror> _setters; |
+ void addSetter(String name, MethodMirror mirror) { |
+ if (_setters == null) { |
+ _setters = new Map<String, MethodMirror>(); |
+ } |
+ _setters[name] = mirror; |
+ addMember(name, mirror); |
+ } |
+ Map<String, MethodMirror> get setters => _setters; |
+ |
+ Map<String, VariableMirror> _variables; |
+ void addVariable(String name, VariableMirror mirror) { |
+ if (_variables == null) { |
+ _variables = new Map<String, MethodMirror>(); |
+ } |
+ _variables[name] = mirror; |
+ addMember(name, mirror); |
+ } |
+ Map<String, VariableMirror> get variables => _variables; |
+ |
+ Map<String, MethodMirror> _constructors; |
+ Map<String, MethodMirror> get constructors => _constructors; |
+ addConstructor(String name, MethodMirror constructor) { |
+ if (_constructors == null) { |
+ _constructors = new Map<String, MethodMirror>(); |
+ } |
+ _constructors[name] = constructor; |
+ } |
+ |
+ Map<String, TypeVariableMirror> _typeVariables; |
+ Map<String, TypeVariableMirror> get typeVariables => _typeVariables; |
+ addTypeVariable(String name, TypeVariableMirror typeVariable) { |
+ if (_typeVariables == null) { |
+ _typeVariables = new Map<String, TypeVariableMirror>(); |
+ } |
+ _typeVariables[name] = typeVariable; |
+ } |
+ |
+ Map<String, TypeMirror> _typeArguments; |
+ Map<String, TypeMirror> get typeArguments => _typeArguments; |
+ addTypeArgument(String name, TypeMirror typeArgument) { |
+ if (_typeArguments == null) { |
+ _typeArguments = new Map<String, TypeMirror>(); |
+ } |
+ _typeArguments[name] = typeArgument; |
+ } |
+ |
+ _LocalClassMirror(this._name, |
+ List<String> qualifiedMembers) { |
+ for (String qualifiedMember in qualifiedMembers) { |
+ int indexSeparator = qualifiedMember.indexOf(':'); |
+ String prefixType = qualifiedMember.substring(0, indexSeparator); |
+ String name = qualifiedMember.substring(indexSeparator + 1); |
+ if (prefixType == 'G') { |
+ var getterMirror = new _LocalMethodMirror.fromQualifiedString(name); |
+ addGetter(getterMirror.simpleName, getterMirror); |
+ } else if (prefixType == 'S') { |
+ var setterMirror = new _LocalMethodMirror.fromQualifiedString(name); |
+ addSetter(setterMirror.simpleName, setterMirror); |
+ } else if (prefixType == 'V') { |
+ var variableMirror = new _LocalVariableMirror.fromQualifiedString(name); |
+ addVariable(variableMirror.simpleName, variableMirror); |
+ } else if (prefixType == 'C') { |
+ addConstructor(name, |
+ new _LocalConstructorMirror.fromQualifiedString(name)); |
+ } else if (prefixType == 'T') { |
+ addTypeVariable(name, new _LocalTypeVariableMirror(name)); |
+ } else if (prefixType == 'A') { |
+ addTypeArgument(name, |
+ new _LocalClassMirror( |
+ name, [], enclosingLibrary: enclosingLibrary)); |
+ } else if (prefixType == 'M') { |
+ var methodMirror = new _LocalMethodMirror.fromQualifiedString(name); |
+ addMethod(methodMirror.simpleName, methodMirror); |
+ } else { |
+ throw new MirrorException( |
+ 'Internal error in _LocalClassMirror constructor: ' |
+ 'invalid member prefix \'$prefixType\' for \'$qualifiedMember\''); |
+ } |
+ } |
+ } |
+ |
+ Future<InstanceMirror> invoke(String memberName, |
+ List<Object> positionalArguments, |
+ [Map<String,Object> namedArguments]) { |
+ throw new UnsupportedError("Not implemented yet."); |
+ } |
+ |
+ Future<InstanceMirror> getField(String fieldName) { |
+ var name; |
+ if (variables != null && variables.containsKey(fieldName)) { |
+ name = variables[fieldName].internalName; |
+ } else if (getters != nulll && getters.containsKey(fieldName)) { |
+ name = getters[fieldName].internalName; |
+ } else { |
+ throw new MirroredCompilationError('$fieldName field not found.'); |
+ } |
+ var completer = new Completer<InstanceMirror>(); |
+ // TODO(ahe): [Completer] or [Future] should have API to create a |
+ // delayed action. Simulating with a [Timer]. |
+ new Timer(0, (timer) { |
+ var statics = Primitives.getGlobalStatics(); |
+ var result = Primitives.getProperty(statics, name); |
+ completer.complete(new _LocalInstanceMirror(result)); |
+ }); |
+ return completer.future; |
+ } |
+ |
+ Future<InstanceMirror> setField(String fieldName, Object value) { |
+ var name; |
+ if (variables != null && variables.containsKey(fieldName)) { |
+ name = variables[fieldName].internalName; |
+ } else if (getters != null && getters.containsKey(fieldName)) { |
+ name = getters[fieldName].internalName; |
+ } else { |
+ throw new MirroredCompilationError('$fieldName field not found.'); |
+ } |
+ var completer = new Completer<InstanceMirror>(); |
+ // TODO(ahe): [Completer] or [Future] should have API to create a |
+ // delayed action. Simulating with a [Timer]. |
+ new Timer(0, (timer) { |
+ var statics = Primitives.getGlobalStatics(); |
+ completer.complete( |
+ Primitives.setProperty(statics, name, value)); |
+ }); |
+ return completer.future; |
+ } |
+ |
+ Future<InstanceMirror> newInstance(String constructorName, |
+ List<Object> positionalArguments, |
+ [Map<String,Object> namedArguments]) { |
+ String fullConstructorName = '$_name\$$constructorName'; |
+ var constructor = Primitives.getConstructor(fullConstructorName); |
+ |
+ var completer = new Completer<InstanceMirror>(); |
+ // TODO(ahe): [Completer] or [Future] should have API to create a |
+ // delayed action. Simulating with a [Timer]. |
+ new Timer(0, (timer) { |
+ if (constructor == null) { |
+ completer.complete(new _LocalEmptyInstanceMirror(this)); |
+ } else { |
+ var jsList = new List.from(positionalArguments); |
+ var result = JS('var', '#.apply(this, #)', constructor, jsList); |
+ completer.complete(new _LocalInstanceMirror(result)); |
+ } |
+ }); |
+ return completer.future; |
+ } |
+ |
+ String toString() => "ClassMirror on '$_name'"; |
+} |
+ |
+class _LocalClosureClassMirror extends _LocalMirror { |
+ String simpleName; |
+ String callMethodName; |
+ |
+ int requiredParameterCount = 0; |
+ int optionalParameterCount = 0; |
+ |
+ MethodMirror _callMethod = null; |
+ MethodMirror get callMethod { |
+ if (_callMethod == null) { |
+ var parameters = |
+ new List<ParameterMirror>(requiredParameterCount |
+ + optionalParameterCount); |
+ _callMethod = |
+ new _LocalMethodMirror.closureMethod( |
+ callMethodName, |
+ parameters); |
+ } |
+ return _callMethod; |
+ } |
+ |
+ _LocalClosureClassMirror(this.simpleName, |
+ this.callMethodName, |
+ this.requiredParameterCount, |
+ this.optionalParameterCount); |
+ |
+ // |
+ // qualifiedName has following format: |
+ // className:callName:requiredParameterCount:optionalParameterCount |
+ // |
+ factory _LocalClosureClassMirror.fromQualifiedString(String qualifiedName) { |
+ var pieces = qualifiedName.split(':'); |
+ return new _LocalClosureClassMirror( |
+ pieces[0], |
+ pieces[1], |
+ int.parse(pieces[2]), |
+ int.parse(pieces[3])); |
+ } |
+} |
+ |
+class _LocalObjectMirror extends _LocalMirror { |
+ String _simpleName; |
+ String get simpleName => _simpleName; |
+ |
+ String _internalName; |
+ String get internalName => _internalName != null? _internalName: simpleName; |
+ |
+ // Support 'simpleName' and 'simpleName[internalName]' formats. |
+ _LocalObjectMirror(String name) { |
+ _simpleName = name; |
+ var indexOpeningSquareBracket = _simpleName.indexOf('['); |
+ var indexClosingSquareBracket = |
+ _simpleName.indexOf(']', indexOpeningSquareBracket + 1); |
+ |
+ if (indexOpeningSquareBracket != -1) { |
+ _simpleName = _simpleName.substring(indexOpeningSquareBracket + 1, |
+ indexClosingSquareBracket); |
+ _internalName = name.substring(0, indexOpeningSquareBracket); |
+ } |
+ } |
+} |
+ |
+class _LocalMethodMirror extends _LocalObjectMirror implements MethodMirror { |
+ bool _isStatic; |
+ bool get isStatic => _isStatic; |
+ |
+ bool get isConstructor => false; |
+ |
+ String _returnTypeName; |
+ |
+ TypeMirror _returnType; |
+ TypeMirror get returnType { |
+ if (_returnType == null) { |
+ _returnType = new _LocalTypeMirror.fromString(_returnTypeName); |
+ } |
+ return _returnType; |
+ } |
+ |
+ List<ParameterMirror> _parameters = null; |
+ List<ParameterMirror> get parameters { |
+ return _parameters; |
+ } |
+ |
+ // [S]:TypeLibrary:TypeName:MethodName |
+ factory _LocalMethodMirror.fromQualifiedString(String qualifiedName) { |
+ int indexSeparator = qualifiedName.indexOf(':'); |
+ var methodType = qualifiedName.substring(0, indexSeparator); |
+ var isStatic = methodType == 'S'; |
+ |
+ var indexReturnTypeSeparator = |
+ qualifiedName.indexOf(':', indexSeparator + 1); |
+ indexReturnTypeSeparator = qualifiedName.indexOf(':', |
+ indexReturnTypeSeparator + 1); |
+ var returnTypeName = qualifiedName.substring(indexSeparator + 1, |
+ indexReturnTypeSeparator); |
+ |
+ var name = qualifiedName.substring(indexReturnTypeSeparator + 1); |
+ return new _LocalMethodMirror(name, returnTypeName, isStatic); |
+ } |
+ |
+ _LocalMethodMirror(name, this._returnTypeName, this._isStatic): super(name); |
+ |
+ _LocalMethodMirror.closureMethod(name, this._parameters): super(name); |
+ |
+ String toString() => "MethodMirror on '$simpleName' " |
+ "returning '$returnType' isStatic=$isStatic"; |
+} |
+ |
+class _LocalConstructorMirror extends _LocalObjectMirror |
+ implements MethodMirror { |
+ String constructorName; |
+ |
+ factory _LocalConstructorMirror.fromQualifiedString(String name) { |
+ return new _LocalConstructorMirror(name); |
+ } |
+ |
+ _LocalConstructorMirror(name): super(name) { |
+ // Class name is separated from constructor name with '$'. |
+ var parts = internalName.split(r'$'); |
+ constructorName = parts[parts.length - 1]; |
+ } |
+ |
+ bool get isConstructor => true; |
+ |
+ String toString() => "ConstructorMirror on '$constructorName'"; |
+} |
+ |
+class _LocalVariableMirror extends _LocalObjectMirror |
+ implements VariableMirror { |
+ TypeMirror get type { |
+ throw new UnsupportedError("Not implemented yet."); |
+ } |
+ |
+ bool _isStatic; |
+ bool get isStatic => _isStatic; |
+ bool _isFinal; |
+ bool get isFinal => _isFinal; |
+ |
+ factory _LocalVariableMirror.fromQualifiedString(String qualifiedName) { |
+ var indexSeparator = qualifiedName.indexOf(':'); |
+ var prefixType = qualifiedName.substring(0, indexSeparator); |
+ var name = qualifiedName.substring(indexSeparator + 1); |
+ var isStatic = prefixType == 'S'; |
+ // Use case to indicate whether field is final or not. |
+ var isFinal = prefixType.toLowerCase() == prefixType; |
+ |
+ return new _LocalVariableMirror(name, isStatic, isFinal); |
+ } |
+ |
+ _LocalVariableMirror(name, this._isStatic, this._isFinal): super(name); |
+ |
+ String toString() => |
+ "VariableMirror on '$simpleName' isStatic=$isStatic isFinal=$isFinal"; |
+} |
+ |
+class _LocalTypedefMirror extends _LocalObjectMirror |
+ implements TypedefMirror { |
+ TypeMirror get value { |
+ throw new UnsupportedError("Not implemented yet."); |
+ } |
+ |
+ _LocalTypedefMirror(String name): super(name); |
+ |
+ String toString() => "TypedefMirror on '$simpleName'"; |
+} |
+ |
+class _LocalTypeVariableMirror extends _LocalObjectMirror |
+ implements TypeMirror { |
+ _LocalTypeVariableMirror(String name): super(name); |
+ |
+ TypeMirror get upperBound { |
+ throw new UnsupportedError("Not implemented yet"); |
+ } |
+ |
+ String toString() => "TypeVariableMirror on '$simpleName'"; |
+} |
+ |
+class _LocalTypeMirror implements TypeMirror { |
+ ClassMirror _typeMirror; |
+ ClassMirror get typeMirror { return _typeMirror; } |
+ |
+ _LocalTypeMirror(this._typeMirror); |
+ |
+ factory _LocalTypeMirror.fromString(String qualifiedName) { |
+ var indexSeparator = qualifiedName.indexOf(':'); |
+ var libraryIndex = qualifiedName.substring(0, indexSeparator); |
+ var name = qualifiedName.substring(indexSeparator + 1); |
+ |
+ var typeMirror = null; |
+ if (name == "void") { |
+ return currentMirrorSystem().voidType; |
+ } |
+ else if (name == "dynamic") { |
+ return currentMirrorSystem().dynamicType; |
+ } else { |
+ var libraryIndexNumber = -1; |
+ try { |
+ libraryIndexNumber = int.parse(libraryIndex); |
+ } on FormatException {} |
+ if (libraryIndexNumber != -1) { |
+ var library = _libraries[libraryIndexNumber]; |
+ typeMirror = library.members[name]; |
+ } |
+ } |
+ |
+ return new _LocalTypeMirror(typeMirror); |
+ } |
- String toString() => 'ClassMirror($_name)'; |
+ String toString() => "LocalTypeMirror on '$_typeMirror'"; |
} |
_ensureEnabled() { |