Chromium Code Reviews| Index: runtime/lib/mirrors_impl.dart |
| =================================================================== |
| --- runtime/lib/mirrors_impl.dart (revision 11716) |
| +++ runtime/lib/mirrors_impl.dart (working copy) |
| @@ -5,11 +5,11 @@ |
| // VM-specific implementation of the dart:mirrors library. |
| // These values are allowed to be passed directly over the wire. |
| -bool isSimpleValue(var value) { |
| +bool _isSimpleValue(var value) { |
| return (value === null || value is num || value is String || value is bool); |
| } |
| -Map filterMap(Map old_map, bool filter(key, value)) { |
| +Map _filterMap(Map old_map, bool filter(key, value)) { |
| Map new_map = new Map(); |
| old_map.forEach((key, value) { |
| if (filter(key, value)) { |
| @@ -19,8 +19,33 @@ |
| return new_map; |
| } |
| +String _makeSignatureString(TypeMirror returnType, |
| + List<ParameterMirror> parameters) { |
| + StringBuffer buf = new StringBuffer(); |
| + buf.add(returnType.qualifiedName); |
| + buf.add(' ('); |
| + bool found_optional_param = false; |
| + for (int i = 0; i < parameters.length; i++) { |
| + var param = parameters[i]; |
| + if (param.isOptional && !found_optional_param) { |
| + buf.add('['); |
| + found_optional_param = true; |
| + } |
| + buf.add(param.type.qualifiedName); |
| + if (i < (parameters.length - 1)) { |
| + buf.add(', '); |
| + } |
| + } |
| + if (found_optional_param) { |
| + buf.add(']'); |
| + } |
| + buf.add(')'); |
| + return buf.toString(); |
| +} |
| + |
| class _LocalMirrorSystemImpl implements MirrorSystem { |
| - _LocalMirrorSystemImpl(this.libraries, this.isolate) {} |
| + _LocalMirrorSystemImpl(this.libraries, this.isolate) |
| + : _functionTypes = new Map<String, FunctionTypeMirror>() {} |
| final Map<String, LibraryMirror> libraries; |
| final IsolateMirror isolate; |
| @@ -31,7 +56,7 @@ |
| if (_dynamicType === null) { |
| _dynamicType = |
| new _LocalClassMirrorImpl( |
| - null, 'Dynamic', false, null, null, [], null, const {}); |
| + null, 'Dynamic', false, null, null, [], null, const {}, const {}); |
| } |
| return _dynamicType; |
| } |
| @@ -42,11 +67,27 @@ |
| if (_voidType === null) { |
| _voidType = |
| new _LocalClassMirrorImpl( |
| - null, 'void', false, null, null, [], null, const {}); |
| + null, 'void', false, null, null, [], null, const {}, const {}); |
| } |
| return _voidType; |
| } |
| + final Map<String, FunctionTypeMirror> _functionTypes; |
| + FunctionTypeMirror _lookupFunctionTypeMirror( |
| + TypeMirror returnType, |
| + List<ParameterMirror> parameters) { |
| + var sigString = _makeSignatureString(returnType, parameters); |
| + var mirror = _functionTypes[sigString]; |
| + if (mirror === null) { |
|
cshapiro
2012/09/12 18:52:07
You don't need === anymore for speed.
turnidge
2012/09/12 21:39:30
Replaced all in this file.
|
| + mirror = new _LocalFunctionTypeMirrorImpl(null, |
| + sigString, |
| + returnType, |
| + parameters); |
| + _functionTypes[sigString] = mirror; |
| + } |
| + return mirror; |
| + } |
| + |
| String toString() => "MirrorSystem for isolate '${isolate.debugName}'"; |
| } |
| @@ -149,7 +190,7 @@ |
| throw new MirrorException( |
| 'positional argument $i ($arg) was not an InstanceMirror'); |
| } |
| - } else if (!isSimpleValue(arg)) { |
| + } else if (!_isSimpleValue(arg)) { |
| throw new MirrorException( |
| 'positional argument $i ($arg) was not a simple value'); |
| } |
| @@ -221,7 +262,7 @@ |
| var _type; |
| ClassMirror get type() { |
| - if (_type is _LazyClassMirror) { |
| + if (_type is! Mirror) { |
| _type = _type.resolve(mirrors); |
| } |
| return _type; |
| @@ -234,7 +275,7 @@ |
| get reflectee() => _reflectee; |
| String toString() { |
| - if (isSimpleValue(_reflectee)) { |
| + if (_isSimpleValue(_reflectee)) { |
| if (_reflectee is String) { |
| return "InstanceMirror on <'${_dartEscape(_reflectee)}'>"; |
| } else { |
| @@ -249,18 +290,18 @@ |
| class _LocalClosureMirrorImpl extends _LocalInstanceMirrorImpl |
| implements ClosureMirror { |
| _LocalClosureMirrorImpl(ref, |
| - klass, |
| - reflectee) : super(ref, klass, reflectee) {} |
| + type, |
| + reflectee, |
| + this.function) : super(ref, type, reflectee) {} |
| - MethodMirror _function; |
| - MethodMirror function() => _function; |
| + final MethodMirror function; |
| String get source() { |
| throw new NotImplementedException('ClosureMirror.source not implemented'); |
| } |
| - Future<ObjectMirror> apply(List<Object> positionalArguments, |
| - [Map<String,Object> namedArguments]) { |
| + Future<InstanceMirror> apply(List<Object> positionalArguments, |
| + [Map<String,Object> namedArguments]) { |
| if (namedArguments !== null) { |
| throw new NotImplementedException('named arguments not implemented'); |
| } |
| @@ -279,7 +320,7 @@ |
| return completer.future; |
| } |
| - Future<ObjectMirror> findInContext(String name) { |
| + Future<InstanceMirror> findInContext(String name) { |
| throw new NotImplementedException( |
| 'ClosureMirror.findInContext() not implemented'); |
| } |
| @@ -288,25 +329,30 @@ |
| native 'LocalClosureMirrorImpl_apply'; |
| } |
| -class _LazyClassMirror { |
| - _LazyClassMirror(this.libraryName, this.interfaceName) {} |
| +class _LazyTypeMirror { |
| + _LazyTypeMirror(this.libraryName, this.typeName) {} |
| - ClassMirror resolve(MirrorSystem mirrors) { |
| + TypeMirror resolve(MirrorSystem mirrors) { |
| if (libraryName === null) { |
| - if (interfaceName == 'Dynamic') { |
| - return mirrors.dynamicType(); |
| - } else if (interfaceName == 'void') { |
| - return mirrors.voidType(); |
| + if (typeName == 'Dynamic') { |
| + return mirrors.dynamicType; |
| + } else if (typeName == 'void') { |
| + return mirrors.voidType; |
| } else { |
| throw new NotImplementedException( |
| - "Mirror for type '$interfaceName' not implemented"); |
| + "Mirror for type '$typeName' not implemented"); |
| } |
| } |
| - return mirrors.libraries[libraryName].members[interfaceName]; |
| + var resolved = mirrors.libraries[libraryName].members[typeName]; |
| + if (resolved === null) { |
|
cshapiro
2012/09/12 18:52:07
ditto
|
| + throw new NotImplementedException( |
| + "Mirror for type '$typeName' not implemented"); |
|
cshapiro
2012/09/12 18:52:07
"is not..." or "is unimplemented"
turnidge
2012/09/12 21:39:30
Fixed here and elsewhere.
|
| + } |
| + return resolved; |
| } |
| final String libraryName; |
| - final String interfaceName; |
| + final String typeName; |
| } |
| class _LocalClassMirrorImpl extends _LocalObjectMirrorImpl |
| @@ -318,21 +364,28 @@ |
| this._superclass, |
| this._superinterfaces, |
| this._defaultFactory, |
| - this.members) : super(ref) {} |
| + this.members, |
| + this.typeVariables) : super(ref) {} |
| final String simpleName; |
| String _qualifiedName = null; |
| String get qualifiedName() { |
| - if (_qualifiedName === null) { |
| - _qualifiedName = '${owner.qualifiedName}.${simpleName}'; |
| + if (_owner !== null) { |
| + if (_qualifiedName === null) { |
| + _qualifiedName = '${owner.qualifiedName}.${simpleName}'; |
| + } |
| + } else { |
| + // The owner of a ClassMirror is null in certain odd cases, like |
| + // 'void', 'Dynamic' and function type mirrors. |
| + _qualifiedName = simpleName; |
| } |
| return _qualifiedName; |
| } |
| var _owner; |
| DeclarationMirror get owner() { |
| - if (_owner is! Mirror) { |
| + if (_owner !== null && _owner is! Mirror) { |
| _owner = _owner.resolve(mirrors); |
| } |
| return _owner; |
| @@ -351,7 +404,7 @@ |
| var _superclass; |
| ClassMirror get superclass() { |
| - if (_superclass is _LazyClassMirror) { |
| + if (_superclass is! Mirror) { |
| _superclass = _superclass.resolve(mirrors); |
| } |
| return _superclass; |
| @@ -360,7 +413,7 @@ |
| var _superinterfaces; |
| List<ClassMirror> get superinterfaces() { |
| if (_superinterfaces.length > 0 && |
| - _superinterfaces[0] is _LazyClassMirror) { |
| + _superinterfaces[0] is! Mirror) { |
| List<ClassMirror> resolved = new List<ClassMirror>(); |
| for (int i = 0; i < _superinterfaces.length; i++) { |
| resolved.add(_superinterfaces[i].resolve(mirrors)); |
| @@ -372,7 +425,7 @@ |
| var _defaultFactory; |
| ClassMirror get defaultFactory() { |
| - if (_defaultFactory is _LazyClassMirror) { |
| + if (_defaultFactory !== null && _defaultFactory is! Mirror) { |
| _defaultFactory = _defaultFactory.resolve(mirrors); |
| } |
| return _defaultFactory; |
| @@ -387,51 +440,48 @@ |
| Map<String, VariableMirror> _variables = null; |
| Map<String, MethodMirror> get methods() { |
| - if (_methods == null) { |
| - _methods = filterMap(members, |
| - (key, value) => (value is MethodMirror)); |
| + if (_methods === null) { |
|
cshapiro
2012/09/12 18:52:07
==
|
| + _methods = _filterMap(members, |
| + (key, value) => (value is MethodMirror)); |
| } |
| return _methods; |
| } |
| Map<String, MethodMirror> get constructors() { |
| - if (_constructors == null) { |
| - _constructors = filterMap(methods, |
| - (key, value) => (value.isConstructor)); |
| + if (_constructors === null) { |
|
cshapiro
2012/09/12 18:52:07
==
|
| + _constructors = _filterMap(methods, |
| + (key, value) => (value.isConstructor)); |
| } |
| return _constructors; |
| } |
| Map<String, MethodMirror> get getters() { |
| - if (_getters == null) { |
| - _getters = filterMap(methods, |
| - (key, value) => (value.isGetter)); |
| + if (_getters === null) { |
|
cshapiro
2012/09/12 18:52:07
more of the same, here and below
|
| + _getters = _filterMap(methods, |
| + (key, value) => (value.isGetter)); |
| } |
| return _getters; |
| } |
| Map<String, MethodMirror> get setters() { |
| - if (_setters == null) { |
| - _setters = filterMap(methods, |
| - (key, value) => (value.isSetter)); |
| + if (_setters === null) { |
| + _setters = _filterMap(methods, |
| + (key, value) => (value.isSetter)); |
| } |
| return _setters; |
| } |
| Map<String, VariableMirror> get variables() { |
| - if (_variables == null) { |
| - _variables = filterMap(members, |
| - (key, value) => (value is VariableMirror)); |
| + if (_variables === null) { |
| + _variables = _filterMap(members, |
| + (key, value) => (value is VariableMirror)); |
| } |
| return _variables; |
| } |
| - List<TypeVariableMirror> get typeVariables() { |
| - throw new NotImplementedException( |
| - 'ClassMirror.typeVariables not yet implemented'); |
| - } |
| + Map<String, TypeVariableMirror> typeVariables; |
| - List<TypeMirror> get typeArguments() { |
| + Map<String, TypeMirror> get typeArguments() { |
| throw new NotImplementedException( |
| 'ClassMirror.typeArguments not yet implemented'); |
| } |
| @@ -473,6 +523,148 @@ |
| native 'LocalClassMirrorImpl_invokeConstructor'; |
| } |
| +class _LazyFunctionTypeMirror { |
| + _LazyFunctionTypeMirror(this.returnType, this.parameters) {} |
| + |
| + ClassMirror resolve(MirrorSystem mirrors) { |
| + return mirrors._lookupFunctionTypeMirror(returnType.resolve(mirrors), |
| + parameters); |
| + } |
| + |
| + final returnType; |
| + final List<ParameterMirror> parameters; |
| +} |
| + |
| +class _LocalFunctionTypeMirrorImpl extends _LocalClassMirrorImpl |
| + implements FunctionTypeMirror { |
| + _LocalFunctionTypeMirrorImpl(ref, |
| + simpleName, |
| + this._returnType, |
| + this.parameters) |
| + : super(ref, |
| + simpleName, |
| + true, |
| + null, |
| + new _LazyTypeMirror('dart:core', 'Object'), |
| + [ new _LazyTypeMirror('dart:core', 'Function') ], |
| + null, |
| + const {}, |
| + const {}); |
| + |
| + var _returnType; |
| + TypeMirror get returnType() { |
| + if (_returnType is! Mirror) { |
| + _returnType = _returnType.resolve(mirrors); |
| + } |
| + return _returnType; |
| + } |
| + |
| + final List<ParameterMirror> parameters; |
| + |
| + String toString() => "FunctionTypeMirror on '$simpleName'"; |
| +} |
| + |
| + |
| +class _LazyTypeVariableMirror { |
| + _LazyTypeVariableMirror(this._variableName, this._owner) {} |
| + |
| + TypeVariableMirror resolve(MirrorSystem mirrors) { |
| + ClassMirror owner = _owner.resolve(mirrors); |
| + return owner.typeVariables[_variableName]; |
| + } |
| + |
| + final String _variableName; |
| + final _LazyTypeMirror _owner; |
| +} |
| + |
| +class _LocalTypeVariableMirrorImpl extends _LocalMirrorImpl |
| + implements TypeVariableMirror { |
| + _LocalTypeVariableMirrorImpl(this.simpleName, |
| + this._owner, |
| + this._upperBound) {} |
| + final String simpleName; |
| + |
| + String _qualifiedName = null; |
| + String get qualifiedName() { |
| + if (_qualifiedName === null) { |
| + _qualifiedName = '${owner.qualifiedName}.${simpleName}'; |
| + } |
| + return _qualifiedName; |
| + } |
| + |
| + var _owner; |
| + DeclarationMirror get owner() { |
| + if (_owner is! Mirror) { |
| + _owner = _owner.resolve(mirrors); |
| + } |
| + return _owner; |
| + } |
| + |
| + bool get isPrivate() => false; |
| + |
| + final bool isTopLevel = false; |
| + |
| + SourceLocation get location() { |
| + throw new NotImplementedException( |
| + 'TypeVariableMirror.location not yet implemented'); |
| + } |
| + |
| + var _upperBound; |
| + TypeMirror get upperBound() { |
|
cshapiro
2012/09/12 18:52:07
no () here and around here
turnidge
2012/09/12 21:39:30
Done.
|
| + if (_upperBound is! Mirror) { |
| + _upperBound = _upperBound.resolve(mirrors); |
| + } |
| + return _upperBound; |
| + } |
| + |
| + String toString() => "TypeVariableMirror on '$simpleName'"; |
| +} |
| + |
| + |
| +class _LocalTypedefMirrorImpl extends _LocalMirrorImpl |
| + implements TypedefMirror { |
| + _LocalTypedefMirrorImpl(this.simpleName, |
| + this._owner, |
| + this._referent) {} |
| + final String simpleName; |
| + |
| + String _qualifiedName = null; |
| + String get qualifiedName() { |
| + if (_qualifiedName === null) { |
| + _qualifiedName = '${owner.qualifiedName}.${simpleName}'; |
| + } |
| + return _qualifiedName; |
| + } |
| + |
| + var _owner; |
| + DeclarationMirror get owner() { |
| + if (_owner is! Mirror) { |
| + _owner = _owner.resolve(mirrors); |
| + } |
| + return _owner; |
| + } |
| + |
| + bool get isPrivate() => false; |
| + |
| + final bool isTopLevel = true; |
| + |
| + SourceLocation get location() { |
| + throw new NotImplementedException( |
| + 'TypedefMirror.location not yet implemented'); |
| + } |
| + |
| + var _referent; |
| + TypeMirror get referent() { |
| + if (_referent is! Mirror) { |
| + _referent = _referent.resolve(mirrors); |
| + } |
| + return _referent; |
| + } |
| + |
| + String toString() => "TypedefMirror on '$simpleName'"; |
| +} |
| + |
| + |
| class _LazyLibraryMirror { |
| _LazyLibraryMirror(this.libraryName) {} |
| @@ -519,41 +711,41 @@ |
| Map<String, VariableMirror> _variables = null; |
| Map<String, ClassMirror> get classes() { |
| - if (_classes == null) { |
| - _classes = filterMap(members, |
| - (key, value) => (value is ClassMirror)); |
| + if (_classes === null) { |
| + _classes = _filterMap(members, |
| + (key, value) => (value is ClassMirror)); |
| } |
| return _classes; |
| } |
| Map<String, MethodMirror> get functions() { |
| - if (_functions == null) { |
| - _functions = filterMap(members, |
| - (key, value) => (value is MethodMirror)); |
| + if (_functions === null) { |
| + _functions = _filterMap(members, |
| + (key, value) => (value is MethodMirror)); |
| } |
| return _functions; |
| } |
| Map<String, MethodMirror> get getters() { |
| - if (_getters == null) { |
| - _getters = filterMap(functions, |
| - (key, value) => (value.isGetter)); |
| + if (_getters === null) { |
| + _getters = _filterMap(functions, |
| + (key, value) => (value.isGetter)); |
| } |
| return _getters; |
| } |
| Map<String, MethodMirror> get setters() { |
| - if (_setters == null) { |
| - _setters = filterMap(functions, |
| - (key, value) => (value.isSetter)); |
| + if (_setters === null) { |
| + _setters = _filterMap(functions, |
| + (key, value) => (value.isSetter)); |
| } |
| return _setters; |
| } |
| Map<String, VariableMirror> get variables() { |
| - if (_variables == null) { |
| - _variables = filterMap(members, |
| - (key, value) => (value is VariableMirror)); |
| + if (_variables === null) { |
| + _variables = _filterMap(members, |
| + (key, value) => (value is VariableMirror)); |
| } |
| return _variables; |
| } |
| @@ -566,6 +758,7 @@ |
| _LocalMethodMirrorImpl(this.simpleName, |
| this._owner, |
| this.parameters, |
| + this._returnType, |
| this.isStatic, |
| this.isAbstract, |
| this.isGetter, |
| @@ -605,9 +798,12 @@ |
| 'MethodMirror.location not yet implemented'); |
| } |
| + var _returnType; |
| TypeMirror get returnType() { |
| - throw new NotImplementedException( |
| - 'MethodMirror.returnType not yet implemented'); |
| + if (_returnType is! Mirror) { |
| + _returnType = _returnType.resolve(mirrors); |
| + } |
| + return _returnType; |
| } |
| final List<ParameterMirror> parameters; |
| @@ -659,6 +855,7 @@ |
| implements VariableMirror { |
| _LocalVariableMirrorImpl(this.simpleName, |
| this._owner, |
| + this._type, |
| this.isStatic, |
| this.isFinal) {} |
| @@ -693,9 +890,12 @@ |
| 'VariableMirror.location not yet implemented'); |
| } |
| + var _type; |
| TypeMirror get type() { |
| - throw new NotImplementedException( |
| - 'VariableMirror.type not yet implemented'); |
| + if (_type is! Mirror) { |
| + _type = _type.resolve(mirrors); |
| + } |
| + return _type; |
| } |
| final bool isStatic; |
| @@ -706,17 +906,11 @@ |
| class _LocalParameterMirrorImpl extends _LocalVariableMirrorImpl |
| implements ParameterMirror { |
| - // TODO(rmacnak): Fill these mirrors will real information |
| - _LocalParameterMirrorImpl(this.isOptional) |
| - : super(null, null, false, false) {} |
| + _LocalParameterMirrorImpl(type, this.isOptional) |
| + : super('<TODO:unnamed>', null, type, false, false) {} |
|
cshapiro
2012/09/12 18:52:07
Strange. Why not leave the TODO comment?
turnidge
2012/09/12 21:39:30
Every class in this file has things that need to b
|
| final bool isOptional; |
| - TypeMirror get type() { |
| - throw new NotImplementedException( |
| - 'ParameterMirror.type not yet implemented'); |
| - } |
| - |
| String get defaultValue() { |
| throw new NotImplementedException( |
| 'ParameterMirror.defaultValue not yet implemented'); |