changeset 1944:f7f271bd74a2

6537020: JCK tests: a compile-time error should be given in case of ambiguously imported fields (types, methods) Summary: Hiding check does not support interface multiple inheritance Reviewed-by: jjg
author mcimadamore
date Mon, 12 Aug 2013 17:25:07 +0100
parents aa6c6f8b5622
children af80273f630a
files src/share/classes/com/sun/tools/javac/code/Scope.java src/share/classes/com/sun/tools/javac/code/Symbol.java src/share/classes/com/sun/tools/javac/comp/Check.java src/share/classes/com/sun/tools/javac/comp/MemberEnter.java src/share/classes/com/sun/tools/javac/comp/Resolve.java test/tools/javac/4980495/static/Test.out test/tools/javac/diags/examples/AlreadyDefinedStaticImport/AlreadDefinedStaticImport.java test/tools/javac/diags/examples/AlreadyDefinedStaticImport/p/E1.java test/tools/javac/diags/examples/AlreadyDefinedStaticImport/p/E2.java test/tools/javac/staticImport/6537020/T6537020.java test/tools/javac/staticImport/6537020/T6537020.out
diffstat 11 files changed, 106 insertions(+), 71 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/com/sun/tools/javac/code/Scope.java	Sat Aug 10 16:29:26 2013 +0100
+++ b/src/share/classes/com/sun/tools/javac/code/Scope.java	Mon Aug 12 17:25:07 2013 +0100
@@ -199,7 +199,7 @@
     }
 
     public void enter(Symbol sym, Scope s) {
-        enter(sym, s, s);
+        enter(sym, s, s, false);
     }
 
     /**
@@ -207,7 +207,7 @@
      * given scope `s' accessed through `origin'.  The last two
      * arguments are only used in import scopes.
      */
-    public void enter(Symbol sym, Scope s, Scope origin) {
+    public void enter(Symbol sym, Scope s, Scope origin, boolean staticallyImported) {
         Assert.check(shared == 0);
         if (nelems * 3 >= hashMask * 2)
             dble();
@@ -217,7 +217,7 @@
             old = sentinel;
             nelems++;
         }
-        Entry e = makeEntry(sym, old, elems, s, origin);
+        Entry e = makeEntry(sym, old, elems, s, origin, staticallyImported);
         table[hash] = e;
         elems = e;
 
@@ -227,7 +227,7 @@
         }
     }
 
-    Entry makeEntry(Symbol sym, Entry shadowed, Entry sibling, Scope scope, Scope origin) {
+    Entry makeEntry(Symbol sym, Entry shadowed, Entry sibling, Scope scope, Scope origin, boolean staticallyImported) {
         return new Entry(sym, shadowed, sibling, scope);
     }
 
@@ -499,6 +499,10 @@
             else return shadowed.next(sf);
         }
 
+        public boolean isStaticallyImported() {
+            return false;
+        }
+
         public Scope getOrigin() {
             // The origin is only recorded for import scopes.  For all
             // other scope entries, the "enclosing" type is available
@@ -517,20 +521,19 @@
         }
 
         @Override
-        Entry makeEntry(Symbol sym, Entry shadowed, Entry sibling, Scope scope, Scope origin) {
-            return new ImportEntry(sym, shadowed, sibling, scope, origin);
-        }
-
-        static class ImportEntry extends Entry {
-            private Scope origin;
+        Entry makeEntry(Symbol sym, Entry shadowed, Entry sibling, Scope scope,
+                final Scope origin, final boolean staticallyImported) {
+            return new Entry(sym, shadowed, sibling, scope) {
+                @Override
+                public Scope getOrigin() {
+                    return origin;
+                }
 
-            ImportEntry(Symbol sym, Entry shadowed, Entry sibling, Scope scope, Scope origin) {
-                super(sym, shadowed, sibling, scope);
-                this.origin = origin;
-            }
-
-            @Override
-            public Scope getOrigin() { return origin; }
+                @Override
+                public boolean isStaticallyImported() {
+                    return staticallyImported;
+                }
+            };
         }
     }
 
@@ -724,7 +727,7 @@
         }
 
         @Override
-        public void enter(Symbol sym, Scope s, Scope origin) {
+        public void enter(Symbol sym, Scope s, Scope origin, boolean staticallyImported) {
             throw new UnsupportedOperationException();
         }
 
--- a/src/share/classes/com/sun/tools/javac/code/Symbol.java	Sat Aug 10 16:29:26 2013 +0100
+++ b/src/share/classes/com/sun/tools/javac/code/Symbol.java	Mon Aug 12 17:25:07 2013 +0100
@@ -463,26 +463,34 @@
         return false;
     }
 
