| Index: frog/type.dart
|
| diff --git a/frog/type.dart b/frog/type.dart
|
| index 52134f2ae05544b2e4901b4413cb9261ebff2fd3..6bf9a0ad4debed21a5c40a172072e0f2a56a1c17 100644
|
| --- a/frog/type.dart
|
| +++ b/frog/type.dart
|
| @@ -18,10 +18,10 @@ class Type extends Element {
|
| /** Stubs used to call into this method dynamically. */
|
| Map<String, VarMember> varStubs;
|
|
|
| - /** Cache of [Member]s that have been found. */
|
| - Map<String, Member> _foundMembers;
|
| + /** Cache of [MemberSet]s that have been resolved. */
|
| + Map<String, MemberSet> _resolvedMembers;
|
|
|
| - Type(String name): _foundMembers = {}, varStubs = {}, super(name, null);
|
| + Type(String name): _resolvedMembers = {}, varStubs = {}, super(name, null);
|
|
|
| void markUsed() {}
|
| abstract void genMethod(Member method);
|
| @@ -203,6 +203,41 @@ class Type extends Element {
|
| }
|
| }
|
|
|
| + MemberSet resolveMember(String memberName) {
|
| + MemberSet ret = _resolvedMembers[memberName];
|
| + if (ret != null) return ret;
|
| +
|
| + Member member = getMember(memberName);
|
| + if (member == null) {
|
| + // TODO(jimhug): Check for members on subtypes given dart's dynamism.
|
| + return null;
|
| + }
|
| +
|
| + // 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 subtypes) {
|
| + 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;
|
| + }
|
| + }
|
| +
|
| void ensureSubtypeOf(Type other, SourceSpan span, [bool typeErrors=false]) {
|
| if (!isSubtypeOf(other)) {
|
| var msg = 'type $name is not a subtype of ${other.name}';
|
| @@ -435,6 +470,10 @@ class ParameterType extends Type {
|
| //bool isSubtypeOf(Type other) => extendsType.isSubtypeOf(other);
|
| bool isSubtypeOf(Type other) => true;
|
|
|
| + MemberSet resolveMember(String memberName) {
|
| + return extendsType.resolveMember(memberName);
|
| + }
|
| +
|
| MethodMember getConstructor(String constructorName) {
|
| world.internalError('no constructors on type parameters yet');
|
| }
|
| @@ -495,6 +534,7 @@ class NonNullableType extends Type {
|
| void markUsed() { type.markUsed(); }
|
| void genMethod(Member method) { type.genMethod(method); }
|
| SourceSpan get span() => type.span;
|
| + MemberSet resolveMember(String name) => type.resolveMember(name);
|
| Member getMember(String name) => type.getMember(name);
|
| MethodMember getConstructor(String name) => type.getConstructor(name);
|
| MethodMember getFactory(Type t, String name) => type.getFactory(t, name);
|
| @@ -665,14 +705,9 @@ class ConcreteType extends Type {
|
| }
|
|
|
| Member getMember(String memberName) {
|
| - Member member = _foundMembers[memberName];
|
| - if (member != null) return member;
|
| -
|
| -
|
| - member = members[memberName];
|
| + Member member = members[memberName];
|
| if (member != null) {
|
| _checkOverride(member);
|
| - _foundMembers[memberName] = member;
|
| return member;
|
| }
|
|
|
| @@ -682,13 +717,10 @@ class ConcreteType extends Type {
|
| if (genericMember != null) {
|
| member = new ConcreteMember(genericMember.name, this, genericMember);
|
| members[memberName] = member;
|
| - _foundMembers[memberName] = member;
|
| return member;
|
| }
|
|
|
| - member = _getMemberInParents(memberName);
|
| - _foundMembers[memberName] = member;
|
| - return member;
|
| + return _getMemberInParents(memberName);
|
| }
|
|
|
| Type resolveType(TypeReference node, bool isRequired) {
|
| @@ -1217,16 +1249,11 @@ class DefinedType extends Type {
|
| return null;
|
| }
|
|
|
| - // TODO(jimhug): Too much copy-paster with ConcreteType...
|
| Member getMember(String memberName) {
|
| - Member member = _foundMembers[memberName];
|
| - if (member != null) return member;
|
| -
|
| + Member member = members[memberName];
|
|
|
| - member = members[memberName];
|
| if (member != null) {
|
| _checkOverride(member);
|
| - _foundMembers[memberName] = member;
|
| return member;
|
| }
|
|
|
| @@ -1236,15 +1263,11 @@ class DefinedType extends Type {
|
| // getters.
|
| var libType = this.library.findTypeByName(memberName);
|
| if (libType != null) {
|
| - member = libType.typeMember;
|
| - _foundMembers[memberName] = member;
|
| - return member;
|
| + return libType.typeMember;
|
| }
|
| }
|
|
|
| - member = _getMemberInParents(memberName);
|
| - _foundMembers[memberName] = member;
|
| - return member;
|
| + return _getMemberInParents(memberName);
|
| }
|
|
|
| Type resolveTypeParams(ConcreteType inType) => this;
|
|
|