Index: frog/type.dart |
diff --git a/frog/type.dart b/frog/type.dart |
index d98a4e47f115f46d70cd0188abc9502bd475676b..bef2a2dce91997e8abb9d8b24a50ba3f2438c4ad 100644 |
--- a/frog/type.dart |
+++ b/frog/type.dart |
@@ -506,6 +506,7 @@ class ConcreteType extends Type { |
* generate appropriate concrete checks on. |
*/ |
Map<String, Member> members; |
+ Map<String, MemberSet> _resolvedMembers; |
Map<String, MethodMember> constructors; |
FactoryMap factories; |
@@ -513,7 +514,8 @@ class ConcreteType extends Type { |
this.genericType, |
this.typeArguments, |
this.typeArgsInOrder): |
- super(name), constructors = {}, members = {}, factories = new FactoryMap(); |
+ super(name), constructors = {}, members = {}, _resolvedMembers = {}, |
+ factories = new FactoryMap(); |
Type resolveTypeParams(ConcreteType inType) { |
var newTypeArgs = []; |
@@ -630,19 +632,40 @@ class ConcreteType extends Type { |
} |
MemberSet resolveMember(String memberName) { |
- var mem = getMember(memberName); |
- if (mem == null) return null; |
- |
- var ret = new MemberSet(mem); |
- if (mem.isStatic) return ret; |
+ // TODO(jimhug): Cut-and-paste and tweak from Type <frown>. |
+ MemberSet ret = _resolvedMembers[memberName]; |
+ if (ret != null) return ret; |
- for (var t in genericType.subtypes) { |
- // TODO(jimhug): Do I resolve any type params here? |
- var m = t.members[memberName]; |
- if (m != null) ret.add(m); |
+ Member member = getMember(memberName); |
+ if (member == null) { |
+ // TODO(jimhug): Check for members on subtypes given dart's dynamism. |
+ return null; |
} |
- return ret; |
+ // TODO(jimhug): Move this adding subtypes logic to MemberSet? |
+ ret = new MemberSet(member); |
+ _resolvedMembers[memberName] = ret; |
+ if (member.isStatic) { |
+ return ret; |
+ } else { |
+ for (var t in genericType.subtypes) { |
+ // TODO(jimhug): Make these non-generic! |
+ if (!isClass && t.isClass) { |
+ // If this is an interface, the actual implementation may |
+ // come from a class that does not implement this interface. |
+ // TODO(vsm): Use a more efficient lookup strategy. |
+ // TODO(jimhug): This is made uglier by need to avoid dups. |
+ final m = t.getMember(memberName); |
+ if (m != null && ret.members.indexOf(m) == -1) { |
+ ret.add(m); |
+ } |
+ } else { |
+ final m = t.members[memberName]; |
+ if (m != null) ret.add(m); |
+ } |
+ } |
+ return ret; |
+ } |
} |
Type resolveType(TypeReference node, bool isRequired) { |