mirror of
https://github.com/openjdk/jdk.git
synced 2026-05-05 19:25:41 +00:00
6537020: JCK tests: a compile-time error should be given in case of ambiguously imported fields (types, methods)
Hiding check does not support interface multiple inheritance Reviewed-by: jjg
This commit is contained in:
parent
190f9337b1
commit
4e85a5ae43
@ -199,7 +199,7 @@ public class Scope {
|
||||
}
|
||||
|
||||
public void enter(Symbol sym, Scope s) {
|
||||
enter(sym, s, s);
|
||||
enter(sym, s, s, false);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -207,7 +207,7 @@ public class Scope {
|
||||
* 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 @@ public class Scope {
|
||||
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 @@ public class Scope {
|
||||
}
|
||||
}
|
||||
|
||||
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 @@ public class Scope {
|
||||
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 @@ public class Scope {
|
||||
}
|
||||
|
||||
@Override
|
||||
Entry makeEntry(Symbol sym, Entry shadowed, Entry sibling, Scope scope, Scope origin) {
|
||||
return new ImportEntry(sym, shadowed, sibling, 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;
|
||||
}
|
||||
|
||||
static class ImportEntry extends Entry {
|
||||
private Scope 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 @@ public class Scope {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enter(Symbol sym, Scope s, Scope origin) {
|
||||
public void enter(Symbol sym, Scope s, Scope origin, boolean staticallyImported) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
||||
@ -463,26 +463,34 @@ public abstract class Symbol implements Element {
|
||||
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?
|
||||
|
||||
@ -3329,14 +3329,15 @@ public class Check {
|
||||
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);
|
||||
|
||||
@ -189,7 +189,7 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
|
||||
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 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
|
||||
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 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
|
||||
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 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1344,32 +1344,23 @@ public class Resolve {
|
||||
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;
|
||||
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);
|
||||
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);
|
||||
}
|
||||
}
|
||||
if (bestSoFar.exists()) break;
|
||||
}
|
||||
if (bestSoFar.kind == VAR && bestSoFar.owner.type != origin.type)
|
||||
return bestSoFar.clone(origin);
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -23,4 +23,6 @@
|
||||
|
||||
package p;
|
||||
|
||||
public enum E1 { A, B, C}
|
||||
public class E1 {
|
||||
public static class A { }
|
||||
}
|
||||
|
||||
@ -23,4 +23,6 @@
|
||||
|
||||
package p;
|
||||
|
||||
public enum E2 { A, B, C }
|
||||
public class E2 {
|
||||
public static class A { }
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
@ -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
|
||||
Loading…
x
Reference in New Issue
Block a user