Index: runtime/lib/mirrors_impl.dart |
diff --git a/runtime/lib/mirrors_impl.dart b/runtime/lib/mirrors_impl.dart |
index 8476c15fcc085852aadc4c3d416162c7aec1b54d..2f820e9cc1a791e8a66377f4e529f28dcf6fa725 100644 |
--- a/runtime/lib/mirrors_impl.dart |
+++ b/runtime/lib/mirrors_impl.dart |
@@ -160,6 +160,76 @@ class _InvocationTrampoline implements Function { |
} |
} |
+class _SyntheticAccessor implements MethodMirror { |
+ final DeclarationMirror owner; |
+ final Symbol simpleName; |
+ final bool isGetter; |
+ final bool isStatic; |
+ final bool isTopLevel; |
+ final _target; |
+ |
+ _SyntheticAccessor(this.owner, |
+ this.simpleName, |
+ this.isGetter, |
+ this.isStatic, |
+ this.isTopLevel, |
+ this._target); |
+ |
+ bool get isSynthetic => true; |
+ bool get isRegularMethod => false; |
+ bool get isOperator => false; |
+ bool get isConstructor => false; |
+ bool get isConstConstructor => false; |
+ bool get isGenerativeConstructor => false; |
+ bool get isFactoryConstructor => false; |
+ bool get isRedirectingConstructor => false; |
+ bool get isAbstract => false; |
+ |
+ bool get isSetter => !isGetter; |
+ bool get isPrivate => _n(simpleName).startsWith('_'); |
+ |
+ Symbol get qualifiedName => _computeQualifiedName(owner, simpleName); |
+ Symbol get constructorName => const Symbol(''); |
+ |
+ TypeMirror get returnType => _target.type; |
+ List<ParameterMirror> get parameters { |
+ if (isGetter) return emptyList; |
+ return new UnmodifiableListView( |
+ [new _SyntheticSetterParameter(this, this._target)]); |
+ } |
+ |
+ List<InstanceMirror> get metadata => emptyList; |
+ |
+ String get source => '<synthetic code>'; |
ahe
2013/12/06 12:20:40
I'm worried that returning illegal syntax leads to
rmacnak
2013/12/07 02:09:06
Done.
|
+} |
+ |
+class _SyntheticSetterParameter implements ParameterMirror { |
+ final DeclarationMirror owner; |
+ final VariableMirror _target; |
+ |
+ _SyntheticSetterParameter(this.owner, this._target); |
+ |
+ Symbol get simpleName => _target.simpleName; |
+ Symbol get qualifiedName => _computeQualifiedName(owner, simpleName); |
+ TypeMirror get type => _target.type; |
+ |
+ bool get isOptional => false; |
+ bool get isNamed => false; |
+ bool get isStatic => false; |
+ bool get isTopLevel => false; |
+ bool get isConst => false; |
+ bool get isFinal => true; |
+ bool get isPrivate => false; |
+ bool get hasDefaultValue => false; |
+ InstanceMirror get defaultValue => null; |
+} |
+ |
+class _SyntheticTypeGetter extends _SyntheticAccessor { |
ahe
2013/12/06 12:20:40
I want to make sure that we're building a mirror A
rmacnak
2013/12/06 19:41:35
Right, the intention of instance/static/topLevelMe
|
+ _SyntheticTypeGetter(owner, simpleName, target) |
+ : super(owner, simpleName, true, true, true, target); |
+ TypeMirror get returnType => reflectClass(Type); |
+} |
+ |
abstract class _LocalObjectMirror extends _LocalMirror implements ObjectMirror { |
final _reflectee; // May be a MirrorReference or an ordinary object. |
@@ -500,6 +570,55 @@ class _LocalClassMirror extends _LocalObjectMirror |
return _mixin; |
} |
+ var _cachedStaticMembers; |
+ Map<Symbol, MethodMirror> get staticMembers { |
+ if (_cachedStaticMembers != null) return _cachedStaticMembers; |
+ var result = new Map<Symbol, MethodMirror>(); |
+ declarations.values.forEach((decl) { |
+ if (decl is MethodMirror && decl.isStatic && |
+ !decl.isConstructor && !decl.isAbstract) { |
+ result[decl.simpleName] = decl; |
+ } |
+ if (decl is VariableMirror && decl.isStatic) { |
+ var getterName = decl.simpleName; |
+ result[getterName] = |
+ new _SyntheticAccessor(this, getterName, true, true, false, decl); |
+ if (!decl.isFinal) { |
+ var setterName = _asSetter(decl.simpleName, this.owner); |
+ result[setterName] = new _SyntheticAccessor( |
+ this, setterName, false, true, false, decl); |
+ } |
+ } |
+ }); |
+ return _cachedStaticMembers = result; |
+ } |
+ |
+ var _cachedInstanceMembers; |
+ Map<Symbol, MethodMirror> get instanceMembers { |
+ if (_cachedInstanceMembers != null) return _cachedInstanceMembers; |
+ var result = new Map<Symbol, MethodMirror>(); |
+ if (superclass != null) { |
+ result.addAll(superclass.instanceMembers); |
+ } |
+ declarations.values.forEach((decl) { |
+ if (decl is MethodMirror && !decl.isStatic && |
+ !decl.isConstructor && !decl.isAbstract) { |
+ result[decl.simpleName] = decl; |
+ } |
+ if (decl is VariableMirror && !decl.isStatic) { |
+ var getterName = decl.simpleName; |
+ result[getterName] = |
+ new _SyntheticAccessor(this, getterName, true, false, false, decl); |
+ if (!decl.isFinal) { |
+ var setterName = _asSetter(decl.simpleName, this.owner); |
+ result[setterName] = new _SyntheticAccessor( |
+ this, setterName, false, false, false, decl); |
+ } |
+ } |
+ }); |
+ return _cachedInstanceMembers = result; |
+ } |
+ |
Map<Symbol, DeclarationMirror> _declarations; |
Map<Symbol, DeclarationMirror> get declarations { |
if (_declarations != null) return _declarations; |
@@ -966,8 +1085,12 @@ class _LocalTypedefMirror extends _LocalDeclarationMirror |
native "TypedefMirror_declaration"; |
} |
-class _LocalLibraryMirror extends _LocalObjectMirror |
- implements LibraryMirror { |
+Symbol _asSetter(Symbol getter, LibraryMirror library) { |
+ var unwrapped = MirrorSystem.getName(getter); |
+ return MirrorSystem.getSymbol('${unwrapped}=', library); |
+} |
+ |
+class _LocalLibraryMirror extends _LocalObjectMirror implements LibraryMirror { |
final Symbol simpleName; |
final Uri uri; |
@@ -992,6 +1115,32 @@ class _LocalLibraryMirror extends _LocalObjectMirror |
throw new UnimplementedError('LibraryMirror.location is not implemented'); |
} |
+ var _cachedTopLevelMembers; |
+ Map<Symbol, MethodMirror> get topLevelMembers { |
+ if (_cachedTopLevelMembers != null) return _cachedTopLevelMembers; |
+ var result = new Map<Symbol, MethodMirror>(); |
+ declarations.values.forEach((decl) { |
+ if (decl is MethodMirror && !decl.isAbstract) { |
+ result[decl.simpleName] = decl; |
+ } |
+ if (decl is VariableMirror) { |
+ var getterName = decl.simpleName; |
+ result[getterName] = |
+ new _SyntheticAccessor(this, getterName, true, true, true, decl); |
+ if (!decl.isFinal) { |
+ var setterName = _asSetter(decl.simpleName, this); |
+ result[setterName] = new _SyntheticAccessor( |
+ this, setterName, false, true, true, decl); |
+ } |
+ } |
+ if (decl is TypeMirror) { |
+ var getterName = decl.simpleName; |
+ result[getterName] = new _SyntheticTypeGetter(this, getterName, decl); |
+ } |
+ }); |
+ return _cachedTopLevelMembers = result; |
+ } |
+ |
Map<Symbol, DeclarationMirror> _declarations; |
Map<Symbol, DeclarationMirror> get declarations { |
if (_declarations != null) return _declarations; |
@@ -1094,7 +1243,7 @@ class _LocalLibraryMirror extends _LocalObjectMirror |
native "LibraryMirror_members"; |
} |
-class _LocalMethodMirror extends _LocalDeclarationMirror |
+class _LocalMethodMirror extends _LocalDeclarationMirror |
implements MethodMirror { |
final bool isStatic; |
final bool isAbstract; |
@@ -1139,6 +1288,7 @@ class _LocalMethodMirror extends _LocalDeclarationMirror |
_n(constructorName).startsWith('_'); |
bool get isTopLevel => owner is LibraryMirror; |
+ bool get isSynthetic => false; |
SourceLocation get location { |
throw new UnimplementedError('MethodMirror.location is not implemented'); |