8246353: Sealed types not supported by jshell
Reviewed-by: rfield, vromero
This commit is contained in:
parent
3943f9d0b7
commit
358714bcd0
@ -5091,7 +5091,12 @@ public class Attr extends JCTree.Visitor {
|
||||
|
||||
if (sealedSupers.isEmpty()) {
|
||||
if ((c.flags_field & Flags.NON_SEALED) != 0) {
|
||||
log.error(TreeInfo.diagnosticPositionFor(c, env.tree), Errors.NonSealedWithNoSealedSupertype(c));
|
||||
boolean hasErrorSuper = types.directSupertypes(c.type)
|
||||
.stream()
|
||||
.anyMatch(s -> s.tsym.kind == Kind.ERR);
|
||||
if (!hasErrorSuper) {
|
||||
log.error(TreeInfo.diagnosticPositionFor(c, env.tree), Errors.NonSealedWithNoSealedSupertype(c));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (c.isLocal() && !c.isEnum()) {
|
||||
|
@ -1237,8 +1237,11 @@ class Eval {
|
||||
case PRIVATE:
|
||||
// quietly ignore, user cannot see effects one way or the other
|
||||
break;
|
||||
case STATIC:
|
||||
case FINAL:
|
||||
//OK to declare an element final
|
||||
//final classes needed for sealed classes
|
||||
break;
|
||||
case STATIC:
|
||||
list.add(mod);
|
||||
break;
|
||||
}
|
||||
|
@ -37,11 +37,11 @@ import java.util.stream.Stream;
|
||||
class MaskCommentsAndModifiers {
|
||||
|
||||
private final static Set<String> IGNORED_MODIFIERS =
|
||||
Stream.of( "public", "protected", "private", "static", "final" )
|
||||
Stream.of( "public", "protected", "private", "static" )
|
||||
.collect( Collectors.toSet() );
|
||||
|
||||
private final static Set<String> OTHER_MODIFIERS =
|
||||
Stream.of( "abstract", "strictfp", "transient", "volatile", "synchronized", "native", "default" )
|
||||
Stream.of( "abstract", "strictfp", "transient", "volatile", "synchronized", "native", "default", "final" )
|
||||
.collect( Collectors.toSet() );
|
||||
|
||||
// Builder to accumulate non-masked characters
|
||||
|
@ -66,11 +66,13 @@ class TreeDependencyScanner extends TreeScanner<Void, Set<String>> {
|
||||
// -- Differentiate declaration references from body references ---
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("preview")
|
||||
public Void visitClass(ClassTree node, Set<String> p) {
|
||||
scan(node.getModifiers(), p);
|
||||
scan(node.getTypeParameters(), p);
|
||||
scan(node.getExtendsClause(), p);
|
||||
scan(node.getImplementsClause(), p);
|
||||
scan(node.getPermitsClause(), p);
|
||||
scan(node.getMembers(), body);
|
||||
return null;
|
||||
}
|
||||
|
@ -23,7 +23,7 @@
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8145239 8129559 8080354 8189248 8010319
|
||||
* @bug 8145239 8129559 8080354 8189248 8010319 8246353
|
||||
* @summary Tests for EvaluationState.classes
|
||||
* @build KullaTesting TestingInputStream ExpectedDiagnostic
|
||||
* @run testng ClassesTest
|
||||
@ -251,8 +251,8 @@ public class ClassesTest extends KullaTesting {
|
||||
assertEval("public interface A { }");
|
||||
assertDeclareWarn1("static class B implements A { }",
|
||||
new ExpectedDiagnostic("jdk.eval.warn.illegal.modifiers", 0, 6, 0, -1, -1, Diagnostic.Kind.WARNING));
|
||||
assertDeclareWarn1("final interface C extends A { }",
|
||||
new ExpectedDiagnostic("jdk.eval.warn.illegal.modifiers", 0, 5, 0, -1, -1, Diagnostic.Kind.WARNING));
|
||||
assertDeclareWarn1("static interface C extends A { }",
|
||||
new ExpectedDiagnostic("jdk.eval.warn.illegal.modifiers", 0, 6, 0, -1, -1, Diagnostic.Kind.WARNING));
|
||||
assertActiveKeys();
|
||||
}
|
||||
|
||||
@ -261,8 +261,8 @@ public class ClassesTest extends KullaTesting {
|
||||
assertEval("@X public interface A { }");
|
||||
assertDeclareWarn1("@X static class B implements A { }",
|
||||
new ExpectedDiagnostic("jdk.eval.warn.illegal.modifiers", 0, 9, 0, -1, -1, Diagnostic.Kind.WARNING));
|
||||
assertDeclareWarn1("@X final interface C extends A { }",
|
||||
new ExpectedDiagnostic("jdk.eval.warn.illegal.modifiers", 0, 8, 0, -1, -1, Diagnostic.Kind.WARNING));
|
||||
assertDeclareWarn1("@X static interface C extends A { }",
|
||||
new ExpectedDiagnostic("jdk.eval.warn.illegal.modifiers", 0, 9, 0, -1, -1, Diagnostic.Kind.WARNING));
|
||||
assertActiveKeys();
|
||||
}
|
||||
|
||||
@ -270,8 +270,8 @@ public class ClassesTest extends KullaTesting {
|
||||
assertEval("strictfp public interface A { }");
|
||||
assertDeclareWarn1("strictfp static class B implements A { }",
|
||||
new ExpectedDiagnostic("jdk.eval.warn.illegal.modifiers", 0, 15, 0, -1, -1, Diagnostic.Kind.WARNING));
|
||||
assertDeclareWarn1("strictfp final interface C extends A { }",
|
||||
new ExpectedDiagnostic("jdk.eval.warn.illegal.modifiers", 0, 14, 0, -1, -1, Diagnostic.Kind.WARNING));
|
||||
assertDeclareWarn1("strictfp static interface C extends A { }",
|
||||
new ExpectedDiagnostic("jdk.eval.warn.illegal.modifiers", 0, 15, 0, -1, -1, Diagnostic.Kind.WARNING));
|
||||
assertActiveKeys();
|
||||
}
|
||||
|
||||
|
@ -78,7 +78,7 @@ public class ErrorTranslationTest extends ReplToolTesting {
|
||||
ExpectedDiagnostic[] diagnostics = new ExpectedDiagnostic[]{
|
||||
newExpectedDiagnostic(0, 6, 0, -1, -1, Diagnostic.Kind.WARNING),
|
||||
newExpectedDiagnostic(0, 5, 0, -1, -1, Diagnostic.Kind.WARNING)};
|
||||
String[] mods = {"static", "final"};
|
||||
String[] mods = {"static"};
|
||||
for (int i = 0; i < mods.length; ++i) {
|
||||
for (String code : new String[] {"class A {}", "void f() {}", "int a;"}) {
|
||||
final int finalI = i;
|
||||
|
@ -22,7 +22,8 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test 8129559
|
||||
* @test
|
||||
* @bug 8129559 8246353
|
||||
* @summary Test the ignoring of comments and certain modifiers
|
||||
* @build KullaTesting TestingInputStream
|
||||
* @run testng IgnoreTest
|
||||
@ -66,8 +67,8 @@ public class IgnoreTest extends KullaTesting {
|
||||
assertVariableDeclSnippet(x3, "x3", "int", VALID, VAR_DECLARATION_SUBKIND, 0, 0);
|
||||
VarSnippet x4 = (VarSnippet) assertDeclareWarn1("static int x4;", "jdk.eval.warn.illegal.modifiers");
|
||||
assertVariableDeclSnippet(x4, "x4", "int", VALID, VAR_DECLARATION_SUBKIND, 0, 1);
|
||||
VarSnippet x5 = (VarSnippet) assertDeclareWarn1("final int x5;", "jdk.eval.warn.illegal.modifiers");
|
||||
assertVariableDeclSnippet(x5, "x5", "int", VALID, VAR_DECLARATION_SUBKIND, 0, 1);
|
||||
VarSnippet x5 = varKey(assertEval("final int x5;"));
|
||||
assertVariableDeclSnippet(x5, "x5", "int", VALID, VAR_DECLARATION_SUBKIND, 0, 0);
|
||||
}
|
||||
|
||||
public void testVarModifierAnnotation() {
|
||||
@ -80,8 +81,8 @@ public class IgnoreTest extends KullaTesting {
|
||||
assertVariableDeclSnippet(x3, "x3", "int", VALID, VAR_DECLARATION_SUBKIND, 0, 0);
|
||||
VarSnippet x4 = (VarSnippet) assertDeclareWarn1("@A static int x4;", "jdk.eval.warn.illegal.modifiers");
|
||||
assertVariableDeclSnippet(x4, "x4", "int", VALID, VAR_DECLARATION_SUBKIND, 0, 1);
|
||||
VarSnippet x5 = (VarSnippet) assertDeclareWarn1("@A(1111) final int x5;", "jdk.eval.warn.illegal.modifiers");
|
||||
assertVariableDeclSnippet(x5, "x5", "int", VALID, VAR_DECLARATION_SUBKIND, 0, 1);
|
||||
VarSnippet x5 = varKey(assertEval("@A(1111) final int x5;"));
|
||||
assertVariableDeclSnippet(x5, "x5", "int", VALID, VAR_DECLARATION_SUBKIND, 0, 0);
|
||||
}
|
||||
|
||||
public void testVarModifierOtherModifier() {
|
||||
@ -93,8 +94,8 @@ public class IgnoreTest extends KullaTesting {
|
||||
assertVariableDeclSnippet(x3, "x3", "int", VALID, VAR_DECLARATION_SUBKIND, 0, 0);
|
||||
VarSnippet x4 = (VarSnippet) assertDeclareWarn1("volatile static int x4;", "jdk.eval.warn.illegal.modifiers");
|
||||
assertVariableDeclSnippet(x4, "x4", "int", VALID, VAR_DECLARATION_SUBKIND, 0, 1);
|
||||
VarSnippet x5 = (VarSnippet) assertDeclareWarn1("transient final int x5;", "jdk.eval.warn.illegal.modifiers");
|
||||
assertVariableDeclSnippet(x5, "x5", "int", VALID, VAR_DECLARATION_SUBKIND, 0, 1);
|
||||
VarSnippet x5 = varKey(assertEval("transient final int x5;"));
|
||||
assertVariableDeclSnippet(x5, "x5", "int", VALID, VAR_DECLARATION_SUBKIND, 0, 0);
|
||||
}
|
||||
|
||||
public void testMisplacedIgnoredModifier() {
|
||||
@ -106,23 +107,23 @@ public class IgnoreTest extends KullaTesting {
|
||||
public void testMethodModifier() {
|
||||
MethodSnippet m4 = (MethodSnippet) assertDeclareWarn1("static void m4() {}", "jdk.eval.warn.illegal.modifiers");
|
||||
assertMethodDeclSnippet(m4, "m4", "()void", VALID, 0, 1);
|
||||
MethodSnippet m5 = (MethodSnippet) assertDeclareWarn1("final void m5() {}", "jdk.eval.warn.illegal.modifiers");
|
||||
assertMethodDeclSnippet(m5, "m5", "()void", VALID, 0, 1);
|
||||
MethodSnippet m5 = methodKey(assertEval("final void m5() {}"));
|
||||
assertMethodDeclSnippet(m5, "m5", "()void", VALID, 0, 0);
|
||||
}
|
||||
|
||||
public void testMethodModifierAnnotation() {
|
||||
assertEval("@interface A { int value() default 0; }");
|
||||
MethodSnippet m4 = (MethodSnippet) assertDeclareWarn1("@A static void m4() {}", "jdk.eval.warn.illegal.modifiers");
|
||||
assertMethodDeclSnippet(m4, "m4", "()void", VALID, 0, 1);
|
||||
MethodSnippet m5 = (MethodSnippet) assertDeclareWarn1("@A(value=66)final void m5() {}", "jdk.eval.warn.illegal.modifiers");
|
||||
assertMethodDeclSnippet(m5, "m5", "()void", VALID, 0, 1);
|
||||
MethodSnippet m5 = methodKey(assertEval("@A(value=66)final void m5() {}"));
|
||||
assertMethodDeclSnippet(m5, "m5", "()void", VALID, 0, 0);
|
||||
}
|
||||
|
||||
public void testClassModifier() {
|
||||
TypeDeclSnippet c4 = (TypeDeclSnippet) assertDeclareWarn1("static class C4 {}", "jdk.eval.warn.illegal.modifiers");
|
||||
assertTypeDeclSnippet(c4, "C4", VALID, CLASS_SUBKIND, 0, 1);
|
||||
TypeDeclSnippet c5 = (TypeDeclSnippet) assertDeclareWarn1("final class C5 {}", "jdk.eval.warn.illegal.modifiers");
|
||||
assertTypeDeclSnippet(c5, "C5", VALID, CLASS_SUBKIND, 0, 1);
|
||||
TypeDeclSnippet c5 = classKey(assertEval("final class C5 {}"));
|
||||
assertTypeDeclSnippet(c5, "C5", VALID, CLASS_SUBKIND, 0, 0);
|
||||
}
|
||||
|
||||
public void testInsideModifier() {
|
||||
|
@ -23,7 +23,7 @@
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8080357 8167643 8187359 8199762 8080353
|
||||
* @bug 8080357 8167643 8187359 8199762 8080353 8246353
|
||||
* @summary Tests for EvaluationState.methods
|
||||
* @build KullaTesting TestingInputStream ExpectedDiagnostic
|
||||
* @run testng MethodsTest
|
||||
@ -298,8 +298,8 @@ public class MethodsTest extends KullaTesting {
|
||||
assertActiveKeys();
|
||||
|
||||
assertDeclareWarn1("final String f() {return null;}",
|
||||
new ExpectedDiagnostic("jdk.eval.warn.illegal.modifiers", 0, 5, 0, -1, -1, Diagnostic.Kind.WARNING),
|
||||
ste(MAIN_SNIPPET, VALID, VALID, false, null),
|
||||
null,
|
||||
ste(MAIN_SNIPPET, VALID, VALID, true, null),
|
||||
ste(f, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
|
||||
assertNumberOfActiveMethods(1);
|
||||
assertActiveKeys();
|
||||
|
@ -44,13 +44,13 @@ public class ModifiersTest extends KullaTesting {
|
||||
public Object[][] getTestCases() {
|
||||
List<Object[]> testCases = new ArrayList<>();
|
||||
String[] ignoredModifiers = new String[] {
|
||||
"static", "final"
|
||||
"static"
|
||||
};
|
||||
String[] silentlyIgnoredModifiers = new String[] {
|
||||
"public", "protected", "private"
|
||||
};
|
||||
String[] before = new String[] {
|
||||
"strictfp", "abstract", "@X", "@X(value=9)"
|
||||
"strictfp", "abstract", "final", "@X", "@X(value=9)"
|
||||
};
|
||||
String context = "@interface X { int value() default 0; }";
|
||||
Consumer<String> eval = this::assertEval;
|
||||
|
72
test/langtools/jdk/jshell/SealedClassesTest.java
Normal file
72
test/langtools/jdk/jshell/SealedClassesTest.java
Normal file
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8246353
|
||||
* @summary Test sealed class in jshell
|
||||
* @modules jdk.jshell
|
||||
* @build KullaTesting TestingInputStream ExpectedDiagnostic
|
||||
* @run testng SealedClassesTest
|
||||
*/
|
||||
|
||||
import javax.lang.model.SourceVersion;
|
||||
|
||||
import jdk.jshell.TypeDeclSnippet;
|
||||
import jdk.jshell.Snippet.Status;
|
||||
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import static jdk.jshell.Snippet.Status.VALID;
|
||||
|
||||
@Test
|
||||
public class SealedClassesTest extends KullaTesting {
|
||||
|
||||
public void testSealed() {
|
||||
TypeDeclSnippet base = classKey(
|
||||
assertEval("sealed class B permits I {}",
|
||||
ste(MAIN_SNIPPET, Status.NONEXISTENT, Status.RECOVERABLE_NOT_DEFINED, false, null)));
|
||||
assertEval("final class I extends B {}",
|
||||
added(VALID),
|
||||
ste(base, Status.RECOVERABLE_NOT_DEFINED, Status.VALID, true, null));
|
||||
assertEval("new I()");
|
||||
}
|
||||
|
||||
public void testNonSealed() {
|
||||
TypeDeclSnippet base = classKey(
|
||||
assertEval("sealed class B permits I {}",
|
||||
ste(MAIN_SNIPPET, Status.NONEXISTENT, Status.RECOVERABLE_NOT_DEFINED, false, null)));
|
||||
assertEval("non-sealed class I extends B {}",
|
||||
added(VALID),
|
||||
ste(base, Status.RECOVERABLE_NOT_DEFINED, Status.VALID, true, null));
|
||||
assertEval("class I2 extends I {}");
|
||||
assertEval("new I2()");
|
||||
}
|
||||
|
||||
@BeforeMethod
|
||||
public void setUp() {
|
||||
setUp(b -> b.compilerOptions("--enable-preview", "-source", String.valueOf(SourceVersion.latest().ordinal()))
|
||||
.remoteVMOptions("--enable-preview"));
|
||||
}
|
||||
}
|
@ -27,6 +27,7 @@
|
||||
* SealedCompilationTests
|
||||
*
|
||||
* @test
|
||||
* @bug 8246353
|
||||
* @summary Negative compilation tests, and positive compilation (smoke) tests for sealed classes
|
||||
* @library /lib/combo /tools/lib
|
||||
* @modules
|
||||
@ -58,11 +59,13 @@ import javax.annotation.processing.RoundEnvironment;
|
||||
import javax.annotation.processing.SupportedAnnotationTypes;
|
||||
|
||||
import javax.lang.model.element.TypeElement;
|
||||
import javax.lang.model.SourceVersion;
|
||||
|
||||
import com.sun.tools.javac.util.Assert;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
import static org.testng.Assert.fail;
|
||||
import org.testng.annotations.Test;
|
||||
import tools.javac.combo.CompilationTestCase;
|
||||
|
||||
@ -90,11 +93,18 @@ public class SealedCompilationTests extends CompilationTestCase {
|
||||
|
||||
/* simplest annotation processor just to force a round of annotation processing for all tests
|
||||
*/
|
||||
@SupportedAnnotationTypes("*")
|
||||
public static class SimplestAP extends AbstractProcessor {
|
||||
@Override
|
||||
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SourceVersion getSupportedSourceVersion() {
|
||||
return SourceVersion.latest();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public SealedCompilationTests() {
|
||||
@ -693,6 +703,18 @@ public class SealedCompilationTests extends CompilationTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
public void testNonSealedErroneousSuper() {
|
||||
assertFail("compiler.err.cant.resolve",
|
||||
d -> {
|
||||
if (diags.keys().size() != 1) {
|
||||
fail("Unexpected errors: " + diags.toString());
|
||||
}
|
||||
},
|
||||
"""
|
||||
non-sealed class C extends Undefined {}
|
||||
""");
|
||||
}
|
||||
|
||||
public void testIllFormedNonSealed() {
|
||||
for (String s : List.of(
|
||||
"""
|
||||
|
Loading…
Reference in New Issue
Block a user