8293348: A false cyclic inheritance error reported
Reviewed-by: vromero
This commit is contained in:
parent
85ec1f8d02
commit
c0ee30a25a
@ -497,6 +497,7 @@ public class Enter extends JCTree.Visitor {
|
||||
c.flags_field = chk.checkFlags(tree.pos(), tree.mods.flags, c, tree) | FROM_SOURCE;
|
||||
c.classfile = c.sourcefile = env.toplevel.sourcefile;
|
||||
c.members_field = WriteableScope.create(c);
|
||||
c.isPermittedExplicit = tree.permitting.nonEmpty();
|
||||
c.clearAnnotationMetadata();
|
||||
|
||||
ClassType ct = (ClassType)c.type;
|
||||
|
@ -728,14 +728,6 @@ public class TypeEnter implements Completer {
|
||||
}
|
||||
}
|
||||
|
||||
// Determine permits.
|
||||
ListBuffer<Symbol> permittedSubtypeSymbols = new ListBuffer<>();
|
||||
List<JCExpression> permittedTrees = tree.permitting;
|
||||
for (JCExpression permitted : permittedTrees) {
|
||||
Type pt = attr.attribBase(permitted, baseEnv, false, false, false);
|
||||
permittedSubtypeSymbols.append(pt.tsym);
|
||||
}
|
||||
|
||||
if ((sym.flags_field & ANNOTATION) != 0) {
|
||||
ct.interfaces_field = List.of(syms.annotationType);
|
||||
ct.all_interfaces_field = ct.interfaces_field;
|
||||
@ -744,15 +736,6 @@ public class TypeEnter implements Completer {
|
||||
ct.all_interfaces_field = (all_interfaces == null)
|
||||
? ct.interfaces_field : all_interfaces.toList();
|
||||
}
|
||||
|
||||
/* it could be that there are already some symbols in the permitted list, for the case
|
||||
* where there are subtypes in the same compilation unit but the permits list is empty
|
||||
* so don't overwrite the permitted list if it is not empty
|
||||
*/
|
||||
if (!permittedSubtypeSymbols.isEmpty()) {
|
||||
sym.permitted = permittedSubtypeSymbols.toList();
|
||||
}
|
||||
sym.isPermittedExplicit = !permittedSubtypeSymbols.isEmpty();
|
||||
}
|
||||
//where:
|
||||
protected JCExpression clearTypeParams(JCExpression superType) {
|
||||
@ -763,7 +746,7 @@ public class TypeEnter implements Completer {
|
||||
private final class HierarchyPhase extends AbstractHeaderPhase implements Completer {
|
||||
|
||||
public HierarchyPhase() {
|
||||
super(CompletionCause.HIERARCHY_PHASE, new PermitsPhase());
|
||||
super(CompletionCause.HIERARCHY_PHASE, new HeaderPhase());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -837,33 +820,6 @@ public class TypeEnter implements Completer {
|
||||
|
||||
}
|
||||
|
||||
private final class PermitsPhase extends AbstractHeaderPhase {
|
||||
|
||||
public PermitsPhase() {
|
||||
super(CompletionCause.HIERARCHY_PHASE, new HeaderPhase());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void runPhase(Env<AttrContext> env) {
|
||||
JCClassDecl tree = env.enclClass;
|
||||
if (!tree.sym.isAnonymous() || tree.sym.isEnum()) {
|
||||
for (Type supertype : types.directSupertypes(tree.sym.type)) {
|
||||
if (supertype.tsym.kind == TYP) {
|
||||
ClassSymbol supClass = (ClassSymbol) supertype.tsym;
|
||||
Env<AttrContext> supClassEnv = enter.getEnv(supClass);
|
||||
if (supClass.isSealed() &&
|
||||
!supClass.isPermittedExplicit &&
|
||||
supClassEnv != null &&
|
||||
supClassEnv.toplevel == env.toplevel) {
|
||||
supClass.permitted = supClass.permitted.append(tree.sym);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private final class HeaderPhase extends AbstractHeaderPhase {
|
||||
|
||||
public HeaderPhase() {
|
||||
@ -887,6 +843,8 @@ public class TypeEnter implements Completer {
|
||||
|
||||
attribSuperTypes(env, baseEnv);
|
||||
|
||||
fillPermits(tree, baseEnv);
|
||||
|
||||
Set<Type> interfaceSet = new HashSet<>();
|
||||
|
||||
for (JCExpression iface : tree.implementing) {
|
||||
@ -915,6 +873,36 @@ public class TypeEnter implements Completer {
|
||||
sym.flags_field |= AUXILIARY;
|
||||
}
|
||||
}
|
||||
|
||||
private void fillPermits(JCClassDecl tree, Env<AttrContext> baseEnv) {
|
||||
ClassSymbol sym = tree.sym;
|
||||
|
||||
//fill in implicit permits in supertypes:
|
||||
if (!sym.isAnonymous() || sym.isEnum()) {
|
||||
for (Type supertype : types.directSupertypes(sym.type)) {
|
||||
if (supertype.tsym.kind == TYP) {
|
||||
ClassSymbol supClass = (ClassSymbol) supertype.tsym;
|
||||
Env<AttrContext> supClassEnv = enter.getEnv(supClass);
|
||||
if (supClass.isSealed() &&
|
||||
!supClass.isPermittedExplicit &&
|
||||
supClassEnv != null &&
|
||||
supClassEnv.toplevel == baseEnv.toplevel) {
|
||||
supClass.permitted = supClass.permitted.append(sym);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// attribute (explicit) permits of the current class:
|
||||
if (sym.isPermittedExplicit) {
|
||||
ListBuffer<Symbol> permittedSubtypeSymbols = new ListBuffer<>();
|
||||
List<JCExpression> permittedTrees = tree.permitting;
|
||||
for (JCExpression permitted : permittedTrees) {
|
||||
Type pt = attr.attribBase(permitted, baseEnv, false, false, false);
|
||||
permittedSubtypeSymbols.append(pt.tsym);
|
||||
}
|
||||
sym.permitted = permittedSubtypeSymbols.toList();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private abstract class AbstractMembersPhase extends Phase {
|
||||
|
@ -22,7 +22,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test 8247352
|
||||
* @test 8247352 8293348
|
||||
* @summary test different configurations of sealed classes, same compilation unit, diff pkg or mdl, etc
|
||||
* @library /tools/lib
|
||||
* @modules jdk.compiler/com.sun.tools.javac.api
|
||||
@ -662,4 +662,35 @@ public class SealedDiffConfigurationsTest extends TestRunner {
|
||||
.writeAll()
|
||||
.getOutputLines(OutputKind.DIRECT);
|
||||
}
|
||||
|
||||
@Test //JDK-8293348
|
||||
public void testSupertypePermitsLoop(Path base) throws Exception {
|
||||
Path src = base.resolve("src");
|
||||
|
||||
tb.writeJavaFiles(src,
|
||||
"class Main implements T2 {}",
|
||||
"non-sealed interface T2 extends T {}",
|
||||
"sealed interface T permits T2 {}");
|
||||
|
||||
Path out = base.resolve("out");
|
||||
|
||||
Files.createDirectories(out);
|
||||
|
||||
new JavacTask(tb)
|
||||
.outdir(out)
|
||||
.files(findJavaFiles(src))
|
||||
.run()
|
||||
.writeAll();
|
||||
|
||||
Files.delete(out.resolve("Main.class"));
|
||||
Files.delete(out.resolve("T.class"));
|
||||
|
||||
new JavacTask(tb)
|
||||
.outdir(out)
|
||||
.options("-cp", out.toString(),
|
||||
"-sourcepath", src.toString())
|
||||
.files(src.resolve("Main.java"))
|
||||
.run()
|
||||
.writeAll();
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user