8247352: improve error messages for sealed classes and records
Reviewed-by: mcimadamore
This commit is contained in:
parent
3e81b3ad48
commit
4b3a0b789e
@ -1075,7 +1075,7 @@ public class Attr extends JCTree.Visitor {
|
||||
if (app == null ||
|
||||
TreeInfo.name(app.meth) != names._this ||
|
||||
!checkFirstConstructorStat(app, tree, false)) {
|
||||
log.error(tree, Errors.FirstStatementMustBeCallToAnotherConstructor);
|
||||
log.error(tree, Errors.FirstStatementMustBeCallToAnotherConstructor(env.enclClass.sym));
|
||||
}
|
||||
} else {
|
||||
// but if it is the canonical:
|
||||
@ -5052,7 +5052,7 @@ public class Attr extends JCTree.Visitor {
|
||||
Errors.InvalidPermitsClause(Fragments.IsATypeVariable(subTypeSym.type)));
|
||||
}
|
||||
if (subTypeSym.isAnonymous() && !c.isEnum()) {
|
||||
log.error(TreeInfo.diagnosticPositionFor(subTypeSym, env.tree), Errors.CantInheritFromSealed(c));
|
||||
log.error(TreeInfo.diagnosticPositionFor(subTypeSym, env.tree), Errors.LocalClassesCantExtendSealed(Fragments.Anonymous));
|
||||
}
|
||||
if (permittedTypes.contains(subTypeSym)) {
|
||||
DiagnosticPosition pos =
|
||||
@ -5065,10 +5065,14 @@ public class Attr extends JCTree.Visitor {
|
||||
}
|
||||
if (sealedInUnnamed) {
|
||||
if (subTypeSym.packge() != c.packge()) {
|
||||
log.error(TreeInfo.diagnosticPositionFor(subTypeSym, env.tree), Errors.CantInheritFromSealed(c));
|
||||
log.error(TreeInfo.diagnosticPositionFor(subTypeSym, env.tree),
|
||||
Errors.ClassInUnnamedModuleCantExtendSealedInDiffPackage(c)
|
||||
);
|
||||
}
|
||||
} else if (subTypeSym.packge().modle != c.packge().modle) {
|
||||
log.error(TreeInfo.diagnosticPositionFor(subTypeSym, env.tree), Errors.CantInheritFromSealed(c));
|
||||
log.error(TreeInfo.diagnosticPositionFor(subTypeSym, env.tree),
|
||||
Errors.ClassInModuleCantExtendSealedInDiffModule(c, c.packge().modle)
|
||||
);
|
||||
}
|
||||
if (subTypeSym == c.type.tsym || types.isSuperType(subTypeSym.type, c.type)) {
|
||||
log.error(TreeInfo.diagnosticPositionFor(subTypeSym, ((JCClassDecl)env.tree).permitting),
|
||||
@ -5107,7 +5111,7 @@ public class Attr extends JCTree.Visitor {
|
||||
}
|
||||
} else {
|
||||
if (c.isLocal() && !c.isEnum()) {
|
||||
log.error(TreeInfo.diagnosticPositionFor(c, env.tree), Errors.LocalClassesCantExtendSealed);
|
||||
log.error(TreeInfo.diagnosticPositionFor(c, env.tree), Errors.LocalClassesCantExtendSealed(c.isAnonymous() ? Fragments.Anonymous : Fragments.Local));
|
||||
}
|
||||
|
||||
for (ClassSymbol supertypeSym : sealedSupers) {
|
||||
|
@ -3489,7 +3489,16 @@ compiler.err.sealed.class.must.have.subclasses=\
|
||||
# errors in subclasses of sealed classes
|
||||
# 0: symbol
|
||||
compiler.err.cant.inherit.from.sealed=\
|
||||
class is not allowed to extend sealed class: {0}
|
||||
class is not allowed to extend sealed class: {0} \
|
||||
(as it is not listed in its 'permits' clause)
|
||||
|
||||
# 0: symbol
|
||||
compiler.err.class.in.unnamed.module.cant.extend.sealed.in.diff.package=\
|
||||
class {0} in unnamed module cannot extend a sealed class in a different package
|
||||
|
||||
# 0: symbol, 1: symbol
|
||||
compiler.err.class.in.module.cant.extend.sealed.in.diff.module=\
|
||||
class {0} in module {1} cannot extend a sealed class in a different module
|
||||
|
||||
# 0: symbol
|
||||
compiler.err.non.sealed.with.no.sealed.supertype=\
|
||||
@ -3505,8 +3514,15 @@ compiler.err.non.sealed.or.sealed.expected=\
|
||||
compiler.err.sealed.or.non.sealed.local.classes.not.allowed=\
|
||||
sealed or non-sealed local classes are not allowed
|
||||
|
||||
# 0: fragment
|
||||
compiler.err.local.classes.cant.extend.sealed=\
|
||||
local classes must not extend sealed classes
|
||||
{0} classes must not extend sealed classes\
|
||||
|
||||
compiler.misc.anonymous=\
|
||||
anonymous
|
||||
|
||||
compiler.misc.local=\
|
||||
local
|
||||
|
||||
###
|
||||
# errors related to records
|
||||
@ -3588,8 +3604,9 @@ compiler.err.record.cannot.declare.instance.fields=\
|
||||
compiler.err.invalid.supertype.record=\
|
||||
classes cannot directly extend {0}
|
||||
|
||||
# 0: symbol
|
||||
compiler.err.first.statement.must.be.call.to.another.constructor=\
|
||||
constructor is not canonical, so its first statement must invoke another constructor
|
||||
constructor is not canonical, so its first statement must invoke another constructor of class {0}
|
||||
|
||||
compiler.err.instance.initializer.not.allowed.in.records=\
|
||||
instance initializers not allowed in records
|
||||
|
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
// key: compiler.err.local.classes.cant.extend.sealed
|
||||
// key: compiler.err.sealed.class.must.have.subclasses
|
||||
// key: compiler.note.preview.filename
|
||||
// key: compiler.note.preview.recompile
|
||||
// key: compiler.misc.anonymous
|
||||
// options: --enable-preview -source ${jdk.version}
|
||||
|
||||
class Main {
|
||||
void m() {
|
||||
Shape shape = new Shape() {};
|
||||
}
|
||||
}
|
||||
|
||||
sealed interface Shape {}
|
||||
|
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
// key: compiler.err.class.in.module.cant.extend.sealed.in.diff.module
|
||||
// key: compiler.note.preview.filename
|
||||
// key: compiler.note.preview.recompile
|
||||
// options: --add-reads mSealed=mSub --enable-preview -source ${jdk.version}
|
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package a;
|
||||
|
||||
public sealed class Base permits b.Impl {}
|
@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
module mSealed { exports a; }
|
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package b;
|
||||
|
||||
public final class Impl extends a.Base {}
|
@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
module mSub { exports b; requires mSealed; }
|
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
// key: compiler.err.class.in.unnamed.module.cant.extend.sealed.in.diff.package
|
||||
// key: compiler.note.preview.filename
|
||||
// key: compiler.note.preview.recompile
|
||||
// options: --enable-preview -source ${jdk.version}
|
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package p1;
|
||||
|
||||
import p2.*;
|
||||
|
||||
public sealed class Sealed permits p2.Sub {}
|
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package p2;
|
||||
|
||||
import p1.*;
|
||||
|
||||
public final class Sub extends p1.Sealed {}
|
@ -25,6 +25,7 @@
|
||||
// key: compiler.err.sealed.class.must.have.subclasses
|
||||
// key: compiler.note.preview.filename
|
||||
// key: compiler.note.preview.recompile
|
||||
// key: compiler.misc.local
|
||||
// options: --enable-preview -source ${jdk.version}
|
||||
|
||||
sealed class C {
|
||||
@ -32,3 +33,4 @@ sealed class C {
|
||||
final class D extends C { }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,7 @@
|
||||
/**
|
||||
* RecordCompilationTests
|
||||
*
|
||||
* @test 8250629 8252307
|
||||
* @test 8250629 8252307 8247352
|
||||
* @summary Negative compilation tests, and positive compilation (smoke) tests for records
|
||||
* @library /lib/combo /tools/lib /tools/javac/lib
|
||||
* @modules
|
||||
@ -394,6 +394,9 @@ public class RecordCompilationTests extends CompilationTestCase {
|
||||
assertFail("compiler.err.first.statement.must.be.call.to.another.constructor",
|
||||
"record R(int x, int y) { public R(int y, int x, int z) { this.x = this.y = 0; } }");
|
||||
|
||||
assertFail("compiler.err.first.statement.must.be.call.to.another.constructor",
|
||||
"record R(int x, int y) { public R(int y, int x, int z) { super(); this.x = this.y = 0; } }");
|
||||
|
||||
assertOK("record R(int x, int y) { " +
|
||||
" public R(int x, int y, int z) { this(x, y); } " +
|
||||
"}");
|
||||
|
@ -22,7 +22,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @test 8247352
|
||||
* @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
|
||||
@ -373,7 +373,7 @@ public class SealedDiffConfigurationsTest extends TestRunner {
|
||||
tb.writeJavaFiles(sub1,
|
||||
"package pkg2;\n" +
|
||||
"import pkg1.*;\n" +
|
||||
"public class Sub1 extends pkg1.Sealed {\n" +
|
||||
"public final class Sub1 extends pkg1.Sealed {\n" +
|
||||
"}");
|
||||
|
||||
List<String> error = new JavacTask(tb)
|
||||
@ -384,9 +384,8 @@ public class SealedDiffConfigurationsTest extends TestRunner {
|
||||
.getOutputLines(OutputKind.DIRECT);
|
||||
|
||||
List<String> expected = List.of(
|
||||
"Sub1.java:3:8: compiler.err.non.sealed.sealed.or.final.expected",
|
||||
"Sealed.java:3:40: compiler.err.cant.inherit.from.sealed: pkg1.Sealed",
|
||||
"2 errors");
|
||||
"Sealed.java:3:40: compiler.err.class.in.unnamed.module.cant.extend.sealed.in.diff.package: pkg1.Sealed",
|
||||
"1 error");
|
||||
if (!error.containsAll(expected)) {
|
||||
throw new AssertionError("Expected output not found. Expected: " + expected);
|
||||
}
|
||||
@ -461,7 +460,7 @@ public class SealedDiffConfigurationsTest extends TestRunner {
|
||||
.getOutputLines(OutputKind.DIRECT);
|
||||
|
||||
List<String> expected = List.of(
|
||||
"Sealed.java:3:40: compiler.err.cant.inherit.from.sealed: pkg1.Sealed",
|
||||
"Sealed.java:3:40: compiler.err.class.in.unnamed.module.cant.extend.sealed.in.diff.package: pkg1.Sealed",
|
||||
"1 error");
|
||||
if (!error.containsAll(expected)) {
|
||||
throw new AssertionError("Expected output not found. Found: " + error);
|
||||
@ -601,9 +600,7 @@ public class SealedDiffConfigurationsTest extends TestRunner {
|
||||
.getOutputLines(OutputKind.DIRECT);
|
||||
|
||||
List<String> expected = List.of(
|
||||
"Base.java:1:46: compiler.err.cant.inherit.from.sealed: a.Base",
|
||||
"- compiler.note.preview.filename: Base.java",
|
||||
"- compiler.note.preview.recompile",
|
||||
"Base.java:1:46: compiler.err.class.in.module.cant.extend.sealed.in.diff.module: a.Base, mSealed",
|
||||
"1 error"
|
||||
);
|
||||
if (!error.containsAll(expected)) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user