7118412: Shadowing of type-variables vs. member types
authoremc
Wed, 21 Aug 2013 20:23:36 -0400
changeset 19652 1186c404a994
parent 19651 b1aa46cc2198
child 19653 e49999626675
7118412: Shadowing of type-variables vs. member types 4987840: What is the scope of an annotation? Summary: Fixed issue with shadowing of type names. Reviewed-by: jjg, abuckley, mcimadamore
langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Wed Aug 21 16:13:50 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Wed Aug 21 20:23:36 2013 -0400
@@ -1859,7 +1859,10 @@
         }
     }
 
-    /** Find qualified member type.
+
+    /**
+     * Find a type declared in a scope (not inherited).  Return null
+     * if none is found.
      *  @param env       The current environment.
      *  @param site      The original type from where the selection takes
      *                   place.
@@ -1868,12 +1871,10 @@
      *                   always a superclass or implemented interface of
      *                   site's class.
      */
-    Symbol findMemberType(Env<AttrContext> env,
-                          Type site,
-                          Name name,
-                          TypeSymbol c) {
-        Symbol bestSoFar = typeNotFound;
-        Symbol sym;
+    Symbol findImmediateMemberType(Env<AttrContext> env,
+                                   Type site,
+                                   Name name,
+                                   TypeSymbol c) {
         Scope.Entry e = c.members().lookup(name);
         while (e.scope != null) {
             if (e.sym.kind == TYP) {
@@ -1883,6 +1884,24 @@
             }
             e = e.next();
         }
+        return typeNotFound;
+    }
+
+    /** Find a member type inherited from a superclass or interface.
+     *  @param env       The current environment.
+     *  @param site      The original type from where the selection takes
+     *                   place.
+     *  @param name      The type's name.
+     *  @param c         The class to search for the member type. This is
+     *                   always a superclass or implemented interface of
+     *                   site's class.
+     */
+    Symbol findInheritedMemberType(Env<AttrContext> env,
+                                   Type site,
+                                   Name name,
+                                   TypeSymbol c) {
+        Symbol bestSoFar = typeNotFound;
+        Symbol sym;
         Type st = types.supertype(c.type);
         if (st != null && st.hasTag(CLASS)) {
             sym = findMemberType(env, site, name, st.tsym);
@@ -1901,6 +1920,28 @@
         return bestSoFar;
     }
 
+    /** Find qualified member type.
+     *  @param env       The current environment.
+     *  @param site      The original type from where the selection takes
+     *                   place.
+     *  @param name      The type's name.
+     *  @param c         The class to search for the member type. This is
+     *                   always a superclass or implemented interface of
+     *                   site's class.
+     */
+    Symbol findMemberType(Env<AttrContext> env,
+                          Type site,
+                          Name name,
+                          TypeSymbol c) {
+        Symbol sym = findImmediateMemberType(env, site, name, c);
+
+        if (sym != typeNotFound)
+            return sym;
+
+        return findInheritedMemberType(env, site, name, c);
+
+    }
+
     /** Find a global type in given scope and load corresponding class.
      *  @param env       The current environment.
      *  @param scope     The scope in which to look for the type.
@@ -1919,6 +1960,21 @@
         return bestSoFar;
     }
 
+    Symbol findTypeVar(Env<AttrContext> env, Name name, boolean staticOnly) {
+        for (Scope.Entry e = env.info.scope.lookup(name);
+             e.scope != null;
+             e = e.next()) {
+            if (e.sym.kind == TYP) {
+                if (staticOnly &&
+                    e.sym.type.hasTag(TYPEVAR) &&
+                    e.sym.owner.kind == TYP)
+                    return new StaticError(e.sym);
+                return e.sym;
+            }
+        }
+        return typeNotFound;
+    }
+
     /** Find an unqualified type symbol.
      *  @param env       The current environment.
      *  @param name      The type's name.
@@ -1929,19 +1985,26 @@
         boolean staticOnly = false;
         for (Env<AttrContext> env1 = env; env1.outer != null; env1 = env1.outer) {
             if (isStatic(env1)) staticOnly = true;
-            for (Scope.Entry e = env1.info.scope.lookup(name);
-                 e.scope != null;
-                 e = e.next()) {
-                if (e.sym.kind == TYP) {
-                    if (staticOnly &&
-                        e.sym.type.hasTag(TYPEVAR) &&
-                        e.sym.owner.kind == TYP) return new StaticError(e.sym);
-                    return e.sym;
-                }
+            // First, look for a type variable and the first member type
+            final Symbol tyvar = findTypeVar(env1, name, staticOnly);
+            sym = findImmediateMemberType(env1, env1.enclClass.sym.type,
+                                          name, env1.enclClass.sym);
+
+            // Return the type variable if we have it, and have no
+            // immediate member, OR the type variable is for a method.
+            if (tyvar != typeNotFound) {
+                if (sym == typeNotFound ||
+                    (tyvar.kind == TYP && tyvar.exists() &&
+                     tyvar.owner.kind == MTH))
+                    return tyvar;
             }
 
-            sym = findMemberType(env1, env1.enclClass.sym.type, name,
-                                 env1.enclClass.sym);
+            // If the environment is a class def, finish up,
+            // otherwise, do the entire findMemberType
+            if (sym == typeNotFound)
+                sym = findInheritedMemberType(env1, env1.enclClass.sym.type,
+                                              name, env1.enclClass.sym);
+
             if (staticOnly && sym.kind == TYP &&
                 sym.type.hasTag(CLASS) &&
                 sym.type.getEnclosingType().hasTag(CLASS) &&