langtools/src/share/classes/com/sun/tools/javac/code/Types.java
changeset 8242 3873b4aaf4a8
parent 8230 b761a23e78d8
child 8427 703181b01773
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java	Mon Feb 07 18:09:46 2011 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java	Mon Feb 07 18:10:13 2011 +0000
@@ -36,6 +36,7 @@
 import com.sun.tools.javac.code.Lint.LintCategory;
 import com.sun.tools.javac.comp.Check;
 
+import static com.sun.tools.javac.code.Scope.*;
 import static com.sun.tools.javac.code.Type.*;
 import static com.sun.tools.javac.code.TypeTags.*;
 import static com.sun.tools.javac.code.Symbol.*;
@@ -70,7 +71,6 @@
         new Context.Key<Types>();
 
     final Symtab syms;
-    final Scope.ScopeCounter scopeCounter;
     final JavacMessages messages;
     final Names names;
     final boolean allowBoxing;
@@ -91,7 +91,6 @@
     protected Types(Context context) {
         context.put(typesKey, this);
         syms = Symtab.instance(context);
-        scopeCounter = Scope.ScopeCounter.instance(context);
         names = Names.instance(context);
         allowBoxing = Source.instance(context).allowBoxing();
         reader = ClassReader.instance(context);
@@ -2024,26 +2023,22 @@
             final MethodSymbol cachedImpl;
             final Filter<Symbol> implFilter;
             final boolean checkResult;
-            final Scope.ScopeCounter scopeCounter;
 
             public Entry(MethodSymbol cachedImpl,
                     Filter<Symbol> scopeFilter,
-                    boolean checkResult,
-                    Scope.ScopeCounter scopeCounter) {
+                    boolean checkResult) {
                 this.cachedImpl = cachedImpl;
                 this.implFilter = scopeFilter;
                 this.checkResult = checkResult;
-                this.scopeCounter = scopeCounter;
             }
 
-            boolean matches(Filter<Symbol> scopeFilter, boolean checkResult, Scope.ScopeCounter scopeCounter) {
+            boolean matches(Filter<Symbol> scopeFilter, boolean checkResult) {
                 return this.implFilter == scopeFilter &&
-                        this.checkResult == checkResult &&
-                        this.scopeCounter.val() >= scopeCounter.val();
+                        this.checkResult == checkResult;
             }
         }
 
-        MethodSymbol get(MethodSymbol ms, TypeSymbol origin, boolean checkResult, Filter<Symbol> implFilter, Scope.ScopeCounter scopeCounter) {
+        MethodSymbol get(MethodSymbol ms, TypeSymbol origin, boolean checkResult, Filter<Symbol> implFilter) {
             SoftReference<Map<TypeSymbol, Entry>> ref_cache = _map.get(ms);
             Map<TypeSymbol, Entry> cache = ref_cache != null ? ref_cache.get() : null;
             if (cache == null) {
@@ -2052,9 +2047,9 @@
             }
             Entry e = cache.get(origin);
             if (e == null ||
-                    !e.matches(implFilter, checkResult, scopeCounter)) {
+                    !e.matches(implFilter, checkResult)) {
                 MethodSymbol impl = implementationInternal(ms, origin, Types.this, checkResult, implFilter);
-                cache.put(origin, new Entry(impl, implFilter, checkResult, scopeCounter));
+                cache.put(origin, new Entry(impl, implFilter, checkResult));
                 return impl;
             }
             else {
@@ -2081,9 +2076,53 @@
 
     private ImplementationCache implCache = new ImplementationCache();
 
-    public MethodSymbol implementation(MethodSymbol ms, TypeSymbol origin, Types types, boolean checkResult, Filter<Symbol> implFilter) {
-        return implCache.get(ms, origin, checkResult, implFilter, scopeCounter);
+    public MethodSymbol implementation(MethodSymbol ms, TypeSymbol origin, boolean checkResult, Filter<Symbol> implFilter) {
+        return implCache.get(ms, origin, checkResult, implFilter);
+    }
+    // </editor-fold>
+
+    // <editor-fold defaultstate="collapsed" desc="compute transitive closure of all members in given site">
+    public Scope membersClosure(Type site) {
+        return membersClosure.visit(site);
     }
+
+    UnaryVisitor<Scope> membersClosure = new UnaryVisitor<Scope>() {
+
+        public Scope visitType(Type t, Void s) {
+            return null;
+        }
+
+        @Override
+        public Scope visitClassType(ClassType t, Void s) {
+            ClassSymbol csym = (ClassSymbol)t.tsym;
+            if (csym.membersClosure == null) {
+                Scope membersClosure = new Scope(csym);
+                for (Type i : interfaces(t)) {
+                    enterAll(visit(i), membersClosure);
+                }
+                enterAll(visit(supertype(t)), membersClosure);
+                enterAll(csym.members(), membersClosure);
+                csym.membersClosure = membersClosure;
+            }
+            return csym.membersClosure;
+        }
+
+        @Override
+        public Scope visitTypeVar(TypeVar t, Void s) {
+            return visit(t.getUpperBound());
+        }
+
+        public void enterAll(Scope s, Scope to) {
+            if (s == null) return;
+            List<Symbol> syms = List.nil();
+            for (Scope.Entry e = s.elems ; e != null ; e = e.sibling) {
+                syms = syms.prepend(e.sym);
+            }
+            for (Symbol sym : syms) {
+                to.enter(sym);
+            }
+        }
+    };
     // </editor-fold>
 
     /**