-    /** Check for hiding.  Note that this doesn't handle multiple
-     *  (interface) inheritance. */
     private boolean hiddenIn(ClassSymbol clazz, Types types) {
-        if (kind == MTH && (flags() & STATIC) == 0) return false;
-        while (true) {
-            if (owner == clazz) return false;
-            Scope.Entry e = clazz.members().lookup(name);
-            while (e.scope != null) {
-                if (e.sym == this) return false;
-                if (e.sym.kind == kind &&
+        Symbol sym = hiddenInInternal(clazz, types);
+        return sym != null && sym != this;
+    }
+
+    private Symbol hiddenInInternal(ClassSymbol c, Types types) {
+        Scope.Entry e = c.members().lookup(name);
+        while (e.scope != null) {
+            if (e.sym.kind == kind &&
                     (kind != MTH ||
-                     (e.sym.flags() & STATIC) != 0 &&
-                     types.isSubSignature(e.sym.type, type)))
-                    return true;
-                e = e.next();
+                    (e.sym.flags() & STATIC) != 0 &&
+                    types.isSubSignature(e.sym.type, type))) {
+                return e.sym;
             }
-            Type superType = types.supertype(clazz.type);
-            if (!superType.hasTag(CLASS)) return false;
-            clazz = (ClassSymbol)superType.tsym;
+            e = e.next();
         }
+        List<Symbol> hiddenSyms = List.nil();
+        for (Type st : types.interfaces(c.type).prepend(types.supertype(c.type))) {
+            if (st != null && (st.hasTag(CLASS))) {
+                Symbol sym = hiddenInInternal((ClassSymbol)st.tsym, types);
+                if (sym != null) {
+                    hiddenSyms = hiddenSyms.prepend(hiddenInInternal((ClassSymbol)st.tsym, types));
+                }
+            }
+        }
+        return hiddenSyms.contains(this) ?
+                this :
+                (hiddenSyms.isEmpty() ? null : hiddenSyms.head);
     }
 
     /** Is this symbol inherited into a given class?
--- a/src/share/classes/com/sun/tools/javac/comp/Check.java	Sat Aug 10 16:29:26 2013 +0100
+++ b/src/share/classes/com/sun/tools/javac/comp/Check.java	Mon Aug 12 17:25:07 2013 +0100
@@ -3329,14 +3329,15 @@
             boolean isClassDecl = e.scope == s;
             if ((isClassDecl || sym != e.sym) &&
                 sym.kind == e.sym.kind &&
-                sym.name != names.error) {
+                sym.name != names.error &&
+                (!staticImport || !e.isStaticallyImported())) {
                 if (!e.sym.type.isErroneous()) {
                     String what = e.sym.toString();
                     if (!isClassDecl) {
                         if (staticImport)
                             log.error(pos, "already.defined.static.single.import", what);
                         else
-                            log.error(pos, "already.defined.single.import", what);
+                        log.error(pos, "already.defined.single.import", what);
                     }
                     else if (sym != e.sym)
                         log.error(pos, "already.defined.this.unit", what);
--- a/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java	Sat Aug 10 16:29:26 2013 +0100
+++ b/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java	Mon Aug 12 17:25:07 2013 +0100
@@ -189,7 +189,7 @@
                         staticImportAccessible(sym, packge) &&
                         sym.isMemberOf(origin, types) &&
                         !toScope.includes(sym))
-                        toScope.enter(sym, fromScope, origin.members());
+                        toScope.enter(sym, fromScope, origin.members(), true);
                 }
             }
         }.importFrom(tsym);
@@ -217,7 +217,7 @@
                         staticImportAccessible(sym, packge) &&
                         !toScope.includes(sym) &&
                         sym.isMemberOf(origin, types)) {
-                        toScope.enter(sym, fromScope, origin.members());
+                        toScope.enter(sym, fromScope, origin.members(), true);
                     }
                 }
             }
@@ -283,7 +283,7 @@
                         staticImportAccessible(sym, packge) &&
                         sym.isMemberOf(origin, types) &&
                         chk.checkUniqueStaticImport(pos, sym, toScope))
-                        toScope.enter(sym, sym.owner.members(), origin.members());
+                        toScope.enter(sym, sym.owner.members(), origin.members(), true);
                 }
             }
         }.importFrom(tsym);
@@ -313,9 +313,9 @@
                         staticImportAccessible(sym, packge) &&
                         sym.isMemberOf(origin, types)) {
                         found = true;
-                        if (sym.kind == MTH ||
-                            sym.kind != TYP && chk.checkUniqueStaticImport(pos, sym, toScope))
-                            toScope.enter(sym, sym.owner.members(), origin.members());
+                        if (sym.kind != TYP) {
+                            toScope.enter(sym, sym.owner.members(), origin.members(), true);
+                        }
                     }
                 }
             }
--- a/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Sat Aug 10 16:29:26 2013 +0100
+++ b/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Mon Aug 12 17:25:07 2013 +0100
@@ -1344,32 +1344,23 @@
         if (bestSoFar.exists())
             return bestSoFar;
 
-        Scope.Entry e = env.toplevel.namedImportScope.lookup(name);
-        for (; e.scope != null; e = e.next()) {
-            sym = e.sym;
-            Type origin = e.getOrigin().owner.type;
-            if (sym.kind == VAR) {
-                if (e.sym.owner.type != origin)
-                    sym = sym.clone(e.getOrigin().owner);
-                return isAccessible(env, origin, sym)
-                    ? sym : new AccessError(env, origin, sym);
+        Symbol origin = null;
+        for (Scope sc : new Scope[] { env.toplevel.namedImportScope, env.toplevel.starImportScope }) {
+            Scope.Entry e = sc.lookup(name);
+            for (; e.scope != null; e = e.next()) {
+                sym = e.sym;
+                if (sym.kind != VAR)
+                    continue;
+                // invariant: sym.kind == VAR
+                if (bestSoFar.kind < AMBIGUOUS && sym.owner != bestSoFar.owner)
+                    return new AmbiguityError(bestSoFar, sym);
+                else if (bestSoFar.kind >= VAR) {
+                    origin = e.getOrigin().owner;
+                    bestSoFar = isAccessible(env, origin.type, sym)
+                        ? sym : new AccessError(env, origin.type, sym);
+                }
             }
-        }
-
-        Symbol origin = null;
-        e = env.toplevel.starImportScope.lookup(name);
-        for (; e.scope != null; e = e.next()) {
-            sym = e.sym;
-            if (sym.kind != VAR)
-                continue;
-            // invariant: sym.kind == VAR
-            if (bestSoFar.kind < AMBIGUOUS && sym.owner != bestSoFar.owner)
-                return new AmbiguityError(bestSoFar, sym);
-            else if (bestSoFar.kind >= VAR) {
-                origin = e.getOrigin().owner;
-                bestSoFar = isAccessible(env, origin.type, sym)
-                    ? sym : new AccessError(env, origin.type, sym);
-            }
+            if (bestSoFar.exists()) break;
         }
         if (bestSoFar.kind == VAR && bestSoFar.owner.type != origin.type)
             return bestSoFar.clone(origin);
--- a/test/tools/javac/4980495/static/Test.out	Sat Aug 10 16:29:26 2013 +0100
+++ b/test/tools/javac/4980495/static/Test.out	Mon Aug 12 17:25:07 2013 +0100
@@ -1,2 +1,2 @@
-Test.java:9:1: compiler.err.already.defined.static.single.import: f
+Test.java:15:9: compiler.err.ref.ambiguous: f, kindname.variable, f, p1.A1, kindname.variable, f, p2.A2
 1 error
--- a/test/tools/javac/diags/examples/AlreadyDefinedStaticImport/AlreadDefinedStaticImport.java	Sat Aug 10 16:29:26 2013 +0100
+++ b/test/tools/javac/diags/examples/AlreadyDefinedStaticImport/AlreadDefinedStaticImport.java	Mon Aug 12 17:25:07 2013 +0100
@@ -23,5 +23,5 @@
 
 // key: compiler.err.already.defined.static.single.import
 
-import static p.E1.A;
+import p.E1.A;
 import static p.E2.A;
--- a/test/tools/javac/diags/examples/AlreadyDefinedStaticImport/p/E1.java	Sat Aug 10 16:29:26 2013 +0100
+++ b/test/tools/javac/diags/examples/AlreadyDefinedStaticImport/p/E1.java	Mon Aug 12 17:25:07 2013 +0100
@@ -23,4 +23,6 @@
 
 package p;
 
-public enum E1 { A, B, C}
+public class E1 {
+    public static class A { }
+}
--- a/test/tools/javac/diags/examples/AlreadyDefinedStaticImport/p/E2.java	Sat Aug 10 16:29:26 2013 +0100
+++ b/test/tools/javac/diags/examples/AlreadyDefinedStaticImport/p/E2.java	Mon Aug 12 17:25:07 2013 +0100
@@ -23,4 +23,6 @@
 
 package p;
 
-public enum E2 { A, B, C }
+public class E2 {
+    public static class A { }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/staticImport/6537020/T6537020.java	Mon Aug 12 17:25:07 2013 +0100
@@ -0,0 +1,26 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 6537020
+ * @summary JCK tests: a compile-time error should be given in case of ambiguously imported fields (types, methods)
+ *
+ * @compile/fail/ref=T6537020.out -XDrawDiagnostics T6537020.java
+ */
+
+package p;
+
+import static p.T6537020.C.s;
+
+class T6537020 {
+
+    static class A {
+       static String s;
+    }
+
+    interface B {
+       String s = "";
+    }
+
+    static class C extends A implements B { }
+
+    Object o = s;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/staticImport/6537020/T6537020.out	Mon Aug 12 17:25:07 2013 +0100
@@ -0,0 +1,2 @@
+T6537020.java:25:16: compiler.err.ref.ambiguous: s, kindname.variable, s, p.T6537020.B, kindname.variable, s, p.T6537020.A
+1 error