2059 if (cache == null) { |
2059 if (cache == null) { |
2060 cache = new HashMap<TypeSymbol, Entry>(); |
2060 cache = new HashMap<TypeSymbol, Entry>(); |
2061 _map.put(ms, new SoftReference<Map<TypeSymbol, Entry>>(cache)); |
2061 _map.put(ms, new SoftReference<Map<TypeSymbol, Entry>>(cache)); |
2062 } |
2062 } |
2063 Entry e = cache.get(origin); |
2063 Entry e = cache.get(origin); |
2064 CompoundScope members = membersClosure(origin.type); |
2064 CompoundScope members = membersClosure(origin.type, true); |
2065 if (e == null || |
2065 if (e == null || |
2066 !e.matches(implFilter, checkResult, members.getMark())) { |
2066 !e.matches(implFilter, checkResult, members.getMark())) { |
2067 MethodSymbol impl = implementationInternal(ms, origin, checkResult, implFilter); |
2067 MethodSymbol impl = implementationInternal(ms, origin, checkResult, implFilter); |
2068 cache.put(origin, new Entry(impl, implFilter, checkResult, members.getMark())); |
2068 cache.put(origin, new Entry(impl, implFilter, checkResult, members.getMark())); |
2069 return impl; |
2069 return impl; |
2096 return implCache.get(ms, origin, checkResult, implFilter); |
2096 return implCache.get(ms, origin, checkResult, implFilter); |
2097 } |
2097 } |
2098 // </editor-fold> |
2098 // </editor-fold> |
2099 |
2099 |
2100 // <editor-fold defaultstate="collapsed" desc="compute transitive closure of all members in given site"> |
2100 // <editor-fold defaultstate="collapsed" desc="compute transitive closure of all members in given site"> |
2101 public CompoundScope membersClosure(Type site) { |
2101 class MembersClosureCache extends SimpleVisitor<CompoundScope, Boolean> { |
2102 return membersClosure.visit(site); |
2102 |
2103 } |
2103 private WeakHashMap<TypeSymbol, Entry> _map = |
2104 |
2104 new WeakHashMap<TypeSymbol, Entry>(); |
2105 UnaryVisitor<CompoundScope> membersClosure = new UnaryVisitor<CompoundScope>() { |
2105 |
2106 |
2106 class Entry { |
2107 public CompoundScope visitType(Type t, Void s) { |
2107 final boolean skipInterfaces; |
|
2108 final CompoundScope compoundScope; |
|
2109 |
|
2110 public Entry(boolean skipInterfaces, CompoundScope compoundScope) { |
|
2111 this.skipInterfaces = skipInterfaces; |
|
2112 this.compoundScope = compoundScope; |
|
2113 } |
|
2114 |
|
2115 boolean matches(boolean skipInterfaces) { |
|
2116 return this.skipInterfaces == skipInterfaces; |
|
2117 } |
|
2118 } |
|
2119 |
|
2120 /** members closure visitor methods **/ |
|
2121 |
|
2122 public CompoundScope visitType(Type t, Boolean skipInterface) { |
2108 return null; |
2123 return null; |
2109 } |
2124 } |
2110 |
2125 |
2111 @Override |
2126 @Override |
2112 public CompoundScope visitClassType(ClassType t, Void s) { |
2127 public CompoundScope visitClassType(ClassType t, Boolean skipInterface) { |
2113 ClassSymbol csym = (ClassSymbol)t.tsym; |
2128 ClassSymbol csym = (ClassSymbol)t.tsym; |
2114 if (csym.membersClosure == null) { |
2129 Entry e = _map.get(csym); |
|
2130 if (e == null || !e.matches(skipInterface)) { |
2115 CompoundScope membersClosure = new CompoundScope(csym); |
2131 CompoundScope membersClosure = new CompoundScope(csym); |
2116 for (Type i : interfaces(t)) { |
2132 if (!skipInterface) { |
2117 membersClosure.addSubScope(visit(i)); |
2133 for (Type i : interfaces(t)) { |
2118 } |
2134 membersClosure.addSubScope(visit(i, skipInterface)); |
2119 membersClosure.addSubScope(visit(supertype(t))); |
2135 } |
|
2136 } |
|
2137 membersClosure.addSubScope(visit(supertype(t), skipInterface)); |
2120 membersClosure.addSubScope(csym.members()); |
2138 membersClosure.addSubScope(csym.members()); |
2121 csym.membersClosure = membersClosure; |
2139 e = new Entry(skipInterface, membersClosure); |
2122 } |
2140 _map.put(csym, e); |
2123 return csym.membersClosure; |
2141 } |
|
2142 return e.compoundScope; |
2124 } |
2143 } |
2125 |
2144 |
2126 @Override |
2145 @Override |
2127 public CompoundScope visitTypeVar(TypeVar t, Void s) { |
2146 public CompoundScope visitTypeVar(TypeVar t, Boolean skipInterface) { |
2128 return visit(t.getUpperBound()); |
2147 return visit(t.getUpperBound(), skipInterface); |
2129 } |
2148 } |
2130 }; |
2149 } |
|
2150 |
|
2151 private MembersClosureCache membersCache = new MembersClosureCache(); |
|
2152 |
|
2153 public CompoundScope membersClosure(Type site, boolean skipInterface) { |
|
2154 return membersCache.visit(site, skipInterface); |
|
2155 } |
2131 // </editor-fold> |
2156 // </editor-fold> |
2132 |
2157 |
2133 /** |
2158 /** |
2134 * Does t have the same arguments as s? It is assumed that both |
2159 * Does t have the same arguments as s? It is assumed that both |
2135 * types are (possibly polymorphic) method types. Monomorphic |
2160 * types are (possibly polymorphic) method types. Monomorphic |