diff --git a/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/IncrementalTests.java b/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/IncrementalTests.java index 25629f50723..c9dfa9230cc 100644 --- a/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/IncrementalTests.java +++ b/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/IncrementalTests.java @@ -1664,4 +1664,61 @@ public final class Child extends Parent { env.removeProject(projectPath); } + public void testExhaustiveness() throws JavaModelException { + IPath projectPath = env.addProject("Project", "18"); + env.addExternalJars(projectPath, Util.getJavaClassLibs()); + + // remove old package fragment root so that names don't collide + env.removePackageFragmentRoot(projectPath, ""); + + IPath root = env.addPackageFragmentRoot(projectPath, "src"); + env.setOutputFolder(projectPath, "bin"); + + IPath pathToX = env.addClass(root, "", "X", + """ + public class X { + + public static void main(String[] args) { + E e = E.getE(); + + String s = switch (e) { + case A -> "A"; + case B -> "B"; + case C -> "C"; + }; + System.out.println(s); + } + } + """); + + env.addClass(root, "", "E", + """ + public enum E { + A, B, C; + static E getE() { + return C; + } + } + """); + + fullBuild(projectPath); + expectingNoProblems(); + executeClass(projectPath, "X", "C", ""); + + env.addClass(root, "", "E", + """ + public enum E { + A, B, C, D; + static E getE() { + return D; + } + } + """); + + + incrementalBuild(projectPath); + expectingSpecificProblemFor(pathToX, new Problem("E", "A Switch expression should cover all possible values", pathToX, 100, 101, CategorizedProblem.CAT_SYNTAX, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$ + env.removeProject(projectPath); + } + } diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest_17.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest_17.java index 996b96a73cf..559b3362dc2 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest_17.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest_17.java @@ -24,7 +24,9 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import junit.framework.Test; +import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.core.tests.compiler.regression.BatchCompilerTest.SubstringMatcher; +import org.eclipse.jdt.core.tests.util.Util; public class BatchCompilerTest_17 extends AbstractBatchCompilerTest { @@ -45,6 +47,10 @@ public BatchCompilerTest_17(String name) { super(name); } + static { + // TESTS_NAMES = new String [] { "testGHI1774_Expression" }; + } + /** * Test tries to compile same sources in parallel to different output directories. * There should be no interdependencies between compiler threads, but the test failed @@ -145,4 +151,76 @@ boolean match(String err) { return "StdErr: " + error + " StdOut: " + output; } + + // https://github.com/eclipse-jdt/eclipse.jdt.core/issues/1774 + // Check behavior of expression switch in JDK18- + // https://github.com/eclipse-jdt/eclipse.jdt.core/issues/3096#issuecomment-2417954288 + public void testGHI1774_Expression() throws Exception { + + String path = LIB_DIR; + String libPath = null; + if (path.endsWith(File.separator)) { + libPath = path + "lib.jar"; + } else { + libPath = path + File.separator + "lib.jar"; + } + Util.createJar(new String[] { + "p/Color.java", + "package p;\n" + + "public enum Color {\n" + + " R, Y;\n" + + " public static Color getColor() {\n" + + " return R;\n" + + " }\n" + + "}", + }, + libPath, + JavaCore.VERSION_18); + this.runConformTest( + new String[] { + "src/p/X.java", + "package p;\n" + + "import p.Color;\n" + + "public class X {\n" + + " public static void main(String argv[]) {\n" + + " Color c = Color.getColor();\n" + + " try {\n" + + " int a = switch (c) {\n" + + " case R -> 1;\n" + + " case Y -> 2;\n" + + " };\n" + + " } catch (IncompatibleClassChangeError e) {\n" + + " System.out.print(\"OK\");\n" + + " } catch (Exception e) {\n" + + " System.out.print(\"NOT OK: \" + e);\n" + + " }\n" + + " System.out.print(\"END\");\n" + + " }\n" + + "}", + }, + "\"" + OUTPUT_DIR + File.separator + "src/p/X.java\"" + + " -cp \"" + LIB_DIR + File.separator + "lib.jar\"" + + " -sourcepath \"" + OUTPUT_DIR + File.separator + "src\"" + + " -source 18 -warn:none" + + " -d \"" + OUTPUT_DIR + File.separator + "bin\" ", + "", + "", + true); + this.verifier.execute("p.X", new String[] {OUTPUT_DIR + File.separator + "bin", libPath}, new String[0], new String[] {"--enable-preview"}); + assertEquals("Incorrect output", "END", this.verifier.getExecutionOutput()); + Util.createJar(new String[] { + "p/Color.java", + "package p;\n" + + "public enum Color {\n" + + " R, Y, B;\n" + + " public static Color getColor() {\n" + + " return B;\n" + + " }\n" + + "}", + }, + libPath, + JavaCore.VERSION_18); + this.verifier.execute("p.X", new String[] {OUTPUT_DIR + File.separator + "bin", libPath}, new String[0], new String[] {"--enable-preview"}); + assertEquals("Incorrect output", "OKEND", this.verifier.getExecutionOutput()); + } }