34 import com.sun.tools.javac.jvm.ClassReader; |
34 import com.sun.tools.javac.jvm.ClassReader; |
35 import com.sun.tools.javac.code.Attribute.RetentionPolicy; |
35 import com.sun.tools.javac.code.Attribute.RetentionPolicy; |
36 import com.sun.tools.javac.code.Lint.LintCategory; |
36 import com.sun.tools.javac.code.Lint.LintCategory; |
37 import com.sun.tools.javac.comp.Check; |
37 import com.sun.tools.javac.comp.Check; |
38 |
38 |
|
39 import static com.sun.tools.javac.code.Scope.*; |
39 import static com.sun.tools.javac.code.Type.*; |
40 import static com.sun.tools.javac.code.Type.*; |
40 import static com.sun.tools.javac.code.TypeTags.*; |
41 import static com.sun.tools.javac.code.TypeTags.*; |
41 import static com.sun.tools.javac.code.Symbol.*; |
42 import static com.sun.tools.javac.code.Symbol.*; |
42 import static com.sun.tools.javac.code.Flags.*; |
43 import static com.sun.tools.javac.code.Flags.*; |
43 import static com.sun.tools.javac.code.BoundKind.*; |
44 import static com.sun.tools.javac.code.BoundKind.*; |
89 } |
89 } |
90 |
90 |
91 protected Types(Context context) { |
91 protected Types(Context context) { |
92 context.put(typesKey, this); |
92 context.put(typesKey, this); |
93 syms = Symtab.instance(context); |
93 syms = Symtab.instance(context); |
94 scopeCounter = Scope.ScopeCounter.instance(context); |
|
95 names = Names.instance(context); |
94 names = Names.instance(context); |
96 allowBoxing = Source.instance(context).allowBoxing(); |
95 allowBoxing = Source.instance(context).allowBoxing(); |
97 reader = ClassReader.instance(context); |
96 reader = ClassReader.instance(context); |
98 source = Source.instance(context); |
97 source = Source.instance(context); |
99 chk = Check.instance(context); |
98 chk = Check.instance(context); |
2022 |
2021 |
2023 class Entry { |
2022 class Entry { |
2024 final MethodSymbol cachedImpl; |
2023 final MethodSymbol cachedImpl; |
2025 final Filter<Symbol> implFilter; |
2024 final Filter<Symbol> implFilter; |
2026 final boolean checkResult; |
2025 final boolean checkResult; |
2027 final Scope.ScopeCounter scopeCounter; |
|
2028 |
2026 |
2029 public Entry(MethodSymbol cachedImpl, |
2027 public Entry(MethodSymbol cachedImpl, |
2030 Filter<Symbol> scopeFilter, |
2028 Filter<Symbol> scopeFilter, |
2031 boolean checkResult, |
2029 boolean checkResult) { |
2032 Scope.ScopeCounter scopeCounter) { |
|
2033 this.cachedImpl = cachedImpl; |
2030 this.cachedImpl = cachedImpl; |
2034 this.implFilter = scopeFilter; |
2031 this.implFilter = scopeFilter; |
2035 this.checkResult = checkResult; |
2032 this.checkResult = checkResult; |
2036 this.scopeCounter = scopeCounter; |
2033 } |
2037 } |
2034 |
2038 |
2035 boolean matches(Filter<Symbol> scopeFilter, boolean checkResult) { |
2039 boolean matches(Filter<Symbol> scopeFilter, boolean checkResult, Scope.ScopeCounter scopeCounter) { |
|
2040 return this.implFilter == scopeFilter && |
2036 return this.implFilter == scopeFilter && |
2041 this.checkResult == checkResult && |
2037 this.checkResult == checkResult; |
2042 this.scopeCounter.val() >= scopeCounter.val(); |
2038 } |
2043 } |
2039 } |
2044 } |
2040 |
2045 |
2041 MethodSymbol get(MethodSymbol ms, TypeSymbol origin, boolean checkResult, Filter<Symbol> implFilter) { |
2046 MethodSymbol get(MethodSymbol ms, TypeSymbol origin, boolean checkResult, Filter<Symbol> implFilter, Scope.ScopeCounter scopeCounter) { |
|
2047 SoftReference<Map<TypeSymbol, Entry>> ref_cache = _map.get(ms); |
2042 SoftReference<Map<TypeSymbol, Entry>> ref_cache = _map.get(ms); |
2048 Map<TypeSymbol, Entry> cache = ref_cache != null ? ref_cache.get() : null; |
2043 Map<TypeSymbol, Entry> cache = ref_cache != null ? ref_cache.get() : null; |
2049 if (cache == null) { |
2044 if (cache == null) { |
2050 cache = new HashMap<TypeSymbol, Entry>(); |
2045 cache = new HashMap<TypeSymbol, Entry>(); |
2051 _map.put(ms, new SoftReference<Map<TypeSymbol, Entry>>(cache)); |
2046 _map.put(ms, new SoftReference<Map<TypeSymbol, Entry>>(cache)); |
2052 } |
2047 } |
2053 Entry e = cache.get(origin); |
2048 Entry e = cache.get(origin); |
2054 if (e == null || |
2049 if (e == null || |
2055 !e.matches(implFilter, checkResult, scopeCounter)) { |
2050 !e.matches(implFilter, checkResult)) { |
2056 MethodSymbol impl = implementationInternal(ms, origin, Types.this, checkResult, implFilter); |
2051 MethodSymbol impl = implementationInternal(ms, origin, Types.this, checkResult, implFilter); |
2057 cache.put(origin, new Entry(impl, implFilter, checkResult, scopeCounter)); |
2052 cache.put(origin, new Entry(impl, implFilter, checkResult)); |
2058 return impl; |
2053 return impl; |
2059 } |
2054 } |
2060 else { |
2055 else { |
2061 return e.cachedImpl; |
2056 return e.cachedImpl; |
2062 } |
2057 } |
2079 } |
2074 } |
2080 } |
2075 } |
2081 |
2076 |
2082 private ImplementationCache implCache = new ImplementationCache(); |
2077 private ImplementationCache implCache = new ImplementationCache(); |
2083 |
2078 |
2084 public MethodSymbol implementation(MethodSymbol ms, TypeSymbol origin, Types types, boolean checkResult, Filter<Symbol> implFilter) { |
2079 public MethodSymbol implementation(MethodSymbol ms, TypeSymbol origin, boolean checkResult, Filter<Symbol> implFilter) { |
2085 return implCache.get(ms, origin, checkResult, implFilter, scopeCounter); |
2080 return implCache.get(ms, origin, checkResult, implFilter); |
2086 } |
2081 } |
|
2082 // </editor-fold> |
|
2083 |
|
2084 // <editor-fold defaultstate="collapsed" desc="compute transitive closure of all members in given site"> |
|
2085 public Scope membersClosure(Type site) { |
|
2086 return membersClosure.visit(site); |
|
2087 } |
|
2088 |
|
2089 UnaryVisitor<Scope> membersClosure = new UnaryVisitor<Scope>() { |
|
2090 |
|
2091 public Scope visitType(Type t, Void s) { |
|
2092 return null; |
|
2093 } |
|
2094 |
|
2095 @Override |
|
2096 public Scope visitClassType(ClassType t, Void s) { |
|
2097 ClassSymbol csym = (ClassSymbol)t.tsym; |
|
2098 if (csym.membersClosure == null) { |
|
2099 Scope membersClosure = new Scope(csym); |
|
2100 for (Type i : interfaces(t)) { |
|
2101 enterAll(visit(i), membersClosure); |
|
2102 } |
|
2103 enterAll(visit(supertype(t)), membersClosure); |
|
2104 enterAll(csym.members(), membersClosure); |
|
2105 csym.membersClosure = membersClosure; |
|
2106 } |
|
2107 return csym.membersClosure; |
|
2108 } |
|
2109 |
|
2110 @Override |
|
2111 public Scope visitTypeVar(TypeVar t, Void s) { |
|
2112 return visit(t.getUpperBound()); |
|
2113 } |
|
2114 |
|
2115 public void enterAll(Scope s, Scope to) { |
|
2116 if (s == null) return; |
|
2117 List<Symbol> syms = List.nil(); |
|
2118 for (Scope.Entry e = s.elems ; e != null ; e = e.sibling) { |
|
2119 syms = syms.prepend(e.sym); |
|
2120 } |
|
2121 for (Symbol sym : syms) { |
|
2122 to.enter(sym); |
|
2123 } |
|
2124 } |
|
2125 }; |
2087 // </editor-fold> |
2126 // </editor-fold> |
2088 |
2127 |
2089 /** |
2128 /** |
2090 * Does t have the same arguments as s? It is assumed that both |
2129 * Does t have the same arguments as s? It is assumed that both |
2091 * types are (possibly polymorphic) method types. Monomorphic |
2130 * types are (possibly polymorphic) method types. Monomorphic |