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
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Scope.java Sat Aug 10 16:29:26 2013 +0100
+++ b/langtools/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/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java Sat Aug 10 16:29:26 2013 +0100
+++ b/langtools/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/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java Sat Aug 10 16:29:26 2013 +0100
+++ b/langtools/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/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java Sat Aug 10 16:29:26 2013 +0100
+++ b/langtools/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/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java Sat Aug 10 16:29:26 2013 +0100
+++ b/langtools/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/langtools/test/tools/javac/4980495/static/Test.out Sat Aug 10 16:29:26 2013 +0100
+++ b/langtools/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/langtools/test/tools/javac/diags/examples/AlreadyDefinedStaticImport/AlreadDefinedStaticImport.java Sat Aug 10 16:29:26 2013 +0100
+++ b/langtools/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/langtools/test/tools/javac/diags/examples/AlreadyDefinedStaticImport/p/E1.java Sat Aug 10 16:29:26 2013 +0100
+++ b/langtools/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/langtools/test/tools/javac/diags/examples/AlreadyDefinedStaticImport/p/E2.java Sat Aug 10 16:29:26 2013 +0100
+++ b/langtools/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/langtools/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/langtools/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