Index: reflectable/lib/src/reflectable_mirror_based.dart |
diff --git a/reflectable/lib/src/reflectable_mirror_based.dart b/reflectable/lib/src/reflectable_mirror_based.dart |
index 2fcbe4bd401f1d696d8148c14038a026d4017572..54c35e7a56e3e36beda4b8e0faf7f00b26abc3b2 100644 |
--- a/reflectable/lib/src/reflectable_mirror_based.dart |
+++ b/reflectable/lib/src/reflectable_mirror_based.dart |
@@ -257,9 +257,9 @@ bool reflectableSupportsInstanceInvoke( |
bool result = reflectable.hasCapability(predicate); |
if (!result && |
impliesCorrespondingSetter(reflectable.capabilities) && |
- name.endsWith("=")) { |
+ _isSetterName(name)) { |
return reflectableSupportsInstanceInvoke( |
- reflectable, name.substring(0, name.length - 1), classMirror); |
+ reflectable, _setterNameToGetterName(name), classMirror); |
} |
return result; |
} |
@@ -316,16 +316,16 @@ bool reflectableSupportsStaticInvoke(ReflectableImpl reflectable, String name, |
bool result = reflectable.hasCapability(predicate); |
if (!result && |
impliesCorrespondingSetter(reflectable.capabilities) && |
- name.endsWith("=")) { |
+ _isSetterName(name)) { |
result = reflectableSupportsStaticInvoke( |
- reflectable, name.substring(0, name.length - 1), getterMetadata, null); |
+ reflectable, _setterNameToGetterName(name), getterMetadata, null); |
} |
return result; |
} |
/// Returns true iff [reflectable] supports top-level invoke of [name]. |
bool reflectableSupportsTopLevelInvoke(ReflectableImpl reflectable, String name, |
- List<dm.InstanceMirror> metadata) { |
+ List<dm.InstanceMirror> metadata, List<dm.InstanceMirror> getterMetadata) { |
// We don't have to check for `libraryCapability` because this method is only |
// ever called from the methods of a `LibraryMirrorImpl` and the existence of |
// an instance of a `LibraryMirrorImpl` implies the `libraryMirrorCapability`. |
@@ -340,6 +340,11 @@ bool reflectableSupportsTopLevelInvoke(ReflectableImpl reflectable, String name, |
if (capability is TopLevelInvokeMetaCapability) { |
return metadataSupported(metadata, capability); |
} |
+ if (impliesCorrespondingSetter(reflectable.capabilities) && |
sigurdm
2015/10/15 12:30:58
I think the changes related to getter/setters idea
eernst
2015/10/15 13:46:11
Agreed in meat space to not separate them this tim
|
+ _isSetterName(name)) { |
+ return reflectableSupportsTopLevelInvoke( |
+ reflectable, _setterNameToGetterName(name), getterMetadata, null); |
+ } |
return false; |
}); |
} |
@@ -379,16 +384,16 @@ bool reflectableSupportsDeclarations(Reflectable reflectable) { |
/// Returns [setterName] with final "=" removed. |
/// If the it does not have a final "=" it is returned as is. |
String _setterToGetter(String setterName) { |
- if (!setterName.endsWith("=")) { |
+ if (!_isSetterName(setterName)) { |
return setterName; |
} |
- return setterName.substring(0, setterName.length - 1); |
+ return _setterNameToGetterName(setterName); |
} |
/// Returns [getterName] with a final "=" added. |
/// If [getter] already ends with "=" an error is thrown. |
String _getterToSetter(String getterName) { |
- if (getterName.endsWith("=")) { |
+ if (_isSetterName(getterName)) { |
throw new ArgumentError( |
"$getterName is a setter name (ends with `=`) already."); |
} |
@@ -421,28 +426,73 @@ class _LibraryMirrorImpl extends _DeclarationMirrorImpl |
throw new NoSuchCapabilityError( |
"Attempt to get declarations without capability"); |
} |
- Map<Symbol, dm.DeclarationMirror> decls = _libraryMirror.declarations; |
- Iterable<Symbol> relevantKeys = decls.keys.where((k) { |
- List<dm.InstanceMirror> metadata = decls[k].metadata; |
- for (var item in metadata) { |
- if (item.hasReflectee && item.reflectee == _reflectable) return true; |
+ Map<String, rm.DeclarationMirror> result = |
+ new Map<String, rm.DeclarationMirror>(); |
+ _libraryMirror.declarations |
+ .forEach((Symbol nameSymbol, dm.DeclarationMirror declarationMirror) { |
+ String name = dm.MirrorSystem.getName(nameSymbol); |
+ if (declarationMirror is dm.MethodMirror) { |
+ List<dm.InstanceMirror> getterMetadata = null; |
+ if (declarationMirror.isSetter && |
+ !declarationMirror.isSynthetic && |
+ _isSetterName(name)) { |
+ dm.DeclarationMirror correspondingGetter = |
+ _libraryMirror.declarations[ |
+ new Symbol(_setterNameToGetterName(name))]; |
+ getterMetadata = correspondingGetter?.metadata; |
+ } |
+ if (reflectableSupportsTopLevelInvoke( |
+ _reflectable, name, declarationMirror.metadata, getterMetadata)) { |
+ result[name] = wrapDeclarationMirror(declarationMirror, _reflectable); |
+ } |
+ } else if (declarationMirror is dm.VariableMirror) { |
+ // For variableMirrors we test both for support of the name and the |
+ // derived setter name. |
+ if (reflectableSupportsTopLevelInvoke( |
+ _reflectable, name, declarationMirror.metadata, null) || |
+ reflectableSupportsTopLevelInvoke(_reflectable, |
+ _getterToSetter(name), declarationMirror.metadata, null)) { |
+ result[name] = wrapDeclarationMirror(declarationMirror, _reflectable); |
+ } |
+ } else { |
+ // The additional subtypes of [dm.DeclarationMirror] are |
+ // [dm.LibraryMirror]: doees not occur inside another library, |
+ // [dm.ParameterMirror]: not declared in a library, [dm.TypeMirror], |
+ // and the 4 subtypes thereof; [dm.ClassMirror]: processed here, |
+ // [dm.TypedefMirror]: not yet supported, [dm.FunctionTypeMirror]: not |
+ // yet supported, and [dm.TypeVariableMirror]: not yet supported. |
+ if (declarationMirror is dm.ClassMirror) { |
+ if (_reflectable._supportedClasses.contains(declarationMirror)) { |
+ result[name] = |
+ wrapDeclarationMirror(declarationMirror, _reflectable); |
+ } |
+ } else { |
+ // TODO(eernst) implement: currently ignoring the unsupported cases. |
+ } |
} |
- return false; |
}); |
- return new Map<String, rm.DeclarationMirror>.fromIterable(relevantKeys, |
- key: (k) => dm.MirrorSystem.getName(k), |
- value: (v) => wrapDeclarationMirror(decls[v], _reflectable)); |
+ return result; |
} |
@override |
Object invoke(String memberName, List positionalArguments, |
[Map<Symbol, dynamic> namedArguments]) { |
- if (!reflectableSupportsTopLevelInvoke(_reflectable, memberName, |
- _libraryMirror.declarations[new Symbol(memberName)].metadata)) { |
+ dm.DeclarationMirror declaration = |
+ _libraryMirror.declarations[new Symbol(memberName)]; |
+ List<dm.InstanceMirror> metadata = declaration.metadata; |
+ List<dm.InstanceMirror> getterMetadata = null; |
+ if (impliesCorrespondingSetter(_reflectable.capabilities) && |
+ declaration is dm.MethodMirror && |
+ declaration.isSetter) { |
+ dm.MethodMirror correspondingGetter = _libraryMirror.declarations[ |
+ new Symbol(_setterNameToGetterName(memberName))]; |
+ getterMetadata = correspondingGetter?.metadata; |
+ } |
+ if (!reflectableSupportsTopLevelInvoke( |
+ _reflectable, memberName, metadata, getterMetadata)) { |
throw new NoSuchInvokeCapabilityError( |
_receiver, memberName, positionalArguments, namedArguments); |
} |
- |
return _libraryMirror |
.invoke(new Symbol(memberName), positionalArguments, namedArguments) |
.reflectee; |
@@ -451,7 +501,7 @@ class _LibraryMirrorImpl extends _DeclarationMirrorImpl |
@override |
Object invokeGetter(String getterName) { |
if (!reflectableSupportsTopLevelInvoke(_reflectable, getterName, |
- _libraryMirror.declarations[new Symbol(getterName)].metadata)) { |
+ _libraryMirror.declarations[new Symbol(getterName)].metadata, null)) { |
throw new NoSuchInvokeCapabilityError(_receiver, getterName, [], null); |
} |
Symbol getterNameSymbol = new Symbol(getterName); |
@@ -460,13 +510,24 @@ class _LibraryMirrorImpl extends _DeclarationMirrorImpl |
@override |
Object invokeSetter(String setterName, Object value) { |
- if (!reflectableSupportsTopLevelInvoke(_reflectable, setterName, |
- _libraryMirror.declarations[new Symbol(setterName)].metadata)) { |
+ dm.DeclarationMirror declaration = |
+ _libraryMirror.declarations[new Symbol(setterName)]; |
+ List<dm.InstanceMirror> metadata = declaration.metadata; |
+ List<dm.InstanceMirror> getterMetadata = null; |
+ String getterName = _setterToGetter(setterName); |
+ Symbol getterNameSymbol = new Symbol(getterName); |
+ if (impliesCorrespondingSetter(_reflectable.capabilities) && |
+ declaration is dm.MethodMirror && |
+ declaration.isSetter) { |
+ dm.MethodMirror correspondingGetter = |
+ _libraryMirror.declarations[getterNameSymbol]; |
+ getterMetadata = correspondingGetter?.metadata; |
+ } |
+ if (!reflectableSupportsTopLevelInvoke( |
+ _reflectable, setterName, metadata, getterMetadata)) { |
throw new NoSuchInvokeCapabilityError( |
_receiver, setterName, [value], null); |
} |
- String getterName = _setterToGetter(setterName); |
- Symbol getterNameSymbol = new Symbol(getterName); |
return _libraryMirror.setField(getterNameSymbol, value).reflectee; |
} |
@@ -685,10 +746,10 @@ class ClassMirrorImpl extends _TypeMirrorImpl |
List<dm.InstanceMirror> getterMetadata = null; |
if (declarationMirror.isSetter && |
!declarationMirror.isSynthetic && |
- name.endsWith("=")) { |
+ _isSetterName(name)) { |
dm.DeclarationMirror correspondingGetter = |
_classMirror.declarations[ |
- new Symbol(name.substring(0, name.length - 1))]; |
+ new Symbol(_setterNameToGetterName(name))]; |
getterMetadata = correspondingGetter?.metadata; |
} |
included = included || |
@@ -787,9 +848,9 @@ class ClassMirrorImpl extends _TypeMirrorImpl |
if (declaration is dm.MethodMirror && |
declaration.isSetter && |
!declaration.isSynthetic && |
- memberName.endsWith("=")) { |
+ _isSetterName(memberName)) { |
dm.DeclarationMirror correspondingGetter = _classMirror.declarations[ |
- memberName.substring(0, memberName.length - 1)]; |
+ new Symbol(_setterNameToGetterName(memberName))]; |
getterMetadata = correspondingGetter?.metadata; |
} |
if (reflectableSupportsStaticInvoke( |
@@ -818,9 +879,9 @@ class ClassMirrorImpl extends _TypeMirrorImpl |
List<dm.InstanceMirror> metadata = |
_classMirror.declarations[new Symbol(setterName)]?.metadata; |
List<dm.InstanceMirror> getterMetadata = null; |
- if (setterName.endsWith("=")) { |
+ if (_isSetterName(setterName)) { |
dm.DeclarationMirror correspondingGetter = _classMirror.declarations[ |
- new Symbol(setterName.substring(0, setterName.length - 1))]; |
+ new Symbol(_setterNameToGetterName(setterName))]; |
getterMetadata = correspondingGetter?.metadata; |
} |
if (reflectableSupportsStaticInvoke( |
@@ -1784,3 +1845,10 @@ class _TypeAnnotationsFixedPoint extends FixedPoint<dm.ClassMirror> { |
} |
} |
} |
+ |
+bool _isSetterName(String name) => name.endsWith("="); |
+ |
+String _setterNameToGetterName(String name) { |
+ assert(_isSetterName(name)); |
+ return name.substring(0, name.length - 1); |
+} |