87 } |
88 } |
88 |
89 |
89 protected Types(Context context) { |
90 protected Types(Context context) { |
90 context.put(typesKey, this); |
91 context.put(typesKey, this); |
91 syms = Symtab.instance(context); |
92 syms = Symtab.instance(context); |
|
93 scopeCounter = Scope.ScopeCounter.instance(context); |
92 names = Names.instance(context); |
94 names = Names.instance(context); |
93 allowBoxing = Source.instance(context).allowBoxing(); |
95 allowBoxing = Source.instance(context).allowBoxing(); |
94 reader = ClassReader.instance(context); |
96 reader = ClassReader.instance(context); |
95 source = Source.instance(context); |
97 source = Source.instance(context); |
96 chk = Check.instance(context); |
98 chk = Check.instance(context); |
1982 |
1984 |
1983 class Entry { |
1985 class Entry { |
1984 final MethodSymbol cachedImpl; |
1986 final MethodSymbol cachedImpl; |
1985 final Filter<Symbol> implFilter; |
1987 final Filter<Symbol> implFilter; |
1986 final boolean checkResult; |
1988 final boolean checkResult; |
|
1989 final Scope.ScopeCounter scopeCounter; |
1987 |
1990 |
1988 public Entry(MethodSymbol cachedImpl, |
1991 public Entry(MethodSymbol cachedImpl, |
1989 Filter<Symbol> scopeFilter, |
1992 Filter<Symbol> scopeFilter, |
1990 boolean checkResult) { |
1993 boolean checkResult, |
|
1994 Scope.ScopeCounter scopeCounter) { |
1991 this.cachedImpl = cachedImpl; |
1995 this.cachedImpl = cachedImpl; |
1992 this.implFilter = scopeFilter; |
1996 this.implFilter = scopeFilter; |
1993 this.checkResult = checkResult; |
1997 this.checkResult = checkResult; |
1994 } |
1998 this.scopeCounter = scopeCounter; |
1995 |
1999 } |
1996 boolean matches(Filter<Symbol> scopeFilter, boolean checkResult) { |
2000 |
|
2001 boolean matches(Filter<Symbol> scopeFilter, boolean checkResult, Scope.ScopeCounter scopeCounter) { |
1997 return this.implFilter == scopeFilter && |
2002 return this.implFilter == scopeFilter && |
1998 this.checkResult == checkResult; |
2003 this.checkResult == checkResult && |
1999 } |
2004 this.scopeCounter.val() >= scopeCounter.val(); |
2000 } |
2005 } |
2001 |
2006 } |
2002 MethodSymbol get(MethodSymbol ms, TypeSymbol origin, boolean checkResult, Filter<Symbol> implFilter) { |
2007 |
|
2008 MethodSymbol get(MethodSymbol ms, TypeSymbol origin, boolean checkResult, Filter<Symbol> implFilter, Scope.ScopeCounter scopeCounter) { |
2003 SoftReference<Map<TypeSymbol, Entry>> ref_cache = _map.get(ms); |
2009 SoftReference<Map<TypeSymbol, Entry>> ref_cache = _map.get(ms); |
2004 Map<TypeSymbol, Entry> cache = ref_cache != null ? ref_cache.get() : null; |
2010 Map<TypeSymbol, Entry> cache = ref_cache != null ? ref_cache.get() : null; |
2005 if (cache == null) { |
2011 if (cache == null) { |
2006 cache = new HashMap<TypeSymbol, Entry>(); |
2012 cache = new HashMap<TypeSymbol, Entry>(); |
2007 _map.put(ms, new SoftReference<Map<TypeSymbol, Entry>>(cache)); |
2013 _map.put(ms, new SoftReference<Map<TypeSymbol, Entry>>(cache)); |
2008 } |
2014 } |
2009 Entry e = cache.get(origin); |
2015 Entry e = cache.get(origin); |
2010 if (e == null || |
2016 if (e == null || |
2011 !e.matches(implFilter, checkResult)) { |
2017 !e.matches(implFilter, checkResult, scopeCounter)) { |
2012 MethodSymbol impl = implementationInternal(ms, origin, Types.this, checkResult, implFilter); |
2018 MethodSymbol impl = implementationInternal(ms, origin, Types.this, checkResult, implFilter); |
2013 cache.put(origin, new Entry(impl, implFilter, checkResult)); |
2019 cache.put(origin, new Entry(impl, implFilter, checkResult, scopeCounter)); |
2014 return impl; |
2020 return impl; |
2015 } |
2021 } |
2016 else { |
2022 else { |
2017 return e.cachedImpl; |
2023 return e.cachedImpl; |
2018 } |
2024 } |
2036 } |
2042 } |
2037 |
2043 |
2038 private ImplementationCache implCache = new ImplementationCache(); |
2044 private ImplementationCache implCache = new ImplementationCache(); |
2039 |
2045 |
2040 public MethodSymbol implementation(MethodSymbol ms, TypeSymbol origin, Types types, boolean checkResult, Filter<Symbol> implFilter) { |
2046 public MethodSymbol implementation(MethodSymbol ms, TypeSymbol origin, Types types, boolean checkResult, Filter<Symbol> implFilter) { |
2041 return implCache.get(ms, origin, checkResult, implFilter); |
2047 return implCache.get(ms, origin, checkResult, implFilter, scopeCounter); |
2042 } |
2048 } |
2043 // </editor-fold> |
2049 // </editor-fold> |
2044 |
2050 |
2045 /** |
2051 /** |
2046 * Does t have the same arguments as s? It is assumed that both |
2052 * Does t have the same arguments as s? It is assumed that both |