diff options
208 files changed, 14055 insertions, 1235 deletions
diff --git a/org.eclipse.jdt.compiler.apt.tests/.classpath b/org.eclipse.jdt.compiler.apt.tests/.classpath index 3592a9572a..8102373411 100644 --- a/org.eclipse.jdt.compiler.apt.tests/.classpath +++ b/org.eclipse.jdt.compiler.apt.tests/.classpath @@ -16,7 +16,7 @@ </attributes> </classpathentry> <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> - <classpathentry kind="lib" path="java10/java10api.jar"/> + <classpathentry kind="lib" path="lib/java10api.jar"/> <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/> <classpathentry kind="output" path="bin"/> </classpath> diff --git a/org.eclipse.jdt.compiler.apt.tests/META-INF/MANIFEST.MF b/org.eclipse.jdt.compiler.apt.tests/META-INF/MANIFEST.MF index cd2f132a06..f08a46a4dd 100644 --- a/org.eclipse.jdt.compiler.apt.tests/META-INF/MANIFEST.MF +++ b/org.eclipse.jdt.compiler.apt.tests/META-INF/MANIFEST.MF @@ -19,6 +19,6 @@ Export-Package: org.eclipse.jdt.compiler.apt.tests, org.eclipse.jdt.compiler.apt.tests.processors.visitors Import-Package: org.eclipse.jdt.internal.compiler.tool;resolution:=optional Eclipse-BundleShape: dir -Bundle-ClassPath: java10/java10api.jar, +Bundle-ClassPath: lib/java10api.jar, . Automatic-Module-Name: org.eclipse.jdt.compiler.apt.tests diff --git a/org.eclipse.jdt.compiler.apt.tests/build.properties b/org.eclipse.jdt.compiler.apt.tests/build.properties index e872602914..e9a85ccd3b 100644 --- a/org.eclipse.jdt.compiler.apt.tests/build.properties +++ b/org.eclipse.jdt.compiler.apt.tests/build.properties @@ -1,5 +1,5 @@ ############################################################################### -# Copyright (c) 2006, 2018 BEA Systems Inc. and others +# Copyright (c) 2006, 2019 BEA Systems Inc. and others # # This program and the accompanying materials # are made available under the terms of the Eclipse Public License 2.0 @@ -23,9 +23,8 @@ bin.includes = about.html,\ test.xml,\ META-INF/,\ resources/,\ - java10/,\ lib/,\ . src.includes = about.html compilerArg=-proc:none -jars.extra.classpath = java10/java10api.jar +jars.extra.classpath = lib/java10api.jar diff --git a/org.eclipse.jdt.compiler.apt.tests/lib/apttestprocessors8.jar b/org.eclipse.jdt.compiler.apt.tests/lib/apttestprocessors8.jar Binary files differindex 363e26f2b8..e18d62ebc3 100644 --- a/org.eclipse.jdt.compiler.apt.tests/lib/apttestprocessors8.jar +++ b/org.eclipse.jdt.compiler.apt.tests/lib/apttestprocessors8.jar diff --git a/org.eclipse.jdt.compiler.apt.tests/java10/java10api.jar b/org.eclipse.jdt.compiler.apt.tests/lib/java10api.jar Binary files differindex 464b69134f..464b69134f 100644 --- a/org.eclipse.jdt.compiler.apt.tests/java10/java10api.jar +++ b/org.eclipse.jdt.compiler.apt.tests/lib/java10api.jar diff --git a/org.eclipse.jdt.compiler.apt.tests/processors8/META-INF/services/javax.annotation.processing.Processor b/org.eclipse.jdt.compiler.apt.tests/processors8/META-INF/services/javax.annotation.processing.Processor index 8b8bccf832..4d8344550a 100644 --- a/org.eclipse.jdt.compiler.apt.tests/processors8/META-INF/services/javax.annotation.processing.Processor +++ b/org.eclipse.jdt.compiler.apt.tests/processors8/META-INF/services/javax.annotation.processing.Processor @@ -1,3 +1,4 @@ org.eclipse.jdt.compiler.apt.tests.processors.elements.Java8ElementProcessor
org.eclipse.jdt.compiler.apt.tests.processors.elements.Java9ElementProcessor
-org.eclipse.jdt.compiler.apt.tests.processors.elements.Java11ElementProcessor
\ No newline at end of file +org.eclipse.jdt.compiler.apt.tests.processors.elements.Java11ElementProcessor
+org.eclipse.jdt.compiler.apt.tests.processors.elements.Java12ElementProcessor
\ No newline at end of file diff --git a/org.eclipse.jdt.compiler.apt.tests/processors8/org/eclipse/jdt/compiler/apt/tests/processors/elements/Java12ElementProcessor.java b/org.eclipse.jdt.compiler.apt.tests/processors8/org/eclipse/jdt/compiler/apt/tests/processors/elements/Java12ElementProcessor.java new file mode 100644 index 0000000000..8fcd6b1817 --- /dev/null +++ b/org.eclipse.jdt.compiler.apt.tests/processors8/org/eclipse/jdt/compiler/apt/tests/processors/elements/Java12ElementProcessor.java @@ -0,0 +1,345 @@ +/******************************************************************************* + * Copyright (c) 2019 IBM Corporation. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ + +package org.eclipse.jdt.compiler.apt.tests.processors.elements; + +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.annotation.processing.Filer; +import javax.annotation.processing.Messager; +import javax.annotation.processing.ProcessingEnvironment; +import javax.annotation.processing.RoundEnvironment; +import javax.annotation.processing.SupportedAnnotationTypes; +import javax.lang.model.element.Element; +import javax.lang.model.element.Modifier; +import javax.lang.model.element.ModuleElement; +import javax.lang.model.element.PackageElement; +import javax.lang.model.element.TypeElement; + +import org.eclipse.jdt.compiler.apt.tests.processors.base.BaseProcessor; + +/** + * A processor that explores the java 9 specific elements and validates the lambda and + * type annotated elements. To enable this processor, add + * -Aorg.eclipse.jdt.compiler.apt.tests.processors.elements.Java11ElementProcessor to the command line. + * @since 3.14 + */ +@SupportedAnnotationTypes("*") +public class Java12ElementProcessor extends BaseProcessor { + boolean reportSuccessAlready = true; + RoundEnvironment roundEnv = null; + Messager _messager = null; + Filer _filer = null; + boolean isBinaryMode = false; + @Override + public synchronized void init(ProcessingEnvironment processingEnv) { + super.init(processingEnv); + _elementUtils = processingEnv.getElementUtils(); + _messager = processingEnv.getMessager(); + _filer = processingEnv.getFiler(); + } + // Always return false from this processor, because it supports "*". + // The return value does not signify success or failure! + @Override + public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { + if (roundEnv.processingOver()) { + return false; + } + + this.roundEnv = roundEnv; + Map<String, String> options = processingEnv.getOptions(); + if (!options.containsKey(this.getClass().getName())) { + // Disable this processor unless we are intentionally performing the test. + return false; + } else { + try { + if (options.containsKey("binary")) { + this.isBinaryMode = true; + } + if (!invokeTestMethods(options)) { + testAll(); + } + if (this.reportSuccessAlready) { + super.reportSuccess(); + } + } catch (AssertionFailedError e) { + super.reportError(getExceptionStackTrace(e)); + } catch (Throwable e) { + e.printStackTrace(); + } + } + return false; + } + + private boolean invokeTestMethods(Map<String, String> options) throws Throwable { + Method testMethod = null; + Set<String> keys = options.keySet(); + boolean testsFound = false; + for (String option : keys) { + if (option.startsWith("test")) { + try { + testMethod = this.getClass().getDeclaredMethod(option, new Class[0]); + if (testMethod != null) { + testsFound = true; + testMethod.invoke(this, new Object[0]); + } + } catch (InvocationTargetException e) { + throw e.getCause(); + } catch (Exception e) { + super.reportError(getExceptionStackTrace(e)); + } + } + } + return testsFound; + } + + public void testAll() throws AssertionFailedError, IOException { + testRootElements1(); + } + + public void testRootElements1() throws IOException { + Set<? extends Element> rootElements = this.roundEnv.getRootElements(); + List<String> types = new ArrayList<>(); + List<String> modules = new ArrayList<>(); + ModuleElement mod1 = null, mod2 = null, mod3 = null; + for (Element element : rootElements) { + Element root = getRoot(element); + String modName = null; + ModuleElement mod = null; + if (element instanceof ModuleElement) { + mod = (ModuleElement) element; + modName = mod.getQualifiedName().toString(); + if (!modules.contains(modName) && !modName.equals("java.base")) + modules.add(modName); + assertNull("module should not have an enclosing element", root); + } else { + if (element instanceof TypeElement) { + types.add(((TypeElement) element).getQualifiedName().toString()); + } + assertTrue("Should be a module element", (root instanceof ModuleElement)); + mod = (ModuleElement) root; + modName = mod.getQualifiedName().toString(); + assertFalse("should be a named module", mod.isUnnamed()); + String string = mod.getQualifiedName().toString(); + if (!modules.contains(string) && !modName.equals("java.base")) + modules.add(string); + } + if (modName.equals("module.main")) { + mod1 = mod; + } else if (modName.equals("module.readable.one")) { + mod2 = mod; + } else if (modName.equals("module.readable.two")) { + mod3 = mod; + } + } + Collections.sort(types, (x, y) -> x.compareTo(y)); //unused as of now + Collections.sort(modules, (x, y) -> x.compareTo(y)); + assertEquals("incorrect no of modules in root elements", 3, modules.size()); + assertEquals("incorrect modules among root elements", "[module.main, module.readable.one, module.readable.two]", modules.toString()); + assertNotNull("module should not be null", mod1); + assertNotNull("module should not be null", mod2); + assertNotNull("module should not be null", mod3); + assertEquals("Incorrect enclosed packages", "[lang.MOD.same, ]", getElementsAsString(mod3.getEnclosedElements())); + assertEquals("Incorrect enclosed packages", "[lang.MOD.same, ]", getElementsAsString(mod2.getEnclosedElements())); + assertEquals("Incorrect enclosed packages", "[lang.MOD, ]", getElementsAsString(mod1.getEnclosedElements())); + } + + public void testRootElements2() throws IOException { + Set<? extends Element> rootElements = this.roundEnv.getRootElements(); + List<String> types = new ArrayList<>(); + List<String> modules = new ArrayList<>(); + ModuleElement mod1 = null, mod2 = null, mod3 = null; + for (Element element : rootElements) { + Element root = getRoot(element); + String modName = null; + ModuleElement mod = null; + if (element instanceof ModuleElement) { + mod = (ModuleElement) element; + modName = mod.getQualifiedName().toString(); + if (!modules.contains(modName) && !modName.equals("java.base")) + modules.add(modName); + assertNull("module should not have an enclosing element", root); + } else { + if (element instanceof TypeElement) { + types.add(((TypeElement) element).getQualifiedName().toString()); + } + assertTrue("Should be a module element", (root instanceof ModuleElement)); + mod = (ModuleElement) root; + modName = mod.getQualifiedName().toString(); + assertFalse("should be a named module", mod.isUnnamed()); + String string = mod.getQualifiedName().toString(); + if (!modules.contains(string) && !modName.equals("java.base")) + modules.add(string); + } + if (modName.equals("module.main")) { + mod1 = mod; + } else if (modName.equals("module.readable.one")) { + mod2 = mod; + } else if (modName.equals("module.readable.two")) { + mod3 = mod; + } + } + Collections.sort(types, (x, y) -> x.compareTo(y)); //unused as of now + Collections.sort(modules, (x, y) -> x.compareTo(y)); + assertEquals("incorrect no of modules in root elements", this.isBinaryMode ? 2 : 3, modules.size()); + assertEquals("incorrect modules among root elements", "[module.main, module.readable.one" + + (this.isBinaryMode ? "" : ", module.readable.two") + "]", modules.toString()); + assertNotNull("module should not be null", mod1); + assertEquals("Incorrect enclosed packages", "[my.mod, ]", getElementsAsString(mod1.getEnclosedElements())); + assertEquals("Incorrect enclosed packages", "[my.mod.same, ]", getElementsAsString(mod2.getEnclosedElements())); + assertNotNull("module should not be null", mod2); + if (!this.isBinaryMode) { + assertNotNull("module should not be null", mod3); + assertEquals("Incorrect enclosed packages", "[]", getElementsAsString(mod3.getEnclosedElements())); + } + } + private Element getRoot(Element elem) { + Element enclosingElement = elem.getEnclosingElement(); + while (enclosingElement != null) { + if (enclosingElement instanceof ModuleElement) { + return enclosingElement; + } + enclosingElement = enclosingElement.getEnclosingElement(); + } + return enclosingElement; + } + + @Override + public void reportError(String msg) { + throw new AssertionFailedError(msg); + } + private String getExceptionStackTrace(Throwable t) { + StringBuffer buf = new StringBuffer(t.getMessage()); + StackTraceElement[] traces = t.getStackTrace(); + for (int i = 0; i < traces.length; i++) { + StackTraceElement trace = traces[i]; + buf.append("\n\tat " + trace); + if (i == 12) + break; // Don't dump all stacks + } + return buf.toString(); + } + protected String getElementsAsString(List<? extends Element> list) { + StringBuilder builder = new StringBuilder("["); + for (Element element : list) { + if (element instanceof PackageElement) { + builder.append(((PackageElement) element).getQualifiedName()); + } else if (element instanceof ModuleElement) { + builder.append(((ModuleElement) element).getQualifiedName()); + } else if (element instanceof TypeElement) { + builder.append(((TypeElement) element).getQualifiedName()); + } else { + builder.append(element.getSimpleName()); + } + builder.append(", "); + } + builder.append("]"); + return builder.toString(); + } + public void assertModifiers(Set<Modifier> modifiers, String[] expected) { + assertEquals("Incorrect no of modifiers", modifiers.size(), expected.length); + Set<String> actual = new HashSet<String>(expected.length); + for (Modifier modifier : modifiers) { + actual.add(modifier.toString()); + } + for(int i = 0, length = expected.length; i < length; i++) { + boolean result = actual.remove(expected[i]); + if (!result) reportError("Modifier not present :" + expected[i]); + } + if (!actual.isEmpty()) { + reportError("Unexpected modifiers present:" + actual.toString()); + } + } + public void assertTrue(String msg, boolean value) { + if (!value) reportError(msg); + } + public void assertFalse(String msg, boolean value) { + if (value) reportError(msg); + } + public void assertSame(String msg, Object obj1, Object obj2) { + if (obj1 != obj2) { + reportError(msg + ", should be " + obj1.toString() + " but " + obj2.toString()); + } + } + public void assertNotSame(String msg, Object obj1, Object obj2) { + if (obj1 == obj2) { + reportError(msg + ", " + obj1.toString() + " should not be same as " + obj2.toString()); + } + } + public void assertNotNull(String msg, Object obj) { + if (obj == null) { + reportError(msg); + } + } + public void assertNull(String msg, Object obj) { + if (obj != null) { + reportError(msg); + } + } + public void assertEquals(String message, Object expected, Object actual) { + if (equalsRegardingNull(expected, actual)) { + return; + } else { + reportError(message + ", expected " + expected.toString() + " but was " + actual.toString()); + } + } + + public void assertEquals(String message, Object expected, Object alternateExpected, Object actual) { + if (equalsRegardingNull(expected, actual) || equalsRegardingNull(alternateExpected, actual)) { + return; + } else { + reportError(message + ", expected " + expected.toString() + " but was " + actual.toString()); + } + } + + static boolean equalsRegardingNull(Object expected, Object actual) { + if (expected == null) { + return actual == null; + } + return expected.equals(actual); + } + + public void assertEquals(String msg, int expected, int actual) { + if (expected != actual) { + StringBuffer buf = new StringBuffer(); + buf.append(msg); + buf.append(", expected " + expected + " but was " + actual); + reportError(buf.toString()); + } + } + public void assertEquals(Object expected, Object actual) { + if (expected != actual) { + + } + } + private class AssertionFailedError extends Error { + private static final long serialVersionUID = 1L; + + public AssertionFailedError(String msg) { + super(msg); + } + } +} diff --git a/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/modules2/module.main/lang/MOD/Main.java b/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/modules2/module.main/lang/MOD/Main.java new file mode 100644 index 0000000000..c11e8d9972 --- /dev/null +++ b/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/modules2/module.main/lang/MOD/Main.java @@ -0,0 +1,8 @@ +package lang.MOD; + +class MyClass { static int meth(lang.MOD.same.SomeType arg) { return arg.value; } } + +public class Main { + public static void main(String argv[]) { + } +}
\ No newline at end of file diff --git a/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/modules2/module.main/module-info.java b/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/modules2/module.main/module-info.java new file mode 100644 index 0000000000..fd0dc7b74d --- /dev/null +++ b/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/modules2/module.main/module-info.java @@ -0,0 +1,5 @@ +module module.main { + requires module.readable.one; + requires module.readable.two; + exports lang.MOD; +}
\ No newline at end of file diff --git a/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/modules2/module.readable.one/lang/MOD/same/SomeType.java b/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/modules2/module.readable.one/lang/MOD/same/SomeType.java new file mode 100644 index 0000000000..f7b1468bfa --- /dev/null +++ b/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/modules2/module.readable.one/lang/MOD/same/SomeType.java @@ -0,0 +1,7 @@ +package lang.MOD.same; + +public class SomeType { + public static class NestedClass { + } + public static int value = 1; +}
\ No newline at end of file diff --git a/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/modules2/module.readable.one/module-info.java b/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/modules2/module.readable.one/module-info.java new file mode 100644 index 0000000000..c0dc95931d --- /dev/null +++ b/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/modules2/module.readable.one/module-info.java @@ -0,0 +1,3 @@ +module module.readable.one { + exports lang.MOD.same to module.main; +}
\ No newline at end of file diff --git a/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/modules2/module.readable.two/lang/MOD/same/SomeType.java b/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/modules2/module.readable.two/lang/MOD/same/SomeType.java new file mode 100644 index 0000000000..33a983543d --- /dev/null +++ b/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/modules2/module.readable.two/lang/MOD/same/SomeType.java @@ -0,0 +1,4 @@ +package lang.MOD.same; + +public class SomeType { +}
\ No newline at end of file diff --git a/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/modules2/module.readable.two/module-info.java b/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/modules2/module.readable.two/module-info.java new file mode 100644 index 0000000000..df9b457d55 --- /dev/null +++ b/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/modules2/module.readable.two/module-info.java @@ -0,0 +1,2 @@ +module module.readable.two { +}
\ No newline at end of file diff --git a/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/modules3/module.main/module-info.java b/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/modules3/module.main/module-info.java new file mode 100644 index 0000000000..b755208a1b --- /dev/null +++ b/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/modules3/module.main/module-info.java @@ -0,0 +1,5 @@ +module module.main { + requires module.readable.one; + requires module.readable.two; + exports my.mod; +}
\ No newline at end of file diff --git a/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/modules3/module.main/my/mod/Main.java b/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/modules3/module.main/my/mod/Main.java new file mode 100644 index 0000000000..b60ff762a8 --- /dev/null +++ b/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/modules3/module.main/my/mod/Main.java @@ -0,0 +1,10 @@ +package my.mod; + +import java.io.PrintStream; + +class MyClass { static int meth(my.mod.same.SomeType arg) { return arg.value; } } + +public class Main { + public static void main(String argv[]) { + } +}
\ No newline at end of file diff --git a/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/modules3/module.readable.one/module-info.java b/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/modules3/module.readable.one/module-info.java new file mode 100644 index 0000000000..75fa2b7cc1 --- /dev/null +++ b/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/modules3/module.readable.one/module-info.java @@ -0,0 +1,3 @@ +module module.readable.one { + exports my.mod.same to module.main; +}
\ No newline at end of file diff --git a/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/modules3/module.readable.one/my/mod/same/SomeType.java b/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/modules3/module.readable.one/my/mod/same/SomeType.java new file mode 100644 index 0000000000..8315b02925 --- /dev/null +++ b/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/modules3/module.readable.one/my/mod/same/SomeType.java @@ -0,0 +1,7 @@ +package my.mod.same; + +public class SomeType { + public static class NestedClass { + } + public static int value = 1; +}
\ No newline at end of file diff --git a/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/modules3/module.readable.two/module-info.java b/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/modules3/module.readable.two/module-info.java new file mode 100644 index 0000000000..df9b457d55 --- /dev/null +++ b/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/modules3/module.readable.two/module-info.java @@ -0,0 +1,2 @@ +module module.readable.two { +}
\ No newline at end of file diff --git a/org.eclipse.jdt.compiler.apt.tests/src/org/eclipse/jdt/compiler/apt/tests/AllTests.java b/org.eclipse.jdt.compiler.apt.tests/src/org/eclipse/jdt/compiler/apt/tests/AllTests.java index 9491959c63..413a63d6bc 100644 --- a/org.eclipse.jdt.compiler.apt.tests/src/org/eclipse/jdt/compiler/apt/tests/AllTests.java +++ b/org.eclipse.jdt.compiler.apt.tests/src/org/eclipse/jdt/compiler/apt/tests/AllTests.java @@ -36,6 +36,7 @@ public class AllTests extends TestCase { suite.addTestSuite(Java8ElementsTests.class); suite.addTestSuite(Java9ElementsTests.class); suite.addTestSuite(Java11ElementsTests.class); + suite.addTestSuite(Java12ElementsTests.class); suite.addTestSuite(AnnotationProcessorTests.class); return suite; } diff --git a/org.eclipse.jdt.compiler.apt.tests/src/org/eclipse/jdt/compiler/apt/tests/BatchTestUtils.java b/org.eclipse.jdt.compiler.apt.tests/src/org/eclipse/jdt/compiler/apt/tests/BatchTestUtils.java index 576b5f57c5..75bad9352d 100644 --- a/org.eclipse.jdt.compiler.apt.tests/src/org/eclipse/jdt/compiler/apt/tests/BatchTestUtils.java +++ b/org.eclipse.jdt.compiler.apt.tests/src/org/eclipse/jdt/compiler/apt/tests/BatchTestUtils.java @@ -122,11 +122,11 @@ public class BatchTestUtils { } public static void compileInModuleMode(JavaCompiler compiler, List<String> options, String processor, - File targetFolder, DiagnosticListener<? super JavaFileObject> listener, boolean multiModule) { + File targetFolder, DiagnosticListener<? super JavaFileObject> listener, boolean multiModule) throws IOException { compileInModuleMode(compiler, options, processor, targetFolder, listener, multiModule, true); } public static void compileInModuleMode(JavaCompiler compiler, List<String> options, String processor, - File targetFolder, DiagnosticListener<? super JavaFileObject> listener, boolean multiModule, boolean processBinariesAgain) { + File targetFolder, DiagnosticListener<? super JavaFileObject> listener, boolean multiModule, boolean processBinariesAgain) throws IOException { StandardJavaFileManager manager = compiler.getStandardFileManager(null, Locale.getDefault(), Charset.defaultCharset()); Iterable<? extends File> location = manager.getLocation(StandardLocation.CLASS_PATH); // create new list containing inputfile @@ -145,7 +145,7 @@ public class BatchTestUtils { copyOptions.add(_tmpBinFolderName); copyOptions.add("-s"); copyOptions.add(_tmpGenFolderName); - addModuleProcessorPath(copyOptions, getSrcFolderName(), multiModule); + addModuleProcessorPath(copyOptions, targetFolder.getAbsolutePath(), multiModule); copyOptions.add("-XprintRounds"); CompilationTask task = compiler.getTask(printWriter, manager, listener, copyOptions, null, units); Boolean result = task.call(); @@ -154,6 +154,8 @@ public class BatchTestUtils { String errorOutput = stringWriter.getBuffer().toString(); System.err.println("Compilation failed: " + errorOutput); junit.framework.TestCase.assertTrue("Compilation failed : " + errorOutput, false); + } else { + junit.framework.TestCase.assertEquals("succeeded", System.getProperty(processor)); } if (!processBinariesAgain) { return; @@ -164,6 +166,7 @@ public class BatchTestUtils { System.clearProperty(processor); copyOptions = new ArrayList<>(); copyOptions.addAll(options); + copyOptions.add("-Abinary"); copyOptions.add("-cp"); copyOptions.add(_jls8ProcessorJarPath + File.pathSeparator + _tmpGenFolderName); copyOptions.add("--processor-module-path"); @@ -257,6 +260,7 @@ public class BatchTestUtils { System.clearProperty(processor); copyOptions = new ArrayList<>(); copyOptions.addAll(options); + copyOptions.add("-Abinary"); copyOptions.add("-cp"); copyOptions.add(_tmpBinFolderName + File.pathSeparator + _jls8ProcessorJarPath + File.pathSeparator + _tmpGenFolderName); copyOptions.add("-processorpath"); diff --git a/org.eclipse.jdt.compiler.apt.tests/src/org/eclipse/jdt/compiler/apt/tests/Java12ElementsTests.java b/org.eclipse.jdt.compiler.apt.tests/src/org/eclipse/jdt/compiler/apt/tests/Java12ElementsTests.java new file mode 100644 index 0000000000..24f27a71de --- /dev/null +++ b/org.eclipse.jdt.compiler.apt.tests/src/org/eclipse/jdt/compiler/apt/tests/Java12ElementsTests.java @@ -0,0 +1,109 @@ +/******************************************************************************* + * Copyright (c) 2019 IBM Corporation. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ + +package org.eclipse.jdt.compiler.apt.tests; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import javax.lang.model.SourceVersion; +import javax.tools.JavaCompiler; +import javax.tools.ToolProvider; + +import org.eclipse.jdt.internal.compiler.tool.EclipseCompiler; + +import junit.framework.TestCase; + +public class Java12ElementsTests extends TestCase { + private static final String MODULE_PROC = "org.eclipse.jdt.compiler.apt.tests.processors.elements.Java12ElementProcessor"; + + public void testRootElements1Javac() throws IOException { + JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); + internalTestWithBinary(compiler, MODULE_PROC, "12", "testRootElements1", null, "modules2"); + } + public void testRootElements1() throws IOException { + JavaCompiler compiler = BatchTestUtils.getEclipseCompiler(); + internalTestWithBinary(compiler, MODULE_PROC, "12", "testRootElements1", null, "modules2"); + } + public void testRootElements2Javac() throws IOException { + JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); + internalTestWithBinary(compiler, MODULE_PROC, "12", "testRootElements2", null, "modules3"); + } + public void testRootElements2() throws IOException { + JavaCompiler compiler = BatchTestUtils.getEclipseCompiler(); + internalTestWithBinary(compiler, MODULE_PROC, "12", "testRootElements2", null, "modules3"); + } + + protected void internalTestWithBinary(JavaCompiler compiler, String processor, String compliance, String testMethod, String testClass, String resourceArea) throws IOException { + if (!canRunJava12()) { + return; + } + System.clearProperty(processor); + File targetFolder = TestUtils.concatPath(BatchTestUtils.getSrcFolderName(), "mod_locations", resourceArea); + if (testClass == null || testClass.equals("")) { + BatchTestUtils.copyResources("mod_locations/" + resourceArea, targetFolder); + } else { + BatchTestUtils.copyResource("mod_locations/" + resourceArea + "/" + testClass, targetFolder); + } + + + List<String> options = new ArrayList<String>(); + options.add("-A" + processor); + options.add("-A" + testMethod); + options.add("-processor"); + options.add(processor); + // Javac 1.8 doesn't (yet?) support the -1.8 option + if (compiler instanceof EclipseCompiler) { + options.add("-" + compliance); + } else { + options.add("-source"); + options.add(compliance); + } + BatchTestUtils.compileInModuleMode(compiler, options, processor, targetFolder, null, true); + // If it succeeded, the processor will have set this property to "succeeded"; + // if not, it will set it to an error value. + assertEquals("succeeded", System.getProperty(processor)); + } + public boolean canRunJava12() { + try { + SourceVersion.valueOf("RELEASE_12"); + } catch(IllegalArgumentException iae) { + return false; + } + return true; + } + /* (non-Javadoc) + * @see junit.framework.TestCase#setUp() + */ + @Override + protected void setUp() throws Exception { + super.setUp(); + BatchTestUtils.init(); + } + + /* (non-Javadoc) + * @see junit.framework.TestCase#tearDown() + */ + @Override + protected void tearDown() throws Exception { + super.tearDown(); + } + +}
\ No newline at end of file diff --git a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/RoundEnvImpl.java b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/RoundEnvImpl.java index 185dfd8f8a..00afab42dd 100644 --- a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/RoundEnvImpl.java +++ b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/RoundEnvImpl.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2017 IBM Corporation and others. + * Copyright (c) 2005, 2019 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -8,6 +8,10 @@ * * SPDX-License-Identifier: EPL-2.0 * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * IBM Corporation - initial API and implementation * IBM Corporation - Fix for bug 328575 @@ -34,6 +38,7 @@ import org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding; import org.eclipse.jdt.internal.compiler.lookup.Binding; import org.eclipse.jdt.internal.compiler.lookup.FieldBinding; import org.eclipse.jdt.internal.compiler.lookup.MethodBinding; +import org.eclipse.jdt.internal.compiler.lookup.ModuleBinding; import org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding; import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding; import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding; @@ -235,6 +240,11 @@ public class RoundEnvImpl implements RoundEnvironment throw new IllegalArgumentException("Top-level type binding could not be converted to element: " + typeBinding); //$NON-NLS-1$ } elements.add(element); + ModuleBinding binding = typeBinding.module(); + if (binding != null) { + Element m = _factory.newElement(binding); + elements.add(m); + } } } _rootElements = elements; diff --git a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/ModuleElementImpl.java b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/ModuleElementImpl.java index adda859990..e6e473e91c 100644 --- a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/ModuleElementImpl.java +++ b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/ModuleElementImpl.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2018 IBM Corporation and others. + * Copyright (c) 2018, 2019 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -7,7 +7,11 @@ * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 - * + * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * IBM Corporation - initial API and implementation * @@ -90,8 +94,18 @@ public class ModuleElementImpl extends ElementImpl implements ModuleElement { for (PackageBinding p : packs) { if (p == null) continue; - if (!p.hasCompilationUnit(true)) + if (p instanceof SplitPackageBinding) { + // select from incarnations the unique package containing CUs, if any: + for (PackageBinding incarnation : ((SplitPackageBinding) p).incarnations) { + if (incarnation.enclosingModule == module && incarnation.hasCompilationUnit(true)) { + unique.add(getModulesPackageBinding(p)); + } + } continue; + } else { + if (!p.hasCompilationUnit(true)) + continue; + } unique.add(getModulesPackageBinding(p)); } if (module.isUnnamed()) { diff --git a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/util/JrtFileSystem.java b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/util/JrtFileSystem.java index b23b9f4192..a34fbbf62e 100644 --- a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/util/JrtFileSystem.java +++ b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/util/JrtFileSystem.java @@ -92,12 +92,8 @@ public class JrtFileSystem extends Archive { } @Override - public FileVisitResult visitModule(Path mod) throws IOException { - String name = mod.getFileName().toString(); - if (name.endsWith("/")) { //$NON-NLS-1$ - name = name.substring(0, name.length() - 1); - } - JrtFileSystem.this.modulePathMap.put(name, mod); + public FileVisitResult visitModule(Path path, String name) throws IOException { + JrtFileSystem.this.modulePathMap.put(name, path); return FileVisitResult.CONTINUE; } }, JRTUtil.NOTIFY_MODULES); diff --git a/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/EclipseCompiler.java b/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/EclipseCompiler.java index 4b3d38a849..b942161690 100644 --- a/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/EclipseCompiler.java +++ b/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/EclipseCompiler.java @@ -119,9 +119,10 @@ public class EclipseCompiler implements JavaCompiler { eclipseCompiler2.fileManager = this.getStandardFileManager(someDiagnosticListener, null, null); } - eclipseCompiler2.options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_11); - eclipseCompiler2.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_11); - eclipseCompiler2.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_11); + String latest = CompilerOptions.getLatestVersion(); + eclipseCompiler2.options.put(CompilerOptions.OPTION_Compliance, latest); + eclipseCompiler2.options.put(CompilerOptions.OPTION_Source, latest); + eclipseCompiler2.options.put(CompilerOptions.OPTION_TargetPlatform, latest); ArrayList<String> allOptions = new ArrayList<>(); if (options != null) { diff --git a/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/EclipseFileManager.java b/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/EclipseFileManager.java index 05fcedbc18..cd80ce6633 100644 --- a/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/EclipseFileManager.java +++ b/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/EclipseFileManager.java @@ -1365,10 +1365,10 @@ public class EclipseFileManager implements StandardJavaFileManager { // FIXME: same for module source path? Map<String, String> options = new HashMap<>(); // FIXME: Find a way to get the options from the EclipseCompiler and pass it to the parser. - // FIXME: need to be the latest and not hardcoded value - options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_11); - options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_11); - options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_11); + String latest = CompilerOptions.getLatestVersion(); + options.put(CompilerOptions.OPTION_Compliance, latest); + options.put(CompilerOptions.OPTION_Source, latest); + options.put(CompilerOptions.OPTION_TargetPlatform, latest); CompilerOptions compilerOptions = new CompilerOptions(options); ProblemReporter problemReporter = new ProblemReporter( diff --git a/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/JrtFileSystem.java b/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/JrtFileSystem.java index 57e6bd9a82..a140e15240 100644 --- a/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/JrtFileSystem.java +++ b/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/JrtFileSystem.java @@ -92,12 +92,8 @@ public class JrtFileSystem extends Archive { } @Override - public FileVisitResult visitModule(Path mod) throws IOException { - String name = mod.getFileName().toString(); - if (name.endsWith("/")) { //$NON-NLS-1$ - name = name.substring(0, name.length() - 1); - } - JrtFileSystem.this.modulePathMap.put(name, mod); + public FileVisitResult visitModule(Path path, String name) throws IOException { + JrtFileSystem.this.modulePathMap.put(name, path); return FileVisitResult.CONTINUE; } }, JRTUtil.NOTIFY_MODULES); diff --git a/org.eclipse.jdt.core.internal.tools/.classpath b/org.eclipse.jdt.core.internal.tools/.classpath index 01836c4842..ea3258e180 100644 --- a/org.eclipse.jdt.core.internal.tools/.classpath +++ b/org.eclipse.jdt.core.internal.tools/.classpath @@ -3,5 +3,6 @@ <classpathentry kind="src" path="src"/> <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/> + <classpathentry combineaccessrules="false" kind="src" path="/org.eclipse.jdt.core"/> <classpathentry kind="output" path="bin"/> </classpath> diff --git a/org.eclipse.jdt.core.internal.tools/src/org/eclipse/jdt/core/internal/tools/disassembler/Disassembler.java b/org.eclipse.jdt.core.internal.tools/src/org/eclipse/jdt/core/internal/tools/disassembler/Disassembler.java new file mode 100644 index 0000000000..82ed5c2605 --- /dev/null +++ b/org.eclipse.jdt.core.internal.tools/src/org/eclipse/jdt/core/internal/tools/disassembler/Disassembler.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright (c) 2019 IBM Corporation and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.core.internal.tools.disassembler; + +import java.io.File; +import java.io.IOException; + +import org.eclipse.jdt.core.ToolFactory; +import org.eclipse.jdt.core.util.ClassFileBytesDisassembler; +import org.eclipse.jdt.core.util.ClassFormatException; +import org.eclipse.jdt.internal.compiler.util.Util; + +public class Disassembler { + + public static void main(String[] args) throws IOException, ClassFormatException { + if (args.length != 1) { + System.out.println("Usage: Disassembler <path to a .class file>"); //$NON-NLS-1$ + return; + } + ClassFileBytesDisassembler disassembler = ToolFactory.createDefaultClassFileBytesDisassembler(); + byte[] classFileBytes = Util.getFileByteContent(new File(args[0])); + System.out.println(disassembler.disassemble(classFileBytes, System.getProperty("line.separator"), org.eclipse.jdt.core.util.ClassFileBytesDisassembler.SYSTEM)); //$NON-NLS-1$ + } + +} diff --git a/org.eclipse.jdt.core.internal.tools/src/org/eclipse/jdt/core/internal/tools/unicode/CodePointsBuilder.java b/org.eclipse.jdt.core.internal.tools/src/org/eclipse/jdt/core/internal/tools/unicode/CodePointsBuilder.java index b86075dede..ca8ae6c104 100644 --- a/org.eclipse.jdt.core.internal.tools/src/org/eclipse/jdt/core/internal/tools/unicode/CodePointsBuilder.java +++ b/org.eclipse.jdt.core.internal.tools/src/org/eclipse/jdt/core/internal/tools/unicode/CodePointsBuilder.java @@ -1,3 +1,20 @@ +/*******************************************************************************
+ * Copyright (c) 2019 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
package org.eclipse.jdt.core.internal.tools.unicode;
import java.text.DecimalFormat;
diff --git a/org.eclipse.jdt.core.internal.tools/src/org/eclipse/jdt/core/internal/tools/unicode/Environment.java b/org.eclipse.jdt.core.internal.tools/src/org/eclipse/jdt/core/internal/tools/unicode/Environment.java index e2fa003283..599cdfa231 100644 --- a/org.eclipse.jdt.core.internal.tools/src/org/eclipse/jdt/core/internal/tools/unicode/Environment.java +++ b/org.eclipse.jdt.core.internal.tools/src/org/eclipse/jdt/core/internal/tools/unicode/Environment.java @@ -1,3 +1,20 @@ +/******************************************************************************* + * Copyright (c) 2019 IBM Corporation and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ package org.eclipse.jdt.core.internal.tools.unicode; public abstract class Environment { diff --git a/org.eclipse.jdt.core.internal.tools/src/org/eclipse/jdt/core/internal/tools/unicode/FileEncoder.java b/org.eclipse.jdt.core.internal.tools/src/org/eclipse/jdt/core/internal/tools/unicode/FileEncoder.java index ad189dde3d..904e32b1a0 100644 --- a/org.eclipse.jdt.core.internal.tools/src/org/eclipse/jdt/core/internal/tools/unicode/FileEncoder.java +++ b/org.eclipse.jdt.core.internal.tools/src/org/eclipse/jdt/core/internal/tools/unicode/FileEncoder.java @@ -1,3 +1,20 @@ +/*******************************************************************************
+ * Copyright (c) 2019 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
package org.eclipse.jdt.core.internal.tools.unicode;
import java.io.DataOutputStream;
diff --git a/org.eclipse.jdt.core.internal.tools/src/org/eclipse/jdt/core/internal/tools/unicode/GenerateIdentifierPartResources.java b/org.eclipse.jdt.core.internal.tools/src/org/eclipse/jdt/core/internal/tools/unicode/GenerateIdentifierPartResources.java index 8ed6e75dd0..dc29b005b2 100644 --- a/org.eclipse.jdt.core.internal.tools/src/org/eclipse/jdt/core/internal/tools/unicode/GenerateIdentifierPartResources.java +++ b/org.eclipse.jdt.core.internal.tools/src/org/eclipse/jdt/core/internal/tools/unicode/GenerateIdentifierPartResources.java @@ -1,3 +1,20 @@ +/******************************************************************************* + * Copyright (c) 2019 IBM Corporation and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ package org.eclipse.jdt.core.internal.tools.unicode; import java.io.IOException; diff --git a/org.eclipse.jdt.core.internal.tools/src/org/eclipse/jdt/core/internal/tools/unicode/GenerateIdentifierStartResources.java b/org.eclipse.jdt.core.internal.tools/src/org/eclipse/jdt/core/internal/tools/unicode/GenerateIdentifierStartResources.java index d60b983090..6e070a6071 100644 --- a/org.eclipse.jdt.core.internal.tools/src/org/eclipse/jdt/core/internal/tools/unicode/GenerateIdentifierStartResources.java +++ b/org.eclipse.jdt.core.internal.tools/src/org/eclipse/jdt/core/internal/tools/unicode/GenerateIdentifierStartResources.java @@ -1,3 +1,20 @@ +/******************************************************************************* + * Copyright (c) 2019 IBM Corporation and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ package org.eclipse.jdt.core.internal.tools.unicode; import java.io.IOException; diff --git a/org.eclipse.jdt.core.internal.tools/src/org/eclipse/jdt/core/internal/tools/unicode/PartEnvironment.java b/org.eclipse.jdt.core.internal.tools/src/org/eclipse/jdt/core/internal/tools/unicode/PartEnvironment.java index 1abf8350f1..399d962418 100644 --- a/org.eclipse.jdt.core.internal.tools/src/org/eclipse/jdt/core/internal/tools/unicode/PartEnvironment.java +++ b/org.eclipse.jdt.core.internal.tools/src/org/eclipse/jdt/core/internal/tools/unicode/PartEnvironment.java @@ -1,3 +1,20 @@ +/******************************************************************************* + * Copyright (c) 2019 IBM Corporation and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ package org.eclipse.jdt.core.internal.tools.unicode; import java.util.HashSet; diff --git a/org.eclipse.jdt.core.internal.tools/src/org/eclipse/jdt/core/internal/tools/unicode/StartEnvironment.java b/org.eclipse.jdt.core.internal.tools/src/org/eclipse/jdt/core/internal/tools/unicode/StartEnvironment.java index ec6b50ad87..bde56b3d6d 100644 --- a/org.eclipse.jdt.core.internal.tools/src/org/eclipse/jdt/core/internal/tools/unicode/StartEnvironment.java +++ b/org.eclipse.jdt.core.internal.tools/src/org/eclipse/jdt/core/internal/tools/unicode/StartEnvironment.java @@ -1,3 +1,20 @@ +/******************************************************************************* + * Copyright (c) 2019 IBM Corporation and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ package org.eclipse.jdt.core.internal.tools.unicode; import java.util.HashSet; diff --git a/org.eclipse.jdt.core.internal.tools/src/org/eclipse/jdt/core/internal/tools/unicode/TableBuilder.java b/org.eclipse.jdt.core.internal.tools/src/org/eclipse/jdt/core/internal/tools/unicode/TableBuilder.java index 870d3eb1b3..df2b2bb762 100644 --- a/org.eclipse.jdt.core.internal.tools/src/org/eclipse/jdt/core/internal/tools/unicode/TableBuilder.java +++ b/org.eclipse.jdt.core.internal.tools/src/org/eclipse/jdt/core/internal/tools/unicode/TableBuilder.java @@ -1,3 +1,20 @@ +/*******************************************************************************
+ * Copyright (c) 2019 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
package org.eclipse.jdt.core.internal.tools.unicode;
import java.io.File;
diff --git a/org.eclipse.jdt.core.internal.tools/src/org/eclipse/jdt/core/internal/tools/unicode/UnicodeResourceGenerator.java b/org.eclipse.jdt.core.internal.tools/src/org/eclipse/jdt/core/internal/tools/unicode/UnicodeResourceGenerator.java index 4d26774271..626272af47 100644 --- a/org.eclipse.jdt.core.internal.tools/src/org/eclipse/jdt/core/internal/tools/unicode/UnicodeResourceGenerator.java +++ b/org.eclipse.jdt.core.internal.tools/src/org/eclipse/jdt/core/internal/tools/unicode/UnicodeResourceGenerator.java @@ -1,3 +1,20 @@ +/******************************************************************************* + * Copyright (c) 2019 IBM Corporation and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ package org.eclipse.jdt.core.internal.tools.unicode; import java.io.IOException; diff --git a/org.eclipse.jdt.core.tests.compiler/pom.xml b/org.eclipse.jdt.core.tests.compiler/pom.xml index dd399716a6..424ffdc126 100644 --- a/org.eclipse.jdt.core.tests.compiler/pom.xml +++ b/org.eclipse.jdt.core.tests.compiler/pom.xml @@ -137,6 +137,37 @@ <tycho.surefire.argLine>--add-modules ALL-SYSTEM -Dcompliance=1.4,1.7,1.8,11</tycho.surefire.argLine> </properties> </profile> + <profile> + <id>test-on-javase-12</id> + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-toolchains-plugin</artifactId> + <version>1.1</version> + <executions> + <execution> + <phase>validate</phase> + <goals> + <goal>toolchain</goal> + </goals> + </execution> + </executions> + <configuration> + <toolchains> + <jdk> + <id>JavaSE-12</id> + </jdk> + </toolchains> + </configuration> + </plugin> + </plugins> + </build> + <properties> + <!-- Overridden in https://ci.eclipse.org/jdt/job/eclipse.jdt.core-run.javac-12/configure --> + <tycho.surefire.argLine>--add-modules ALL-SYSTEM -Dcompliance=1.4,1.7,1.8,12</tycho.surefire.argLine> + </properties> + </profile> </profiles> </project> diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/ComplianceDiagnoseTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/ComplianceDiagnoseTest.java index 4fb966bd6b..13dadabc3c 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/ComplianceDiagnoseTest.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/ComplianceDiagnoseTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2016 IBM Corporation and others. + * Copyright (c) 2000, 2018 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -8,6 +8,10 @@ * * SPDX-License-Identifier: EPL-2.0 * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * IBM Corporation - initial API and implementation * Jesper S Moller - realigned with bug 399695 @@ -27,7 +31,7 @@ public class ComplianceDiagnoseTest extends AbstractRegressionTest { // Static initializer to specify tests subset using TESTS_* static variables // All specified tests which does not belong to the class are skipped... static { -// TESTS_NAMES = new String[] { "test0061" }; +// TESTS_NAMES = new String[] { "testBug531714" }; // TESTS_NUMBERS = new int[] { 50 }; // TESTS_RANGE = new int[] { 21, 50 }; } @@ -1250,12 +1254,22 @@ public void test0027() { }; String expected13ProblemLog = - "----------\n" + - "1. ERROR in X.java (at line 3)\n" + - " for(Object o : switch){\n" + - " ^\n" + - "Syntax error, insert \"; ; ) Statement\" to complete BlockStatements\n" + - "----------\n"; + "----------\n" + + "1. ERROR in X.java (at line 3)\n" + + " for(Object o : switch){\n" + + " ^\n" + + "Syntax error on token \":\", delete this token\n" + + "----------\n" + + "2. ERROR in X.java (at line 3)\n" + + " for(Object o : switch){\n" + + " ^\n" + + "Syntax error, insert \": Expression )\" to complete EnhancedForStatementHeader\n" + // FIXME: bogus suggestion, this rule is compliance 1.5 + "----------\n" + + "3. ERROR in X.java (at line 3)\n" + + " for(Object o : switch){\n" + + " ^\n" + + "Syntax error, insert \"Statement\" to complete BlockStatements\n" + + "----------\n"; String expected14ProblemLog = expected13ProblemLog; @@ -3510,4 +3524,107 @@ public void testBug440285() { "Type arguments are not allowed here\n" + "----------\n"); } +public void testBug531714_001() { + if (this.complianceLevel >= ClassFileConstants.JDK12) + return; + String[] testFiles = new String[] { + "X.java", + "public class X {\n" + + " static int twice(int i) {\n" + + " int tw = switch (i) {\n" + + " case 0 -> i * 0;\n" + + " case 1 -> 2;\n" + + " default -> 3;\n" + + " };\n" + + " return tw;\n" + + " }\n" + + " public static void main(String[] args) {\n" + + " System.out.print(twice(3));\n" + + " }\n" + + "}\n", + }; + + String expectedProblemLog = + "----------\n" + + "1. ERROR in X.java (at line 3)\n" + + " int tw = switch (i) {\n" + + " case 0 -> i * 0;\n" + + " case 1 -> 2;\n" + + " default -> 3;\n" + + " };\n" + + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + + "The preview feature Switch Expressions is only available with source level 12 and above\n" + + "----------\n" + + "2. ERROR in X.java (at line 4)\n" + + " case 0 -> i * 0;\n" + + " ^^^^^^\n" + + "The preview feature Case Labels with \'->\' is only available with source level 12 and above\n" + + "----------\n" + + "3. ERROR in X.java (at line 5)\n" + + " case 1 -> 2;\n" + + " ^^^^^^\n" + + "The preview feature Case Labels with \'->\' is only available with source level 12 and above\n" + + "----------\n" + + "4. ERROR in X.java (at line 6)\n" + + " default -> 3;\n" + + " ^^^^^^^\n" + + "The preview feature Case Labels with \'->\' is only available with source level 12 and above\n" + + "----------\n"; + + runComplianceParserTest( + testFiles, + expectedProblemLog, + expectedProblemLog, + expectedProblemLog, + expectedProblemLog, + expectedProblemLog + ); +} +public void testBug531714_002() { + if (this.complianceLevel >= ClassFileConstants.JDK12) + return; + String[] testFiles = new String[] { + "X.java", + "public class X {\n" + + " static int twice(int i) {\n" + + " switch (i) {\n" + + " case 0 -> i * 0;\n" + + " case 1 -> 2;\n" + + " default -> 3;\n" + + " }\n" + + " return 0;\n" + + " }\n" + + " public static void main(String[] args) {\n" + + " System.out.print(twice(3));\n" + + " }\n" + + "}\n", + }; + + String expectedProblemLog = + "----------\n" + + "1. ERROR in X.java (at line 4)\n" + + " case 0 -> i * 0;\n" + + " ^^^^^^\n" + + "The preview feature Case Labels with \'->\' is only available with source level 12 and above\n" + + "----------\n" + + "2. ERROR in X.java (at line 5)\n" + + " case 1 -> 2;\n" + + " ^^^^^^\n" + + "The preview feature Case Labels with \'->\' is only available with source level 12 and above\n" + + "----------\n" + + "3. ERROR in X.java (at line 6)\n" + + " default -> 3;\n" + + " ^^^^^^^\n" + + "The preview feature Case Labels with \'->\' is only available with source level 12 and above\n" + + "----------\n"; + + runComplianceParserTest( + testFiles, + expectedProblemLog, + expectedProblemLog, + expectedProblemLog, + expectedProblemLog, + expectedProblemLog + ); +} } diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/JavadocCompletionParserTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/JavadocCompletionParserTest.java index a12ef9f626..2c248093e2 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/JavadocCompletionParserTest.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/JavadocCompletionParserTest.java @@ -8,6 +8,10 @@ * * SPDX-License-Identifier: EPL-2.0 * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ @@ -183,11 +187,16 @@ protected void verifyAllTagsCompletion() { additionalTags = new char[][] { TAG_INHERITDOC, TAG_LINKPLAIN, TAG_VALUE }; - } else if(this.complianceLevel > ClassFileConstants.JDK1_4) { + } else if(this.complianceLevel > ClassFileConstants.JDK1_4 && this.complianceLevel < ClassFileConstants.JDK12) { additionalTags = new char[][] { TAG_INHERITDOC, TAG_LINKPLAIN, TAG_VALUE, TAG_CODE, TAG_LITERAL }; + } else if(this.complianceLevel >= ClassFileConstants.JDK12) { + additionalTags = new char[][] { + TAG_INHERITDOC, TAG_LINKPLAIN, TAG_VALUE, + TAG_CODE, TAG_LITERAL, TAG_SYSTEM_PROPERTY + }; } allTagsFinal = this.complianceLevel > ClassFileConstants.JDK1_8 ? allTagsJava9Plus : allTags; if (additionalTags != null) { @@ -279,11 +288,16 @@ public void test006() { additionalTags = new char[][] { TAG_INHERITDOC, TAG_LINKPLAIN, TAG_VALUE }; - } else if (this.complianceLevel > ClassFileConstants.JDK1_4) { + } else if(this.complianceLevel > ClassFileConstants.JDK1_4 && this.complianceLevel < ClassFileConstants.JDK12) { additionalTags = new char[][] { TAG_INHERITDOC, TAG_LINKPLAIN, TAG_VALUE, TAG_CODE, TAG_LITERAL }; + } else if(this.complianceLevel >= ClassFileConstants.JDK12) { + additionalTags = new char[][] { + TAG_INHERITDOC, TAG_LINKPLAIN, TAG_VALUE, + TAG_CODE, TAG_LITERAL, TAG_SYSTEM_PROPERTY + }; } if (additionalTags != null) { int length = allTags.length; @@ -422,7 +436,9 @@ public void test020() { " */\n" + "public class Test {}\n"; verifyCompletionInJavadoc(source, "@s"); - verifyCompletionOnJavadocTag("s".toCharArray(), new char[][] { TAG_SEE, TAG_SINCE, TAG_SERIAL, TAG_SERIAL_DATA, TAG_SERIAL_FIELD }, false); + char[][] expectedTags = {TAG_SEE, TAG_SINCE, TAG_SERIAL, TAG_SERIAL_DATA, TAG_SERIAL_FIELD}; + char[][] expectedTags12Plus = {TAG_SEE, TAG_SINCE, TAG_SERIAL, TAG_SERIAL_DATA, TAG_SERIAL_FIELD,TAG_SYSTEM_PROPERTY}; + verifyCompletionOnJavadocTag("s".toCharArray(),this.complianceLevel >= ClassFileConstants.JDK12 ? expectedTags12Plus : expectedTags, false); CompletionOnJavadocTag completionTag = (CompletionOnJavadocTag) this.javadoc.getCompletionNode(); assertEquals("Invalid tag start position", 24, completionTag.tagSourceStart); assertEquals("Invalid tag end position", 28, completionTag.tagSourceEnd+1); @@ -500,12 +516,16 @@ public void test025() { additionalTags = new char[][] { TAG_INHERITDOC, TAG_LINKPLAIN, TAG_VALUE }; - } - else if (this.complianceLevel > ClassFileConstants.JDK1_4) { + }else if (this.complianceLevel > ClassFileConstants.JDK1_4 && this.complianceLevel < ClassFileConstants.JDK12) { additionalTags = new char[][] { TAG_INHERITDOC, TAG_LINKPLAIN, TAG_VALUE, TAG_CODE, TAG_LITERAL }; + }else if (this.complianceLevel >= ClassFileConstants.JDK12) { + additionalTags = new char[][] { + TAG_INHERITDOC, TAG_LINKPLAIN, TAG_VALUE, + TAG_CODE, TAG_LITERAL, TAG_SYSTEM_PROPERTY + }; } if (additionalTags != null) { int length = allTags.length; @@ -575,12 +595,18 @@ public void test028() { TAG_INHERITDOC, TAG_LINKPLAIN, TAG_VALUE }; } - else if (this.complianceLevel > ClassFileConstants.JDK1_4) { + else if(this.complianceLevel > ClassFileConstants.JDK1_4 && this.complianceLevel < ClassFileConstants.JDK12) { additionalTags = new char[][] { TAG_INHERITDOC, TAG_LINKPLAIN, TAG_VALUE, TAG_CODE, TAG_LITERAL }; + } else if(this.complianceLevel >= ClassFileConstants.JDK12) { + additionalTags = new char[][] { + TAG_INHERITDOC, TAG_LINKPLAIN, TAG_VALUE, + TAG_CODE, TAG_LITERAL, TAG_SYSTEM_PROPERTY + }; } + if (additionalTags != null) { int length = allTags.length; int add = additionalTags.length; diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/SelectionParserTest12.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/SelectionParserTest12.java new file mode 100644 index 0000000000..d3f097fcb8 --- /dev/null +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/SelectionParserTest12.java @@ -0,0 +1,1074 @@ +/******************************************************************************* + * Copyright (c) 2019 IBM Corporation and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.core.tests.compiler.parser; + +import org.eclipse.jdt.core.JavaModelException; + +import junit.framework.Test; + +public class SelectionParserTest12 extends AbstractSelectionTest { +static { +// TESTS_NUMBERS = new int[] { 1 }; +// TESTS_NAMES = new String[] { "test005" }; +} +public static Test suite() { + return buildMinimalComplianceTestSuite(SelectionParserTest12.class, F_12); +} + +public SelectionParserTest12(String testName) { + super(testName); +} +/* + * Multi constant case statement with ':', selection node is the string constant + */ +public void test001() throws JavaModelException { + String string = "public class X {\n" + + "static final String ONE=\"One\", TWO = \"Two\", THREE=\"Three\";\n" + + " public static void foo(String num) {\n" + + " switch (num) {\n" + + " case ONE, TWO, THREE:\n" + + " System.out.println(num);\n" + + " break;\n" + + " }" + + " }\n" + + "}"; + + String selection = "ONE"; + String selectKey = "<SelectOnName:"; + String expectedSelection = selectKey + selection + ">"; + + String selectionIdentifier = "ONE"; + String expectedUnitDisplayString = + "public class X {\n" + + " static final String ONE;\n" + + " static final String TWO;\n" + + " static final String THREE;\n" + + " <clinit>() {\n" + + " }\n" + + " public X() {\n" + + " }\n" + + " public static void foo(String num) {\n" + + " {\n" + + " switch (num) {\n" + + " case <SelectOnName:ONE> :\n" + + " }\n" + + " }\n" + + " }\n" + + "}\n"; + String expectedReplacedSource = "ONE"; + String testName = "X.java"; + + int selectionStart = string.lastIndexOf(selection); + int selectionEnd = string.lastIndexOf(selection) + selection.length() - 1; + + checkMethodParse(string.toCharArray(), selectionStart, selectionEnd, expectedSelection, expectedUnitDisplayString, + selectionIdentifier, expectedReplacedSource, testName); +} +/* + * Multi constant case statement with ':', selection node is the first enum constant + */ +public void test002() throws JavaModelException { + String string = "public class X {\n" + + " public static void foo(Num num) {\n" + + " switch (num) {\n" + + " case ONE, TWO, THREE:\n" + + " System.out.println(num);\n" + + " break;\n" + + " }" + + " }\n" + + " enum Num { ONE, TWO, THREE;}\n" + + "}"; + + String selection = "ONE"; + String selectKey = "<SelectOnName:"; + String expectedSelection = selectKey + selection + ">"; + + String selectionIdentifier = "ONE"; + String expectedUnitDisplayString = + "public class X {\n" + + " enum Num {\n" + + " ONE(),\n" + + " TWO(),\n" + + " THREE(),\n" + + " <clinit>() {\n" + + " }\n" + + " Num() {\n" + + " }\n" + + " }\n" + + " public X() {\n" + + " }\n" + + " public static void foo(Num num) {\n" + + " {\n" + + " switch (num) {\n" + + " case <SelectOnName:ONE> :\n" + + " }\n" + + " }\n" + + " }\n" + + "}\n"; + String expectedReplacedSource = "ONE"; + String testName = "X.java"; + + int selectionStart = string.indexOf(selection); + int selectionEnd = selectionStart + selection.length() - 1; + + checkMethodParse(string.toCharArray(), selectionStart, selectionEnd, expectedSelection, expectedUnitDisplayString, + selectionIdentifier, expectedReplacedSource, testName); +} +/* + * Multi constant case statement with ':', selection node is the second string constant + */ +public void test003() throws JavaModelException { + String string = "public class X {\n" + + "static final String ONE=\"One\", TWO = \"Two\", THREE=\"Three\";\n" + + " public static void foo(String num) {\n" + + " switch (num) {\n" + + " case ONE, TWO, THREE:\n" + + " System.out.println(num);\n" + + " break;\n" + + " }" + + " }\n" + + "}"; + + String selection = "TWO"; + String selectKey = "<SelectOnName:"; + String expectedSelection = selectKey + selection + ">"; + + String selectionIdentifier = "TWO"; + String expectedUnitDisplayString = + "public class X {\n" + + " static final String ONE;\n" + + " static final String TWO;\n" + + " static final String THREE;\n" + + " <clinit>() {\n" + + " }\n" + + " public X() {\n" + + " }\n" + + " public static void foo(String num) {\n" + + " {\n" + + " switch (num) {\n" + + " case <SelectOnName:TWO> :\n" + + " }\n" + + " }\n" + + " }\n" + + "}\n"; + String expectedReplacedSource = "TWO"; + String testName = "X.java"; + + int selectionStart = string.lastIndexOf(selection); + int selectionEnd = string.lastIndexOf(selection) + selection.length() - 1; + + checkMethodParse(string.toCharArray(), selectionStart, selectionEnd, expectedSelection, expectedUnitDisplayString, + selectionIdentifier, expectedReplacedSource, testName); +} +/* + * Multi constant case statement with ':', selection node is the second enum constant + */ +public void test004() throws JavaModelException { + String string = "public class X {\n" + + " public static void foo(Num num) {\n" + + " switch (num) {\n" + + " case ONE, TWO, THREE:\n" + + " System.out.println(num);\n" + + " break;\n" + + " }" + + " }\n" + + " enum Num { ONE, TWO, THREE;}\n" + + "}"; + + String selection = "TWO"; + String selectKey = "<SelectOnName:"; + String expectedSelection = selectKey + selection + ">"; + + String selectionIdentifier = "TWO"; + String expectedUnitDisplayString = + "public class X {\n" + + " enum Num {\n" + + " ONE(),\n" + + " TWO(),\n" + + " THREE(),\n" + + " <clinit>() {\n" + + " }\n" + + " Num() {\n" + + " }\n" + + " }\n" + + " public X() {\n" + + " }\n" + + " public static void foo(Num num) {\n" + + " {\n" + + " switch (num) {\n" + + " case <SelectOnName:TWO> :\n" + + " }\n" + + " }\n" + + " }\n" + + "}\n"; + String expectedReplacedSource = "TWO"; + String testName = "X.java"; + + int selectionStart = string.indexOf(selection); + int selectionEnd = selectionStart + selection.length() - 1; + + checkMethodParse(string.toCharArray(), selectionStart, selectionEnd, expectedSelection, expectedUnitDisplayString, + selectionIdentifier, expectedReplacedSource, testName); +} +/* + * Multi constant case statement with '->', selection node is the string constant + */ +public void test005() throws JavaModelException { + String string = "public class X {\n" + + "static final String ONE=\"One\", TWO = \"Two\", THREE=\"Three\";\n" + + " public static void foo(String num) {\n" + + " switch (num) {\n" + + " case ONE, TWO, THREE ->\n" + + " System.out.println(num);\n" + + " }" + + " }\n" + + "}"; + /* + * Note: The completion parser ignores the -> that follows and we end up creating + * the CaseStatement without maring it as an Expression, hence the ':' instead of the '->' + */ + String selection = "ONE"; + String selectKey = "<SelectOnName:"; + String expectedSelection = selectKey + selection + ">"; + String selectionIdentifier = "ONE"; + String expectedUnitDisplayString = + "public class X {\n" + + " static final String ONE;\n" + + " static final String TWO;\n" + + " static final String THREE;\n" + + " <clinit>() {\n" + + " }\n" + + " public X() {\n" + + " }\n" + + " public static void foo(String num) {\n" + + " {\n" + + " switch (num) {\n" + + " case <SelectOnName:ONE> :\n" + + " }\n" + + " }\n" + + " }\n" + + "}\n"; + String expectedReplacedSource = "ONE"; + String testName = "X.java"; + + int selectionStart = string.lastIndexOf(selection); + int selectionEnd = string.lastIndexOf(selection) + selection.length() - 1; + + checkMethodParse(string.toCharArray(), selectionStart, selectionEnd, expectedSelection, expectedUnitDisplayString, + selectionIdentifier, expectedReplacedSource, testName); +} +/* + * Multi constant case statement with '->', selection node is the first enum constant + */ +public void test006() throws JavaModelException { + String string = "public class X {\n" + + " public static void foo(Num num) {\n" + + " switch (num) {\n" + + " case ONE, TWO, THREE ->\n" + + " System.out.println(num);\n" + + " break; // illegal, but should be ignored and shouldn't matter\n" + + " }" + + " }\n" + + " enum Num { ONE, TWO, THREE;}\n" + + "}"; + + String selection = "ONE"; + String selectKey = "<SelectOnName:"; + String expectedSelection = selectKey + selection + ">"; + + String selectionIdentifier = "ONE"; + String expectedUnitDisplayString = + "public class X {\n" + + " enum Num {\n" + + " ONE(),\n" + + " TWO(),\n" + + " THREE(),\n" + + " <clinit>() {\n" + + " }\n" + + " Num() {\n" + + " }\n" + + " }\n" + + " public X() {\n" + + " }\n" + + " public static void foo(Num num) {\n" + + " {\n" + + " switch (num) {\n" + + " case <SelectOnName:ONE> :\n" + + " }\n" + + " }\n" + + " }\n" + + "}\n"; + String expectedReplacedSource = "ONE"; + String testName = "X.java"; + + int selectionStart = string.indexOf(selection); + int selectionEnd = selectionStart + selection.length() - 1; + + checkMethodParse(string.toCharArray(), selectionStart, selectionEnd, expectedSelection, expectedUnitDisplayString, + selectionIdentifier, expectedReplacedSource, testName); +} +/* + * Multi constant case statement with '->', selection node is the second string constant + */ +public void test007() throws JavaModelException { + String string = "public class X {\n" + + "static final String ONE=\"One\", TWO = \"Two\", THREE=\"Three\";\n" + + " public static void foo(String num) {\n" + + " switch (num) {\n" + + " case ONE, TWO, THREE ->\n" + + " System.out.println(num);\n" + + " break;\n" + + " }" + + " }\n" + + "}"; + + String selection = "TWO"; + String selectKey = "<SelectOnName:"; + String expectedSelection = selectKey + selection + ">"; + + String selectionIdentifier = "TWO"; + String expectedUnitDisplayString = + "public class X {\n" + + " static final String ONE;\n" + + " static final String TWO;\n" + + " static final String THREE;\n" + + " <clinit>() {\n" + + " }\n" + + " public X() {\n" + + " }\n" + + " public static void foo(String num) {\n" + + " {\n" + + " switch (num) {\n" + + " case <SelectOnName:TWO> :\n" + + " }\n" + + " }\n" + + " }\n" + + "}\n"; + String expectedReplacedSource = "TWO"; + String testName = "X.java"; + + int selectionStart = string.lastIndexOf(selection); + int selectionEnd = string.lastIndexOf(selection) + selection.length() - 1; + + checkMethodParse(string.toCharArray(), selectionStart, selectionEnd, expectedSelection, expectedUnitDisplayString, + selectionIdentifier, expectedReplacedSource, testName); +} +/* + * Multi constant case statement with '->', selection node is the second enum constant + */ +public void test008() throws JavaModelException { + String string = "public class X {\n" + + " public static void foo(Num num) {\n" + + " switch (num) {\n" + + " case ONE, TWO, THREE ->\n" + + " System.out.println(num);\n" + + " break;\n" + + " }" + + " }\n" + + " enum Num { ONE, TWO, THREE;}\n" + + "}"; + + String selection = "TWO"; + String selectKey = "<SelectOnName:"; + String expectedSelection = selectKey + selection + ">"; + + String selectionIdentifier = "TWO"; + String expectedUnitDisplayString = + "public class X {\n" + + " enum Num {\n" + + " ONE(),\n" + + " TWO(),\n" + + " THREE(),\n" + + " <clinit>() {\n" + + " }\n" + + " Num() {\n" + + " }\n" + + " }\n" + + " public X() {\n" + + " }\n" + + " public static void foo(Num num) {\n" + + " {\n" + + " switch (num) {\n" + + " case <SelectOnName:TWO> :\n" + + " }\n" + + " }\n" + + " }\n" + + "}\n"; + String expectedReplacedSource = "TWO"; + String testName = "X.java"; + + int selectionStart = string.indexOf(selection); + int selectionEnd = selectionStart + selection.length() - 1; + + checkMethodParse(string.toCharArray(), selectionStart, selectionEnd, expectedSelection, expectedUnitDisplayString, + selectionIdentifier, expectedReplacedSource, testName); +} +/* + * Multi constant case statement with '->', selection is a reference in the case block + * which same as the switch's expression + */ +public void test009() throws JavaModelException { + String string = "public class X {\n" + + " public static void foo(Num num_) {\n" + + " switch (num_) {\n" + + " case ONE, TWO, THREE ->\n" + + " System.out.println(num_);\n" + + " break;\n" + + " }" + + " }\n" + + " enum Num { ONE, TWO, THREE;}\n" + + "}"; + + String selection = "num_"; + String selectKey = "<SelectOnName:"; + String expectedSelection = selectKey + selection + ">"; + + String selectionIdentifier = "num_"; + String expectedUnitDisplayString = + "public class X {\n" + + " enum Num {\n" + + " ONE(),\n" + + " TWO(),\n" + + " THREE(),\n" + + " <clinit>() {\n" + + " }\n" + + " Num() {\n" + + " }\n" + + " }\n" + + " public X() {\n" + + " }\n" + + " public static void foo(Num num_) {\n" + + " {\n" + + " <SelectOnName:num_>;\n" + + " }\n" + + " }\n" + + "}\n"; + String expectedReplacedSource = "num_"; + String testName = "X.java"; + + int selectionStart = string.lastIndexOf(selection); + int selectionEnd = selectionStart + selection.length() - 1; + + checkMethodParse(string.toCharArray(), selectionStart, selectionEnd, expectedSelection, expectedUnitDisplayString, + selectionIdentifier, expectedReplacedSource, testName); +} +/* + * Multi constant case statement with '->', selection is a reference in the case block + * which is referencing a local variable defined in the case block + */ +public void test010() throws JavaModelException { + String string = "public class X {\n" + + " public static void foo(Num num_) {\n" + + " switch (num_) {\n" + + " case ONE, TWO, THREE -> {\n" + + " int i_j = 0;" + + " System.out.println(i_j);\n" + + " break;" + + " }\n" + + " }" + + " }\n" + + " enum Num { ONE, TWO, THREE;}\n" + + "}"; + + String selection = "i_j"; + String selectKey = "<SelectOnName:"; + String expectedSelection = selectKey + selection + ">"; + + String selectionIdentifier = "i_j"; + String expectedUnitDisplayString = + "public class X {\n" + + " enum Num {\n" + + " ONE(),\n" + + " TWO(),\n" + + " THREE(),\n" + + " <clinit>() {\n" + + " }\n" + + " Num() {\n" + + " }\n" + + " }\n" + + " public X() {\n" + + " }\n" + + " public static void foo(Num num_) {\n" + + " {\n" + + " {\n" + + " int i_j;\n" + + " <SelectOnName:i_j>;\n" + + " }\n" + + " }\n" + + " }\n" + + "}\n"; + String expectedReplacedSource = "i_j"; + String testName = "X.java"; + + int selectionStart = string.lastIndexOf(selection); + int selectionEnd = selectionStart + selection.length() - 1; + + checkMethodParse(string.toCharArray(), selectionStart, selectionEnd, expectedSelection, expectedUnitDisplayString, + selectionIdentifier, expectedReplacedSource, testName); +} +/* + * Multi constant case statement with '->', selection is a referenced name of type enum in switch expression + */ +public void test011() throws JavaModelException { + String string = "public class X {\n" + + " public static void foo(Num num_) {\n" + + " switch (num_) {\n" + + " case ONE, TWO, THREE -> {\n" + + " break;" + + " }\n" + + " }" + + " }\n" + + " enum Num { ONE, TWO, THREE;}\n" + + "}"; + + String selection = "num_"; + String selectKey = "<SelectOnName:"; + String expectedSelection = selectKey + selection + ">"; + + String selectionIdentifier = "num_"; + String expectedUnitDisplayString = + "public class X {\n" + + " enum Num {\n" + + " ONE(),\n" + + " TWO(),\n" + + " THREE(),\n" + + " <clinit>() {\n" + + " }\n" + + " Num() {\n" + + " }\n" + + " }\n" + + " public X() {\n" + + " }\n" + + " public static void foo(Num num_) {\n" + + " <SelectOnName:num_>;\n" + + " }\n" + + "}\n"; + String expectedReplacedSource = "num_"; + String testName = "X.java"; + + int selectionStart = string.lastIndexOf(selection); + int selectionEnd = selectionStart + selection.length() - 1; + + checkMethodParse(string.toCharArray(), selectionStart, selectionEnd, expectedSelection, expectedUnitDisplayString, + selectionIdentifier, expectedReplacedSource, testName); +} +/* + * Multi constant case statement with '->', selection is a referenced name of type int in switch expression + */ +public void test012() throws JavaModelException { + String string = "public class X {\n" + + " public static void foo(int num_) {\n" + + " switch (num_ + 1) {\n" + + " case 1, 2, 3 -> {\n" + + " break;" + + " }\n" + + " }" + + " }\n" + + "}"; + + String selection = "num_"; + String selectKey = "<SelectOnName:"; + String expectedSelection = selectKey + selection + ">"; + + String selectionIdentifier = "num_"; + String expectedUnitDisplayString = + "public class X {\n" + + " public X() {\n" + + " }\n" + + " public static void foo(int num_) {\n" + + " <SelectOnName:num_>;\n" + + " }\n" + + "}\n"; + String expectedReplacedSource = "num_"; + String testName = "X.java"; + + int selectionStart = string.lastIndexOf(selection); + int selectionEnd = selectionStart + selection.length() - 1; + + checkMethodParse(string.toCharArray(), selectionStart, selectionEnd, expectedSelection, expectedUnitDisplayString, + selectionIdentifier, expectedReplacedSource, testName); +} +/* + * Multi constant case statement with '->', selection is a referenced name of type int in switch expression + */ +public void test013() throws JavaModelException { + String string = "public class X {\n" + + " public static void foo(int num_) {\n" + + " int i = switch (num_) {\n" + + " case 1, 2, 3 -> (num_ + 1);\n" + + " default -> 0;\n" + + " }" + + " }\n" + + "}"; + + String selection = "num_"; + String selectKey = "<SelectOnName:"; + String expectedSelection = selectKey + selection + ">"; + + String selectionIdentifier = "num_"; + String expectedUnitDisplayString = + "public class X {\n" + + " public X() {\n" + + " }\n" + + " public static void foo(int num_) {\n" + + " int i;\n" + + " {\n" + + " <SelectOnName:num_>;\n" + + " }\n" + + " }\n" + + "}\n"; + String expectedReplacedSource = "num_"; + String testName = "X.java"; + + int selectionStart = string.lastIndexOf(selection); + int selectionEnd = selectionStart + selection.length() - 1; + + checkMethodParse(string.toCharArray(), selectionStart, selectionEnd, expectedSelection, expectedUnitDisplayString, + selectionIdentifier, expectedReplacedSource, testName); +} +/* + * Multi constant case statement with '->', selection is a referenced name of type int in switch expression + */ +public void test014() throws JavaModelException { + String string = "public class X {\n" + + " public static void foo(int num_) {\n" + + " int i = switch (num_) {\n" + + " case 1, 2, 3 -> 0;\n" + + " default -> (num_ + 1);\n" + + " }" + + " }\n" + + "}"; + + String selection = "num_"; + String selectKey = "<SelectOnName:"; + String expectedSelection = selectKey + selection + ">"; + + String selectionIdentifier = "num_"; + String expectedUnitDisplayString = + "public class X {\n" + + " public X() {\n" + + " }\n" + + " public static void foo(int num_) {\n" + + " int i;\n" + + " {\n" + + " <SelectOnName:num_>;\n" + + " }\n" + + " }\n" + + "}\n"; + String expectedReplacedSource = "num_"; + String testName = "X.java"; + + int selectionStart = string.lastIndexOf(selection); + int selectionEnd = selectionStart + selection.length() - 1; + + checkMethodParse(string.toCharArray(), selectionStart, selectionEnd, expectedSelection, expectedUnitDisplayString, + selectionIdentifier, expectedReplacedSource, testName); +} +/* + * Multi constant case statement with '->', selection is a referenced name of type int in switch expression + */ +public void test015() throws JavaModelException { + String string = "public class X {\n" + + " public static void foo(int num_) {\n" + + " int i = switch (num_) {\n" + + " case 1, 2, 3 -> 0;\n" + + " default -> (num_ + 1);\n" + + " }" + + " }\n" + + "}"; + + String selection = "num_"; + String selectKey = "<SelectOnName:"; + String expectedSelection = selectKey + selection + ">"; + + String selectionIdentifier = "num_"; + String expectedUnitDisplayString = + "public class X {\n" + + " public X() {\n" + + " }\n" + + " public static void foo(int num_) {\n" + + " int i;\n" + + " {\n" + + " <SelectOnName:num_>;\n" + + " }\n" + + " }\n" + + "}\n"; + String expectedReplacedSource = "num_"; + String testName = "X.java"; + + int selectionStart = string.lastIndexOf(selection); + int selectionEnd = selectionStart + selection.length() - 1; + + checkMethodParse(string.toCharArray(), selectionStart, selectionEnd, expectedSelection, expectedUnitDisplayString, + selectionIdentifier, expectedReplacedSource, testName); +} +/* + * Multi constant case statement with '->', selection is a referenced name of type int in switch expression + */ +public void test016() throws JavaModelException { + String string = "public class X {\n" + + " public void bar(int s) {\n" + + " int i_j = switch (s) {\n" + + " case 1, 2, 3 -> (s+1);\n" + + " default -> i_j;\n" + + " };\n" + + " }\n" + + "}\n"; + + String selection = "i_j"; + String selectKey = "<SelectOnName:"; + String expectedSelection = selectKey + selection + ">"; + + String selectionIdentifier = "i_j"; + String expectedUnitDisplayString = + "public class X {\n" + + " public X() {\n" + + " }\n" + + " public void bar(int s) {\n" + + " int i_j;\n" + + " {\n" + + " <SelectOnName:i_j>;\n" + + " }\n" + + " }\n" + + "}\n"; + String expectedReplacedSource = "i_j"; + String testName = "X.java"; + + int selectionStart = string.lastIndexOf(selection); + int selectionEnd = selectionStart + selection.length() - 1; + + checkMethodParse(string.toCharArray(), selectionStart, selectionEnd, expectedSelection, expectedUnitDisplayString, + selectionIdentifier, expectedReplacedSource, testName); +} +public void test017() throws JavaModelException { + String string = "public class X {\n" + + " public void bar(int s) {\n" + + " int i_j = switch (s) {\n" + + " case 1, 2, 3 -> (s+1);\n" + + " default -> (1+i_j);\n" + + " };\n" + + " }\n" + + "}\n"; + + String selection = "i_j"; + String selectKey = "<SelectOnName:"; + String expectedSelection = selectKey + selection + ">"; + + String selectionIdentifier = "i_j"; + String expectedUnitDisplayString = + "public class X {\n" + + " public X() {\n" + + " }\n" + + " public void bar(int s) {\n" + + " int i_j;\n" + + " {\n" + + " <SelectOnName:i_j>;\n" + + " }\n" + + " }\n" + + "}\n"; + String expectedReplacedSource = "i_j"; + String testName = "X.java"; + + int selectionStart = string.lastIndexOf(selection); + int selectionEnd = selectionStart + selection.length() - 1; + + checkMethodParse(string.toCharArray(), selectionStart, selectionEnd, expectedSelection, expectedUnitDisplayString, + selectionIdentifier, expectedReplacedSource, testName); +} +public void test018() throws JavaModelException { + String string = "import org.eclipse.jdt.annotation.*;\n" + + "import java.util.function.*;\n" + + "interface IN0 {} \n" + + "interface IN1 extends IN0 {} \n" + + "interface IN2 extends IN0 {}\n" + + "public class X {\n" + + " IN1 n_1() { return new IN1() {}; } \n" + + " IN2 n_2() { return null; } \n" + + " <M> void m( Supplier< M> m2) { } \n" + + " void testSw(int i) { \n" + + " m(switch(i) { \n" + + " case 1 -> this::n_1; \n" + + " default -> this::n_2; }); \n" + + " }\n" + + "}"; + + String selection = "n_1"; + String selectKey = "<SelectionOnReferenceExpressionName:this::"; + String expectedSelection = selectKey + selection + ">"; + + String selectionIdentifier = "n_1"; + String expectedUnitDisplayString = + "import org.eclipse.jdt.annotation.*;\n" + + "import java.util.function.*;\n" + + "interface IN0 {\n" + + "}\n" + + "interface IN1 extends IN0 {\n" + + "}\n" + + "interface IN2 extends IN0 {\n" + + "}\n" + + "public class X {\n" + + " public X() {\n" + + " }\n" + + " IN1 n_1() {\n" + + " }\n" + + " IN2 n_2() {\n" + + " }\n" + + " <M>void m(Supplier<M> m2) {\n" + + " }\n" + + " void testSw(int i) {\n" + + " m(switch (i) {\n" + + "case 1 ->\n" + + " <SelectionOnReferenceExpressionName:this::n_1>;\n" + + "default ->\n" + + " this::n_2;\n" + + "});\n" + + " }\n" + + "}\n"; + String expectedReplacedSource = "this::n_1"; + String testName = "X.java"; + + int selectionStart = string.lastIndexOf(selection); + int selectionEnd = selectionStart + selection.length() - 1; + + checkMethodParse(string.toCharArray(), selectionStart, selectionEnd, expectedSelection, expectedUnitDisplayString, + selectionIdentifier, expectedReplacedSource, testName); +} +public void test019() throws JavaModelException { + String string = "import org.eclipse.jdt.annotation.*;\n" + + "import java.util.function.*;\n" + + "interface IN0 {} \n" + + "interface IN1 extends IN0 {} \n" + + "interface IN2 extends IN0 {}\n" + + "public class X {\n" + + " IN1 n_1() { return new IN1() {}; } \n" + + " IN2 n_2() { return null; } \n" + + " <M> void m( Supplier< M> m2) { } \n" + + " void testSw(int i) { \n" + + " m(switch(i) { \n" + + " case 2 -> () -> n_1(); \n" + + " default -> this::n_2; }); \n" + + " }\n" + + "}"; + + String selection = "n_1"; + String selectKey = "<SelectOnMessageSend:"; + String expectedSelection = selectKey + selection + "()>"; + + String selectionIdentifier = "n_1"; + String expectedUnitDisplayString = + "import org.eclipse.jdt.annotation.*;\n" + + "import java.util.function.*;\n" + + "interface IN0 {\n" + + "}\n" + + "interface IN1 extends IN0 {\n" + + "}\n" + + "interface IN2 extends IN0 {\n" + + "}\n" + + "public class X {\n" + + " public X() {\n" + + " }\n" + + " IN1 n_1() {\n" + + " }\n" + + " IN2 n_2() {\n" + + " }\n" + + " <M>void m(Supplier<M> m2) {\n" + + " }\n" + + " void testSw(int i) {\n" + + " m(switch (i) {\n" + + "case 2 ->\n" + + " () -> <SelectOnMessageSend:n_1()>;\n" + + "default ->\n" + + " this::n_2;\n" + + "});\n" + + " }\n" + + "}\n"; + String expectedReplacedSource = "n_1()"; + String testName = "X.java"; + + int selectionStart = string.lastIndexOf(selection); + int selectionEnd = selectionStart + selection.length() - 1; + + checkMethodParse(string.toCharArray(), selectionStart, selectionEnd, expectedSelection, expectedUnitDisplayString, + selectionIdentifier, expectedReplacedSource, testName); +} +public void test020() throws JavaModelException { + String string = "import org.eclipse.jdt.annotation.*;\n" + + "import java.util.function.*;\n" + + "interface IN0 {} \n" + + "interface IN1 extends IN0 {} \n" + + "interface IN2 extends IN0 {}\n" + + "public class X {\n" + + " IN1 n_1() { return new IN1() {}; } \n" + + " IN2 n_2() { return null; } \n" + + " <M> void m( Supplier< M> m2) { } \n" + + " void testSw(int i) { \n" + + " m(switch(i) { \n" + + " default -> this::n_2; }); \n" + + " }\n" + + "}"; + + String selection = "n_2"; + String selectKey = "<SelectionOnReferenceExpressionName:this::"; + String expectedSelection = selectKey + selection + ">"; + + String selectionIdentifier = "n_2"; + String expectedUnitDisplayString = + "import org.eclipse.jdt.annotation.*;\n" + + "import java.util.function.*;\n" + + "interface IN0 {\n" + + "}\n" + + "interface IN1 extends IN0 {\n" + + "}\n" + + "interface IN2 extends IN0 {\n" + + "}\n" + + "public class X {\n" + + " public X() {\n" + + " }\n" + + " IN1 n_1() {\n" + + " }\n" + + " IN2 n_2() {\n" + + " }\n" + + " <M>void m(Supplier<M> m2) {\n" + + " }\n" + + " void testSw(int i) {\n" + + " m(switch (i) {\n" + + "default ->\n" + + " <SelectionOnReferenceExpressionName:this::n_2>;\n" + + "});\n" + + " }\n" + + "}\n"; + String expectedReplacedSource = "this::n_2"; + String testName = "X.java"; + + int selectionStart = string.lastIndexOf(selection); + int selectionEnd = selectionStart + selection.length() - 1; + + checkMethodParse(string.toCharArray(), selectionStart, selectionEnd, expectedSelection, expectedUnitDisplayString, + selectionIdentifier, expectedReplacedSource, testName); +} +public void test021() throws JavaModelException { + String string = "import org.eclipse.jdt.annotation.*;\n" + + "import java.util.function.*;\n" + + "interface IN0 {} \n" + + "interface IN1 extends IN0 {} \n" + + "interface IN2 extends IN0 {}\n" + + "public class X {\n" + + " IN1 n_1(int ijk) { return new IN1() {}; } \n" + + " IN2 n_2() { return null; } \n" + + " <M> void m( Supplier< M> m2) { } \n" + + " void testSw(int ijk) { \n" + + " m(switch(ijk) { \n" + + " default -> () -> n_1(ijk); }); \n" + + " }\n" + + "}"; + + String selection = "n_1"; + String selectKey = "<SelectOnMessageSend:"; + String expectedSelection = selectKey + selection + "(ijk)>"; + + String selectionIdentifier = "n_1"; + String expectedUnitDisplayString = + "import org.eclipse.jdt.annotation.*;\n" + + "import java.util.function.*;\n" + + "interface IN0 {\n" + + "}\n" + + "interface IN1 extends IN0 {\n" + + "}\n" + + "interface IN2 extends IN0 {\n" + + "}\n" + + "public class X {\n" + + " public X() {\n" + + " }\n" + + " IN1 n_1(int ijk) {\n" + + " }\n" + + " IN2 n_2() {\n" + + " }\n" + + " <M>void m(Supplier<M> m2) {\n" + + " }\n" + + " void testSw(int ijk) {\n" + + " m(switch (ijk) {\n" + + "default ->\n" + + " () -> <SelectOnMessageSend:n_1(ijk)>;\n" + + "});\n" + + " }\n" + + "}\n"; + String expectedReplacedSource = "n_1(ijk)"; + String testName = "X.java"; + + int selectionStart = string.lastIndexOf(selection); + int selectionEnd = selectionStart + selection.length() - 1; + + checkMethodParse(string.toCharArray(), selectionStart, selectionEnd, expectedSelection, expectedUnitDisplayString, + selectionIdentifier, expectedReplacedSource, testName); +} +public void test022() throws JavaModelException { + String string = "import org.eclipse.jdt.annotation.*;\n" + + "import java.util.function.*;\n" + + "interface IN0 {} \n" + + "interface IN1 extends IN0 {} \n" + + "interface IN2 extends IN0 {}\n" + + "public class X {\n" + + " IN1 n_1(int ijk) { return new IN1() {}; } \n" + + " IN2 n_2() { return null; } \n" + + " <M> void m( Supplier< M> m2) { } \n" + + " void testSw(int ijk) { \n" + + " m(switch(ijk) { \n" + + " default -> () -> n_1(ijk); }); \n" + + " }\n" + + "}"; + + String selection = "ijk"; + String selectKey = "<SelectOnName:"; + String expectedSelection = selectKey + selection + ">"; + + String selectionIdentifier = "ijk"; + String expectedUnitDisplayString = + "import org.eclipse.jdt.annotation.*;\n" + + "import java.util.function.*;\n" + + "interface IN0 {\n" + + "}\n" + + "interface IN1 extends IN0 {\n" + + "}\n" + + "interface IN2 extends IN0 {\n" + + "}\n" + + "public class X {\n" + + " public X() {\n" + + " }\n" + + " IN1 n_1(int ijk) {\n" + + " }\n" + + " IN2 n_2() {\n" + + " }\n" + + " <M>void m(Supplier<M> m2) {\n" + + " }\n" + + " void testSw(int ijk) {\n" + + " m(switch (ijk) {\n" + + "default ->\n" + + " () -> n_1(<SelectOnName:ijk>);\n" + + "});\n" + + " }\n" + + "}\n"; + String expectedReplacedSource = "ijk"; + String testName = "X.java"; + + int selectionStart = string.lastIndexOf(selection); + int selectionEnd = selectionStart + selection.length() - 1; + + checkMethodParse(string.toCharArray(), selectionStart, selectionEnd, expectedSelection, expectedUnitDisplayString, + selectionIdentifier, expectedReplacedSource, testName); +} +} diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/TestAll.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/TestAll.java index 65287abeb3..8699a67c45 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/TestAll.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/TestAll.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2018 IBM Corporation and others. + * Copyright (c) 2000, 2019 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -153,6 +153,7 @@ public static TestSuite getTestSuite(boolean addComplianceDiagnoseTest) { tests_10.add(CompletionParserTest18.class); tests_10.add(SelectionParserTest18.class); tests_10.add(SelectionParserTest9.class); + tests_10.add(SelectionParserTest10.class); tests_10.add(ModuleDeclarationSyntaxTest.class); tests_10.add(JEP286ReservedWordTest.class); // Reset forgotten subsets tests @@ -173,6 +174,7 @@ public static TestSuite getTestSuite(boolean addComplianceDiagnoseTest) { tests_11.add(CompletionParserTest18.class); tests_11.add(SelectionParserTest18.class); tests_11.add(SelectionParserTest9.class); + tests_11.add(SelectionParserTest10.class); tests_11.add(ModuleDeclarationSyntaxTest.class); tests_11.add(JEP286ReservedWordTest.class); // Reset forgotten subsets tests @@ -183,6 +185,28 @@ public static TestSuite getTestSuite(boolean addComplianceDiagnoseTest) { TestCase.RUN_ONLY_ID = null; all.addTest(AbstractCompilerTest.buildComplianceTestSuite(ClassFileConstants.getComplianceLevelForJavaVersion(ClassFileConstants.MAJOR_VERSION_11), tests_11)); } + if ((possibleComplianceLevels & AbstractCompilerTest.F_12) != 0) { + ArrayList tests_12 = (ArrayList)testClasses.clone(); + tests_12.addAll(TEST_CLASSES_1_5); + tests_12.add(ParserTest1_7.class); + tests_12.add(LambdaExpressionSyntaxTest.class); + tests_12.add(ReferenceExpressionSyntaxTest.class); + tests_12.add(TypeAnnotationSyntaxTest.class); + tests_12.add(CompletionParserTest18.class); + tests_12.add(SelectionParserTest18.class); + tests_12.add(SelectionParserTest9.class); + tests_12.add(SelectionParserTest10.class); + tests_12.add(SelectionParserTest12.class); + tests_12.add(ModuleDeclarationSyntaxTest.class); + tests_12.add(JEP286ReservedWordTest.class); + // Reset forgotten subsets tests + TestCase.TESTS_PREFIX = null; + TestCase.TESTS_NAMES = null; + TestCase.TESTS_NUMBERS= null; + TestCase.TESTS_RANGE = null; + TestCase.RUN_ONLY_ID = null; + all.addTest(AbstractCompilerTest.buildComplianceTestSuite(ClassFileConstants.getComplianceLevelForJavaVersion(ClassFileConstants.MAJOR_VERSION_12), tests_12)); + } return all; } public static Test suite() { diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractComparableTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractComparableTest.java index c0e95a3c06..b6dcf42ad3 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractComparableTest.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractComparableTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2018 IBM Corporation and others. + * Copyright (c) 2000, 2019 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -8,6 +8,10 @@ * * SPDX-License-Identifier: EPL-2.0 * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * IBM Corporation - initial API and implementation * Stephan Herrmann - Contribution for @@ -110,6 +114,29 @@ public class AbstractComparableTest extends AbstractRegressionTest { } protected String intersection(String... types) { + // From JDK 12, Comparable gets two new super interfaces, namely Constable and ConstantDesc. + // The idea is to append Comparable with &Constable&ConstantDesc automatically. + if (isJRE12Plus) { + int index = -1; + for(int i = 0; i < types.length; i++) { + if (types[i].startsWith("Comparable") && !types[i].endsWith("ConstantDesc")) { + if ((types.length <= i+1) || !types[i+1].startsWith("CharSequence")) { + index = i; + break; + } + } + } + if (index >= 0) { + index++; + String[] temp = new String[types.length + 2]; + System.arraycopy(types, 0, temp, 0, index); + temp[index] = "Constable"; + temp[index+1] = "ConstantDesc"; + if (index < types.length) + System.arraycopy(types, index, temp, index+2, types.length - index); + types = temp; + } + } if (this.complianceLevel >= ClassFileConstants.JDK1_8) return String.join(" & ", types); return String.join("&", types); diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java index bdbc45a2aa..a60834331f 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java @@ -6,6 +6,10 @@ * which accompanies this distribution, and is available at * https://www.eclipse.org/legal/epl-2.0/ * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * SPDX-License-Identifier: EPL-2.0 * * Contributors: @@ -298,6 +302,8 @@ static class JavacCompiler { return JavaCore.VERSION_10; } else if(rawVersion.startsWith("11")) { return JavaCore.VERSION_11; + } else if(rawVersion.startsWith("12")) { + return JavaCore.VERSION_12; } else { throw new RuntimeException("unknown javac version: " + rawVersion); } @@ -408,6 +414,17 @@ static class JavacCompiler { return 0200; } } + if (version == JavaCore.VERSION_12) { + if ("12".equals(rawVersion)) { + return 0000; + } + if ("12.0.1".equals(rawVersion)) { + return 0100; + } + if ("12.0.2".equals(rawVersion)) { + return 0200; + } + } throw new RuntimeException("unknown raw javac version: " + rawVersion); } // returns 0L if everything went fine; else the lower word contains the @@ -1719,6 +1736,9 @@ protected static class JavacTestOptions { JavacTestOptions.DEFAULT /* default javac test options */); } protected void runConformTest(String[] testFiles, String expectedOutput, Map customOptions) { + runConformTest(testFiles, expectedOutput, customOptions, null); + } + protected void runConformTest(String[] testFiles, String expectedOutput, Map customOptions, String[] vmArguments) { runTest( // test directory preparation true /* flush output directory */, @@ -1733,7 +1753,7 @@ protected static class JavacTestOptions { null /* do not check compiler log */, // runtime options false /* do not force execution */, - null /* no vm arguments */, + vmArguments /* no vm arguments */, // runtime results expectedOutput /* expected output string */, null /* do not check error string */, @@ -2553,10 +2573,19 @@ protected void runNegativeTest(boolean skipJavac, JavacTestOptions javacTestOpti JavacTestOptions.DEFAULT /* javac test options */); } protected void runNegativeTest( + String[] testFiles, + String expectedCompilerLog, + String[] classLibraries, + boolean shouldFlushOutputDirectory, + Map customOptions) { + runNegativeTest(testFiles, expectedCompilerLog, classLibraries, shouldFlushOutputDirectory, null, customOptions); + } + protected void runNegativeTest( String[] testFiles, String expectedCompilerLog, String[] classLibraries, boolean shouldFlushOutputDirectory, + String[] vmArguments, Map customOptions) { runTest( // test directory preparation @@ -2577,7 +2606,7 @@ protected void runNegativeTest(boolean skipJavac, JavacTestOptions javacTestOpti expectedCompilerLog /* expected compiler log */, // runtime options false /* do not force execution */, - null /* no vm arguments */, + vmArguments /* no vm arguments */, // runtime results null /* do not check output string */, null /* do not check error string */, diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java index 398e5acd37..1ccbeb201b 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java @@ -1020,7 +1020,6 @@ public void test012b(){ " <option key=\"org.eclipse.jdt.core.compiler.generateClassFiles\" value=\"enabled\"/>\n" + " <option key=\"org.eclipse.jdt.core.compiler.maxProblemPerUnit\" value=\"100\"/>\n" + " <option key=\"org.eclipse.jdt.core.compiler.problem.APILeak\" value=\"warning\"/>\n" + - " <option key=\"org.eclipse.jdt.core.compiler.problem.EnablePreviews\" value=\"disabled\"/>\n" + " <option key=\"org.eclipse.jdt.core.compiler.problem.annotationSuperInterface\" value=\"warning\"/>\n" + " <option key=\"org.eclipse.jdt.core.compiler.problem.assertIdentifier\" value=\"warning\"/>\n" + " <option key=\"org.eclipse.jdt.core.compiler.problem.autoboxing\" value=\"ignore\"/>\n" + @@ -1032,6 +1031,7 @@ public void test012b(){ " <option key=\"org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod\" value=\"disabled\"/>\n" + " <option key=\"org.eclipse.jdt.core.compiler.problem.discouragedReference\" value=\"warning\"/>\n" + " <option key=\"org.eclipse.jdt.core.compiler.problem.emptyStatement\" value=\"ignore\"/>\n" + + " <option key=\"org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures\" value=\"disabled\"/>\n" + " <option key=\"org.eclipse.jdt.core.compiler.problem.enumIdentifier\" value=\"warning\"/>\n" + " <option key=\"org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable\" value=\"ignore\"/>\n" + " <option key=\"org.eclipse.jdt.core.compiler.problem.fallthroughCase\" value=\"ignore\"/>\n" + @@ -1091,6 +1091,7 @@ public void test012b(){ " <option key=\"org.eclipse.jdt.core.compiler.problem.redundantSuperinterface\" value=\"ignore\"/>\n" + " <option key=\"org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic\" value=\"ignore\"/>\n" + " <option key=\"org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic\" value=\"ignore\"/>\n" + + " <option key=\"org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures\" value=\"warning\"/>\n" + " <option key=\"org.eclipse.jdt.core.compiler.problem.specialParameterHidingField\" value=\"disabled\"/>\n" + " <option key=\"org.eclipse.jdt.core.compiler.problem.staticAccessReceiver\" value=\"warning\"/>\n" + " <option key=\"org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors\" value=\"disabled\"/>\n" + diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java index 4d94eadc08..d40a5652d9 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006, 2018 IBM Corporation and others. + * Copyright (c) 2006, 2019 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -8,6 +8,10 @@ * * SPDX-License-Identifier: EPL-2.0 * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * IBM Corporation - initial API and implementation * Benjamin Muskalla - Contribution for bug 239066 @@ -76,270 +80,240 @@ import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities; @SuppressWarnings({ "unchecked", "rawtypes" }) public class CompilerInvocationTests extends AbstractRegressionTest { -public CompilerInvocationTests(String name) { - super(name); -} + public CompilerInvocationTests(String name) { + super(name); + } // Static initializer to specify tests subset using TESTS_* static variables - // All specified tests which does not belong to the class are skipped... - // Only the highest compliance level is run; add the VM argument - // -Dcompliance=1.4 (for example) to lower it if needed - static { -// TESTS_NAMES = new String[] { "test003_task_tags_options" }; + // All specified tests which does not belong to the class are skipped... + // Only the highest compliance level is run; add the VM argument + // -Dcompliance=1.4 (for example) to lower it if needed + static { +// TESTS_NAMES = new String[] { "test011_problem_categories" }; // TESTS_NUMBERS = new int[] { 1 }; // TESTS_RANGE = new int[] { 1, -1 }; // TESTS_RANGE = new int[] { 1, 2049 }; // TESTS_RANGE = new int[] { 449, 451 }; // TESTS_RANGE = new int[] { 900, 999 }; - } + } -public static Test suite() { - return buildAllCompliancesTestSuite(testClass()); -} + public static Test suite() { + return buildAllCompliancesTestSuite(testClass()); + } -public static Class testClass() { - return CompilerInvocationTests.class; -} + public static Class testClass() { + return CompilerInvocationTests.class; + } // irritant vs warning token - check To/From symmetry -public void test001_irritant_warning_token() { - Map matcher = new HashMap(); - for (int group = 0; group < IrritantSet.GROUP_MAX; group++) { - for (int i = 0; i < 29; i++) { - int irritant = (group << IrritantSet.GROUP_SHIFT) + (1 << i); - String token = CompilerOptions.warningTokenFromIrritant(irritant); - if (token != null) { - matcher.put(token, token); - assertTrue(CompilerOptions.warningTokenToIrritants(token) != null); + public void test001_irritant_warning_token() { + Map matcher = new HashMap(); + for (int group = 0; group < IrritantSet.GROUP_MAX; group++) { + for (int i = 0; i < 29; i++) { + int irritant = (group << IrritantSet.GROUP_SHIFT) + (1 << i); + String token = CompilerOptions.warningTokenFromIrritant(irritant); + if (token != null) { + matcher.put(token, token); + assertTrue(CompilerOptions.warningTokenToIrritants(token) != null); + } } } + // Add one for "preview", which doesn't have any irritant at the moment + matcher.put("preview", "preview"); + String[] allTokens = CompilerOptions.warningTokens; + int length = allTokens.length; + matcher.put("all", "all"); // all gets undetected in the From/To loop + assertEquals(allTokens.length, matcher.size()); + for (int i = 0; i < length; i++) { + Object object = matcher.get(allTokens[i]); + assertNotNull(object); + } } - // Add one for "preview", which doesn't have any irritant at the moment - matcher.put("preview", "preview"); - String [] allTokens = CompilerOptions.warningTokens; - int length = allTokens.length; - matcher.put("all", "all"); // all gets undetected in the From/To loop - assertEquals(allTokens.length, matcher.size()); - for (int i = 0; i < length; i++) { - Object object = matcher.get(allTokens[i]); - assertNotNull(object); - } -} // problem categories - check that none is left unspecified // see also discussion in https://bugs.eclipse.org/bugs/show_bug.cgi?id=208383 -public void test002_problem_categories() { - try { - Class iProblemClass; - Field[] fields = (iProblemClass = IProblem.class).getFields(); - for (int i = 0, length = fields.length; i < length; i++) { - Field field = fields[i]; - if (field.getType() == Integer.TYPE) { - int problemId = field.getInt(iProblemClass), maskedProblemId = problemId & IProblem.IgnoreCategoriesMask; - if (maskedProblemId != 0 && maskedProblemId != IProblem.IgnoreCategoriesMask - && ProblemReporter.getProblemCategory(ProblemSeverities.Error, problemId) - == CategorizedProblem.CAT_UNSPECIFIED) { - fail("unspecified category for problem " + field.getName()); + public void test002_problem_categories() { + try { + Class iProblemClass; + Field[] fields = (iProblemClass = IProblem.class).getFields(); + for (int i = 0, length = fields.length; i < length; i++) { + Field field = fields[i]; + if (field.getType() == Integer.TYPE) { + int problemId = field.getInt(iProblemClass), + maskedProblemId = problemId & IProblem.IgnoreCategoriesMask; + if (maskedProblemId != 0 && maskedProblemId != IProblem.IgnoreCategoriesMask + && ProblemReporter.getProblemCategory(ProblemSeverities.Error, + problemId) == CategorizedProblem.CAT_UNSPECIFIED) { + fail("unspecified category for problem " + field.getName()); + } } } + } catch (IllegalAccessException e) { + fail("could not access members"); } } - catch (IllegalAccessException e) { - fail("could not access members"); - } -} -class TasksReader implements ICompilerRequestor { - CompilationResult result; - public void acceptResult(CompilationResult compilationResult) { - this.result = compilationResult; + + class TasksReader implements ICompilerRequestor { + CompilationResult result; + + public void acceptResult(CompilationResult compilationResult) { + this.result = compilationResult; + } } -} -static String taskTagsAsCutAndPaste(CategorizedProblem tasks[]) { - StringBuffer result = new StringBuffer(); - String arguments[]; - for (int i = 0; i < tasks.length - 1; i++) { - arguments = tasks[i].getArguments(); + + static String taskTagsAsCutAndPaste(CategorizedProblem tasks[]) { + StringBuffer result = new StringBuffer(); + String arguments[]; + for (int i = 0; i < tasks.length - 1; i++) { + arguments = tasks[i].getArguments(); + System.out.print("\t\t\"["); + System.out.print(arguments[0]); + System.out.print(','); + System.out.print(arguments[1]); + System.out.print(','); + System.out.print(arguments[2]); + System.out.println("]\\n\" +"); + } + arguments = tasks[tasks.length - 1].getArguments(); System.out.print("\t\t\"["); System.out.print(arguments[0]); System.out.print(','); System.out.print(arguments[1]); System.out.print(','); System.out.print(arguments[2]); - System.out.println("]\\n\" +"); - } - arguments = tasks[tasks.length - 1].getArguments(); - System.out.print("\t\t\"["); - System.out.print(arguments[0]); - System.out.print(','); - System.out.print(arguments[1]); - System.out.print(','); - System.out.print(arguments[2]); - System.out.println("]\\n\""); - return result.toString(); -} -static String taskTagsAsStrings(CategorizedProblem tasks[]) { - StringBuffer result = new StringBuffer(); - String arguments[]; - for (int i = 0; i < tasks.length; i++) { - arguments = tasks[i].getArguments(); - result.append('['); - result.append(arguments[0]); - result.append(','); - result.append(arguments[1]); - result.append(','); - result.append(arguments[2]); - result.append(']'); - result.append("\n"); + System.out.println("]\\n\""); + return result.toString(); } - return result.toString(); -} -public void runTaskTagsOptionsTest( - String[] testFiles, - Map customOptions, - String expectedTags) { - TasksReader reader = new TasksReader(); - Map options = JavaCore.getDefaultOptions(); - if (customOptions != null) { - options.putAll(customOptions); + + static String taskTagsAsStrings(CategorizedProblem tasks[]) { + StringBuffer result = new StringBuffer(); + String arguments[]; + for (int i = 0; i < tasks.length; i++) { + arguments = tasks[i].getArguments(); + result.append('['); + result.append(arguments[0]); + result.append(','); + result.append(arguments[1]); + result.append(','); + result.append(arguments[2]); + result.append(']'); + result.append("\n"); + } + return result.toString(); } - this.runConformTest( - testFiles, - "", - null /* no extra class libraries */, - true /* flush output directory */, - null, /* no VM args */ - options, - reader, - true /* skip javac */); - String tags = taskTagsAsStrings(reader.result.tasks); - if (! tags.equals(expectedTags)) { - System.out.println(getClass().getName() + '#' + getName()); - System.out.println("Effective results:"); - System.out.println(tags); - System.out.println("Cut and paste:"); - taskTagsAsCutAndPaste(reader.result.tasks); - assertEquals(expectedTags, tags); + + public void runTaskTagsOptionsTest(String[] testFiles, Map customOptions, String expectedTags) { + TasksReader reader = new TasksReader(); + Map options = JavaCore.getDefaultOptions(); + if (customOptions != null) { + options.putAll(customOptions); + } + this.runConformTest(testFiles, "", null /* no extra class libraries */, true /* flush output directory */, + null, /* no VM args */ + options, reader, true /* skip javac */); + String tags = taskTagsAsStrings(reader.result.tasks); + if (!tags.equals(expectedTags)) { + System.out.println(getClass().getName() + '#' + getName()); + System.out.println("Effective results:"); + System.out.println(tags); + System.out.println("Cut and paste:"); + taskTagsAsCutAndPaste(reader.result.tasks); + assertEquals(expectedTags, tags); + } } -} + // Basic test on task tags: watch default behavior -public void test003_task_tags_options() { - runTaskTagsOptionsTest( - new String[] { - "X.java", - "public class X {\n" + - " void foo(X x) {\n" + - " // FIXME TODO XXX message contents\n" + - " }\n" + - "}\n"}, - null, - "[FIXME, message contents,HIGH]\n" + - "[TODO, message contents,NORMAL]\n" + - "[XXX, message contents,NORMAL]\n"); -} + public void test003_task_tags_options() { + runTaskTagsOptionsTest( + new String[] { "X.java", + "public class X {\n" + " void foo(X x) {\n" + " // FIXME TODO XXX message contents\n" + + " }\n" + "}\n" }, + null, "[FIXME, message contents,HIGH]\n" + "[TODO, message contents,NORMAL]\n" + + "[XXX, message contents,NORMAL]\n"); + } + // effect of cancelling priorities // reactivate when bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=143402 is fixed -public void _test004_task_tags_options() { - Map customOptions = new HashMap(); - customOptions.put(JavaCore.COMPILER_TASK_PRIORITIES, ""); - runTaskTagsOptionsTest( - new String[] { - "X.java", - "public class X {\n" + - " void foo(X x) {\n" + - " // FIXME TODO XXX message contents\n" + - " }\n" + - "}\n"}, - customOptions, - "[FIXME, message contents,NORMAL]\n" + - "[TODO, message contents,NORMAL]\n" + - "[XXX, message contents,NORMAL]\n"); -} + public void _test004_task_tags_options() { + Map customOptions = new HashMap(); + customOptions.put(JavaCore.COMPILER_TASK_PRIORITIES, ""); + runTaskTagsOptionsTest( + new String[] { "X.java", + "public class X {\n" + " void foo(X x) {\n" + " // FIXME TODO XXX message contents\n" + + " }\n" + "}\n" }, + customOptions, "[FIXME, message contents,NORMAL]\n" + "[TODO, message contents,NORMAL]\n" + + "[XXX, message contents,NORMAL]\n"); + } + // effect of cancelling priorities // reactivate when bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=143402 is fixed -public void _test005_task_tags_options() { - Map customOptions = new HashMap(); - customOptions.put(JavaCore.COMPILER_TASK_PRIORITIES, ",,"); - runTaskTagsOptionsTest( - new String[] { - "X.java", - "public class X {\n" + - " void foo(X x) {\n" + - " // FIXME TODO XXX message contents\n" + - " }\n" + - "}\n"}, - customOptions, - "[FIXME,message contents,NORMAL]\n" + - "[TODO,message contents,NORMAL]\n" + - "[XXX,message contents,NORMAL]\n"); - // would expect an exception of some sort -} + public void _test005_task_tags_options() { + Map customOptions = new HashMap(); + customOptions.put(JavaCore.COMPILER_TASK_PRIORITIES, ",,"); + runTaskTagsOptionsTest( + new String[] { "X.java", + "public class X {\n" + " void foo(X x) {\n" + " // FIXME TODO XXX message contents\n" + + " }\n" + "}\n" }, + customOptions, "[FIXME,message contents,NORMAL]\n" + "[TODO,message contents,NORMAL]\n" + + "[XXX,message contents,NORMAL]\n"); + // would expect an exception of some sort + } + // effect of changing priorities // reactivate when bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=143402 is fixed -public void _test006_task_tags_options() { - Map customOptions = new HashMap(); - customOptions.put(JavaCore.COMPILER_TASK_PRIORITIES, "A,B,C,D,E"); - runTaskTagsOptionsTest( - new String[] { - "X.java", - "public class X {\n" + - " void foo(X x) {\n" + - " // FIXME TODO XXX message contents\n" + - " }\n" + - "}\n"}, - customOptions, - "[FIXME,message contents,NORMAL]\n" + - "[TODO,message contents,NORMAL]\n" + - "[XXX,message contents,NORMAL]\n"); - // would expect an exception of some sort -} + public void _test006_task_tags_options() { + Map customOptions = new HashMap(); + customOptions.put(JavaCore.COMPILER_TASK_PRIORITIES, "A,B,C,D,E"); + runTaskTagsOptionsTest( + new String[] { "X.java", + "public class X {\n" + " void foo(X x) {\n" + " // FIXME TODO XXX message contents\n" + + " }\n" + "}\n" }, + customOptions, "[FIXME,message contents,NORMAL]\n" + "[TODO,message contents,NORMAL]\n" + + "[XXX,message contents,NORMAL]\n"); + // would expect an exception of some sort + } + // effect of changing priorities -public void test007_task_tags_options() { - Map customOptions = new HashMap(); - customOptions.put(JavaCore.COMPILER_TASK_PRIORITIES, "NORMAL,NORMAL,NORMAL"); - runTaskTagsOptionsTest( - new String[] { - "X.java", - "public class X {\n" + - " void foo(X x) {\n" + - " // FIXME TODO XXX message contents\n" + - " }\n" + - "}\n"}, - customOptions, - "[FIXME, message contents,NORMAL]\n" + - "[TODO, message contents,NORMAL]\n" + - "[XXX, message contents,NORMAL]\n"); -} + public void test007_task_tags_options() { + Map customOptions = new HashMap(); + customOptions.put(JavaCore.COMPILER_TASK_PRIORITIES, "NORMAL,NORMAL,NORMAL"); + runTaskTagsOptionsTest( + new String[] { "X.java", + "public class X {\n" + " void foo(X x) {\n" + " // FIXME TODO XXX message contents\n" + + " }\n" + "}\n" }, + customOptions, "[FIXME, message contents,NORMAL]\n" + "[TODO, message contents,NORMAL]\n" + + "[XXX, message contents,NORMAL]\n"); + } + // effect of changing priorities // reactivate when bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=143402 is fixed -public void _test008_task_tags_options() { - Map customOptions = new HashMap(); - customOptions.put(JavaCore.COMPILER_TASK_PRIORITIES, "NORMAL,NORMAL"); // one less than the number of tags - runTaskTagsOptionsTest( - new String[] { - "X.java", - "public class X {\n" + - " void foo(X x) {\n" + - " // FIXME TODO XXX message contents\n" + - " }\n" + - "}\n"}, - customOptions, - "[FIXME,message contents,NORMAL]\n" + - "[TODO,message contents,NORMAL]\n" + - "[XXX,message contents,NORMAL]\n"); -} + public void _test008_task_tags_options() { + Map customOptions = new HashMap(); + customOptions.put(JavaCore.COMPILER_TASK_PRIORITIES, "NORMAL,NORMAL"); // one less than the number of tags + runTaskTagsOptionsTest( + new String[] { "X.java", + "public class X {\n" + " void foo(X x) {\n" + " // FIXME TODO XXX message contents\n" + + " }\n" + "}\n" }, + customOptions, "[FIXME,message contents,NORMAL]\n" + "[TODO,message contents,NORMAL]\n" + + "[XXX,message contents,NORMAL]\n"); + } + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=206423 // that bug showed that we had no coverage in the area of missing message // templates, which can occur downstream in the localization process (assuming // that we always release the English version right) -public void test009_missing_message_templates() { - assertEquals("Unable to retrieve the error message for problem id: 8388607. Check compiler resources.", - new DefaultProblemFactory().getLocalizedMessage(Integer.MAX_VALUE, new String[]{})); -} + public void test009_missing_message_templates() { + assertEquals("Unable to retrieve the error message for problem id: 4194303. Check compiler resources.", + new DefaultProblemFactory().getLocalizedMessage(Integer.MAX_VALUE, new String[] {})); + } + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=206423 -public void test010_missing_elaboration_templates() { - assertEquals("Unable to retrieve the error message elaboration for elaboration id: 1073741823. Check compiler resources.", - new DefaultProblemFactory().getLocalizedMessage(0, Integer.MAX_VALUE / 2, new String[]{"Zork"})); -} + public void test010_missing_elaboration_templates() { + assertEquals( + "Unable to retrieve the error message elaboration for elaboration id: 1073741823. Check compiler resources.", + new DefaultProblemFactory().getLocalizedMessage(0, Integer.MAX_VALUE / 2, new String[] { "Zork" })); + } + // problem categories - check that categories match expected ones // see also discussion in https://bugs.eclipse.org/bugs/show_bug.cgi?id=208383 public void test011_problem_categories() { @@ -1188,6 +1162,23 @@ public void test011_problem_categories() { expectedProblemAttributes.put("IllegalArrayOfUnionType", new ProblemAttributes(CategorizedProblem.CAT_TYPE)); expectedProblemAttributes.put("IllegalArrayTypeInIntersectionCast", new ProblemAttributes(CategorizedProblem.CAT_TYPE)); expectedProblemAttributes.put("ProblemNotAnalysed", new ProblemAttributes(CategorizedProblem.CAT_UNNECESSARY_CODE)); + expectedProblemAttributes.put("SwitchExpressionsIncompatibleResultExpressionTypes", new ProblemAttributes(CategorizedProblem.CAT_TYPE)); + expectedProblemAttributes.put("SwitchExpressionsEmptySwitchBlock", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL)); + expectedProblemAttributes.put("SwitchExpressionsNoResultExpression", new ProblemAttributes(CategorizedProblem.CAT_TYPE)); + expectedProblemAttributes.put("SwitchExpressionSwitchLabeledBlockCompletesNormally", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL)); + expectedProblemAttributes.put("SwitchExpressionLastStatementCompletesNormally", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL)); + expectedProblemAttributes.put("SwitchExpressionTrailingSwitchLabels", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL)); + expectedProblemAttributes.put("switchMixedCase", new ProblemAttributes(CategorizedProblem.CAT_SYNTAX)); + expectedProblemAttributes.put("SwitchExpressionMissingDefaultCase", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL)); + expectedProblemAttributes.put("SwitchExpressionNotBelow12", new ProblemAttributes(CategorizedProblem.CAT_SYNTAX)); + expectedProblemAttributes.put("SwitchCaseLabelWithArrowNotBelow12", new ProblemAttributes(CategorizedProblem.CAT_SYNTAX)); + expectedProblemAttributes.put("SwitchExpressionPreviewDisabled", new ProblemAttributes(CategorizedProblem.CAT_SYNTAX)); + expectedProblemAttributes.put("SwitchCaseLabelWithArrowPreviewDisabled", new ProblemAttributes(CategorizedProblem.CAT_SYNTAX)); + expectedProblemAttributes.put("SwitchExpressionBreakMissingValue", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL)); + expectedProblemAttributes.put("SwitchExpressionMissingEnumConstantCase", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL)); + expectedProblemAttributes.put("PreviewFeatureDisabled", new ProblemAttributes(CategorizedProblem.CAT_COMPLIANCE)); + expectedProblemAttributes.put("PreviewFeatureUsed", new ProblemAttributes(CategorizedProblem.CAT_COMPLIANCE)); + expectedProblemAttributes.put("PreviewFeatureNotSupported", new ProblemAttributes(CategorizedProblem.CAT_COMPLIANCE)); StringBuffer failures = new StringBuffer(); StringBuffer correctResult = new StringBuffer(70000); Field[] fields = (iProblemClass = IProblem.class).getFields(); @@ -1196,71 +1187,79 @@ public void test011_problem_categories() { Field field1 = (Field) o1; Field field2 = (Field) o2; return field1.getName().compareTo(field2.getName()); - } - }); - boolean watchInternalCategory = false, printHeader = true; - for (int i = 0, length = fields.length; i < length; i++) { - Field field = fields[i]; - if (field.getType() == Integer.TYPE) { - int problemId = field.getInt(iProblemClass); - int maskedProblemId = problemId & IProblem.IgnoreCategoriesMask; - if (maskedProblemId != 0 && maskedProblemId != IProblem.IgnoreCategoriesMask) { - String name = field.getName(); - ProblemAttributes expectedAttributes = (ProblemAttributes) expectedProblemAttributes.get(name); - if (expectedAttributes == null) { - failures.append("missing expected problem attributes for problem " + name + "\n"); - int actualCategory = ProblemReporter.getProblemCategory(ProblemSeverities.Error, problemId); - correctResult.append("\t\texpectedProblemAttributes.put(\"" + name + "\", new ProblemAttributes(CategorizedProblem." + categoryName(actualCategory) + "));\n"); - } else if (!expectedAttributes.deprecated) { - int actualCategory = ProblemReporter.getProblemCategory(ProblemSeverities.Error, problemId); - correctResult.append("\t\texpectedProblemAttributes.put(\"" + name + "\", new ProblemAttributes(CategorizedProblem." + categoryName(actualCategory) + "));\n"); - if (expectedAttributes.category != actualCategory) { - failures.append("category mismatch for problem " + name + " (expected " + categoryName(expectedAttributes.category) + ", got " + categoryName(actualCategory) + ")\n"); - } - if (watchInternalCategory && actualCategory == CategorizedProblem.CAT_INTERNAL) { - if (printHeader) { - printHeader = false; - System.err.println("CAT_INTERNAL for problems:"); + } + }); + boolean watchInternalCategory = false, printHeader = true; + for (int i = 0, length = fields.length; i < length; i++) { + Field field = fields[i]; + if (field.getType() == Integer.TYPE) { + int problemId = field.getInt(iProblemClass); + int maskedProblemId = problemId & IProblem.IgnoreCategoriesMask; + if (maskedProblemId != 0 && maskedProblemId != IProblem.IgnoreCategoriesMask) { + String name = field.getName(); + ProblemAttributes expectedAttributes = (ProblemAttributes) expectedProblemAttributes.get(name); + if (expectedAttributes == null) { + failures.append("missing expected problem attributes for problem " + name + "\n"); + int actualCategory = ProblemReporter.getProblemCategory(ProblemSeverities.Error, problemId); + correctResult.append("\t\texpectedProblemAttributes.put(\"" + name + + "\", new ProblemAttributes(CategorizedProblem." + categoryName(actualCategory) + + "));\n"); + } else if (!expectedAttributes.deprecated) { + int actualCategory = ProblemReporter.getProblemCategory(ProblemSeverities.Error, problemId); + correctResult.append("\t\texpectedProblemAttributes.put(\"" + name + + "\", new ProblemAttributes(CategorizedProblem." + categoryName(actualCategory) + + "));\n"); + if (expectedAttributes.category != actualCategory) { + failures.append("category mismatch for problem " + name + " (expected " + + categoryName(expectedAttributes.category) + ", got " + + categoryName(actualCategory) + ")\n"); + } + if (watchInternalCategory && actualCategory == CategorizedProblem.CAT_INTERNAL) { + if (printHeader) { + printHeader = false; + System.err.println("CAT_INTERNAL for problems:"); + } + System.err.println("\t" + name); } - System.err.println("\t" + name); + } else { + correctResult.append("\t\texpectedProblemAttributes.put(\"" + name + "\", DEPRECATED);\n"); } - } else { - correctResult.append("\t\texpectedProblemAttributes.put(\"" + name + "\", DEPRECATED);\n"); } } } + if (failures.length() > 0) { + System.out.println(correctResult); + System.out.println(); + } + assertEquals(failures.toString(), 0, failures.length()); + } catch (IllegalAccessException e) { + fail("could not access members"); } - if (failures.length() > 0) { - System.out.println(correctResult); - System.out.println(); - } - assertEquals(failures.toString(), 0, failures.length()); - } - catch (IllegalAccessException e) { - fail("could not access members"); } -} -private static Map categoryNames; -private String categoryName(int category) { - if (categoryNames == null) { - categoryNames = new HashMap(); - Field[] fields = CategorizedProblem.class.getFields(); - for (int i = 0, length = fields.length; i < length; i++) { - Field field = fields[i]; - if (field.getType() == Integer.TYPE) { - String name = field.getName(); - if (name.startsWith("CAT_")) { - try { - categoryNames.put(Integer.valueOf(field.getInt(CategorizedProblem.class)), name); - } catch (IllegalArgumentException e) { - } catch (IllegalAccessException e) { + + private static Map categoryNames; + + private String categoryName(int category) { + if (categoryNames == null) { + categoryNames = new HashMap(); + Field[] fields = CategorizedProblem.class.getFields(); + for (int i = 0, length = fields.length; i < length; i++) { + Field field = fields[i]; + if (field.getType() == Integer.TYPE) { + String name = field.getName(); + if (name.startsWith("CAT_")) { + try { + categoryNames.put(Integer.valueOf(field.getInt(CategorizedProblem.class)), name); + } catch (IllegalArgumentException e) { + } catch (IllegalAccessException e) { + } } } } } + return (String) categoryNames.get(Integer.valueOf(category)); } - return (String) categoryNames.get(Integer.valueOf(category)); -} + // compiler problems tuning // https://bugs.eclipse.org/bugs/show_bug.cgi?id=218603 public void test012_compiler_problems_tuning() { @@ -2108,6 +2107,23 @@ public void test012_compiler_problems_tuning() { expectedProblemAttributes.put("VarLocalReferencesItself", SKIP); expectedProblemAttributes.put("VarLocalTooManyBrackets", SKIP); expectedProblemAttributes.put("VarLocalWithoutInitizalier", SKIP); + expectedProblemAttributes.put("SwitchExpressionsIncompatibleResultExpressionTypes",SKIP); + expectedProblemAttributes.put("SwitchExpressionsEmptySwitchBlock",SKIP); + expectedProblemAttributes.put("SwitchExpressionsNoResultExpression",SKIP); + expectedProblemAttributes.put("SwitchExpressionSwitchLabeledBlockCompletesNormally",SKIP); + expectedProblemAttributes.put("SwitchExpressionLastStatementCompletesNormally",SKIP); + expectedProblemAttributes.put("SwitchExpressionTrailingSwitchLabels",SKIP); + expectedProblemAttributes.put("switchMixedCase", SKIP); + expectedProblemAttributes.put("SwitchExpressionMissingDefaultCase",SKIP); + expectedProblemAttributes.put("SwitchExpressionNotBelow12", SKIP); + expectedProblemAttributes.put("SwitchCaseLabelWithArrowNotBelow12", SKIP); + expectedProblemAttributes.put("SwitchExpressionPreviewDisabled", SKIP); + expectedProblemAttributes.put("SwitchCaseLabelWithArrowPreviewDisabled", SKIP); + expectedProblemAttributes.put("SwitchExpressionBreakMissingValue", SKIP); + expectedProblemAttributes.put("SwitchExpressionMissingEnumConstantCase", SKIP); + expectedProblemAttributes.put("PreviewFeatureDisabled", SKIP); + expectedProblemAttributes.put("PreviewFeatureUsed", SKIP); + expectedProblemAttributes.put("PreviewFeatureNotSupported", SKIP); Map constantNamesIndex = new HashMap(); Field[] fields = JavaCore.class.getFields(); for (int i = 0, length = fields.length; i < length; i++) { @@ -2115,46 +2131,47 @@ public void test012_compiler_problems_tuning() { String fieldName; if (field.getType() == String.class && (fieldName = field.getName()).startsWith("COMPILER_PB_")) { constantNamesIndex.put(field.get(null), fieldName); + } } - } - fields = IProblem.class.getFields(); - StringBuffer failures = new StringBuffer(); - StringBuffer correctResult = new StringBuffer(70000); - Arrays.sort(fields, new Comparator() { - public int compare(Object o1, Object o2) { - Field field1 = (Field) o1; - Field field2 = (Field) o2; - return field1.getName().compareTo(field2.getName()); - } - }); - for (int i = 0, length = fields.length; i < length; i++) { - Field field = fields[i]; - if (field.getType() == Integer.TYPE) { - int problemId = field.getInt(null), maskedProblemId = problemId & IProblem.IgnoreCategoriesMask; - if (maskedProblemId != 0 && maskedProblemId != IProblem.IgnoreCategoriesMask) { - String name = field.getName(); - ProblemAttributes expectedAttributes = (ProblemAttributes) expectedProblemAttributes.get(name); - String actualTuningOption = JavaCore.getOptionForConfigurableSeverity(problemId); - if (expectedAttributes == null) { - failures.append("missing expected problem attributes for problem " + name + "\n"); - } else if (!expectedAttributes.skip && !expectedAttributes.option.equals(actualTuningOption)) { - failures.append("tuning option mismatch for problem " + name + " (expected " + expectedAttributes.option + ", got " + actualTuningOption + ")\n"); + fields = IProblem.class.getFields(); + StringBuffer failures = new StringBuffer(); + StringBuffer correctResult = new StringBuffer(70000); + Arrays.sort(fields, new Comparator() { + public int compare(Object o1, Object o2) { + Field field1 = (Field) o1; + Field field2 = (Field) o2; + return field1.getName().compareTo(field2.getName()); + } + }); + for (int i = 0, length = fields.length; i < length; i++) { + Field field = fields[i]; + if (field.getType() == Integer.TYPE) { + int problemId = field.getInt(null), maskedProblemId = problemId & IProblem.IgnoreCategoriesMask; + if (maskedProblemId != 0 && maskedProblemId != IProblem.IgnoreCategoriesMask) { + String name = field.getName(); + ProblemAttributes expectedAttributes = (ProblemAttributes) expectedProblemAttributes.get(name); + String actualTuningOption = JavaCore.getOptionForConfigurableSeverity(problemId); + if (expectedAttributes == null) { + failures.append("missing expected problem attributes for problem " + name + "\n"); + } else if (!expectedAttributes.skip && !expectedAttributes.option.equals(actualTuningOption)) { + failures.append("tuning option mismatch for problem " + name + " (expected " + + expectedAttributes.option + ", got " + actualTuningOption + ")\n"); + } + String optionFieldName = (String) constantNamesIndex.get(actualTuningOption); + correctResult.append("\t\texpectedProblemAttributes.put(\"" + name + "\", " + + (optionFieldName != null ? "new ProblemAttributes(JavaCore." + optionFieldName + ")" + : "SKIP") + + ");\n"); } - String optionFieldName = (String) constantNamesIndex.get(actualTuningOption); - correctResult.append("\t\texpectedProblemAttributes.put(\"" + name + "\", " + - (optionFieldName != null ? "new ProblemAttributes(JavaCore." + optionFieldName + ")" : - "SKIP") + ");\n"); } } + if (failures.length() > 0) { + System.out.println(correctResult); + System.out.println(); + } + assertEquals(failures.toString(), 0, failures.length()); + } catch (IllegalAccessException e) { + fail("could not access members"); } - if (failures.length() > 0) { - System.out.println(correctResult); - System.out.println(); - } - assertEquals(failures.toString(), 0, failures.length()); - } - catch (IllegalAccessException e) { - fail("could not access members"); } } -} diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/FlowAnalysisTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/FlowAnalysisTest.java index 5602566218..ac0da2fa40 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/FlowAnalysisTest.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/FlowAnalysisTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2018 IBM Corporation and others. + * Copyright (c) 2005, 2019 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -8,6 +8,10 @@ * * SPDX-License-Identifier: EPL-2.0 * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * IBM Corporation - initial API and implementation * Stephan Herrmann - Contributions for @@ -2904,6 +2908,1944 @@ public void testBug537804_comment5() { "The local variable action may not have been initialized\n" + "----------\n"); } +public void testBug542707_001() { + if (this.complianceLevel != ClassFileConstants.JDK12) + return; + Map<String, String> defaultOptions = super.getCompilerOptions(); + defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED); + defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE); + String expectedProblemLog = + "----------\n" + + "1. ERROR in X.java (at line 11)\n" + + " break k;\n" + + " ^\n" + + "The local variable k may not have been initialized\n" + + "----------\n" + + "2. ERROR in X.java (at line 14)\n" + + " return k + it;\n" + + " ^\n" + + "The local variable k may not have been initialized\n" + + "----------\n"; + String[] testFiles = new String[] { + "X.java", // ================= + "public class X {\n" + + " public static int foo(int i) {\n" + + " final int k;\n" + + "\n" + + " int it = switch (i) { \n" + + " case 1 -> {\n" + + " k = 1;\n" + + " break k ;\n" + + " }\n" + + " default -> {\n" + + " break k;\n" + + " }\n" + + " };\n" + + " return k + it;\n" + + " }\n" + + "\n" + + " public boolean bar() {\n" + + " return true;\n" + + " }\n" + + " public static void main(String[] args) {\n" + + " System.out.println(foo(3));\n" + + " }\n" + + "}\n", + }; + this.runNegativeTest( + testFiles, + expectedProblemLog, + null, + true, + defaultOptions); + +} +public void testBug542707_002() { + if (this.complianceLevel != ClassFileConstants.JDK12) + return; + Map<String, String> defaultOptions = super.getCompilerOptions(); + defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED); + defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE); + String expectedProblemLog = + "----------\n" + + "1. ERROR in X.java (at line 5)\n" + + " k = switch (i) { \n" + + " ^\n" + + "The final local variable k may already have been assigned\n" + + "----------\n" + + "2. ERROR in X.java (at line 11)\n" + + " break k;\n" + + " ^\n" + + "The local variable k may not have been initialized\n" + + "----------\n"; + String[] testFiles = new String[] { + "X.java", // ================= + "public class X {\n" + + " public static int foo(int i) {\n" + + " final int k;\n" + + "\n" + + " k = switch (i) { \n" + + " case 1 -> {\n" + + " k = 1;\n" + + " break k ;\n" + + " }\n" + + " default -> {\n" + + " break k;\n" + + " }\n" + + " };\n" + + " return k;\n" + + " }\n" + + "\n" + + " public boolean bar() {\n" + + " return true;\n" + + " }\n" + + " public static void main(String[] args) {\n" + + " System.out.println(foo(3));\n" + + " }\n" + + "}\n", + }; + this.runNegativeTest( + testFiles, + expectedProblemLog, + null, + true, + defaultOptions); +} +/* + * k is definitely assigned - no errors on that front. + */ +public void testBug542707_003() { + if (this.complianceLevel != ClassFileConstants.JDK12) + return; + Map<String, String> defaultOptions = super.getCompilerOptions(); + defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED); + defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE); + String expectedProblemLog = + "----------\n" + + "1. ERROR in X.java (at line 23)\n" + + " Zork();\n" + + " ^^^^\n" + + "The method Zork() is undefined for the type X\n" + + "----------\n"; + String[] testFiles = new String[] { + "X.java", // ================= + "public class X {\n" + + " public static int foo(int i) {\n" + + " final int k;\n" + + "\n" + + " int it = switch (i) { \n" + + " case 1 -> {\n" + + " k = 1;\n" + + " break k ;\n" + + " }\n" + + " case 2 -> {\n" + + " k = 2;\n" + + " break k ;\n" + + " }\n" + + " default -> {\n" + + " k = 3;\n" + + " break k;\n" + + " }\n" + + " };\n" + + " return k;\n" + + " }\n" + + "\n" + + " public boolean bar() {\n" + + " Zork();\n" + + " return true;\n" + + " }\n" + + " public static void main(String[] args) {\n" + + " System.out.println(foo(3));\n" + + " }\n" + + "}\n", + }; + this.runNegativeTest( + testFiles, + expectedProblemLog, + null, + true, + defaultOptions); +} +public void testBug542707_004() { + if (this.complianceLevel != ClassFileConstants.JDK12) + return; + Map<String, String> defaultOptions = super.getCompilerOptions(); + defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED); + defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE); + String expectedProblemLog = + "----------\n" + + "1. ERROR in X.java (at line 7)\n" + + " k = 1;\n" + + " ^\n" + + "The final local variable k cannot be assigned. It must be blank and not using a compound assignment\n" + + "----------\n" + + "2. ERROR in X.java (at line 11)\n" + + " k = 2;\n" + + " ^\n" + + "The final local variable k cannot be assigned. It must be blank and not using a compound assignment\n" + + "----------\n" + + "3. ERROR in X.java (at line 15)\n" + + " k = 3;\n" + + " ^\n" + + "The final local variable k cannot be assigned. It must be blank and not using a compound assignment\n" + + "----------\n" + + "4. ERROR in X.java (at line 23)\n" + + " Zork();\n" + + " ^^^^\n" + + "The method Zork() is undefined for the type X\n" + + "----------\n"; + String[] testFiles = new String[] { + "X.java", // ================= + "public class X {\n" + + " public static int foo(int i) {\n" + + " final int k = 1;\n" + + "\n" + + " int it = switch (i) { \n" + + " case 1 -> {\n" + + " k = 1;\n" + + " break k ;\n" + + " }\n" + + " case 2 -> {\n" + + " k = 2;\n" + + " break k ;\n" + + " }\n" + + " default -> {\n" + + " k = 3;\n" + + " break k;\n" + + " }\n" + + " };\n" + + " return k;\n" + + " }\n" + + "\n" + + " public boolean bar() {\n" + + " Zork();\n" + + " return true;\n" + + " }\n" + + " public static void main(String[] args) {\n" + + " System.out.println(foo(3));\n" + + " }\n" + + "}\n", + }; + this.runNegativeTest( + testFiles, + expectedProblemLog, + null, + true, + defaultOptions); +} +public void testBug542707_005() { + if (this.complianceLevel != ClassFileConstants.JDK12) + return; + Map<String, String> defaultOptions = super.getCompilerOptions(); + defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED); + defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE); + String expectedProblemLog = + "----------\n" + + "1. ERROR in X.java (at line 11)\n" + + " break k ;\n" + + " ^\n" + + "The local variable k may not have been initialized\n" + + "----------\n" + + "2. ERROR in X.java (at line 18)\n" + + " return k;\n" + + " ^\n" + + "The local variable k may not have been initialized\n" + + "----------\n" + + "3. ERROR in X.java (at line 22)\n" + + " Zork();\n" + + " ^^^^\n" + + "The method Zork() is undefined for the type X\n" + + "----------\n"; + String[] testFiles = new String[] { + "X.java", // ================= + "public class X {\n" + + " public static int foo(int i) {\n" + + " final int k;\n" + + "\n" + + " int it = switch (i) { \n" + + " case 1 -> {\n" + + " k = 1;\n" + + " break k ;\n" + + " }\n" + + " case 2 -> {\n" + + " break k ;\n" + + " }\n" + + " default -> {\n" + + " k = 3;\n" + + " break k;\n" + + " }\n" + + " };\n" + + " return k;\n" + + " }\n" + + "\n" + + " public boolean bar() {\n" + + " Zork();\n" + + " return true;\n" + + " }\n" + + " public static void main(String[] args) {\n" + + " System.out.println(foo(3));\n" + + " }\n" + + "}\n", + }; + this.runNegativeTest( + testFiles, + expectedProblemLog, + null, + true, + defaultOptions); +} +/** + * From JLS 12 16.1.7 , Suppose that the switch expression has result expressions e1, …, en, all of + * which are boolean-valued. + * V is definitely assigned after a switch expression when true iff for every value break statement with + * expression e in the switch block that may exit the switch expression, V is definitely assigned after e when true. + * V is definitely assigned after a switch expression when false iff for every value break statement with + * expression e in the switch block that may exit the switch expression, V is definitely assigned after e when false. + */ +public void testBug542707_006() { + if (this.complianceLevel != ClassFileConstants.JDK12) + return; + Map<String, String> defaultOptions = super.getCompilerOptions(); + defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED); + defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE); + String expectedProblemLog = + "----------\n" + + "1. ERROR in X.java (at line 22)\n" + + " Zork();\n" + + " ^^^^\n" + + "The method Zork() is undefined for the type X\n" + + "----------\n"; + String[] testFiles = new String[] { + "X.java", // ================= + "public class X {\n" + + " public static int foo(int i) {\n" + + " int v;\n" + + " boolean b = switch (i) {\n" + + " case 1 :\n" + + " v = 1;\n" + + " break true;\n" + + " case 2 : {\n" + + " v = 2;\n" + + " break true;\n" + + " }\n" + + " default : {\n" + + " v = 3;\n" + + " break false;\n" + + " }\n" + + " };\n" + + " int d = b == true ? 0 : 1; \n" + + " return v + d;\n" + + " }\n" + + "\n" + + " public boolean bar() {\n" + + " Zork();\n" + + " return true;\n" + + " }\n" + + " public static void main(String[] args) {\n" + + " System.out.println(foo(3));\n" + + " }\n" + + "}\n", + }; + this.runNegativeTest( + testFiles, + expectedProblemLog, + null, + true, + defaultOptions); +} +/** + * From JLS 12 16.1.7 , Suppose that the switch expression has result expressions e1, …, en, all of + * which are boolean-valued. + * V is definitely unassigned after a switch expression when true iff for every value break statement with expression + * e in the switch block that may exit the switch expression, V is definitely unassigned before the value break + * statement and V is definitely unassigned after e when true. + * V is definitely unassigned after a switch expression when false iff for every value break statement with expression + * e in the switch block that may exit the switch expression, V is definitely unassigned before the value break + * statement and V is definitely unassigned after e when false. + */ +public void testBug542707_007() { + if (this.complianceLevel != ClassFileConstants.JDK12) + return; + Map<String, String> defaultOptions = super.getCompilerOptions(); + defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED); + defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE); + String expectedProblemLog = + "----------\n" + + "1. ERROR in X.java (at line 18)\n" + + " return v + d;\n" + + " ^\n" + + "The local variable v may not have been initialized\n" + + "----------\n" + + "2. ERROR in X.java (at line 22)\n" + + " Zork();\n" + + " ^^^^\n" + + "The method Zork() is undefined for the type X\n" + + "----------\n"; + String[] testFiles = new String[] { + "X.java", // ================= + "public class X {\n" + + " public static int foo(int i) {\n" + + " int v;\n" + + " boolean b = switch (i) {\n" + + " case 1 :\n" + + " //v = 1;\n" + + " break true;\n" + + " case 2 : {\n" + + " //v = 2;\n" + + " break true;\n" + + " }\n" + + " default : {\n" + + " //v = 3;\n" + + " break false;\n" + + " }\n" + + " };\n" + + " int d = b == true ? 0 : 1; \n" + + " return v + d;\n" + + " }\n" + + "\n" + + " public boolean bar() {\n" + + " Zork();\n" + + " return true;\n" + + " }\n" + + " public static void main(String[] args) {\n" + + " System.out.println(foo(3));\n" + + " }\n" + + "}\n", + }; + this.runNegativeTest( + testFiles, + expectedProblemLog, + null, + true, + defaultOptions); +} +/** + * From JLS 12 16.1.7 , Suppose that the switch expression has result expressions e1, …, en, all of + * which are boolean-valued. + * V is [un]assigned before the selector expression iff V is [un]assigned before the switch statement. + */ +public void testBug542707_008() { + if (this.complianceLevel != ClassFileConstants.JDK12) + return; + Map<String, String> defaultOptions = super.getCompilerOptions(); + defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED); + defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE); + String expectedProblemLog = + "----------\n" + + "1. ERROR in X.java (at line 22)\n" + + " Zork();\n" + + " ^^^^\n" + + "The method Zork() is undefined for the type X\n" + + "----------\n"; + String[] testFiles = new String[] { + "X.java", // ================= + "public class X {\n" + + " public static int foo(int i) {\n" + + " int v = 1;\n" + + " boolean b = switch (i) {\n" + + " case 1 :\n" + + " //v = 1;\n" + + " break true;\n" + + " case 2 : {\n" + + " //v = 2;\n" + + " break true;\n" + + " }\n" + + " default : {\n" + + " //v = 3;\n" + + " break false;\n" + + " }\n" + + " };\n" + + " int d = b == true ? 0 : 1; \n" + + " return v + d;\n" + + " }\n" + + "\n" + + " public boolean bar() {\n" + + " Zork();\n" + + " return true;\n" + + " }\n" + + " public static void main(String[] args) {\n" + + " System.out.println(foo(3));\n" + + " }\n" + + "}\n", + }; + this.runNegativeTest( + testFiles, + expectedProblemLog, + null, + true, + defaultOptions); +} +/** + * From JLS 12 16.1.7 , Suppose that the switch expression has result expressions e1, …, en, all of + * which are boolean-valued. + * V is [un]assigned before the selector expression iff V is [un]assigned before the switch statement. + */ +public void testBug542707_009() { + if (this.complianceLevel != ClassFileConstants.JDK12) + return; + Map<String, String> defaultOptions = super.getCompilerOptions(); + defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED); + defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE); + String expectedProblemLog = + "----------\n" + + "1. ERROR in X.java (at line 4)\n" + + " boolean b = switch (v) {\n" + + " ^\n" + + "The local variable v may not have been initialized\n" + + "----------\n" + + "2. ERROR in X.java (at line 22)\n" + + " Zork();\n" + + " ^^^^\n" + + "The method Zork() is undefined for the type X\n" + + "----------\n"; + String[] testFiles = new String[] { + "X.java", // ================= + "public class X {\n" + + " public static int foo(int i) {\n" + + " int v;\n" + + " boolean b = switch (v) {\n" + + " case 1 :\n" + + " v = 1;\n" + + " break true;\n" + + " case 2 : {\n" + + " v = 2;\n" + + " break true;\n" + + " }\n" + + " default : {\n" + + " v = 3;\n" + + " break false;\n" + + " }\n" + + " };\n" + + " int d = b == true ? 0 : 1; \n" + + " return v + d;\n" + + " }\n" + + "\n" + + " public boolean bar() {\n" + + " Zork();\n" + + " return true;\n" + + " }\n" + + " public static void main(String[] args) {\n" + + " System.out.println(foo(3));\n" + + " }\n" + + "}\n", + }; + this.runNegativeTest( + testFiles, + expectedProblemLog, + null, + true, + defaultOptions); +} +/** + * From JLS 12 16.1.7 , Suppose that the switch expression has result expressions e1, …, en, all of + * which are boolean-valued. + * V is [un]assigned before the first statement of the first switch labeled statement group in the switch block + * iff V is [un]assigned after the selector expression. + */ +public void testBug542707_010() { + if (this.complianceLevel != ClassFileConstants.JDK12) + return; + Map<String, String> defaultOptions = super.getCompilerOptions(); + defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED); + defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE); + String expectedProblemLog = + "----------\n" + + "1. ERROR in X.java (at line 22)\n" + + " Zork();\n" + + " ^^^^\n" + + "The method Zork() is undefined for the type X\n" + + "----------\n"; + String[] testFiles = new String[] { + "X.java", // ================= + "public class X {\n" + + " public static int foo(int i) {\n" + + " int v;\n" + + " boolean b = switch (i + (v =1)) {\n" + + " case 1 :\n" + + " v += 1;\n" + + " break true;\n" + + " case 2 : {\n" + + " v = 2;\n" + + " break true;\n" + + " }\n" + + " default : {\n" + + " v = 3;\n" + + " break false;\n" + + " }\n" + + " };\n" + + " int d = b == true ? 0 : 1; \n" + + " return v + d;\n" + + " }\n" + + "\n" + + " public boolean bar() {\n" + + " Zork();\n" + + " return true;\n" + + " }\n" + + " public static void main(String[] args) {\n" + + " System.out.println(foo(3));\n" + + " }\n" + + "}\n", + }; + this.runNegativeTest( + testFiles, + expectedProblemLog, + null, + true, + defaultOptions); +} +/** + * From JLS 12 16.1.7 , Suppose that the switch expression has result expressions e1, …, en, all of + * which are boolean-valued. + * V is [un]assigned before the first statement of the first switch labeled statement group in the switch block + * iff V is [un]assigned after the selector expression. + */ +public void testBug542707_011() { + if (this.complianceLevel != ClassFileConstants.JDK12) + return; + Map<String, String> defaultOptions = super.getCompilerOptions(); + defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED); + defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE); + String expectedProblemLog = + "----------\n" + + "1. ERROR in X.java (at line 6)\n" + + " v += 1;\n" + + " ^\n" + + "The local variable v may not have been initialized\n" + + "----------\n" + + "2. ERROR in X.java (at line 22)\n" + + " Zork();\n" + + " ^^^^\n" + + "The method Zork() is undefined for the type X\n" + + "----------\n"; + String[] testFiles = new String[] { + "X.java", // ================= + "public class X {\n" + + " public static int foo(int i) {\n" + + " int v;\n" + + " boolean b = switch (i) {\n" + + " case 1 :\n" + + " v += 1;\n" + + " break true;\n" + + " case 2 : {\n" + + " v = 2;\n" + + " break true;\n" + + " }\n" + + " default : {\n" + + " v = 3;\n" + + " break false;\n" + + " }\n" + + " };\n" + + " int d = b == true ? 0 : 1; \n" + + " return v + d;\n" + + " }\n" + + "\n" + + " public boolean bar() {\n" + + " Zork();\n" + + " return true;\n" + + " }\n" + + " public static void main(String[] args) {\n" + + " System.out.println(foo(3));\n" + + " }\n" + + "}\n", + }; + this.runNegativeTest( + testFiles, + expectedProblemLog, + null, + true, + defaultOptions); +} +/** + * From JLS 12 16.1.7 , Suppose that the switch expression has result expressions e1, …, en, all of + * which are boolean-valued. + * V is [un]assigned before the first statement of any switch labeled statement group other than the first iff + * V is [un]assigned after the selector expression and V is [un]assigned after the preceding statement. + * TODO: the second part - "and V is [un]assigned after the preceding statement" needs to be checked, now it looks identical to the + * preceding rule + */ +public void testBug542707_012() { + if (this.complianceLevel != ClassFileConstants.JDK12) + return; + Map<String, String> defaultOptions = super.getCompilerOptions(); + defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED); + defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE); + String expectedProblemLog = + "----------\n" + + "1. ERROR in X.java (at line 22)\n" + + " Zork();\n" + + " ^^^^\n" + + "The method Zork() is undefined for the type X\n" + + "----------\n"; + String[] testFiles = new String[] { + "X.java", // ================= + "public class X {\n" + + " public static int foo(int i) {\n" + + " int v;\n" + + " boolean b = switch (i + (v =1)) {\n" + + " case 1 :\n" + + " v = 1;\n" + + " break true;\n" + + " case 2 : {\n" + + " v += 2;\n" + + " break true;\n" + + " }\n" + + " default : {\n" + + " v = 3;\n" + + " break false;\n" + + " }\n" + + " };\n" + + " int d = b == true ? 0 : 1; \n" + + " return v + d;\n" + + " }\n" + + "\n" + + " public boolean bar() {\n" + + " Zork();\n" + + " return true;\n" + + " }\n" + + " public static void main(String[] args) {\n" + + " System.out.println(foo(3));\n" + + " }\n" + + "}\n", + }; + this.runNegativeTest( + testFiles, + expectedProblemLog, + null, + true, + defaultOptions); +} +/** + * From JLS 12 16.1.7 , Suppose that the switch expression has result expressions e1, …, en, all of + * which are boolean-valued. + * V is [un]assigned before the first statement of any switch labeled statement group other than the first iff + * V is [un]assigned after the selector expression and V is [un]assigned after the preceding statement. + * TODO: the second part - "and V is [un]assigned after the preceding statement" needs to be checked, now it looks identical to the + * preceding rule + */ +public void testBug542707_013() { + if (this.complianceLevel != ClassFileConstants.JDK12) + return; + Map<String, String> defaultOptions = super.getCompilerOptions(); + defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED); + defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE); + String expectedProblemLog = + "----------\n" + + "1. ERROR in X.java (at line 9)\n" + + " v += 2;\n" + + " ^\n" + + "The local variable v may not have been initialized\n" + + "----------\n" + + "2. ERROR in X.java (at line 22)\n" + + " Zork();\n" + + " ^^^^\n" + + "The method Zork() is undefined for the type X\n" + + "----------\n"; + String[] testFiles = new String[] { + "X.java", // ================= + "public class X {\n" + + " public static int foo(int i) {\n" + + " int v;\n" + + " boolean b = switch (i) {\n" + + " case 1 :\n" + + " v = 1;\n" + + " break true;\n" + + " case 2 : {\n" + + " v += 2;\n" + + " break true;\n" + + " }\n" + + " default : {\n" + + " v = 3;\n" + + " break false;\n" + + " }\n" + + " };\n" + + " int d = b == true ? 0 : 1; \n" + + " return v + d;\n" + + " }\n" + + "\n" + + " public boolean bar() {\n" + + " Zork();\n" + + " return true;\n" + + " }\n" + + " public static void main(String[] args) {\n" + + " System.out.println(foo(3));\n" + + " }\n" + + "}\n", + }; + this.runNegativeTest( + testFiles, + expectedProblemLog, + null, + true, + defaultOptions); +} +/** + * From JLS 12 16.1.7 , Suppose that the switch expression has result expressions e1, …, en, all of + * which are boolean-valued. + * The following rules apply only if the switch block of a switch expression consists of switch labeled rules: + * V is definitely assigned after a switch expression when true iff for every switch labeled rule one of the following is true: + * It is a switch labeled expression e and V is definitely assigned after e when true. + * It is a switch labeled block b and for every value break statement expression e contained in b that may exit the switch expression, + * V is definitely assigned after e when true. + * It is a switch labeled throw statement. + * + * V is definitely assigned after a switch expression when false iff for every switch labeled rule one of the following is true: + * It is a switch labeled expression e and V is definitely assigned after e when false. + * It is a switch labeled block b and for every value break statement expression e contained in b that may exit the switch expression, + * V is definitely assigned after e when false. + * It is a switch labeled throw statement. + */ +public void testBug542707_014() { + if (this.complianceLevel != ClassFileConstants.JDK12) + return; + Map<String, String> defaultOptions = super.getCompilerOptions(); + defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED); + defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE); + String expectedProblemLog = + "----------\n" + + "1. ERROR in X.java (at line 23)\n" + + " Zork();\n" + + " ^^^^\n" + + "The method Zork() is undefined for the type X\n" + + "----------\n"; + String[] testFiles = new String[] { + "X.java", // ================= + "import java.io.IOException;\n" + + "public class X {\n" + + " public static int foo(int i) throws IOException {\n" + + " int v;\n" + + " boolean b = switch (i ) {\n" + + " case 0 -> (v = 1) != 0;\n" + + " case 1 -> (v = 1) == 0;\n" + + " case 2 -> {\n" + + " v = 2;\n" + + " break true;\n" + + " }\n" + + " case 3 -> {\n" + + " v = 3;\n" + + " break false;\n" + + " }\n" + + " default -> throw new IOException();\n" + + " };\n" + + " int d = b == true ? 0 : 1; \n" + + " return v + d;\n" + + " }\n" + + " \n" + + " public boolean bar() {\n" + + " Zork();\n" + + " return true;\n" + + " }\n" + + " public static void main(String[] args) {\n" + + " try {\n" + + " System.out.println(foo(3));\n" + + " } catch (IOException e) {\n" + + " e.printStackTrace();\n" + + " }\n" + + " }\n" + + "}\n", + }; + this.runNegativeTest( + testFiles, + expectedProblemLog, + null, + true, + defaultOptions); +} +/** + * From JLS 12 16.1.7 , Suppose that the switch expression has result expressions e1, …, en, all of + * which are boolean-valued. + * The following rules apply only if the switch block of a switch expression consists of switch labeled rules: + * V is definitely unassigned after a switch expression when true iff for every switch labeled rule one of the following is true: + * It is a switch labeled expression e and V is definitely unassigned after e when true . + * It is a switch labeled block b and for every value break statement expression e contained in b that + * may exit the switch expression, V is definitely unassigned before the value break statement and + * V is definitely unassigned after e when true. + * It is a switch labeled throw statement. + * + * V is definitely unassigned after a switch expression when false iff for every switch labeled rule one of the following is true: + * It is a switch labeled expression e and V is definitely unassigned after e when false. + * It is a switch labeled block b and for every value break statement expression e contained in b that may + * exit the switch expression, V is definitely unassigned before the value break statement and V is definitely unassigned + * after e when false. + * It is a switch labeled throw statement. + */ +public void testBug542707_015() { + if (this.complianceLevel != ClassFileConstants.JDK12) + return; + Map<String, String> defaultOptions = super.getCompilerOptions(); + defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED); + defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE); + String expectedProblemLog = + "----------\n" + + "1. ERROR in X.java (at line 17)\n" + + " return v + d;\n" + + " ^\n" + + "The local variable v may not have been initialized\n" + + "----------\n" + + "2. ERROR in X.java (at line 21)\n" + + " Zork();\n" + + " ^^^^\n" + + "The method Zork() is undefined for the type X\n" + + "----------\n"; + String[] testFiles = new String[] { + "X.java", // ================= + "import java.io.IOException;\n" + + "public class X {\n" + + " public static int foo(int i) throws IOException {\n" + + " int v;\n" + + " boolean b = switch (i ) {\n" + + " case 0 -> true;\n" + + " case 1 -> false;\n" + + " case 2 -> {\n" + + " break true;\n" + + " }\n" + + " case 3 -> {\n" + + " break false;\n" + + " }\n" + + " default -> throw new IOException();\n" + + " };\n" + + " int d = b == true ? 0 : 1; \n" + + " return v + d;\n" + + " }\n" + + " \n" + + " public boolean bar() {\n" + + " Zork();\n" + + " return true;\n" + + " }\n" + + " public static void main(String[] args) {\n" + + " try {\n" + + " System.out.println(foo(3));\n" + + " } catch (IOException e) {\n" + + " e.printStackTrace();\n" + + " }\n" + + " }\n" + + "}\n", + }; + this.runNegativeTest( + testFiles, + expectedProblemLog, + null, + true, + defaultOptions); +} +/** + * From JLS 12 16.1.7 , Suppose that the switch expression has result expressions e1, …, en, all of + * which are boolean-valued. + * V is [un]assigned before any switch labeled expression or statement in the switch + * block iff V is [un]assigned after the selector expression. + */ +public void testBug542707_016() { + if (this.complianceLevel != ClassFileConstants.JDK12) + return; + Map<String, String> defaultOptions = super.getCompilerOptions(); + defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED); + defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE); + String expectedProblemLog = + "----------\n" + + "1. ERROR in X.java (at line 14)\n" + + " Zork();\n" + + " ^^^^\n" + + "The method Zork() is undefined for the type X\n" + + "----------\n"; + String[] testFiles = new String[] { + "X.java", // ================= + "import java.io.IOException;\n" + + "public class X {\n" + + " public static int foo(int i) throws IOException {\n" + + " int v;\n" + + " boolean b = switch ((v = 1)) {\n" + + " case 0 -> v != 0;\n" + + " default -> throw new IOException();\n" + + " };\n" + + " int d = b == true ? 0 : 1; \n" + + " return v + d;\n" + + " }\n" + + " \n" + + " public boolean bar() {\n" + + " Zork();\n" + + " return true;\n" + + " }\n" + + " public static void main(String[] args) {\n" + + " try {\n" + + " System.out.println(foo(3));\n" + + " } catch (IOException e) {\n" + + " e.printStackTrace();\n" + + " }\n" + + " }\n" + + "}\n", + }; + this.runNegativeTest( + testFiles, + expectedProblemLog, + null, + true, + defaultOptions); +} +/** + * From JLS 12 16.1.7 , Suppose that the switch expression has result expressions e1, …, en, all of + * which are boolean-valued. + * The following rules apply only if the switch block of a switch expression consists of switch labeled rules: + * V is [un]assigned before any switch labeled expression or statement in the switch + * block iff V is [un]assigned after the selector expression. + */ +public void testBug542707_017() { + if (this.complianceLevel != ClassFileConstants.JDK12) + return; + Map<String, String> defaultOptions = super.getCompilerOptions(); + defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED); + defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE); + String expectedProblemLog = + "----------\n" + + "1. ERROR in X.java (at line 6)\n" + + " case 0 -> v != 0;\n" + + " ^\n" + + "The local variable v may not have been initialized\n" + + "----------\n" + + "2. ERROR in X.java (at line 10)\n" + + " return v + d;\n" + + " ^\n" + + "The local variable v may not have been initialized\n" + + "----------\n" + + "3. ERROR in X.java (at line 14)\n" + + " Zork();\n" + + " ^^^^\n" + + "The method Zork() is undefined for the type X\n" + + "----------\n"; + String[] testFiles = new String[] { + "X.java", // ================= + "import java.io.IOException;\n" + + "public class X {\n" + + " public static int foo(int i) throws IOException {\n" + + " int v;\n" + + " boolean b = switch (i) {\n" + + " case 0 -> v != 0;\n" + + " default -> throw new IOException();\n" + + " };\n" + + " int d = b == true ? 0 : 1; \n" + + " return v + d;\n" + + " }\n" + + " \n" + + " public boolean bar() {\n" + + " Zork();\n" + + " return true;\n" + + " }\n" + + " public static void main(String[] args) {\n" + + " try {\n" + + " System.out.println(foo(3));\n" + + " } catch (IOException e) {\n" + + " e.printStackTrace();\n" + + " }\n" + + " }\n" + + "}\n", + }; + this.runNegativeTest( + testFiles, + expectedProblemLog, + null, + true, + defaultOptions); +} +/** + * From JLS 12 16.1.8, Suppose that the switch expression has result expressions e1, …, en, not all of + * which are boolean-valued. + * The following rules apply only if the switch block of a switch expression (15.28) consists of switch + * labeled statement groups: + * V is definitely assigned after a switch expression iff for every value break statement with expression e + * in the switch block that may exit the switch expression, either V is definitely assigned before the value + * break statement or V is definitely assigned after e. + */ +public void testBug542707_018() { + if (this.complianceLevel != ClassFileConstants.JDK12) + return; + Map<String, String> defaultOptions = super.getCompilerOptions(); + defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED); + defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE); + String expectedProblemLog = + "----------\n" + + "1. ERROR in X.java (at line 20)\n" + + " Zork();\n" + + " ^^^^\n" + + "The method Zork() is undefined for the type X\n" + + "----------\n"; + String[] testFiles = new String[] { + "X.java", // ================= + "public class X {\n" + + " public static int foo(int i) {\n" + + " int v;\n" + + " int t = switch (i) {\n" + + " case 0 : {\n" + + " v = 1; // definitely assigned before break\n" + + " break v;\n" + + " }\n" + + " case 2 : {\n" + + " break v =1; // definitely assigned after e\n" + + " }\n" + + " default : {\n" + + " break v = 2;\n" + + " }\n" + + " };\n" + + " return v + t;\n" + + " }\n" + + " \n" + + " public boolean bar() {\n" + + " Zork();\n" + + " return true;\n" + + " }\n" + + " public static void main(String[] args) {\n" + + " System.out.println(foo(3));\n" + + " }\n" + + "}\n", + }; + this.runNegativeTest( + testFiles, + expectedProblemLog, + null, + true, + defaultOptions); +} +/** + * From JLS 12 16.1.8, Suppose that the switch expression has result expressions e1, …, en, not all of + * which are boolean-valued. + * The following rules apply only if the switch block of a switch expression (15.28) consists of switch + * labeled statement groups: + * V is definitely unassigned after a switch expression iff for every value break statement with expression e + * in the switch block that may exit the switch expression, V is definitely unassigned before the value break + * statement and V is definitely unassigned after e. + */ +public void testBug542707_019() { + if (this.complianceLevel != ClassFileConstants.JDK12) + return; + Map<String, String> defaultOptions = super.getCompilerOptions(); + defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED); + defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE); + String expectedProblemLog = + "----------\n" + + "1. ERROR in X.java (at line 15)\n" + + " return v + t;\n" + + " ^\n" + + "The local variable v may not have been initialized\n" + + "----------\n" + + "2. ERROR in X.java (at line 19)\n" + + " Zork();\n" + + " ^^^^\n" + + "The method Zork() is undefined for the type X\n" + + "----------\n"; + String[] testFiles = new String[] { + "X.java", // ================= + "public class X {\n" + + " public static int foo(int i) {\n" + + " int v;\n" + + " int t = switch (i) {\n" + + " case 0 : {\n" + + " break 1;\n" + + " }\n" + + " case 2 : {\n" + + " break 2;\n" + + " }\n" + + " default : {\n" + + " break 3;\n" + + " }\n" + + " };\n" + + " return v + t;\n" + + " }\n" + + " \n" + + " public boolean bar() {\n" + + " Zork();\n" + + " return true;\n" + + " }\n" + + " public static void main(String[] args) {\n" + + " System.out.println(foo(3));\n" + + " }\n" + + "}\n", + }; + this.runNegativeTest( + testFiles, + expectedProblemLog, + null, + true, + defaultOptions); +} +/** + * From JLS 12 16.1.8, Suppose that the switch expression has result expressions e1, …, en, not all of + * which are boolean-valued. + * The following rules apply only if the switch block of a switch expression (15.28) consists of switch + * labeled statement groups: + * V is [un]assigned before the selector expression iff V is [un]assigned before the switch statement. + */ +public void testBug542707_020() { + if (this.complianceLevel != ClassFileConstants.JDK12) + return; + Map<String, String> defaultOptions = super.getCompilerOptions(); + defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED); + defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE); + String expectedProblemLog = + "----------\n" + + "1. ERROR in X.java (at line 19)\n" + + " Zork();\n" + + " ^^^^\n" + + "The method Zork() is undefined for the type X\n" + + "----------\n"; + String[] testFiles = new String[] { + "X.java", // ================= + "public class X {\n" + + " public static int foo(int i) {\n" + + " int v =1;\n" + + " int t = switch (v) {\n" + + " case 0 : {\n" + + " break 1;\n" + + " }\n" + + " case 2 : {\n" + + " break 2;\n" + + " }\n" + + " default : {\n" + + " break 3;\n" + + " }\n" + + " };\n" + + " return t;\n" + + " }\n" + + " \n" + + " public boolean bar() {\n" + + " Zork();\n" + + " return true;\n" + + " }\n" + + " public static void main(String[] args) {\n" + + " System.out.println(foo(3));\n" + + " }\n" + + "}\n", + }; + this.runNegativeTest( + testFiles, + expectedProblemLog, + null, + true, + defaultOptions); +} +/** + * From JLS 12 16.1.8, Suppose that the switch expression has result expressions e1, …, en, not all of + * which are boolean-valued. + * The following rules apply only if the switch block of a switch expression (15.28) consists of switch + * labeled statement groups: + * V is [un]assigned before the selector expression iff V is [un]assigned before the switch statement. + */ +public void testBug542707_021() { + if (this.complianceLevel != ClassFileConstants.JDK12) + return; + Map<String, String> defaultOptions = super.getCompilerOptions(); + defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED); + defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE); + String expectedProblemLog = + "----------\n" + + "1. ERROR in X.java (at line 4)\n" + + " int t = switch (v) {\n" + + " ^\n" + + "The local variable v may not have been initialized\n" + + "----------\n" + + "2. ERROR in X.java (at line 19)\n" + + " Zork();\n" + + " ^^^^\n" + + "The method Zork() is undefined for the type X\n" + + "----------\n"; + String[] testFiles = new String[] { + "X.java", // ================= + "public class X {\n" + + " public static int foo(int i) {\n" + + " int v;\n" + + " int t = switch (v) {\n" + + " case 0 : {\n" + + " break 1;\n" + + " }\n" + + " case 2 : {\n" + + " break 2;\n" + + " }\n" + + " default : {\n" + + " break 3;\n" + + " }\n" + + " };\n" + + " return t;\n" + + " }\n" + + " \n" + + " public boolean bar() {\n" + + " Zork();\n" + + " return true;\n" + + " }\n" + + " public static void main(String[] args) {\n" + + " System.out.println(foo(3));\n" + + " }\n" + + "}\n", + }; + this.runNegativeTest( + testFiles, + expectedProblemLog, + null, + true, + defaultOptions); +} +/** + * From JLS 12 16.1.8, Suppose that the switch expression has result expressions e1, …, en, not all of + * which are boolean-valued. + * The following rules apply only if the switch block of a switch expression (15.28) consists of switch + * labeled statement groups: + * V is [un]assigned before the first statement of the first switch labeled statement group in the switch block + * iff V is [un]assigned after the selector expression. + */ +public void testBug542707_022() { + if (this.complianceLevel != ClassFileConstants.JDK12) + return; + Map<String, String> defaultOptions = super.getCompilerOptions(); + defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED); + defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE); + String expectedProblemLog = + "----------\n" + + "1. ERROR in X.java (at line 19)\n" + + " Zork();\n" + + " ^^^^\n" + + "The method Zork() is undefined for the type X\n" + + "----------\n"; + String[] testFiles = new String[] { + "X.java", // ================= + "public class X {\n" + + " public static int foo(int i) {\n" + + " int v =1;\n" + + " int t = switch (v) {\n" + + " case 0 : {\n" + + " break v;\n" + + " }\n" + + " case 2 : {\n" + + " break 2;\n" + + " }\n" + + " default : {\n" + + " break 3;\n" + + " }\n" + + " };\n" + + " return t;\n" + + " }\n" + + " \n" + + " public boolean bar() {\n" + + " Zork();\n" + + " return true;\n" + + " }\n" + + " public static void main(String[] args) {\n" + + " System.out.println(foo(3));\n" + + " }\n" + + "}\n", + }; + this.runNegativeTest( + testFiles, + expectedProblemLog, + null, + true, + defaultOptions); +} +/** + * From JLS 12 16.1.8, Suppose that the switch expression has result expressions e1, …, en, not all of + * which are boolean-valued. + * The following rules apply only if the switch block of a switch expression (15.28) consists of switch + * labeled statement groups: + * V is [un]assigned before the first statement of the first switch labeled statement group in the switch block + * iff V is [un]assigned after the selector expression. + */ +public void testBug542707_023() { + if (this.complianceLevel != ClassFileConstants.JDK12) + return; + Map<String, String> defaultOptions = super.getCompilerOptions(); + defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED); + defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE); + String expectedProblemLog = + "----------\n" + + "1. ERROR in X.java (at line 6)\n" + + " break v;\n" + + " ^\n" + + "The local variable v may not have been initialized\n" + + "----------\n" + + "2. ERROR in X.java (at line 19)\n" + + " Zork();\n" + + " ^^^^\n" + + "The method Zork() is undefined for the type X\n" + + "----------\n"; + String[] testFiles = new String[] { + "X.java", // ================= + "public class X {\n" + + " public static int foo(int i) {\n" + + " int v;\n" + + " int t = switch (i) {\n" + + " case 0 : {\n" + + " break v;\n" + + " }\n" + + " case 2 : {\n" + + " break 2;\n" + + " }\n" + + " default : {\n" + + " break 3;\n" + + " }\n" + + " };\n" + + " return t;\n" + + " }\n" + + " \n" + + " public boolean bar() {\n" + + " Zork();\n" + + " return true;\n" + + " }\n" + + " public static void main(String[] args) {\n" + + " System.out.println(foo(3));\n" + + " }\n" + + "}\n", + }; + this.runNegativeTest( + testFiles, + expectedProblemLog, + null, + true, + defaultOptions); +} +/** + * From JLS 12 16.1.8, Suppose that the switch expression has result expressions e1, …, en, not all of + * which are boolean-valued. + * The following rules apply only if the switch block of a switch expression (15.28) consists of switch + * labeled statement groups: + * V is [un]assigned before the first statement of any switch labeled statement group other than the first iff V is [un]assigned + * after the selector expression and V is [un]assigned after the preceding statement. + */ +public void testBug542707_024() { + if (this.complianceLevel != ClassFileConstants.JDK12) + return; + Map<String, String> defaultOptions = super.getCompilerOptions(); + defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED); + defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE); + String expectedProblemLog = + "----------\n" + + "1. ERROR in X.java (at line 9)\n" + + " break v;\n" + + " ^\n" + + "The local variable v may not have been initialized\n" + + "----------\n" + + "2. ERROR in X.java (at line 19)\n" + + " Zork();\n" + + " ^^^^\n" + + "The method Zork() is undefined for the type X\n" + + "----------\n"; + String[] testFiles = new String[] { + "X.java", // ================= + "public class X {\n" + + " public static int foo(int i) {\n" + + " int v ;\n" + + " int t = switch (i) {\n" + + " case 0 : {\n" + + " break 1;\n" + + " }\n" + + " case 2 : {\n" + + " break v;\n" + + " }\n" + + " default : {\n" + + " break 3;\n" + + " }\n" + + " };\n" + + " return t;\n" + + " }\n" + + " \n" + + " public boolean bar() {\n" + + " Zork();\n" + + " return true;\n" + + " }\n" + + " public static void main(String[] args) {\n" + + " System.out.println(foo(3));\n" + + " }\n" + + "}\n", + }; + this.runNegativeTest( + testFiles, + expectedProblemLog, + null, + true, + defaultOptions); +} +/** + * From JLS 12 16.1.8, Suppose that the switch expression has result expressions e1, …, en, not all of + * which are boolean-valued. + * The following rules apply only if the switch block of a switch expression consists of switch labeled rules: + * V is definitely assigned after a switch expression iff for every switch labeled rule one of the following is true: + * It is a switch labeled expression e and V is definitely assigned after e. + * It is a switch labeled block b and for every value break statement expression e contained in b that may exit + * the switch expression, either V is definitely assigned before the value break statement or V is definitely + * assigned after e. + * It is a switch labeled throw statement. + */ +public void testBug542707_025() { + if (this.complianceLevel != ClassFileConstants.JDK12) + return; + Map<String, String> defaultOptions = super.getCompilerOptions(); + defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED); + defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE); + String expectedProblemLog = + "----------\n" + + "1. ERROR in X.java (at line 20)\n" + + " Zork();\n" + + " ^^^^\n" + + "The method Zork() is undefined for the type X\n" + + "----------\n"; + String[] testFiles = new String[] { + "X.java", // ================= + "import java.io.IOException;\n" + + "\n" + + "public class X {\n" + + " public static int foo(int i) throws IOException {\n" + + " int v ;\n" + + " int t = switch (i) {\n" + + " case 0 -> v = 1;\n" + + " case 2 -> {\n" + + " if (i > 1) {\n" + + " break v = 2;\n" + + " }\n" + + " break v = 3;\n" + + " }\n" + + " default -> throw new IOException();\n" + + " };\n" + + " return v + t;\n" + + " }\n" + + " \n" + + " public boolean bar() {\n" + + " Zork();\n" + + " return true;\n" + + " }\n" + + " public static void main(String[] args) {\n" + + " try {\n" + + " System.out.println(foo(3));\n" + + " } catch (IOException e) {\n" + + " // TODO Auto-generated catch block\n" + + " e.printStackTrace();\n" + + " }\n" + + " }\n" + + "}\n", + }; + this.runNegativeTest( + testFiles, + expectedProblemLog, + null, + true, + defaultOptions); +} +/** + * From JLS 12 16.1.8, Suppose that the switch expression has result expressions e1, …, en, not all of + * which are boolean-valued. + * The following rules apply only if the switch block of a switch expression consists of switch labeled rules: + * V is definitely unassigned after a switch expression iff for every switch labeled rule one of the following is true: + * It is a switch labeled expression e and V is definitely unassigned after e. + * It is a switch labeled block b and for every value break statement expression e contained in b that may exit the + * switch expression, V is definitely unassigned before the value break statement + * and V is definitely unassigned after e. + * It is a switch labeled throw statement. + */ +public void testBug542707_026() { + if (this.complianceLevel != ClassFileConstants.JDK12) + return; + Map<String, String> defaultOptions = super.getCompilerOptions(); + defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED); + defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE); + String expectedProblemLog = + "----------\n" + + "1. ERROR in X.java (at line 16)\n" + + " return v + t;\n" + + " ^\n" + + "The local variable v may not have been initialized\n" + + "----------\n" + + "2. ERROR in X.java (at line 20)\n" + + " Zork();\n" + + " ^^^^\n" + + "The method Zork() is undefined for the type X\n" + + "----------\n"; + String[] testFiles = new String[] { + "X.java", // ================= + "import java.io.IOException;\n" + + "\n" + + "public class X {\n" + + " public static int foo(int i) throws IOException {\n" + + " int v ;\n" + + " int t = switch (i) {\n" + + " case 0 -> 1;\n" + + " case 2 -> {\n" + + " if (i > 1) {\n" + + " break 2;\n" + + " }\n" + + " break 3;\n" + + " }\n" + + " default -> throw new IOException();\n" + + " };\n" + + " return v + t;\n" + + " }\n" + + " \n" + + " public boolean bar() {\n" + + " Zork();\n" + + " return true;\n" + + " }\n" + + " public static void main(String[] args) {\n" + + " try {\n" + + " System.out.println(foo(3));\n" + + " } catch (IOException e) {\n" + + " // TODO Auto-generated catch block\n" + + " e.printStackTrace();\n" + + " }\n" + + " }\n" + + "}\n", + }; + this.runNegativeTest( + testFiles, + expectedProblemLog, + null, + true, + defaultOptions); +} +/** + * From JLS 12 16.1.8, Suppose that the switch expression has result expressions e1, …, en, not all of + * which are boolean-valued. + * The following rules apply only if the switch block of a switch expression consists of switch labeled rules: + * V is [un]assigned before any switch labeled expression or statement in the switch block iff + * V is [un]assigned after the selector expression. + */ +public void testBug542707_027() { + if (this.complianceLevel != ClassFileConstants.JDK12) + return; + Map<String, String> defaultOptions = super.getCompilerOptions(); + defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED); + defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE); + String expectedProblemLog = + "----------\n" + + "1. ERROR in X.java (at line 20)\n" + + " Zork();\n" + + " ^^^^\n" + + "The method Zork() is undefined for the type X\n" + + "----------\n"; + String[] testFiles = new String[] { + "X.java", // ================= + "import java.io.IOException;\n" + + "\n" + + "public class X {\n" + + " public static int foo(int i) throws IOException {\n" + + " int v ;\n" + + " int t = switch (v = 1) {\n" + + " case 0 -> v;\n" + + " case 2 -> {\n" + + " if (i > 1) {\n" + + " break 2;\n" + + " }\n" + + " break 3;\n" + + " }\n" + + " default -> throw new IOException();\n" + + " };\n" + + " return v + t;\n" + + " }\n" + + " \n" + + " public boolean bar() {\n" + + " Zork();\n" + + " return true;\n" + + " }\n" + + " public static void main(String[] args) {\n" + + " try {\n" + + " System.out.println(foo(3));\n" + + " } catch (IOException e) {\n" + + " // TODO Auto-generated catch block\n" + + " e.printStackTrace();\n" + + " }\n" + + " }\n" + + "}\n", + }; + this.runNegativeTest( + testFiles, + expectedProblemLog, + null, + true, + defaultOptions); +} +/** + * From JLS 12 16.1.8, Suppose that the switch expression has result expressions e1, …, en, not all of + * which are boolean-valued. + * The following rules apply only if the switch block of a switch expression consists of switch labeled rules: + * V is [un]assigned before any switch labeled expression or statement in the switch block iff + * V is [un]assigned after the selector expression. + */ +public void testBug542707_028() { + if (this.complianceLevel != ClassFileConstants.JDK12) + return; + Map<String, String> defaultOptions = super.getCompilerOptions(); + defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED); + defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE); + String expectedProblemLog = + "----------\n" + + "1. ERROR in X.java (at line 7)\n" + + " case 0 -> v;\n" + + " ^\n" + + "The local variable v may not have been initialized\n" + + "----------\n" + + "2. ERROR in X.java (at line 20)\n" + + " Zork();\n" + + " ^^^^\n" + + "The method Zork() is undefined for the type X\n" + + "----------\n"; + String[] testFiles = new String[] { + "X.java", // ================= + "import java.io.IOException;\n" + + "\n" + + "public class X {\n" + + " public static int foo(int i) throws IOException {\n" + + " int v ;\n" + + " int t = switch (i) {\n" + + " case 0 -> v;\n" + + " case 2 -> {\n" + + " if (i > 1) {\n" + + " break 2;\n" + + " }\n" + + " break 3;\n" + + " }\n" + + " default -> throw new IOException();\n" + + " };\n" + + " return t;\n" + + " }\n" + + " \n" + + " public boolean bar() {\n" + + " Zork();\n" + + " return true;\n" + + " }\n" + + " public static void main(String[] args) {\n" + + " try {\n" + + " System.out.println(foo(3));\n" + + " } catch (IOException e) {\n" + + " // TODO Auto-generated catch block\n" + + " e.printStackTrace();\n" + + " }\n" + + " }\n" + + "}\n", + }; + this.runNegativeTest( + testFiles, + expectedProblemLog, + null, + true, + defaultOptions); +} +/** + * From JLS 12 16.2.9, The following rules apply only if the switch block of the switch statement consists of switch labeled rules: + * V is [un]assigned after a switch statement iff for every switch labeled rule one of the following is true: + * It is a switch labeled expression e and either V is [un]assigned after e or after the selector expression. + * It is a switch labeled block b and either V is [un]assigned after e or V is [un]assigned before every + * break statement contained in b that may exit the switch statement. + * It is a switch labeled throw statement. + */ +public void testBug542707_029() { + if (this.complianceLevel != ClassFileConstants.JDK12) + return; + Map<String, String> defaultOptions = super.getCompilerOptions(); + defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED); + defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE); + String expectedProblemLog = + "----------\n" + + "2. ERROR in X.java (at line 24)\n" + + " Zork();\n" + + " ^^^^\n" + + "The method Zork() is undefined for the type X\n" + + "----------\n"; + String[] testFiles = new String[] { + "X.java", // ================= + "import java.io.IOException;\n" + + "\n" + + "public class X {\n" + + " public static int foo(int i) throws IOException {\n" + + " int v ;\n" + + " switch (i) {\n" + + " case 0 -> {\n" + + " v = 0;\n" + + " }\n" + + " case 2 -> {\n" + + " if (i > 1) {\n" + + " v = 2;\n" + + " break;\n" + + " }\n" + + " v = 3;\n" + + " break;\n" + + " }\n" + + " default -> throw new IOException();\n" + + " };\n" + + " return v;\n" + + " }\n" + + " \n" + + " public boolean bar() {\n" + + " Zork();\n" + + " return true;\n" + + " }\n" + + " public static void main(String[] args) {\n" + + " try {\n" + + " System.out.println(foo(3));\n" + + " } catch (IOException e) {\n" + + " // TODO Auto-generated catch block\n" + + " e.printStackTrace();\n" + + " }\n" + + " }\n" + + "}\n", + }; + this.runNegativeTest( + testFiles, + expectedProblemLog, + null, + true, + defaultOptions); +} +/** + * From JLS 12 16.2.9, The following rules apply only if the switch block of the switch statement consists of switch labeled rules: + * V is [un]assigned after a switch statement iff for every switch labeled rule one of the following is true: + * It is a switch labeled expression e and either V is [un]assigned after e or after the selector expression. + * It is a switch labeled block b and either V is [un]assigned after e or V is [un]assigned before every + * break statement contained in b that may exit the switch statement. + * It is a switch labeled throw statement. + */ +public void testBug542707_030() { + if (this.complianceLevel != ClassFileConstants.JDK12) + return; + Map<String, String> defaultOptions = super.getCompilerOptions(); + defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED); + defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE); + String expectedProblemLog = + "----------\n" + + "1. ERROR in X.java (at line 20)\n" + + " return v;\n" + + " ^\n" + + "The local variable v may not have been initialized\n" + + "----------\n" + + "2. ERROR in X.java (at line 24)\n" + + " Zork();\n" + + " ^^^^\n" + + "The method Zork() is undefined for the type X\n" + + "----------\n"; + String[] testFiles = new String[] { + "X.java", // ================= + "import java.io.IOException;\n" + + "\n" + + "public class X {\n" + + " public static int foo(int i) throws IOException {\n" + + " int v ;\n" + + " switch (i) {\n" + + " case 0 -> {\n" + + " v = 0;\n" + + " }\n" + + " case 2 -> {\n" + + " if (i > 1) {\n" + + " v = 2;\n" + + " break;\n" + + " }\n" + + " // v = 3;\n" + + " break;\n" + + " }\n" + + " default -> throw new IOException();\n" + + " };\n" + + " return v;\n" + + " }\n" + + " \n" + + " public boolean bar() {\n" + + " Zork();\n" + + " return true;\n" + + " }\n" + + " public static void main(String[] args) {\n" + + " try {\n" + + " System.out.println(foo(3));\n" + + " } catch (IOException e) {\n" + + " // TODO Auto-generated catch block\n" + + " e.printStackTrace();\n" + + " }\n" + + " }\n" + + "}\n", + }; + this.runNegativeTest( + testFiles, + expectedProblemLog, + null, + true, + defaultOptions); +} public static Class testClass() { return FlowAnalysisTest.class; } diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericTypeTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericTypeTest.java index 10d7a54ce5..de0df414ab 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericTypeTest.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericTypeTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2018 IBM Corporation and others. + * Copyright (c) 2000, 2019 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -15337,7 +15337,9 @@ public void test0499(){ "1. ERROR in X.java (at line 6)\n" + " Integer[] var = cond ? tab1 : tab2;\n" + " ^^^^^^^^^^^^^^^^^^\n" + - "Type mismatch: cannot convert from Object&Serializable&Comparable<? extends Object&Serializable&Comparable<?>>[] to Integer[]\n" + + "Type mismatch: cannot convert from Object&Serializable&" + + "" + intersection("Comparable<? extends Object&Serializable&" + intersection("Comparable<?>") + ">") + + "[] to Integer[]\n" + "----------\n": "----------\n" + "1. ERROR in X.java (at line 6)\n" + @@ -19815,7 +19817,7 @@ public void test0617() { "1. ERROR in X.java (at line 10)\n" + " String s = l1 != null ? foo(l1, l2) : l3;\n" + " ^^^^^^^^^^^\n" + - "Type mismatch: cannot convert from List<capture#2-of ? extends Number & Comparable<?>> to String\n" + + "Type mismatch: cannot convert from List<capture#2-of ? extends Number & "+intersection("Comparable<?>")+"> to String\n" + "----------\n"); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=92556 @@ -25439,7 +25441,7 @@ public void test0790() { "1. ERROR in X.java (at line 7)\n" + " if (isGreater(i, d)) \n" + " ^^^^^^^^^\n" + - "Bound mismatch: The generic method isGreater(T, T) of type X is not applicable for the arguments (Integer, Double). The inferred type Number&Comparable<?> is not a valid substitute for the bounded parameter <T extends Comparable<T>>\n" + + "Bound mismatch: The generic method isGreater(T, T) of type X is not applicable for the arguments (Integer, Double). The inferred type "+ intersection("Number", "Comparable<?>") +" is not a valid substitute for the bounded parameter <T extends Comparable<T>>\n" + "----------\n" + "2. ERROR in X.java (at line 15)\n" + " isGreater(c1, c2);\n" + @@ -26064,7 +26066,9 @@ public void test0805() { "2. ERROR in X.java (at line 14)\n" + " String s2 = foo(integers, floats);\n" + " ^^^^^^^^^^^^^^^^^^^^^\n" + - "Type mismatch: cannot convert from "+intersection("Number","Comparable<? extends "+intersection("Number","Comparable<?>")+">[]")+" to String\n" + + "Type mismatch: cannot convert from "+intersection("Number", + intersection("Comparable<? extends "+intersection("Number","Comparable<?>")+">") + )+"[] to String\n" + "----------\n"); } //https://bugs.eclipse.org/bugs/show_bug.cgi?id=107079 @@ -33564,12 +33568,12 @@ public void test1000() { "4. WARNING in X.java (at line 14)\n" + " Iterator<Number> it2 = X.chain(l1.iterator(), l2.iterator());\n" + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + - "Type safety: A generic array of Iterator<? extends Number&Comparable<?>> is created for a varargs parameter\n" + + "Type safety: A generic array of Iterator<? extends "+ intersection("Number", "Comparable<?>") +"> is created for a varargs parameter\n" + "----------\n" + "5. ERROR in X.java (at line 14)\n" + " Iterator<Number> it2 = X.chain(l1.iterator(), l2.iterator());\n" + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + - "Type mismatch: cannot convert from Iterator<Number&Comparable<?>> to Iterator<Number>\n" + + "Type mismatch: cannot convert from Iterator<"+ intersection("Number", "Comparable<?>") +"> to Iterator<Number>\n" + "----------\n" + "6. WARNING in X.java (at line 18)\n" + " Iterator<Number> it2 = X.chain(l1.iterator(), l1.iterator());\n" + @@ -33606,12 +33610,12 @@ public void test1000() { "5. WARNING in X.java (at line 14)\n" + " Iterator<Number> it2 = X.chain(l1.iterator(), l2.iterator());\n" + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + - "Type safety: A generic array of Iterator<? extends Number&Comparable<?>> is created for a varargs parameter\n" + + "Type safety: A generic array of Iterator<? extends Number&"+ intersection("Comparable<?>") +"> is created for a varargs parameter\n" + "----------\n" + "6. ERROR in X.java (at line 14)\n" + " Iterator<Number> it2 = X.chain(l1.iterator(), l2.iterator());\n" + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + - "Type mismatch: cannot convert from Iterator<Number&Comparable<?>> to Iterator<Number>\n" + + "Type mismatch: cannot convert from Iterator<Number&"+ intersection("Comparable<?>") +"> to Iterator<Number>\n" + "----------\n" + "7. WARNING in X.java (at line 18)\n" + " Iterator<Number> it2 = X.chain(l1.iterator(), l1.iterator());\n" + @@ -34746,7 +34750,7 @@ public void test1029() { "1. ERROR in X.java (at line 10)\n" + " List<Number> name = makeNumberList(5, 5D);\n" + " ^^^^^^^^^^^^^^^^^^^^^\n" + - "Type mismatch: cannot convert from List<Number&Comparable<?>> to List<Number>\n" + + "Type mismatch: cannot convert from List<"+ intersection("Number", "Comparable<?>") +"> to List<Number>\n" + "----------\n", null, true, @@ -39658,7 +39662,7 @@ public void test1136() { "1. ERROR in X.java (at line 4)\n" + " List<Object> l1 = Arrays.asList(1, \"X\");\n" + " ^^^^^^^^^^^^^^^^^^^^^\n" + - "Type mismatch: cannot convert from List<Object&Comparable<?>&Serializable> to List<Object>\n" + + "Type mismatch: cannot convert from List<Object&"+ intersection("Comparable<?>") +"&Serializable> to List<Object>\n" + "----------\n" + "2. ERROR in X.java (at line 8)\n" + " List<Object> l2 = Arrays.asList(b, c);\n" + @@ -43202,7 +43206,7 @@ public void test1227() { "1. WARNING in X.java (at line 4)\n" + " Arrays.asList(String.class, Integer.class);\n" + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + - "Type safety: A generic array of Class<? extends Object&Serializable&Comparable<?>> is created for a varargs parameter\n" + + "Type safety: A generic array of Class<? extends Object&Serializable&"+ intersection("Comparable<?>") +"> is created for a varargs parameter\n" + "----------\n" + "2. ERROR in X.java (at line 6)\n" + " Zork z;\n" + diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/JEP286Test.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/JEP286Test.java index d7c3fb22de..891f9e4de6 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/JEP286Test.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/JEP286Test.java @@ -1,11 +1,15 @@ /******************************************************************************* - * Copyright (c) 2018 Jesper Steen Møller and others. + * Copyright (c) 2018, 2019 Jesper Steen Møller and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 * which accompanies this distribution, and is available at * https://www.eclipse.org/legal/epl-2.0/ * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * SPDX-License-Identifier: EPL-2.0 * * Contributors: @@ -69,7 +73,11 @@ static { simpleTypeNames.put("ComparableAny", "Comparable<?>"); simpleTypeNames.put("CollectionExt_ComparableAny", "Collection<? extends Comparable<?>>"); simpleTypeNames.put("CollectionSuperComparableAny", "Collection<? super Comparable<?>>"); - simpleTypeNames.put("IntLongFloat", "java.lang.Number & Comparable<?>"); + isJRE12Plus = isJRELevel(F_12); + if (isJRE12Plus) + simpleTypeNames.put("IntLongFloat", "java.lang.Number & Comparable<?> & java.lang.constant.Constable & java.lang.constant.ConstantDesc"); + else + simpleTypeNames.put("IntLongFloat", "java.lang.Number & Comparable<?>"); simpleTypeNames.put("ListTestAndSerializable", "List<? extends Z & java.io.Serializable>"); simpleTypeNames.put("TestAndSerializable", "Z & java.io.Serializable"); } diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ModuleCompilationTests.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ModuleCompilationTests.java index 349e89cf8d..bdbb120e13 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ModuleCompilationTests.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ModuleCompilationTests.java @@ -4325,6 +4325,121 @@ public void testBug521362_emptyFile() { true, /*not tested with javac*/""); } + public void testReleaseOption20() throws Exception { + if (!isJRE12Plus) return; + this.runNegativeTest( + new String[] { + "X.java", + "import java.io.*;\n" + + "\n" + + "public class X {\n" + + " public static void main(String[] args) {\n" + + " String str = Integer.toUnsignedString(1, 1);\n" + + " }\n" + + "}", + }, + "\"" + OUTPUT_DIR + File.separator + "X.java\"" + + " --release 7 -d \"" + OUTPUT_DIR + "\"", + "", + "----------\n" + + "1. ERROR in ---OUTPUT_DIR_PLACEHOLDER---/X.java (at line 5)\n" + + " String str = Integer.toUnsignedString(1, 1);\n" + + " ^^^^^^^^^^^^^^^^\n" + + "The method toUnsignedString(int, int) is undefined for the type Integer\n" + + "----------\n" + + "1 problem (1 error)\n", + true); + } + public void testReleaseOption21() throws Exception { + if (!isJRE12Plus) return; + this.runConformTest( + new String[] { + "X.java", + "public class X {\n" + + " public static void main(String[] args) {\n" + + " Integer.toUnsignedString(1, 1);\n" + + " }\n" + + "}", + }, + "\"" + OUTPUT_DIR + File.separator + "X.java\"" + + " --release 8 -d \"" + OUTPUT_DIR + "\"", + "", + "", + true); + } + public void testReleaseOption22() { + if (isJRE11Plus || isJRE12Plus) return; + runConformTest( + new String[] { + "p/X.java", + "package p;\n" + + "public class X {\n" + + " public static void main(String[] args) {\n" + + " }\n" + + "}", + "module-info.java", + "module mod.one { \n" + + " requires java.base;\n" + + " requires java.xml.ws.annotation;\n" + + "}" + }, + " --limit-modules java.base,java.xml.ws.annotation " + + " --release 10 \"" + OUTPUT_DIR + File.separator + "module-info.java\" " + + "\"" + OUTPUT_DIR + File.separator + "p/X.java\"", + "", + "----------\n" + + "1. WARNING in ---OUTPUT_DIR_PLACEHOLDER---/module-info.java (at line 3)\n" + + " requires java.xml.ws.annotation;\n" + + " ^^^^^^^^^^^^^^^^^^^^^^\n" + + "The module java.xml.ws.annotation has been deprecated since version 9 and marked for removal\n" + + "----------\n" + + "1 problem (1 warning)\n", + true); + } + public void testReleaseOption23() { + if (!isJRE11Plus) return; + runNegativeTest( + new String[] { + "p/X.java", + "package p;\n" + + "public class X {\n" + + " public static void main(String[] args) {\n" + + " }\n" + + "}", + "module-info.java", + "module mod.one { \n" + + " requires java.xml.ws.annotation;\n" + + "}" + }, + " --limit-modules java.base,java.xml.ws.annotation " + + " --release 11 \"" + OUTPUT_DIR + File.separator + "module-info.java\" " + + "\"" + OUTPUT_DIR + File.separator + "p/X.java\"", + "", + "invalid module name: java.xml.ws.annotation\n", + true); + } + public void testReleaseOption24() { + if (!isJRE11Plus) return; + runNegativeTest( + new String[] { + "p/X.java", + "package p;\n" + + "public class X {\n" + + " public static void main(String[] args) {\n" + + " }\n" + + "}", + "module-info.java", + "module mod.one { \n" + + " requires java.xml.ws.annotation;\n" + + "}" + }, + " --limit-modules java.base,java.xml.ws.annotation " + + " --release 12 \"" + OUTPUT_DIR + File.separator + "module-info.java\" " + + "\"" + OUTPUT_DIR + File.separator + "p/X.java\"", + "", + "invalid module name: java.xml.ws.annotation\n", + true); + } public void testLimitModules1() { File outputDirectory = new File(OUTPUT_DIR); Util.flushDirectoryContent(outputDirectory); diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullAnnotationTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullAnnotationTest.java index 57ce8de4d6..3a818b4292 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullAnnotationTest.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullAnnotationTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2010, 2018 GK Software AG and others. + * Copyright (c) 2010, 2019 GK Software AG and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -8,6 +8,10 @@ * * SPDX-License-Identifier: EPL-2.0 * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * Stephan Herrmann - initial API and implementation * Till Brychcy <register.eclipse@brychcy.de> - Contribution for @@ -10359,4 +10363,228 @@ public void testBug530970_on_field_bin() { "----------\n" ); } +public void testBug542707_001() { + if (this.complianceLevel < ClassFileConstants.JDK12) + return; + Map options = getCompilerOptions(); + options.put(JavaCore.COMPILER_PB_POTENTIAL_NULL_REFERENCE, JavaCore.ERROR); + options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_12); + options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_12); + options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_12); + options.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED); + options.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE); + runNegativeTestWithLibs( + new String[] { + "X.java", + "import java.io.IOException;\n"+ + "\n"+ + "import org.eclipse.jdt.annotation.NonNull;\n"+ + "\n"+ + "public class X {\n"+ + " public static int foo(int i) throws IOException {\n"+ + " int k = 0;\n"+ + " @NonNull\n"+ + " X x = new X();\n"+ + " x = switch (i) { \n"+ + " case 1 -> {\n"+ + " x = null;\n"+ + " break x;\n"+ + " }\n"+ + " default -> null;\n"+ + " };\n"+ + "\n"+ + " return k ;\n"+ + " }\n"+ + "\n"+ + " public static void main(String[] args) {\n"+ + " try {\n"+ + " System.out.println(foo(3));\n"+ + " } catch (IOException e) {\n"+ + " // do nothing\n"+ + " }\n"+ + " }\n"+ + "}\n" + }, + options, + "----------\n" + + "1. ERROR in X.java (at line 12)\n" + + " x = null;\n" + + " ^^^^\n" + + "Null type mismatch: required \'@NonNull X\' but the provided value is null\n" + + "----------\n" + + "2. ERROR in X.java (at line 15)\n" + + " default -> null;\n" + + " ^^^^\n" + + "Null type mismatch: required \'@NonNull X\' but the provided value is null\n" + + "----------\n" + ); +} +/** + * should not throw IOOBE while building - a safety check test case. + */ +public void testBug542707_002() { + if (this.complianceLevel != ClassFileConstants.JDK12) + return; + Map options = getCompilerOptions(); + options.put(JavaCore.COMPILER_PB_POTENTIAL_NULL_REFERENCE, JavaCore.ERROR); + options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_12); + options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_12); + options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_12); + options.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED); + options.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE); + runNegativeTestWithLibs( + new String[] { + "X.java", + "import org.eclipse.jdt.annotation.*;\n" + + "public class X {\n" + + " void m1(@NonNull String a) {}\n" + + " void m2(@Nullable String b, int i) {\n" + + " m1(switch(i) {\n" + + " case 0 : {\n" + + " break \"hello\";\n" + + " }\n" + + " default : break \"world\";\n" + + " });\n" + + " }\n" + + " void m3() {\n" + + " Zork();\n" + + " }\n" + + "}\n" + }, + options, + "----------\n" + + "1. ERROR in X.java (at line 13)\n" + + " Zork();\n" + + " ^^^^\n" + + "The method Zork() is undefined for the type X\n" + + "----------\n" + ); +} +public void testBug542707_003() { + if (this.complianceLevel < ClassFileConstants.JDK12) return; // switch expression + // outer expected type (from assignment) is propagated deeply into a switch expression + Runner runner = new Runner(); + runner.customOptions = getCompilerOptions(); + runner.customOptions.put(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, JavaCore.ENABLED); + runner.customOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE); + runner.classLibraries = this.LIBS; + runner.testFiles = new String[] { + "X.java", + "import org.eclipse.jdt.annotation.*;\n" + + "public class X {\n" + + " @Nullable String maybe() { return null; }\n" + + " void test(int i) {\n" + + " @NonNull String s = switch (i) {\n" + + " case 1 -> \"\";\n" + + " default -> i == 3 ? maybe() : \"\";\n" + + " };\n" + + " System.out.println(s.toLowerCase());\n" + + " }\n" + + "}\n" + }; + runner.expectedCompilerLog = + "----------\n" + + "1. ERROR in X.java (at line 7)\n" + + " default -> i == 3 ? maybe() : \"\";\n" + + " ^^^^^^^\n" + + "Null type mismatch (type annotations): required '@NonNull String' but this expression has type '@Nullable String'\n" + + "----------\n"; + runner.runNegativeTest(); +} +// failing, see https://bugs.eclipse.org/543860 +public void _testBug542707_004() { + if (this.complianceLevel < ClassFileConstants.JDK12) return; // switch expression + // outer expected type (from method parameter) is propagated deeply into a switch expression + Runner runner = new Runner(); + runner.customOptions = getCompilerOptions(); + runner.customOptions.put(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, JavaCore.ENABLED); + runner.customOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE); + runner.classLibraries = this.LIBS; + runner.testFiles = new String[] { + "X.java", + "import org.eclipse.jdt.annotation.*;\n" + + "public class X {\n" + + " @Nullable String maybe() { return null; }\n" + + " void need(@NonNull String s) {\n" + + " System.out.println(s.toLowerCase());\n" + + " }\n" + + " void test(int i) {\n" + + " need(switch (i) {\n" + + " case 1 -> \"\";\n" + + " default -> i == 3 ? maybe() : \"\";\n" + + " });\n" + + " }\n" + + "}\n" + }; + runner.expectedCompilerLog = + "----------\n" + + "1. ERROR in X.java (at line 10)\n" + + " default -> i == 3 ? maybe() : \"\";\n" + + " ^^^^^^^\n" + + "Null type mismatch (type annotations): required '@NonNull String' but this expression has type '@Nullable String'\n" + + "----------\n"; + runner.runNegativeTest(); +} +public void testBug542707_005() { + if (this.complianceLevel < ClassFileConstants.JDK12) return; // switch expression + // switch value must not be null (@Nullable) + Runner runner = new Runner(); + runner.customOptions = getCompilerOptions(); + runner.customOptions.put(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, JavaCore.ENABLED); + runner.customOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE); + runner.classLibraries = this.LIBS; + runner.testFiles = new String[] { + "X.java", + "import org.eclipse.jdt.annotation.*;\n" + + "enum SomeDays { Mon, Wed, Fri }\n" + + "public class X {\n" + + " int testEnum(@Nullable SomeDays day) {\n" + + " return switch(day) {\n" + + " case Mon -> 1;\n" + + " case Wed -> 2;\n" + + " case Fri -> 3;\n" + + " };\n" + + " }\n" + + "}\n" + }; + runner.expectedCompilerLog = + "----------\n" + + "1. ERROR in X.java (at line 5)\n" + + " return switch(day) {\n" + + " ^^^\n" + + "Potential null pointer access: this expression has a \'@Nullable\' type\n" + + "----------\n"; + runner.runNegativeTest(); +} +public void testBug542707_006() { + if (this.complianceLevel < ClassFileConstants.JDK12) return; // switch expression + // switch value must not be null (pot-null by flow analysis) + Runner runner = new Runner(); + runner.customOptions = getCompilerOptions(); + runner.customOptions.put(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, JavaCore.ENABLED); + runner.customOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE); + runner.classLibraries = this.LIBS; + runner.testFiles = new String[] { + "X.java", + "enum SomeDays { Mon, Wed, Fri }\n" + + "public class X {\n" + + " int testEnum(boolean b) {\n" + + " SomeDays day = b ? SomeDays.Mon : null;\n" + + " return switch(day) {\n" + + " case Mon -> 1;\n" + + " case Wed -> 2;\n" + + " case Fri -> 3;\n" + + " };\n" + + " }\n" + + "}\n" + }; + runner.expectedCompilerLog = + "----------\n" + + "2. ERROR in X.java (at line 5)\n" + + " return switch(day) {\n" + + " ^^^\n" + + "Potential null pointer access: The variable day may be null at this location\n" + + "----------\n"; + runner.runNegativeTest(); +} } diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceTest.java index 60f05cc089..0eee7cde18 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceTest.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2016 IBM Corporation and others. + * Copyright (c) 2005, 2019 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -8,6 +8,10 @@ * * SPDX-License-Identifier: EPL-2.0 * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * IBM Corporation - initial API and implementation * Stephan Herrmann <stephan@cs.tu-berlin.de> - Contributions for @@ -45,6 +49,7 @@ package org.eclipse.jdt.core.tests.compiler.regression; import java.io.File; +import java.util.HashMap; import java.util.Map; import junit.framework.Test; @@ -18237,4 +18242,31 @@ public void testBug536408() { runner.javacTestOptions = JavacTestOptions.Excuse.EclipseWarningConfiguredAsError; runner.runNegativeTest(); } +public void testBug542707_1() { + if (this.complianceLevel < ClassFileConstants.JDK12) return; // switch expression + Runner runner = new Runner(); + runner.customOptions = new HashMap<>(); + runner.customOptions.put(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, JavaCore.ENABLED); + runner.customOptions.put(JavaCore.COMPILER_PB_REPORT_PREVIEW_FEATURES, JavaCore.IGNORE); + runner.testFiles = new String[] { + "X.java", + "public class X {\n" + + " void test(int i) {\n" + + " String s = switch (i) {\n" + + " case 1 -> \"one\";\n" + + " default -> null;\n" + + " };\n" + + " System.out.println(s.toLowerCase());\n" + + " }\n" + + "}\n" + }; + runner.expectedCompilerLog = + "----------\n" + + "1. ERROR in X.java (at line 7)\n" + + " System.out.println(s.toLowerCase());\n" + + " ^\n" + + "Potential null pointer access: The variable s may be null at this location\n" + + "----------\n"; + runner.runNegativeTest(); +} }
\ No newline at end of file diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullTypeAnnotationTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullTypeAnnotationTest.java index ccbd91de8a..9cbfdcf73e 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullTypeAnnotationTest.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullTypeAnnotationTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2012, 2018 GK Software AG and others. + * Copyright (c) 2012, 2019 GK Software AG and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -8,6 +8,10 @@ * * SPDX-License-Identifier: EPL-2.0 * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * Stephan Herrmann - initial API and implementation * IBM Corporation @@ -17749,4 +17753,52 @@ public void testBug540264() { "----------\n" ); } +public void testBug542707_1() { + if (this.complianceLevel < ClassFileConstants.JDK12) return; // switch expression + // switch expression has a functional type with interesting type inference and various null issues: + Runner runner = new Runner(); + runner.customOptions = getCompilerOptions(); + runner.customOptions.put(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, JavaCore.ENABLED); + runner.customOptions.put(JavaCore.COMPILER_PB_REPORT_PREVIEW_FEATURES, JavaCore.IGNORE); + runner.classLibraries = this.LIBS; + runner.testFiles = new String[] { + "X.java", + "import org.eclipse.jdt.annotation.*;\n" + + "import java.util.function.*;\n" + + "interface IN0 {}\n" + + "interface IN1 extends IN0 {}\n" + + "interface IN2 extends IN0 {}\n" + + "public class X {\n" + + " @NonNull IN1 n1() { return new IN1() {}; }\n" + + " IN2 n2() { return null; }\n" + + " <M> void m(@NonNull Supplier<@NonNull M> m2) { }\n" + + " void testSw(int i) {\n" + + " m(switch(i) {\n" + + " case 1 -> this::n1;\n" + + " case 2 -> () -> n1();\n" + + " case 3 -> null;\n" + + " case 4 -> () -> n2();\n" + + " default -> this::n2; });\n" + + " }\n" + + "}\n" + }; + runner.expectedCompilerLog = + "----------\n" + + "1. ERROR in X.java (at line 14)\n" + + " case 3 -> null;\n" + + " ^^^^\n" + + "Null type mismatch: required \'@NonNull Supplier<@NonNull IN0>\' but the provided value is null\n" + + "----------\n" + + "2. WARNING in X.java (at line 15)\n" + + " case 4 -> () -> n2();\n" + + " ^^^^\n" + + "Null type safety (type annotations): The expression of type \'IN2\' needs unchecked conversion to conform to \'@NonNull IN0\'\n" + + "----------\n" + + "3. WARNING in X.java (at line 16)\n" + + " default -> this::n2; });\n" + + " ^^^^^^^^\n" + + "Null type safety at method return type: Method descriptor Supplier<IN0>.get() promises \'@NonNull IN0\' but referenced method provides \'IN2\'\n" + + "----------\n"; + runner.runNegativeTest(); +} } diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ResourceLeakTests.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ResourceLeakTests.java index 0d2d7a5b82..7169599dc8 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ResourceLeakTests.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ResourceLeakTests.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2011, 2014 GK Software AG and others. + * Copyright (c) 2011, 2019 GK Software AG and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -8,6 +8,10 @@ * * SPDX-License-Identifier: EPL-2.0 * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * Stephan Herrmann - initial API and implementation * Nikolay Metchev (nikolaymetchev@gmail.com) - Contributions for @@ -53,7 +57,7 @@ private static final String APACHE_DBUTILS_CONTENT = "package org.apache.commons "}\n"; static { -// TESTS_NAMES = new String[] { "testBug462371_shouldWarn" }; +// TESTS_NAMES = new String[] { "testBug542707" }; // TESTS_NUMBERS = new int[] { 50 }; // TESTS_RANGE = new int[] { 11, -1 }; } @@ -5496,4 +5500,176 @@ public void testBug541705b() { }; runner.runConformTest(); } +public void testBug542707_001() { + if (this.complianceLevel < ClassFileConstants.JDK12) return; // uses switch expression + Map options = getCompilerOptions(); + options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR); + options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR); + options.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED); + options.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE); + runLeakTest( + new String[] { + "X.java", + "import java.io.Closeable;\n"+ + "import java.io.IOException;\n"+ + "\n"+ + "public class X implements Closeable{\n"+ + " public static int foo(int i) throws IOException {\n"+ + " int k = 0;\n"+ + " X x = null;\n"+ + " try {\n"+ + " x = new X();\n"+ + " x = switch (i) { \n"+ + " case 1 -> {\n"+ + " break x;\n"+ + " }\n"+ + " default -> x;\n"+ + " };\n"+ + " } finally {\n"+ + " x.close();\n"+ + " }\n"+ + " return k ;\n"+ + " }\n"+ + "\n"+ + " public static void main(String[] args) {\n"+ + " try {\n"+ + " System.out.println(foo(3));\n"+ + " } catch (IOException e) {\n"+ + " // do nothing\n"+ + " }\n"+ + " }\n"+ + " @Override\n"+ + " public void close() throws IOException {\n"+ + " Zork();\n"+ + " }\n"+ + "}\n" + }, + "----------\n" + + "1. ERROR in X.java (at line 31)\n" + + " Zork();\n" + + " ^^^^\n" + + "The method Zork() is undefined for the type X\n" + + "----------\n", + options); +} +public void testBug542707_002() { + if (this.complianceLevel < ClassFileConstants.JDK12) return; // uses switch expression + Map options = getCompilerOptions(); + options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR); + options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR); + options.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED); + options.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE); + runLeakTest( + new String[] { + "X.java", + "import java.io.Closeable;\n"+ + "import java.io.IOException;\n"+ + "\n"+ + "public class X implements Closeable{\n"+ + " public static int foo(int i) throws IOException {\n"+ + " int k = 0;\n"+ + " X x = null;\n"+ + " try {\n"+ + " x = new X();\n"+ + " x = switch (i) { \n"+ + " case 1 -> {\n"+ + " x = new X();\n"+ + " break x;\n"+ + " }\n"+ + " default -> x;\n"+ + " };\n"+ + " } finally {\n"+ + " x.close();\n"+ + " }\n"+ + " return k ;\n"+ + " }\n"+ + "\n"+ + " public static void main(String[] args) {\n"+ + " try {\n"+ + " System.out.println(foo(3));\n"+ + " } catch (IOException e) {\n"+ + " // do nothing\n"+ + " }\n"+ + " }\n"+ + " @Override\n"+ + " public void close() throws IOException {\n"+ + " Zork();\n"+ + " }\n"+ + "}\n" + }, + "----------\n" + + "1. ERROR in X.java (at line 12)\n" + + " x = new X();\n" + + " ^^^^^^^^^^^\n" + + "Resource leak: \'x\' is not closed at this location\n" + + "----------\n" + + "2. ERROR in X.java (at line 32)\n" + + " Zork();\n" + + " ^^^^\n" + + "The method Zork() is undefined for the type X\n" + + "----------\n", + options); +} +public void testBug542707_003() { + if (this.complianceLevel < ClassFileConstants.JDK12) return; // uses switch expression + Map options = getCompilerOptions(); + options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR); + options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR); + options.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED); + options.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE); + runLeakTest( + new String[] { + "X.java", + "import java.io.Closeable;\n"+ + "import java.io.IOException;\n"+ + "\n"+ + "public class X implements Closeable{\n"+ + " public static int foo(int i) throws IOException {\n"+ + " int k = 0;\n"+ + " X x = null;\n"+ + " try {\n"+ + " x = new X();\n"+ + " x = switch (i) { \n"+ + " case 1 -> {\n"+ + " break new X();\n"+ + " }\n"+ + " default -> x;\n"+ + " };\n"+ + " } finally {\n"+ + " x.close();\n"+ + " }\n"+ + " return k ;\n"+ + " }\n"+ + "\n"+ + " public static void main(String[] args) {\n"+ + " try {\n"+ + " System.out.println(foo(3));\n"+ + " } catch (IOException e) {\n"+ + " // do nothing\n"+ + " }\n"+ + " }\n"+ + " @Override\n"+ + " public void close() throws IOException {\n"+ + " Zork();\n"+ + " }\n"+ + "}\n" + }, + "----------\n" + + "1. ERROR in X.java (at line 10)\n" + + " x = switch (i) { \n" + + " case 1 -> {\n" + + " break new X();\n" + + " }\n" + + " default -> x;\n" + + " };\n" + + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + + "Resource leak: \'x\' is not closed at this location\n" + + "----------\n" + + "2. ERROR in X.java (at line 31)\n" + + " Zork();\n" + + " ^^^^\n" + + "The method Zork() is undefined for the type X\n" + + "----------\n", + options); +} } diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/SwitchExpressionTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/SwitchExpressionTest.java new file mode 100644 index 0000000000..b3cf79860e --- /dev/null +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/SwitchExpressionTest.java @@ -0,0 +1,2185 @@ +/******************************************************************************* + * Copyright (c) 2018, 2019 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.core.tests.compiler.regression; + +import java.util.Map; + +import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; + +import junit.framework.Test; + +public class SwitchExpressionTest extends AbstractRegressionTest { + + static { +// TESTS_NUMBERS = new int [] { 40 }; +// TESTS_NAMES = new String[] { "testBug543240_1" }; + } + + public static Class<?> testClass() { + return SwitchExpressionTest.class; + } + public static Test suite() { + return buildMinimalComplianceTestSuite(testClass(), F_12); + } + public SwitchExpressionTest(String testName){ + super(testName); + } + + // Enables the tests to run individually + protected Map<String, String> getCompilerOptions() { + Map<String, String> defaultOptions = super.getCompilerOptions(); + defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_12); // FIXME + defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_12); + defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED); + defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE); + return defaultOptions; + } + + @Override + protected void runConformTest(String[] testFiles, Map customOptions) { + super.runConformTest(testFiles, "", null, true, new String[] {"--enable-preview"}, customOptions, null); + } + + @Override + protected void runConformTest(String[] testFiles, String expectedOutput, Map customOptions) { + super.runConformTest(testFiles, expectedOutput, null, true, new String[] {"--enable-preview"}, customOptions, null); + } + public void testSimpleExpressions() { + runConformTest( + new String[] { + "X.java", + "public class X {\n" + + " static int twice(int i) {\n" + + " int tw = switch (i) {\n" + + " case 0 -> i * 0;\n" + + " case 1 -> 2;\n" + + " default -> 3;\n" + + " };\n" + + " return tw;\n" + + " }\n" + + " public static void main(String... args) {\n" + + " System.out.print(twice(3));\n" + + " }\n" + + "}\n" + }, + "3", + null, + new String[] {"--enable-preview"}); + } + public void testSwitchExpression_531714_002() { + runConformTest( + new String[] { + "X.java", + "public class X {\n"+ + " static int twice(int i) throws Exception {\n"+ + " int tw = switch (i) {\n"+ + " case 0 -> 0;\n"+ + " case 1 -> { \n"+ + " System.out.println(\"do_not_print\");\n"+ + " break 1;\n"+ + " } \n"+ + " case 3 -> throw new Exception();\n"+ + " default -> throw new Exception();\n"+ + " };\n"+ + " return tw;\n"+ + " }\n"+ + " public static void main(String[] args) {\n"+ + " try {\n"+ + " try {\n"+ + " System.out.print(twice(3));\n"+ + " } catch (Exception e) {\n"+ + " System.out.print(\"Got Exception - expected\");\n"+ + " }\n"+ + " } catch (Exception e) {\n"+ + " System.out.print(\"Got Exception\");\n"+ + " }\n"+ + " }\n"+ + "}\n" + }, + "Got Exception - expected", + null, + new String[] {"--enable-preview"}); + } + public void testBug531714_error_003() { + this.runNegativeTest( + new String[] { + "X.java", + "public class X {\n" + + " public static void main(String[] args) {\n" + + " twice(1);\n" + + " }\n" + + " public static int twice(int i) {\n" + + " int tw = switch (i) {\n" + + " };\n" + + " return tw;\n" + + " }\n" + + "}\n", + }, + "----------\n" + + "1. ERROR in X.java (at line 6)\n" + + " int tw = switch (i) {\n" + + " };\n" + + " ^^^^^^^^^^^^^^^^\n" + + "A switch expression should have a non-empty switch block\n" + + "----------\n" + + "2. ERROR in X.java (at line 6)\n" + + " int tw = switch (i) {\n" + + " ^\n" + + "A switch expression should have a default case\n" + + "----------\n"); + } + public void testBug531714_error_004() { + this.runNegativeTest( + new String[] { + "X.java", + "public class X {\n" + + " public static void main(String[] args) {\n" + + " twice(1);\n" + + " }\n" + + " public static int twice(int i) {\n" + + " int tw = switch (i) {\n" + + " case 0 -> 0;\n" + + " case 1 -> { \n" + + " System.out.println(\"heel\");\n" + + " break 1;\n" + + " } \n" + + " case \"hello\" -> throw new java.io.IOException(\"hello\");\n" + + " default -> throw new java.io.IOException(\"world\");\n" + + " };\n" + + " return tw;\n" + + " }\n" + + "}\n", + }, + "----------\n" + + "1. ERROR in X.java (at line 12)\n" + + " case \"hello\" -> throw new java.io.IOException(\"hello\");\n" + + " ^^^^^^^\n" + + "Type mismatch: cannot convert from String to int\n" + + "----------\n"); + } + public void testBug531714_error_005() { + this.runNegativeTest( + new String[] { + "X.java", + "public class X {\n" + + " public static void main(String[] args) {\n" + + " twice(1);\n" + + " }\n" + + " public static int twice(int i) {\n" + + " int tw = switch (i) {\n" + + " case 0 -> 0;\n" + + " case 1 -> { \n" + + " System.out.println(\"heel\");\n" + + " break 1;\n" + + " } \n" + + " case 2 -> 2;\n" + + " };\n" + + " return tw;\n" + + " }\n" + + "}\n", + }, + "----------\n" + + "1. ERROR in X.java (at line 6)\n" + + " int tw = switch (i) {\n" + + " ^\n" + + "A switch expression should have a default case\n" + + "----------\n"); + } + /** + * Add a test case for enum + * If the type of the selector expression is an enum type, + * then the set of all the case constants associated with the switch block + * must contain all the enum constants of that enum type + * Add a missing enum test case + */ + public void _testBug531714_error_006() { + this.runNegativeTest( + new String[] { + "X.java", + "public class X {\n" + + " public static void main(String[] args) {\n" + + " int x, y;\n" + + " I i = () -> {\n" + + " int z = 10;\n" + + " };\n" + + " i++;\n" + + " }\n" + + " public static int twice(int i) {\n" + + " int tw = switch (i) {\n" + + " case 0 -> 0;\n" + + " case 1 -> { \n" + + " System.out.println(\"heel\");\n" + + " break 1;\n" + + " } \n" + + " // case 2 -> 2;\n" + + " case \"hello\" -> throw new IOException(\"hello\");\n" + + " };\n" + + " return tw;\n" + + " }\n" + + "}\n", + }, + "----------\n" + + "1. ERROR in X.java (at line 7)\n" + + " int tw = switch (i) {\n" + + " ^^^^^\n" + + " The switch expression should have a default case\n" + + "----------\n"); + } + /* + * should compile - test for adding additional nesting in variables + * dev note: ref consumeToken().case Switch + */ + public void testBug531714_error_007() { + runConformTest( + new String[] { + "X.java", + "public class X {\n"+ + " static int foo(int i) {\n"+ + " int tw = \n"+ + " switch (i) {\n"+ + " case 1 -> \n"+ + " {\n"+ + " int z = 100;\n"+ + " break z;\n"+ + " }\n"+ + " default -> {\n"+ + " break 12;\n"+ + " }\n"+ + " };\n"+ + " return tw;\n"+ + " }\n"+ + " public static void main(String[] args) {\n"+ + " System.out.print(foo(1));\n"+ + " }\n"+ + "}\n" + }, + "100", + null, + new String[] {"--enable-preview"}); + } + public void testBug531714_008() { + Map<String, String> disablePreviewOptions = getCompilerOptions(); + disablePreviewOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.DISABLED); + String[] testFiles = new String[] { + "X.java", + "public class X {\n" + + " static int twice(int i) {\n" + + " int tw = switch (i) {\n" + + " case 0 -> i * 0;\n" + + " case 1 -> 2;\n" + + " default -> 3;\n" + + " };\n" + + " return tw;\n" + + " }\n" + + " public static void main(String[] args) {\n" + + " System.out.print(twice(3));\n" + + " }\n" + + "}\n", + }; + + String expectedProblemLog = + "----------\n" + + "1. ERROR in X.java (at line 3)\n" + + " int tw = switch (i) {\n" + + " case 0 -> i * 0;\n" + + " case 1 -> 2;\n" + + " default -> 3;\n" + + " };\n" + + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + + "Switch Expressions is a preview feature and disabled by default. Use --enable-preview to enable\n" + + "----------\n" + + "2. ERROR in X.java (at line 4)\n" + + " case 0 -> i * 0;\n" + + " ^^^^^^\n" + + "Case Labels with '->' is a preview feature and disabled by default. Use --enable-preview to enable\n" + + "----------\n" + + "3. ERROR in X.java (at line 5)\n" + + " case 1 -> 2;\n" + + " ^^^^^^\n" + + "Case Labels with '->' is a preview feature and disabled by default. Use --enable-preview to enable\n" + + "----------\n" + + "4. ERROR in X.java (at line 6)\n" + + " default -> 3;\n" + + " ^^^^^^^\n" + + "Case Labels with '->' is a preview feature and disabled by default. Use --enable-preview to enable\n" + + "----------\n"; + + this.runNegativeTest( + testFiles, + expectedProblemLog, + null, + true, + disablePreviewOptions); + } + public void testBug543667_001() { + runConformTest( + new String[] { + "X.java", + "public class X {\n" + + "\n" + + " public static void bar(int i) {\n" + + " switch (i) {\n" + + " case 1 -> System.out.println(\"hello\");\n" + + " default -> System.out.println(\"DEFAULT\");\n" + + " }\n" + + " }\n" + + " public static void main(String[] args) {\n" + + " bar(1);\n" + + " }\n" + + "}\n" + }, + "hello", + null, + false, + new String[] { "--enable-preview"}); + } + public void testBug531714_009() { + Map<String, String> disablePreviewOptions = getCompilerOptions(); + disablePreviewOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.DISABLED); + String[] testFiles = new String[] { + "X.java", + "public class X {\n" + + " static int twice(int i) {\n" + + " switch (i) {\n" + + " case 0 -> i * 0;\n" + + " case 1 -> 2;\n" + + " default -> 3;\n" + + " }\n" + + " return 0;\n" + + " }\n" + + " public static void main(String[] args) {\n" + + " System.out.print(twice(3));\n" + + " }\n" + + "}\n", + }; + + String expectedProblemLog = + "----------\n" + + "1. ERROR in X.java (at line 4)\n" + + " case 0 -> i * 0;\n" + + " ^^^^^^\n" + + "Case Labels with \'->\' is a preview feature and disabled by default. Use --enable-preview to enable\n" + + "----------\n" + + "2. ERROR in X.java (at line 5)\n" + + " case 1 -> 2;\n" + + " ^^^^^^\n" + + "Case Labels with \'->\' is a preview feature and disabled by default. Use --enable-preview to enable\n" + + "----------\n" + + "3. ERROR in X.java (at line 6)\n" + + " default -> 3;\n" + + " ^^^^^^^\n" + + "Case Labels with \'->\' is a preview feature and disabled by default. Use --enable-preview to enable\n" + + "----------\n"; + this.runNegativeTest( + testFiles, + expectedProblemLog, + null, + true, + disablePreviewOptions); + } + public void testBug531714_010() { + Map<String, String> options = getCompilerOptions(); + options.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED); + options.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.ERROR); + String[] testFiles = new String[] { + "X.java", + "public class X {\n" + + " static int twice(int i) {\n" + + " switch (i) {\n" + + " default -> 3;\n" + + " }\n" + + " return 0;\n" + + " }\n" + + " public static void main(String[] args) {\n" + + " System.out.print(twice(3));\n" + + " }\n" + + "}\n", + }; + + String expectedProblemLog = + "----------\n" + + "1. ERROR in X.java (at line 4)\n" + + " default -> 3;\n" + + " ^^^^^^^\n" + + "You are using a preview language feature that may or may not be supported in a future release\n" + + "----------\n" + + "2. ERROR in X.java (at line 4)\n" + + " default -> 3;\n" + + " ^\n" + + "Invalid expression as statement\n" + + "----------\n"; + this.runNegativeTest( + testFiles, + expectedProblemLog, + null, + true, + options); + } + public void testBug531714_011() { + Map<String, String> options = getCompilerOptions(); + options.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED); + options.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.WARNING); + String[] testFiles = new String[] { + "X.java", + "public class X {\n" + + " @SuppressWarnings(\"preview\")\n" + + " static int twice(int i) {\n" + + " switch (i) {\n" + + " default -> 3;\n" + + " }\n" + + " return 0;\n" + + " }\n" + + " public static void main(String[] args) {\n" + + " System.out.print(twice(3));\n" + + " }\n" + + "}\n", + }; + + String expectedProblemLog = + "----------\n" + + "1. ERROR in X.java (at line 5)\n" + + " default -> 3;\n" + + " ^\n" + + "Invalid expression as statement\n" + + "----------\n"; + this.runNegativeTest( + testFiles, + expectedProblemLog, + null, + true, + getCompilerOptions()); + } + public void testBug531714_012() { + Map<String, String> options = getCompilerOptions(); + options.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED); + options.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.WARNING); + String release = options.get(CompilerOptions.OPTION_Release); + options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_11); + try { + String[] testFiles = new String[] { + "X.java", + "public class X {\n" + + " static int twice(int i) {\n" + + " switch (i) {\n" + + " default -> 3;\n" + + " }\n" + + " return 0;\n" + + " }\n" + + " public static void main(String[] args) {\n" + + " System.out.print(twice(3));\n" + + " }\n" + + "}\n", + }; + + String expectedProblemLog = + "----------\n" + + "1. ERROR in X.java (at line 4)\n" + + " default -> 3;\n" + + " ^^^^^^^\n" + + "The preview feature Case Labels with \'->\' is only available with source level 12 and above\n" + + "----------\n" + + "2. ERROR in X.java (at line 4)\n" + + " default -> 3;\n" + + " ^\n" + + "Invalid expression as statement\n" + + "----------\n"; + this.runNegativeTest( + testFiles, + expectedProblemLog, + null, + true, + options); + } finally { + options.put(CompilerOptions.OPTION_Source, release); + } + } + public void testBug531714_013() { + String[] testFiles = new String[] { + "X.java", + "public class X {\n" + + " public static int foo(int i) {\n" + + " int v;\n" + + " int t = switch (i) {\n" + + " case 0 : {\n" + + " break 0;\n" + + " }\n" + + " default :v = 2;\n" + + " };\n" + + " return t;\n" + + " }\n" + + " \n" + + " public boolean bar() {\n" + + " return true;\n" + + " }\n" + + " public static void main(String[] args) {\n" + + " System.out.println(foo(3));\n" + + " }\n" + + "}\n", + }; + + String expectedProblemLog = + "----------\n" + + "1. ERROR in X.java (at line 8)\n" + + " default :v = 2;\n" + + " ^^^^^\n" + + "A switch labeled block in a switch expression should not complete normally\n" + + "----------\n"; + this.runNegativeTest( + testFiles, + expectedProblemLog, + null, + true, + getCompilerOptions()); + } + public void testBug531714_014() { + // switch expression is not a Primary + Runner runner = new Runner(); + runner.customOptions = getCompilerOptions(); + runner.testFiles = new String[] { + "X.java", + "public class X {\n" + + " void test(int i) {\n" + + " System.out.println(switch (i) {\n" + + " case 1 -> \"one\";\n" + + " default -> null;\n" + + " }.toLowerCase());\n" + + " }\n" + + " public static void main(String[] args) {\n" + + " new X().test(1);\n" + + " }\n" + + "}\n" + }; + runner.expectedCompilerLog = + "----------\n" + + "1. ERROR in X.java (at line 6)\n" + + " }.toLowerCase());\n" + + " ^\n" + + "Syntax error on token \".\", , expected\n" + + "----------\n"; + runner.runNegativeTest(); + } + public void testBug543673_001() { + runConformTest( + new String[] { + "X.java", + "public class X {\n" + + " public static int foo(Day day) {\n" + + "\n" + + " var len= switch (day) {\n" + + " case SUNDAY-> 6;\n" + + " default -> 10;\n" + + " };\n" + + "\n" + + " return len;\n" + + " }\n" + + "\n" + + " public static void main(String[] args) {\n" + + " System.out.println(foo(Day.SUNDAY));\n" + + " }\n" + + "}\n" + + "enum Day {\n" + + " MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY;\n" + + "}\n" + }, + "6", + null, + false, + new String[] { "--enable-preview"}); + } + /* + * A simple multi constant case statement, compiled and run as expected + */ + public void testBug543240_1() { + Map<String, String> options = getCompilerOptions(); + options.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED); + options.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE); + String[] testFiles = new String[] { + "X.java", + "public class X {\n" + + "public static void bar(Day day) {\n" + + " switch (day) {\n" + + " case SATURDAY, SUNDAY: \n" + + " System.out.println(Day.SUNDAY);\n" + + " break;\n" + + " case MONDAY : System.out.println(Day.MONDAY);\n" + + " break;\n" + + " }\n" + + " }" + + " public static void main(String[] args) {\n" + + " bar(Day.SATURDAY);\n" + + " }\n" + + "}\n" + + "enum Day { SATURDAY, SUNDAY, MONDAY;}", + }; + + String expectedProblemLog = + "SUNDAY"; + this.runConformTest( + testFiles, + expectedProblemLog, + options, + new String[] { "--enable-preview"}); + } + /* + * A simple multi constant case statement, compiler reports missing enum constants + */ + public void testBug543240_1a() { + Map<String, String> options = getCompilerOptions(); + options.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED); + options.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE); + String[] testFiles = new String[] { + "X.java", + "public class X {\n" + + " public static void main(String[] args) {\n" + + " }\n" + + "public static void bar(Day day) {\n" + + " switch (day) {\n" + + " case SATURDAY, SUNDAY: \n" + + " System.out.println(Day.SUNDAY);\n" + + " break;\n" + + " case MONDAY : System.out.println(Day.MONDAY);\n" + + " break;\n" + + " }\n" + + " }" + + "}\n" + + "enum Day { SATURDAY, SUNDAY, MONDAY, TUESDAY;}", + }; + + String expectedProblemLog = + "----------\n" + + "1. WARNING in X.java (at line 5)\n" + + " switch (day) {\n" + + " ^^^\n" + + "The enum constant TUESDAY needs a corresponding case label in this enum switch on Day\n" + + "----------\n"; + this.runNegativeTest( + testFiles, + expectedProblemLog, + null, + true, + new String[] { "--enable-preview"}, + options); + } + /* + * A simple multi constant case statement with duplicate enums + */ + public void testBug543240_2() { + Map<String, String> options = getCompilerOptions(); + options.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED); + options.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE); + String[] testFiles = new String[] { + "X.java", + "public class X {\n" + + "public static void bar(Day day) {\n" + + " switch (day) {\n" + + " case SATURDAY, SUNDAY: \n" + + " System.out.println(Day.SUNDAY);\n" + + " break;\n" + + " case SUNDAY : System.out.println(Day.SUNDAY);\n" + + " break;\n" + + " }\n" + + " }" + + " public static void main(String[] args) {\n" + + " bar(Day.SATURDAY);\n" + + " }\n" + + "}\n" + + "enum Day { SATURDAY, SUNDAY, MONDAY;}", + }; + + String expectedProblemLog = + "----------\n" + + "1. ERROR in X.java (at line 7)\n" + + " case SUNDAY : System.out.println(Day.SUNDAY);\n" + + " ^^^^^^^^^^^\n" + + "Duplicate case\n" + + "----------\n" + + "2. ERROR in X.java (at line 7)\n" + + " case SUNDAY : System.out.println(Day.SUNDAY);\n" + + " ^^^^^^^^^^^\n" + + "Duplicate case\n" + + "----------\n"; + this.runNegativeTest( + testFiles, + expectedProblemLog, + null, + true, + options); + } + /* + * A simple multi constant case statement with duplicate enums + */ + public void testBug543240_2a() { + Map<String, String> options = getCompilerOptions(); + options.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED); + options.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE); + String[] testFiles = new String[] { + "X.java", + "public class X {\n" + + "public static void bar(Day day) {\n" + + " switch (day) {\n" + + " case SATURDAY, SUNDAY: \n" + + " System.out.println(Day.SUNDAY);\n" + + " break;\n" + + " case SUNDAY, SATURDAY : \n" + + " System.out.println(Day.SUNDAY);\n" + + " break;\n" + + " }\n" + + " }" + + "}\n" + + "enum Day { SATURDAY, SUNDAY, MONDAY;}", + }; + + String expectedProblemLog = + "----------\n" + + "1. WARNING in X.java (at line 3)\n" + + " switch (day) {\n" + + " ^^^\n" + + "The enum constant MONDAY needs a corresponding case label in this enum switch on Day\n" + + "----------\n" + + "2. ERROR in X.java (at line 7)\n" + + " case SUNDAY, SATURDAY : \n" + + " ^^^^^^^^^^^^^^^^^^^^^\n" + + "Duplicate case\n" + + "----------\n" + + "3. ERROR in X.java (at line 7)\n" + + " case SUNDAY, SATURDAY : \n" + + " ^^^^^^^^^^^^^^^^^^^^^\n" + + "Duplicate case\n" + + "----------\n" + + "4. ERROR in X.java (at line 7)\n" + + " case SUNDAY, SATURDAY : \n" + + " ^^^^^^^^^^^^^^^^^^^^^\n" + + "Duplicate case\n" + + "----------\n"; + this.runNegativeTest( + testFiles, + expectedProblemLog, + null, + true, + options); + } + /* + * + */ + public void testBug543240_3() { + Map<String, String> options = getCompilerOptions(); + options.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED); + options.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE); + String[] testFiles = new String[] { + "X.java", + "public class X {\n" + + "public static void bar(Day day) {\n" + + " switch (day) {\n" + + " case SATURDAY, SUNDAY: \n" + + " System.out.println(Day.SUNDAY);\n" + + " break;\n" + + " case TUESDAY : System.out.println(Day.SUNDAY);\n" + + " break;\n" + + " }\n" + + " }" + + " public static void main(String[] args) {\n" + + " bar(Day.SATURDAY);\n" + + " }\n" + + "}\n" + + "enum Day { SATURDAY, SUNDAY, MONDAY, TUESDAY;}", + }; + + String expectedProblemLog = + "----------\n" + + "1. WARNING in X.java (at line 3)\n" + + " switch (day) {\n" + + " ^^^\n" + + "The enum constant MONDAY needs a corresponding case label in this enum switch on Day\n" + + "----------\n"; + this.runNegativeTest( + testFiles, + expectedProblemLog, + null, + true, + new String[] {"--enable-preview"}, + options); + } + public void testBug543240_4() { + Map<String, String> options = getCompilerOptions(); + options.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED); + options.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE); + String[] testFiles = new String[] { + "X.java", + "public class X {\n" + + "public static void bar(Day day) {\n" + + " switch (day) {\n" + + " case SATURDAY, SUNDAY: \n" + + " System.out.println(day);\n" + + " break;\n" + + " case MONDAY : System.out.println(0);\n" + + " break;\n" + + " }\n" + + " }" + + " public static void main(String[] args) {\n" + + " bar(Day.SATURDAY);\n" + + " bar(Day.MONDAY);\n" + + " bar(Day.SUNDAY);\n" + + " }\n" + + "}\n" + + "enum Day { SATURDAY, SUNDAY, MONDAY;}", + }; + + String expectedProblemLog = + "SATURDAY\n" + + "0\n" + + "SUNDAY"; + this.runConformTest( + testFiles, + expectedProblemLog, + options, + new String[] {"--enable-preview"}); + } + /* + * Simple switch case with string literals + */ + public void testBug543240_5() { + Map<String, String> options = getCompilerOptions(); + options.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED); + options.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE); + String[] testFiles = new String[] { + "X.java", + "public class X {\n" + + " public static void main(String[] args) {\n" + + " bar(\"a\");\n" + + " bar(\"b\");\n" + + " bar(\"c\");\n" + + " bar(\"d\");\n" + + " }\n" + + " public static void bar(String s) {\n" + + " switch(s) {\n" + + " case \"a\":\n" + + " case \"b\":\n" + + " System.out.println(\"A/B\");\n" + + " break;\n" + + " case \"c\":\n" + + " System.out.println(\"C\");\n" + + " break;\n" + + " default:\n" + + " System.out.println(\"NA\");\n" + + " }\n" + + " }\n" + + "}", + }; + String expectedProblemLog = + "A/B\n" + + "A/B\n" + + "C\n" + + "NA"; + this.runConformTest( + testFiles, + expectedProblemLog, + options, + new String[] {"--enable-preview"}); + } + public void testBug543240_6() { + Map<String, String> options = getCompilerOptions(); + options.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED); + options.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE); + String[] testFiles = new String[] { + "X.java", + "public class X {\n" + + " public static void main(String[] args) {\n" + + " bar(\"a\");\n" + + " bar(\"b\");\n" + + " bar(\"c\");\n" + + " bar(\"d\");\n" + + " }\n" + + " public static void bar(String s) {\n" + + " switch(s) {\n" + + " case \"a\", \"b\":\n" + + " System.out.println(\"A/B\");\n" + + " break;\n" + + " case \"c\":\n" + + " System.out.println(\"C\");\n" + + " break;\n" + + " default:\n" + + " System.out.println(\"NA\");\n" + + " }\n" + + " }\n" + + "}", + }; + String expectedProblemLog = + "A/B\n" + + "A/B\n" + + "C\n" + + "NA"; + this.runConformTest( + testFiles, + expectedProblemLog, + options, + new String[] {"--enable-preview"}); + } + /* + * Switch with multi constant case statements with string literals + * two string literals with same hashcode + */ + public void testBug543240_7() { + Map<String, String> options = getCompilerOptions(); + options.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED); + options.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE); + String[] testFiles = new String[] { + "X.java", + "public class X {\n" + + " public static void main(String[] args) {\n" + + " bar(\"FB\");\n" + + " bar(\"Ea\");\n" + + " bar(\"c\");\n" + + " bar(\"D\");\n" + + " }\n" + + " public static void bar(String s) {\n" + + " switch(s) {\n" + + " case \"FB\", \"c\":\n" + + " System.out.println(\"A\");\n" + + " break;\n" + + " case \"Ea\":\n" + + " System.out.println(\"B\");\n" + + " break;\n" + + " default:\n" + + " System.out.println(\"NA\");\n" + + " }\n" + + " }\n" + + "}", + }; + String expectedProblemLog = + "A\n" + + "B\n" + + "A\n" + + "NA"; + this.runConformTest( + testFiles, + expectedProblemLog, + options, + new String[] {"--enable-preview"}); + } + /* + * Switch with multi constant case statements with integer constants + */ + public void testBug543240_8() { + Map<String, String> options = getCompilerOptions(); + options.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED); + options.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE); + String[] testFiles = new String[] { + "X.java", + "public class X {\n" + + " public static void main(String[] args) {\n" + + " bar(1);\n" + + " bar(2);\n" + + " bar(3);\n" + + " bar(4);\n" + + " bar(5);\n" + + " }\n" + + " public static void bar(int i) {\n" + + " switch (i) {\n" + + " case 1, 3: \n" + + " System.out.println(\"Odd\");\n" + + " break;\n" + + " case 2, 4: \n" + + " System.out.println(\"Even\");\n" + + " break;\n" + + " default:\n" + + " System.out.println(\"Out of range\");\n" + + " }\n" + + " }\n" + + "}", + }; + String expectedProblemLog = + "Odd\n" + + "Even\n" + + "Odd\n" + + "Even\n" + + "Out of range"; + this.runConformTest( + testFiles, + expectedProblemLog, + options, + new String[] {"--enable-preview"}); + } + /* + * Switch multi-constant with mixed constant types, reported + */ + public void testBug543240_9() { + Map<String, String> options = getCompilerOptions(); + options.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED); + options.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE); + String[] testFiles = new String[] { + "X.java", + "public class X {\n" + + " public static void main(String[] args) {\n" + + " }\n" + + " public static void bar(int i) {\n" + + " switch (i) {\n" + + " case 1, 3: \n" + + " System.out.println(\"Odd\");\n" + + " break;\n" + + " case \"2\": \n" + + " System.out.println(\"Even\");\n" + + " break;\n" + + " default:\n" + + " System.out.println(\"Out of range\");\n" + + " }\n" + + " }\n" + + "}", + }; + String expectedProblemLog = + "----------\n" + + "1. ERROR in X.java (at line 9)\n" + + " case \"2\": \n" + + " ^^^\n" + + "Type mismatch: cannot convert from String to int\n" + + "----------\n"; + this.runNegativeTest( + testFiles, + expectedProblemLog, + null, + true, + options); + } + /* + * Switch multi-constant without break statement, reported + */ + public void testBug543240_10() { + Map<String, String> options = getCompilerOptions(); + options.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED); + options.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE); + options.put(CompilerOptions.OPTION_ReportFallthroughCase, CompilerOptions.WARNING); + String[] testFiles = new String[] { + "X.java", + "public class X {\n" + + " public static void main(String[] args) {\n" + + " }\n" + + " public static void bar(int i) {\n" + + " switch (i) {\n" + + " case 1, 3: \n" + + " System.out.println(\"Odd\");\n" + + " case 2, 4: \n" + + " System.out.println(\"Even\");\n" + + " break;\n" + + " default:\n" + + " System.out.println(\"Out of range\");\n" + + " }\n" + + " }\n" + + "}", + }; + String expectedProblemLog = + "----------\n" + + "1. WARNING in X.java (at line 8)\n" + + " case 2, 4: \n" + + " ^^^^^^^^^\n" + + "Switch case may be entered by falling through previous case. If intended, add a new comment //$FALL-THROUGH$ on the line above\n" + + "----------\n"; + this.runNegativeTest( + testFiles, + expectedProblemLog, + null, + true, + new String[] { "--enable-preview"}, + options); + } + /* + * Switch multi-constant without break statement, reported + */ + public void testBug543240_11() { + Map<String, String> options = getCompilerOptions(); + options.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED); + options.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE); + options.put(CompilerOptions.OPTION_ReportMissingDefaultCase, CompilerOptions.WARNING); + String[] testFiles = new String[] { + "X.java", + "public class X {\n" + + " public static void main(String[] args) {\n" + + " }\n" + + " public static void bar(int i) {\n" + + " switch (i) {\n" + + " case 1, 3: \n" + + " System.out.println(\"Odd\");\n" + + " case 2, 4: \n" + + " System.out.println(\"Even\");\n" + + " }\n" + + " }\n" + + "}", + }; + String expectedProblemLog = + "----------\n" + + "1. WARNING in X.java (at line 5)\n" + + " switch (i) {\n" + + " ^\n" + + "The switch statement should have a default case\n" + + "----------\n"; + this.runNegativeTest( + testFiles, + expectedProblemLog, + null, + true, + new String[] { "--enable-preview"}, + options); + } + /* + * Switch multi-constant with duplicate int constants + */ + public void testBug543240_12() { + Map<String, String> options = getCompilerOptions(); + options.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED); + options.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE); + String[] testFiles = new String[] { + "X.java", + "public class X {\n" + + " public static void main(String[] args) {\n" + + " }\n" + + " public static void bar(int i) {\n" + + " switch (i) {\n" + + " case 1, 3: \n" + + " System.out.println(\"Odd\");\n" + + " case 3, 4: \n" + + " System.out.println(\"Odd\");\n" + + " }\n" + + " }\n" + + "}", + }; + String expectedProblemLog = + "----------\n" + + "1. ERROR in X.java (at line 8)\n" + + " case 3, 4: \n" + + " ^^^^^^^^^\n" + + "Duplicate case\n" + + "----------\n" + + "2. ERROR in X.java (at line 8)\n" + + " case 3, 4: \n" + + " ^^^^^^^^^\n" + + "Duplicate case\n" + + "----------\n"; + this.runNegativeTest( + testFiles, + expectedProblemLog, + null, + true, + options); + } + /* + * Switch multi-constant with duplicate String literals + */ + public void testBug543240_13() { + Map<String, String> options = getCompilerOptions(); + options.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED); + options.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE); + String[] testFiles = new String[] { + "X.java", + "public class X {\n" + + " public static void main(String[] args) {\n" + + " }\n" + + " public static void bar(String s) {\n" + + " switch (s) {\n" + + " case \"a\", \"b\": \n" + + " System.out.println(\"Odd\");\n" + + " case \"b\", \"c\": \n" + + " System.out.println(\"Odd\");\n" + + " }\n" + + " }\n" + + "}", + }; + String expectedProblemLog = + "----------\n" + + "1. ERROR in X.java (at line 8)\n" + + " case \"b\", \"c\": \n" + + " ^^^^^^^^^^^^^\n" + + "Duplicate case\n" + + "----------\n" + + "2. ERROR in X.java (at line 8)\n" + + " case \"b\", \"c\": \n" + + " ^^^^^^^^^^^^^\n" + + "Duplicate case\n" + + "----------\n"; + this.runNegativeTest( + testFiles, + expectedProblemLog, + null, + true, + options); + } + /* + * Switch multi-constant with illegal qualified enum constant + */ + public void testBug543240_14() { + Map<String, String> options = getCompilerOptions(); + options.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED); + options.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE); + String[] testFiles = new String[] { + "X.java", + "public class X {\n" + + " public static void main(String[] args) {\n" + + " }\n" + + " public static void bar(Num s) {\n" + + " switch (s) {\n" + + " case ONE, Num.TWO: \n" + + " System.out.println(\"Odd\");\n" + + " }\n" + + " }\n" + + "}\n" + + "enum Num { ONE, TWO}\n", + }; + String expectedProblemLog = + "----------\n" + + "1. ERROR in X.java (at line 6)\n" + + " case ONE, Num.TWO: \n" + + " ^^^^^^^\n" + + "The qualified case label Num.TWO must be replaced with the unqualified enum constant TWO\n" + + "----------\n"; + this.runNegativeTest( + testFiles, + expectedProblemLog, + null, + true, + options); + } + public void testBug543240_15() { + Map<String, String> options = getCompilerOptions(); + options.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED); + options.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE); + String[] testFiles = new String[] { + "X.java", + "public class X {\n" + + " public void bar(int s) {\n" + + " int j = switch (s) {\n" + + " case 1, 2, 3 -> (s+1);\n" + + " default -> j;\n" + + " };\n" + + " }\n" + + "}\n", + }; + String expectedProblemLog = + "----------\n" + + "1. ERROR in X.java (at line 5)\n" + + " default -> j;\n" + + " ^\n" + + "The local variable j may not have been initialized\n" + + "----------\n"; + this.runNegativeTest( + testFiles, + expectedProblemLog, + null, + true, + options); + } + public void testBug543240_16() { + Map<String, String> options = getCompilerOptions(); + options.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED); + options.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE); + String[] testFiles = new String[] { + "X.java", + "public class X {\n" + + " public static void main(String[] args) {\n" + + " }\n" + + " public void bar(int s) {\n" + + " int j = 0;" + + " j = switch (s) {\n" + + " case 1, 2, 3 -> (s+1);\n" + + " default -> j;\n" + + " };\n" + + " }\n" + + "}\n", + }; + this.runNegativeTest( + testFiles, + "", + null, + true, + new String[] { "--enable-preview"}, + options); + } + public void testBug543795_01() { + this.runNegativeTest( + new String[] { + "X.java", + "import java.io.IOException;\n" + + "\n" + + "public class X {\n" + + " public static int foo(int i) throws IOException {\n" + + " int t = switch (i) {\n" + + " case 0 : {\n" + + " break 0;\n" + + " }\n" + + " case 2 : {\n" + + " break;\n" + + " }\n" + + " default : break 10;\n" + + " };\n" + + " return t;\n" + + " }\n" + + " \n" + + " public boolean bar() {\n" + + " return true;\n" + + " }\n" + + " public static void main(String[] args) {\n" + + " try {\n" + + " System.out.println(foo(3));\n" + + " } catch (IOException e) {\n" + + " // TODO Auto-generated catch block\n" + + " e.printStackTrace();\n" + + " }\n" + + " }\n" + + "}\n", + }, + "----------\n" + + "1. ERROR in X.java (at line 10)\n" + + " break;\n" + + " ^^^^^^\n" + + "Break of a switch expression should have a value\n" + + "----------\n"); + } + public void testBug543691() { + Map<String, String> options = getCompilerOptions(); + options.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED); + options.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE); + String[] testFiles = new String[] { + "X.java", + "public class X {\n" + + " @SuppressWarnings(\"preview\")\n" + + " public static void bar(int i) {\n" + + " i = switch (i+0) {\n" + + " default: System.out.println(0);\n" + + " }; " + + " }\n" + + "}", + }; + String expectedProblemLog = + "----------\n" + + "1. ERROR in X.java (at line 4)\n" + + " i = switch (i+0) {\n" + + " default: System.out.println(0);\n" + + " }; }\n" + + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + + "A switch expression should have at least one result expression\n" + + "----------\n"; + this.runNegativeTest( + testFiles, + expectedProblemLog, + null, + true, + options); + } + public void testBug543799_1() { + Map<String, String> options = getCompilerOptions(); + options.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED); + options.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE); + String[] testFiles = new String[] { + "X.java", + "public class X {\n" + + " void test(int i) {\n" + + " need(switch (i) {\n" + + " case 1 -> \"\";\n" + + " default -> i == 3 ? null : \"\";\n" + + " }); \n" + + " }\n" + + " void need(String s) {\n" + + " System.out.println(s.toLowerCase());\n" + + " }\n" + + " public static void main(String[] args) {\n" + + " new X().need(\"Hello World\");\n" + + " }\n" + + "}\n" + }; + String expectedOutput = "hello world"; + runConformTest(testFiles, expectedOutput, options); + } + public void testBug543799_2() { + Map<String, String> options = getCompilerOptions(); + options.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED); + options.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE); + String[] testFiles = new String[] { + "X.java", + "public class X {\n" + + " void test(int i) {\n" + + " need(switch (i) {\n" + + " case 1: break \"\";\n" + + " default: break i == 3 ? null : \"\";\n" + + " }); \n" + + " }\n" + + " void need(String s) {\n" + + " System.out.println(s.toLowerCase());\n" + + " }\n" + + " public static void main(String[] args) {\n" + + " new X().need(\"Hello World\");\n" + + " }\n" + + "}\n" + }; + String expectedOutput = "hello world"; + runConformTest(testFiles, expectedOutput, options); + } + public void testBug543799_3() { + Map<String, String> options = getCompilerOptions(); + options.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED); + options.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE); + String[] testFiles = new String[] { + "X.java", + "interface I0 { void i(); }\n" + + "interface I1 extends I0 {}\n" + + "interface I2 extends I0 {}\n" + + "public class X {\n" + + " I1 n1() { return null; }\n" + + " <I extends I2> I n2() { return null; }\n" + + " <M> M m(M m) { return m; }\n" + + " void test(int i, boolean b) {\n" + + " m(switch (i) {\n" + + " case 1 -> n1();\n" + + " default -> b ? n1() : n2();\n" + + " }).i(); \n" + + " }\n" + + " public static void main(String[] args) {\n" + + " try {\n" + + " new X().test(1, true);\n" + + " } catch (NullPointerException e) {\n" + + " System.out.println(\"NPE as expected\");\n" + + " }\n" + + " }\n" + + "}\n" + }; + String expectedOutput = "NPE as expected"; + runConformTest(testFiles, expectedOutput, options); + } + public void testBug543799_4() { + Map<String, String> options = getCompilerOptions(); + options.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED); + options.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE); + String[] testFiles = new String[] { + "X.java", + "import java.util.function.Supplier;\n" + + "interface I0 { void i(); }\n" + + "interface I1 extends I0 {}\n" + + "interface I2 extends I0 {}\n" + + "public class X {\n" + + " I1 n1() { return null; }\n" + + " <I extends I2> I n2() { return null; }\n" + + " <M> M m(Supplier<M> m) { return m.get(); }\n" + + " void test(int i, boolean b) {\n" + + " m(switch (i) {\n" + + " case 1 -> this::n1;\n" + + " default -> this::n2;\n" + + " }).i(); \n" + + " }\n" + + " public static void main(String[] args) {\n" + + " try {\n" + + " new X().test(1, true);\n" + + " } catch (NullPointerException e) {\n" + + " System.out.println(\"NPE as expected\");\n" + + " }\n" + + " }\n" + + "}\n" + }; + String expectedOutput = "NPE as expected"; + runConformTest(testFiles, expectedOutput, options); + } + public void testBug543799_5() { + // require resolving/inferring of poly-switch-expression during ASTNode.resolvePolyExpressionArguments() + Map<String, String> options = getCompilerOptions(); + options.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED); + options.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE); + String[] testFiles = new String[] { + "X.java", + "public class X {\n" + + " void test(int i) {\n" + + " need(switch (i) {\n" + + " case 1 -> 1.0f;\n" + + " default -> i == 3 ? 3 : 5.0d;\n" + + " }); \n" + + " }\n" + + " <N extends Number> void need(N s) {\n" + + " System.out.println(s.toString());\n" + + " }\n" + + " public static void main(String[] args) {\n" + + " new X().need(3);\n" + + " }\n" + + "}\n" + }; + String expectedOutput = "3"; + runConformTest(testFiles, expectedOutput, options); + } + public void testSwitchStatementWithBreakExpression() { + runConformTest( + new String[] { + "X.java", + "public class X {\n" + + " static int twice(int i) throws Exception {\n" + + " switch (i) {\n" + + " case 0 -> System.out.println(\"hellow\");\n" + + " case 1 -> foo();\n" + + " default -> throw new Exception();\n" + + " };\n" + + " return 0;\n" + + " }\n" + + "\n" + + " static int foo() {\n" + + " System.out.println(\"inside foo\");\n" + + " return 1;\n" + + " }\n" + + "\n" + + " public static void main(String[] args) {\n" + + " try {\n" + + " System.out.print(twice(1));\n" + + " } catch (Exception e) {\n" + + " System.out.print(\"Got Exception\");\n" + + " }\n" + + " }\n" + + "}" + }, + "inside foo\n" + + "0", + null, + new String[] {"--enable-preview"}); + } + public void testSwitchStatementWithEnumValues() { + runConformTest( + new String[] { + "X.java", + "enum SomeDays {\n" + + " Mon, Wed, Fri\n" + + "}\n" + + "\n" + + "public class X {\n" + + " int testEnum(boolean b) {\n" + + " SomeDays day = b ? SomeDays.Mon : null;\n" + + " return switch(day) {\n" + + " case Mon -> 1;\n" + + " case Wed -> 2;\n" + + " case Fri -> 3;\n" + + " };\n" + + " }\n" + + "\n" + + " public static void main(String[] args) {\n" + + " System.out.println(new X().testEnum(true));\n" + + " }\n" + + "}\n" + + "" + }, + "1", + null, + new String[] {"--enable-preview"}); + } + public void testBug543967_01() { + Map<String, String> options = getCompilerOptions(); + options.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED); + String[] testFiles = new String[] { + "X.java", + "public class X {\n" + + " static int foo(int i) {\n" + + " switch (i) {\n" + + " default -> 3; // should flag an error\n" + + " \n" + + " };\n" + + " return 0;\n" + + " }\n" + + " public static void main(String[] args) {\n" + + " foo(1);\n" + + " }\n" + + "}\n", + }; + String expectedProblemLog = + "----------\n" + + "1. ERROR in X.java (at line 4)\n" + + " default -> 3; // should flag an error\n" + + " ^\n" + + "Invalid expression as statement\n" + + "----------\n"; + this.runNegativeTest( + testFiles, + expectedProblemLog, + null, + true, + new String[] { "--enable-preview"}, + options); + } + public void testBug544204() { + runConformTest( + new String[] { + "X.java", + "public class X {\n" + + " public void foo(int i) {\n" + + " int j = switch (i) {\n" + + " case 1 -> i;\n" + + " default -> i;\n" + + " };\n" + + " System.out.println(j);\n" + + " }\n" + + " \n" + + " public static void main(String[] args) {\n" + + " new X().foo(1);\n" + + " }\n" + + "}" + }, + "1", + null, + new String[] {"--enable-preview"}); + } + public void testBug544204_2() { + runConformTest( + new String[] { + "X.java", + "public class X {\n" + + " public void foo(int i) {\n" + + " long j = switch (i) {\n" + + " case 1 -> 10L;\n" + + " default -> 20L;\n" + + " };\n" + + " System.out.println(j);\n" + + " }\n" + + " \n" + + " public static void main(String[] args) {\n" + + " new X().foo(1);\n" + + " }\n" + + "}" + }, + "10", + null, + new String[] {"--enable-preview"}); + } + public void testBug544223() { + runConformTest( + new String[] { + "X.java", + "public class X {\n" + + " public int foo(String s) throws Exception {\n" + + " int i = switch (s) {\n" + + " case \"hello\" -> 1;\n" + + " default -> throw new Exception();\n" + + " };\n" + + " return i;\n" + + " }\n" + + "\n" + + " public static void main(String[] argv) {\n" + + " try {\n" + + " System.out.print(new X().foo(\"hello\"));\n" + + " } catch (Exception e) {\n" + + " //\n" + + " }\n" + + " }\n" + + "}" + }, + "1", + null, + new String[] {"--enable-preview"}); + } + public void testBug544258_01() { + this.runNegativeTest( + new String[] { + "X.java", + "public class X {\n" + + " public void foo(Day day) {\n" + + " var today = 1;\n" + + " today = switch (day) {\n" + + " case SATURDAY,SUNDAY :\n" + + " today=1;\n" + + " break today;\n" + + " case MONDAY,TUESDAY,WEDNESDAY,THURSDAY :\n" + + " today=2;\n" + + " break today;\n" + + " };\n" + + " }\n" + + " public static void main(String argv[]) {\n" + + " new X().foo(Day.FRIDAY);\n" + + " }\n" + + "}\n" + + "\n" + + "enum Day {\n" + + " SUNDAY,\n" + + " MONDAY,\n" + + " TUESDAY,\n" + + " WEDNESDAY,\n" + + " THURSDAY,\n" + + " FRIDAY,\n" + + " SATURDAY\n" + + "}\n", + }, + "----------\n" + + "1. ERROR in X.java (at line 4)\n" + + " today = switch (day) {\n" + + " ^^^\n" + + "A Switch expression should cover all possible values\n" + + "----------\n"); + } + public void testBug544253() { + runConformTest( + new String[] { + "X.java", + "public class X {\n" + + " public void foo(int i ) {\n" + + " boolean b = switch (i) {\n" + + " case 0 -> i == 1;\n" + + " default -> true;\n" + + " };\n" + + " System.out.println( b ? \" true\" : \"false\");\n" + + " }\n" + + " public static void main(String[] argv) {\n" + + " new X().foo(0);\n" + + " }\n" + + "}" + }, + "false", + null, + new String[] {"--enable-preview"}); + } + public void testBug544254() { + runConformTest( + new String[] { + "X.java", + "public class X {\n" + + " public void foo(String s) {\n" + + " try {\n" + + " int i = switch (s) {\n" + + " case \"hello\" -> 0;\n" + + " default -> 2;\n" + + " };\n" + + " } finally {\n" + + " System.out.println(s);\n" + + " }\n" + + " }\n" + + " public static void main(String argv[]) {\n" + + " new X().foo(\"hello\");\n" + + " }\n" + + "}" + }, + "hello", + null, + new String[] {"--enable-preview"}); + } + public void testBug544254_2() { + Map<String, String> customOptions = getCompilerOptions(); + customOptions.put(CompilerOptions.OPTION_PreserveUnusedLocal, CompilerOptions.OPTIMIZE_OUT); + runConformTest( + new String[] { + "X.java", + "public class X {\n" + + " public void foo(String s) {\n" + + " try {\n" + + " int i = switch (s) {\n" + + " case \"hello\" -> 0;\n" + + " default -> 2;\n" + + " };\n" + + " } finally {\n" + + " System.out.println(s);\n" + + " }\n" + + " }\n" + + " public static void main(String argv[]) {\n" + + " new X().foo(\"hello\");\n" + + " }\n" + + "}" + }, + "hello", + customOptions, + new String[] {"--enable-preview"}); + } + public void testBug544254_3() { + Map<String, String> customOptions = getCompilerOptions(); + customOptions.put(CompilerOptions.OPTION_PreserveUnusedLocal, CompilerOptions.OPTIMIZE_OUT); + runConformTest( + new String[] { + "X.java", + "public class X {\n" + + " public void foo(String s) {\n" + + " try {\n" + + " long l = switch (s) {\n" + + " case \"hello\" -> 0;\n" + + " default -> 2;\n" + + " };\n" + + " } finally {\n" + + " System.out.println(s);\n" + + " }\n" + + " }\n" + + " public static void main(String argv[]) {\n" + + " new X().foo(\"hello\");\n" + + " }\n" + + "}" + }, + "hello", + customOptions, + new String[] {"--enable-preview"}); + } + public void testBug544224_1() { + Map<String, String> customOptions = getCompilerOptions(); + customOptions.put(CompilerOptions.OPTION_PreserveUnusedLocal, CompilerOptions.OPTIMIZE_OUT); + runConformTest( + new String[] { + "X.java", + "public class X {\n" + + " public int foo(int i) {\n" + + " int j = (switch (i) {\n" + + " case 1 -> 1;\n" + + " default -> 2;\n" + + " });\n" + + " return j;\n" + + " }\n" + + " public static void main(String[] argv) {\n" + + " new X().foo(1);\n" + + " }\n" + + "}\n" + }, + "", + customOptions, + new String[] {"--enable-preview"}); + } + public void testBug544298() { + runConformTest( + new String[] { + "X.java", + "public class X {\n" + + " enum MyEnum {\n" + + " FIRST;\n" + + " }\n" + + "\n" + + " public void foo(MyEnum myEnum) {\n" + + " int i = switch (myEnum) {\n" + + " case FIRST -> 1;\n" + + " };\n" + + " System.out.println( \"i:\" + i);\n" + + " }\n" + + "\n" + + " public static void main(String argv[]) {\n" + + " new X().foo(MyEnum.FIRST);\n" + + " }\n" + + "}" + }, + "i:1", + null, + new String[] {"--enable-preview"}); + } + public void testBug544298_2() { + runConformTest( + new String[] { + "X.java", + "public class X {\n" + + " enum MyEnum {\n" + + " FIRST;\n" + + " }\n" + + "\n" + + " public void foo(MyEnum myEnum) {\n" + + " int i = switch (myEnum) {\n" + + " case FIRST -> 1;\n" + + " default -> 0;\n" + + " };\n" + + " System.out.println( \"i:\" + i);\n" + + " }\n" + + "\n" + + " public static void main(String argv[]) {\n" + + " new X().foo(MyEnum.FIRST);\n" + + " }\n" + + "}" + }, + "i:1", + null, + new String[] {"--enable-preview"}); + } + public void testBug544428_01() { + Map<String, String> options = getCompilerOptions(); + options.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED); + options.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE); + String[] testFiles = new String[] { + "X.java", + "public class X {\n" + + " public int foo(int i) {\n" + + " var v = switch(i) {\n" + + " case 0 -> x;\n" + + " default -> 1;\n" + + " };\n" + + " return v;\n" + + " }\n" + + " public static void main(String[] argv) {\n" + + " System.out.println(new X().foo(0));\n" + + " }\n" + + "}", + }; + String expectedProblemLog = + "----------\n" + + "1. ERROR in X.java (at line 4)\n" + + " case 0 -> x;\n" + + " ^\n" + + "x cannot be resolved to a variable\n" + + "----------\n"; + this.runNegativeTest( + testFiles, + expectedProblemLog, + null, + true, + new String[] { "--enable-preview"}, + options); + } + public void testBug544523_01() { + runConformTest( + new String[] { + "X.java", + "public class X {\n" + + " @SuppressWarnings(\"preview\")\n" + + " public int foo(int i) {\n" + + " int v = switch(i) {\n" + + " case 0 -> switch(i) {\n" + + " case 0 -> 0;\n" + + " default -> 1;\n" + + " };\n" + + " default -> 1;\n" + + " };\n" + + " return v;\n" + + " }\n" + + " public static void main(String[] argv) {\n" + + " System.out.println(new X().foo(0));\n" + + " }\n" + + "}" + }, + "0", + null, + new String[] {"--enable-preview"}); + } + public void testBug544560_01() { + runConformTest( + new String[] { + "X.java", + "public class X {\n" + + " public int foo(int i) {\n" + + " @SuppressWarnings(\"preview\")\n" + + " int v = switch(switch(i) {\n" + + " default -> 1;\n" + + " }) {\n" + + " default -> 1;\n" + + " };\n" + + " return v;\n" + + " }\n" + + "\n" + + " public static void main(String[] argv) {\n" + + " System.out.println(new X().foo(0));\n" + + " }\n" + + "}\n" + }, + "1", + null, + new String[] {"--enable-preview"}); + } + public void testBug544458() { + runConformTest( + new String[] { + "X.java", + "public class X {\n" + + " public static int foo(int i) {\n" + + " boolean v = switch (i) {\n" + + " case 1: i = 10; break true;\n" + + " default: break false;\n" + + " };\n" + + " return v ? 0 : 1;\n" + + " }\n" + + " public static void main(String[] argv) {\n" + + " System.out.println(X.foo(0));\n" + + " }\n" + + "}" + }, + "1", + null, + new String[] {"--enable-preview"}); + } + public void testBug544458_2() { + runConformTest( + new String[] { + "X.java", + "public class X {\n" + + " public static int foo(int i) {\n" + + " boolean v = switch (i) {\n" + + " case 1: i++; break true;\n" + + " default: break false;\n" + + " };\n" + + " return v ? 0 : 1;\n" + + " }\n" + + " public static void main(String[] argv) {\n" + + " System.out.println(X.foo(1));\n" + + " }\n" + + "}" + }, + "0", + null, + new String[] {"--enable-preview"}); + } + public void testBug544458_3() { + runConformTest( + new String[] { + "X.java", + "public class X {\n" + + " public static int foo(int i) {\n" + + " boolean v = switch (i) {\n" + + " case 1: i+= 10; break true;\n" + + " default: break false;\n" + + " };\n" + + " return v ? 0 : 1;\n" + + " }\n" + + " public static void main(String[] argv) {\n" + + " System.out.println(X.foo(1));\n" + + " }\n" + + "}" + }, + "0", + null, + new String[] {"--enable-preview"}); + } + public void testBug544458_4() { + runConformTest( + new String[] { + "X.java", + "public class X {\n" + + " public static int foo(int i) {\n" + + " boolean v = switch (i) {\n" + + " case 1: switch(i) {case 4: break;}; break true;\n" + + " default: break false;\n" + + " };\n" + + " return v ? 0 : 1;\n" + + " }\n" + + " public static void main(String[] argv) {\n" + + " System.out.println(X.foo(1));\n" + + " }\n" + + "}" + }, + "0", + null, + new String[] {"--enable-preview"}); + } + public void testBug544458_5() { + runConformTest( + new String[] { + "X.java", + "public class X {\n" + + " public static int foo(int i) {\n" + + " boolean v = switch (i) {\n" + + " case 1: foo(5); break true;\n" + + " default: break false;\n" + + " };\n" + + " return v ? 0 : 1;\n" + + " }\n" + + " public static void main(String[] argv) {\n" + + " System.out.println(X.foo(1));\n" + + " }\n" + + "}" + }, + "0", + null, + new String[] {"--enable-preview"}); + } + public void testBug544601_1() { + runConformTest( + new String[] { + "X.java", + "public class X {\n" + + " public int foo(int i) {\n" + + " @SuppressWarnings(\"preview\")\n" + + " boolean v = switch (i) {\n" + + " case 1:\n" + + " switch (i) {\n" + + " case 1 : i = 10;\n" + + " break;\n" + + " default :\n" + + " i = 2;\n" + + " break;\n" + + " }\n" + + " break true;\n" + + " default: break false;\n" + + " };\n" + + " return v ? 0 : 1;\n" + + " }\n" + + "\n" + + " public static void main(String[] argv) {\n" + + " System.out.println(new X().foo(0));\n" + + " }\n" + + "}\n" + }, + "1", + null, + new String[] {"--enable-preview"}); + } + public void testBug544556() { + runConformTest( + new String[] { + "X.java", + "public class X {\n" + + " public int foo(int i) {\n" + + " @SuppressWarnings(\"preview\")\n" + + " int v =\n" + + " switch(switch(i) {\n" + + " case 0 -> { break 2; }\n" + + " default -> { break 3; }\n" + + " }) {\n" + + " case 0 -> { break 0; }\n" + + " default -> { break 1; }\n" + + " };\n" + + " return v == 1 ? v : 0;\n" + + " }\n" + + " public static void main(String[] argv) {\n" + + " System.out.println(new X().foo(0));\n" + + " }\n" + + "}" + }, + "1", + null, + new String[] {"--enable-preview"}); + } + public void testBug544702_01() { + runConformTest( + new String[] { + "X.java", + "public class X {\n" + + " @SuppressWarnings(\"preview\")\n" + + " public int foo(int i) {\n" + + " int k = 10;\n" + + " switch (i) {\n" + + " case 0 -> { k = 0;}\n" + + " default -> k = -1;\n" + + " }\n" + + " return k;\n" + + " }\n" + + " public static void main(String[] argv) {\n" + + " System.out.println(new X().foo(0) == 0 ? \"Success\" : \"Failure\");\n" + + " }\n" + + "\n" + + "}\n" + }, + "Success", + null, + new String[] {"--enable-preview"}); + } + public void testBug545168_01() { + runConformTest( + new String[] { + "X.java", + "public class X {\n" + + " @SuppressWarnings(\"preview\")\n" + + " public static void foo(Day day) {\n" + + " switch (day) {\n" + + " case MONDAY, FRIDAY -> System.out.println(Day.SUNDAY);\n" + + " case TUESDAY -> System.out.println(7);\n" + + " case THURSDAY, SATURDAY -> System.out.println(8);\n" + + " case WEDNESDAY -> System.out.println(9);\n" + + " default -> {}\n" + + " } \n" + + " }\n" + + " public static void main(String[] args) {\n" + + " X.foo(Day.WEDNESDAY);\n" + + " }\n" + + "}\n" + + "\n" + + "enum Day {\n" + + " MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY;\n" + + "}\n" + }, + "9", + null, + new String[] {"--enable-preview"}); + } +}
\ No newline at end of file diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TestAll.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TestAll.java index 1b1baca7c6..69bfe88e8e 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TestAll.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TestAll.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2018 IBM Corporation and others. + * Copyright (c) 2000, 2019 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -8,6 +8,10 @@ * * SPDX-License-Identifier: EPL-2.0 * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * IBM Corporation - initial API and implementation * Stephan Herrmann - Contributions for @@ -172,12 +176,18 @@ public static Test suite() { // add 10 specific test here (check duplicates) ArrayList since_10 = new ArrayList(); since_10.add(JEP286Test.class); + since_10.add(Unicode10Test.class); // add 11 specific test here (check duplicates) ArrayList since_11 = new ArrayList(); since_11.add(JEP323VarLambdaParamsTest.class); since_11.add(JEP181NestTest.class); + // add 12 specific test here (check duplicates) + ArrayList since_12 = new ArrayList(); + since_12.add(SwitchExpressionTest.class); + since_12.add(Unicode11Test.class); + // Build final test suite TestSuite all = new TestSuite(TestAll.class.getName()); all.addTest(new TestSuite(StandAloneASTParserTest.class)); @@ -275,6 +285,20 @@ public static Test suite() { TestCase.resetForgottenFilters(tests_11); all.addTest(AbstractCompilerTest.buildComplianceTestSuite(ClassFileConstants.getComplianceLevelForJavaVersion(ClassFileConstants.MAJOR_VERSION_11), tests_11)); } + if ((possibleComplianceLevels & AbstractCompilerTest.F_12) != 0) { + ArrayList tests_12 = (ArrayList)standardTests.clone(); + tests_12.addAll(since_1_4); + tests_12.addAll(since_1_5); + tests_12.addAll(since_1_6); + tests_12.addAll(since_1_7); + tests_12.addAll(since_1_8); + tests_12.addAll(since_9); + tests_12.addAll(since_10); + tests_12.addAll(since_11); + tests_12.addAll(since_12); + TestCase.resetForgottenFilters(tests_12); + all.addTest(AbstractCompilerTest.buildComplianceTestSuite(ClassFileConstants.getComplianceLevelForJavaVersion(ClassFileConstants.MAJOR_VERSION_12), tests_12)); + } all.addTest(new TestSuite(Jsr14Test.class)); return all; } diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/Unicode11Test.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/Unicode11Test.java new file mode 100644 index 0000000000..878286b8a3 --- /dev/null +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/Unicode11Test.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright (c) 2019 IBM Corporation and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.core.tests.compiler.regression; + +import java.util.Map; + +import junit.framework.Test; + +import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; + +public class Unicode11Test extends AbstractRegressionTest { +public Unicode11Test(String name) { + super(name); +} +public static Test suite() { + return buildMinimalComplianceTestSuite(testClass(), F_12); +} +public void test1() { + Map<String, String> options = getCompilerOptions(); + options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_12); + this.runConformTest( + new String[] { + "X.java", + "public class X {\n" + + " public int a\u0560; // new unicode character in unicode 11.0 \n" + + "}", + }, + "", + options); +} +public void test2() { + Map<String, String> options = getCompilerOptions(); + options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_11); + this.runNegativeTest( + new String[] { + "X.java", + "public class X {\n" + + " public int a\\u0560; // new unicode character in unicode 11.0 \n" + + "}", + }, + "----------\n" + + "1. ERROR in X.java (at line 2)\n" + + " public int a\\u0560; // new unicode character in unicode 11.0 \n" + + " ^^^^^^\n" + + "Syntax error on token \"Invalid Character\", delete this token\n" + + "----------\n", + null, + true, + options); +} +public static Class<Unicode11Test> testClass() { + return Unicode11Test.class; +} +} diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/VarargsTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/VarargsTest.java index d0e2f2824d..6e7d315d3c 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/VarargsTest.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/VarargsTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2016 IBM Corporation and others. + * Copyright (c) 2005, 2019 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -50,7 +50,11 @@ public class VarargsTest extends AbstractComparableTest { public static Class testClass() { return VarargsTest.class; } - + protected String intersection(String... types) { + if (this.complianceLevel >= ClassFileConstants.JDK1_8) + return String.join(" & ", types); + return String.join("&", types); + } public void test001() { this.runConformTest( new String[] { diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/util/AbstractCompilerTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/util/AbstractCompilerTest.java index fee9aacbe9..eec4716a5a 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/util/AbstractCompilerTest.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/util/AbstractCompilerTest.java @@ -1,11 +1,15 @@ /******************************************************************************* - * Copyright (c) 2000, 2018 IBM Corporation and others. + * Copyright (c) 2000, 2019 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 * which accompanies this distribution, and is available at * https://www.eclipse.org/legal/epl-2.0/ * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * SPDX-License-Identifier: EPL-2.0 * * Contributors: @@ -43,6 +47,7 @@ public class AbstractCompilerTest extends TestCase { public static final int F_9 = 0x40; public static final int F_10 = 0x80; public static final int F_11 = 0x100; + public static final int F_12 = 0x200; public static final boolean RUN_JAVAC = CompilerOptions.ENABLED.equals(System.getProperty("run.javac")); private static final int UNINITIALIZED = -1; @@ -98,6 +103,9 @@ public class AbstractCompilerTest extends TestCase { if ((complianceLevels & AbstractCompilerTest.F_11) != 0) { suite.addTest(buildUniqueComplianceTestSuite(evaluationTestClass, ClassFileConstants.getComplianceLevelForJavaVersion(ClassFileConstants.MAJOR_VERSION_11))); } + if ((complianceLevels & AbstractCompilerTest.F_12) != 0) { + suite.addTest(buildUniqueComplianceTestSuite(evaluationTestClass, ClassFileConstants.getComplianceLevelForJavaVersion(ClassFileConstants.MAJOR_VERSION_12))); + } } /** @@ -140,6 +148,9 @@ public class AbstractCompilerTest extends TestCase { if ((complianceLevels & AbstractCompilerTest.F_11) != 0) { suite.addTest(buildComplianceTestSuite(testClasses, setupClass, ClassFileConstants.getComplianceLevelForJavaVersion(ClassFileConstants.MAJOR_VERSION_11))); } + if ((complianceLevels & AbstractCompilerTest.F_12) != 0) { + suite.addTest(buildComplianceTestSuite(testClasses, setupClass, ClassFileConstants.getComplianceLevelForJavaVersion(ClassFileConstants.MAJOR_VERSION_12))); + } return suite; } @@ -148,7 +159,7 @@ public class AbstractCompilerTest extends TestCase { int lessthan9 = F_1_3 | F_1_4 | F_1_5 | F_1_6 | F_1_7 | F_1_8; isJRE9Plus = !isJRELevel(lessthan9); isJRE11Plus = isJRELevel(F_11); - isJRE12Plus = "12".equals(System.getProperty("java.specification.version")); + isJRE12Plus = isJRELevel(F_12); } /** @@ -291,6 +302,14 @@ public class AbstractCompilerTest extends TestCase { suite.addTest(buildUniqueComplianceTestSuite(evaluationTestClass, ClassFileConstants.getComplianceLevelForJavaVersion(ClassFileConstants.MAJOR_VERSION_11))); } } + int level12 = complianceLevels & AbstractCompilerTest.F_12; + if (level12 != 0) { + if (level12 < minimalCompliance) { + System.err.println("Cannot run "+evaluationTestClass.getName()+" at compliance 12!"); + } else { + suite.addTest(buildUniqueComplianceTestSuite(evaluationTestClass, ClassFileConstants.getComplianceLevelForJavaVersion(ClassFileConstants.MAJOR_VERSION_12))); + } + } return suite; } @@ -324,7 +343,7 @@ public class AbstractCompilerTest extends TestCase { else if (highestLevel == ClassFileConstants.JDK1_3) complianceString = "1.3"; else { - highestLevel = ClassFileConstants.getComplianceLevelForJavaVersion(ClassFileConstants.MAJOR_VERSION_11); + highestLevel = ClassFileConstants.getLatestJDKLevel(); if (highestLevel > 0) { complianceString = CompilerOptions.versionFromJdkLevel(highestLevel); } else { @@ -349,6 +368,9 @@ public class AbstractCompilerTest extends TestCase { */ public static long highestComplianceLevels() { int complianceLevels = AbstractCompilerTest.getPossibleComplianceLevels(); + if ((complianceLevels & AbstractCompilerTest.F_12) != 0) { + return ClassFileConstants.getComplianceLevelForJavaVersion(ClassFileConstants.MAJOR_VERSION_12); + } if ((complianceLevels & AbstractCompilerTest.F_11) != 0) { return ClassFileConstants.getComplianceLevelForJavaVersion(ClassFileConstants.MAJOR_VERSION_11); } @@ -402,10 +424,10 @@ public class AbstractCompilerTest extends TestCase { public static int getPossibleComplianceLevels() { if (possibleComplianceLevels == UNINITIALIZED) { String specVersion = System.getProperty("java.specification.version"); - isJRE9Plus = CompilerOptions.VERSION_9.equals(specVersion) - || CompilerOptions.VERSION_10.equals(specVersion) - || CompilerOptions.VERSION_11.equals(specVersion); - isJRE11Plus = CompilerOptions.VERSION_11.equals(specVersion); + isJRE12Plus = CompilerOptions.VERSION_12.equals(specVersion); + isJRE11Plus = isJRE12Plus || CompilerOptions.VERSION_11.equals(specVersion); + isJRE9Plus = isJRE11Plus || CompilerOptions.VERSION_9.equals(specVersion) + || CompilerOptions.VERSION_10.equals(specVersion); initReflectionVersion(); String compliances = System.getProperty("compliance"); if (compliances != null) { @@ -429,6 +451,8 @@ public class AbstractCompilerTest extends TestCase { possibleComplianceLevels |= F_10; } else if (CompilerOptions.VERSION_11.equals(compliance)) { possibleComplianceLevels |= F_11; + } else if (CompilerOptions.VERSION_12.equals(compliance)) { + possibleComplianceLevels |= F_12; } else { System.out.println("Ignoring invalid compliance (" + compliance + ")"); System.out.print("Use one of "); @@ -441,7 +465,8 @@ public class AbstractCompilerTest extends TestCase { System.out.print(CompilerOptions.VERSION_1_8 + ", "); System.out.print(CompilerOptions.VERSION_9 + ", "); System.out.print(CompilerOptions.VERSION_10 + ", "); - System.out.println(CompilerOptions.VERSION_11); + System.out.print(CompilerOptions.VERSION_11 + ", "); + System.out.println(CompilerOptions.VERSION_12); } } if (possibleComplianceLevels == 0) { @@ -487,6 +512,10 @@ public class AbstractCompilerTest extends TestCase { if (canRun11) { possibleComplianceLevels |= F_11; } + boolean canRun12 = canRun11 && !CompilerOptions.VERSION_11.equals(specVersion); + if (canRun12) { + possibleComplianceLevels |= F_12; + } } else if ("1.0".equals(specVersion) || CompilerOptions.VERSION_1_1.equals(specVersion) || CompilerOptions.VERSION_1_2.equals(specVersion) @@ -507,6 +536,9 @@ public class AbstractCompilerTest extends TestCase { possibleComplianceLevels |= F_10; if (!CompilerOptions.VERSION_10.equals(specVersion)) { possibleComplianceLevels |= F_11; + if (!CompilerOptions.VERSION_11.equals(specVersion)) { + possibleComplianceLevels |= F_12; + } } } } @@ -662,6 +694,8 @@ public class AbstractCompilerTest extends TestCase { options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_10); options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_10); } else { + // This is already good enough to cover versions from future + // (as long as versionFromJdkLevel does its job) String ver = CompilerOptions.versionFromJdkLevel(this.complianceLevel); options.put(CompilerOptions.OPTION_Compliance, ver); options.put(CompilerOptions.OPTION_Source, ver); @@ -683,6 +717,11 @@ public class AbstractCompilerTest extends TestCase { if (compliance < ClassFileConstants.JDK9) return "version 1.8 : 52.0"; if (compliance == ClassFileConstants.JDK9) return "version 9 : 53.0"; if (compliance == ClassFileConstants.JDK10) return "version 10 : 54.0"; + if (compliance > ClassFileConstants.JDK10) { + String ver = CompilerOptions.versionFromJdkLevel(compliance); + int major = Integer.parseInt(ver) + ClassFileConstants.MAJOR_VERSION_0; + return "version " + ver + " : " + major + ".0"; + } if (compliance >= ClassFileConstants.getComplianceLevelForJavaVersion(ClassFileConstants.MAJOR_VERSION_11)) return version; // keep this stmt for search for next bump up return version; } diff --git a/org.eclipse.jdt.core.tests.model/JCL/converterJclMin12.jar b/org.eclipse.jdt.core.tests.model/JCL/converterJclMin12.jar Binary files differnew file mode 100644 index 0000000000..eed2c4df78 --- /dev/null +++ b/org.eclipse.jdt.core.tests.model/JCL/converterJclMin12.jar diff --git a/org.eclipse.jdt.core.tests.model/JCL/converterJclMin12.zip b/org.eclipse.jdt.core.tests.model/JCL/converterJclMin12.zip Binary files differnew file mode 100644 index 0000000000..35e5589d58 --- /dev/null +++ b/org.eclipse.jdt.core.tests.model/JCL/converterJclMin12.zip diff --git a/org.eclipse.jdt.core.tests.model/JCL/converterJclMin12src.zip b/org.eclipse.jdt.core.tests.model/JCL/converterJclMin12src.zip Binary files differnew file mode 100644 index 0000000000..35e5589d58 --- /dev/null +++ b/org.eclipse.jdt.core.tests.model/JCL/converterJclMin12src.zip diff --git a/org.eclipse.jdt.core.tests.model/JCL/converterJclMin9.jar b/org.eclipse.jdt.core.tests.model/JCL/converterJclMin9.jar Binary files differindex df361f565f..bb48557698 100644 --- a/org.eclipse.jdt.core.tests.model/JCL/converterJclMin9.jar +++ b/org.eclipse.jdt.core.tests.model/JCL/converterJclMin9.jar diff --git a/org.eclipse.jdt.core.tests.model/JCL/converterJclMin9src.zip b/org.eclipse.jdt.core.tests.model/JCL/converterJclMin9src.zip Binary files differindex 23ce774f5e..031b53aa47 100644 --- a/org.eclipse.jdt.core.tests.model/JCL/converterJclMin9src.zip +++ b/org.eclipse.jdt.core.tests.model/JCL/converterJclMin9src.zip diff --git a/org.eclipse.jdt.core.tests.model/JCL/jclMin12.jar b/org.eclipse.jdt.core.tests.model/JCL/jclMin12.jar Binary files differnew file mode 100644 index 0000000000..0f621d1524 --- /dev/null +++ b/org.eclipse.jdt.core.tests.model/JCL/jclMin12.jar diff --git a/org.eclipse.jdt.core.tests.model/JCL/jclMin12src.zip b/org.eclipse.jdt.core.tests.model/JCL/jclMin12src.zip Binary files differnew file mode 100644 index 0000000000..bf05b46301 --- /dev/null +++ b/org.eclipse.jdt.core.tests.model/JCL/jclMin12src.zip diff --git a/org.eclipse.jdt.core.tests.model/pom.xml b/org.eclipse.jdt.core.tests.model/pom.xml index 0743433929..1acae5cc9a 100644 --- a/org.eclipse.jdt.core.tests.model/pom.xml +++ b/org.eclipse.jdt.core.tests.model/pom.xml @@ -139,6 +139,37 @@ <tycho.surefire.argLine>--add-modules ALL-SYSTEM -Dcompliance=1.4,1.7,1.8,11</tycho.surefire.argLine> </properties> </profile> + <profile> + <id>test-on-javase-12</id> + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-toolchains-plugin</artifactId> + <version>1.1</version> + <executions> + <execution> + <phase>validate</phase> + <goals> + <goal>toolchain</goal> + </goals> + </execution> + </executions> + <configuration> + <toolchains> + <jdk> + <id>JavaSE-12</id> + </jdk> + </toolchains> + </configuration> + </plugin> + </plugins> + </build> + <properties> + <!-- Overridden in https://ci.eclipse.org/jdt/job/eclipse.jdt.core-run.javac-12/configure --> + <tycho.surefire.argLine>--add-modules ALL-SYSTEM -Dcompliance=1.4,1.7,1.8,12</tycho.surefire.argLine> + </properties> + </profile> </profiles> </project> diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/RunAllJava12Tests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/RunAllJava12Tests.java new file mode 100644 index 0000000000..55ada0ae80 --- /dev/null +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/RunAllJava12Tests.java @@ -0,0 +1,91 @@ +/******************************************************************************* + * Copyright (c) 2019 IBM Corporation and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.core.tests; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +import org.eclipse.jdt.core.tests.dom.ASTConverter12Test; +import org.eclipse.jdt.core.tests.dom.ConverterTestSetup; +import org.eclipse.jdt.core.tests.util.AbstractCompilerTest; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +@SuppressWarnings({"rawtypes", "unchecked"}) +public class RunAllJava12Tests extends TestCase { + + public RunAllJava12Tests(String name) { + super(name); + } + public static Class[] getAllTestClasses() { + return new Class[] { + // to be filled after other tests are added + }; + } + + public static Class[] getConverterTestClasses() { + return new Class[] { + ASTConverter12Test.class, + }; + } + + public static Class[] getCompilerClasses() { + return new Class[] { + org.eclipse.jdt.core.tests.eval.TestAll.class, + org.eclipse.jdt.core.tests.compiler.regression.TestAll.class, + }; + } + + public static Test suite() { + TestSuite ts = new TestSuite(RunAllJava12Tests.class.getName()); + + Class[] testClasses = getAllTestClasses(); + addTestsToSuite(ts, testClasses); + testClasses = getConverterTestClasses(); + addTestsToSuite(ts, testClasses); + + AbstractCompilerTest.setpossibleComplianceLevels(AbstractCompilerTest.F_11); + addTestsToSuite(ts, getCompilerClasses()); + // ComplianceDiagnoseTest is already added to the test suite through getTestSuite + ts.addTest(org.eclipse.jdt.core.tests.compiler.parser.TestAll.getTestSuite(false)); + return ts; + } + public static void addTestsToSuite(TestSuite suite, Class[] testClasses) { + + for (int i = 0; i < testClasses.length; i++) { + Class testClass = testClasses[i]; + // call the suite() method and add the resulting suite to the suite + try { + Method suiteMethod = testClass.getDeclaredMethod("suite", new Class[0]); //$NON-NLS-1$ + Test test = (Test)suiteMethod.invoke(null, new Object[0]); + suite.addTest(test); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } catch (InvocationTargetException e) { + e.getTargetException().printStackTrace(); + } catch (NoSuchMethodException e) { + e.printStackTrace(); + } + } + } + protected void tearDown() throws Exception { + ConverterTestSetup.PROJECT_SETUP = false; + super.tearDown(); + } +}
\ No newline at end of file diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/RunOnlyJava12Tests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/RunOnlyJava12Tests.java new file mode 100644 index 0000000000..46a8dff16a --- /dev/null +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/RunOnlyJava12Tests.java @@ -0,0 +1,80 @@ +/******************************************************************************* + * Copyright (c) 2019 IBM Corporation and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.core.tests; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Arrays; + +import org.eclipse.jdt.core.tests.dom.ASTConverter12Test; +import org.eclipse.jdt.core.tests.dom.ConverterTestSetup; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +@SuppressWarnings({"rawtypes", "unchecked"}) +public class RunOnlyJava12Tests extends TestCase { + + public RunOnlyJava12Tests(String name) { + super(name); + } + public static Class[] getAllTestClasses() { + return new Class[] { + // to be filled after other tests are added + }; + } + + public static Class[] getConverterTestClasses() { + return new Class[] { + ASTConverter12Test.class + }; + } + public static Test suite() { + TestSuite ts = new TestSuite(RunOnlyJava12Tests.class.getName()); + + Class[] testClasses = getAllTestClasses(); + addTestsToSuite(ts, testClasses); + testClasses = getConverterTestClasses(); + ConverterTestSetup.TEST_SUITES = new ArrayList(Arrays.asList(testClasses)); + addTestsToSuite(ts, testClasses); + return ts; + } + public static void addTestsToSuite(TestSuite suite, Class[] testClasses) { + + for (int i = 0; i < testClasses.length; i++) { + Class testClass = testClasses[i]; + // call the suite() method and add the resulting suite to the suite + try { + Method suiteMethod = testClass.getDeclaredMethod("suite", new Class[0]); //$NON-NLS-1$ + Test test = (Test)suiteMethod.invoke(null, new Object[0]); + suite.addTest(test); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } catch (InvocationTargetException e) { + e.getTargetException().printStackTrace(); + } catch (NoSuchMethodException e) { + e.printStackTrace(); + } + } + } + protected void tearDown() throws Exception { + ConverterTestSetup.PROJECT_SETUP = false; + super.tearDown(); + } +} diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter12Test.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter12Test.java new file mode 100644 index 0000000000..f7637c7ed0 --- /dev/null +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter12Test.java @@ -0,0 +1,165 @@ +/******************************************************************************* + * Copyright (c) 2019 IBM Corporation and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.core.tests.dom; + +import org.eclipse.jdt.core.ICompilationUnit; +import org.eclipse.jdt.core.IJavaProject; +import org.eclipse.jdt.core.JavaCore; +import org.eclipse.jdt.core.JavaModelException; +import org.eclipse.jdt.core.dom.AST; +import org.eclipse.jdt.core.dom.ASTNode; +import org.eclipse.jdt.core.dom.CompilationUnit; +import org.eclipse.jdt.core.dom.IBinding; +import org.eclipse.jdt.core.dom.MethodDeclaration; +import org.eclipse.jdt.core.dom.Statement; +import org.eclipse.jdt.core.dom.SwitchStatement; +import org.eclipse.jdt.core.dom.Type; +import org.eclipse.jdt.core.dom.VariableDeclarationStatement; + +import junit.framework.Test; + +public class ASTConverter12Test extends ConverterTestSetup { + + ICompilationUnit workingCopy; + + public void setUpSuite() throws Exception { + super.setUpSuite(); + this.ast = AST.newAST(getAST12()); + } + + public ASTConverter12Test(String name) { + super(name); + } + + static { +// TESTS_NUMBERS = new int[] { 19 }; +// TESTS_RANGE = new int[] { 1, -1 }; +// TESTS_NAMES = new String[] {"test0001"}; + } + public static Test suite() { + return buildModelTestSuite(ASTConverter12Test.class); + } + + static int getAST12() { + return AST.JLS12; + } + protected void tearDown() throws Exception { + super.tearDown(); + if (this.workingCopy != null) { + this.workingCopy.discardWorkingCopy(); + this.workingCopy = null; + } + } + + public void test0001() throws JavaModelException { + String contents = + " public class X {\n" + + " enum Day\n" + + " {\n" + + " SUNDAY, MONDAY, TUESDAY, WEDNESDAY,\n" + + " THURSDAY, FRIDAY, SATURDAY;\n" + + " }\n" + + " public static void main(String[] args) {\n" + + " Day day = Day.SUNDAY;\n" + + " int k = switch (day) {\n" + + " case MONDAY -> throw new NullPointerException();\n" + + " case TUESDAY -> 1;\n" + + "\n" + + " case WEDNESDAY -> {break 10;}\n" + + " default -> {\n" + + " int g = day.toString().length();\n" + + " break g;\n" + + " }};\n" + + " System.out.println(k);\n" + + " }\n" + + "}" ; + this.workingCopy = getWorkingCopy("/Converter12/src/X.java", true/*resolve*/); + IJavaProject javaProject = this.workingCopy.getJavaProject(); + String old = javaProject.getOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, true); + try { + javaProject.setOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, JavaCore.ENABLED); + javaProject.setOption(JavaCore.COMPILER_PB_REPORT_PREVIEW_FEATURES, JavaCore.IGNORE); + ASTNode node = buildAST( + contents, + this.workingCopy); + assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType()); + CompilationUnit compilationUnit = (CompilationUnit) node; + assertProblemsSize(compilationUnit, 0); + node = getASTNode(compilationUnit, 0, 1); + MethodDeclaration methodDeclaration = (MethodDeclaration) node; + VariableDeclarationStatement vStmt1 = (VariableDeclarationStatement) methodDeclaration.getBody().statements().get(1); + Type type = vStmt1.getType(); + IBinding binding = type.resolveBinding(); + assertTrue("null binding", binding != null); + assertTrue("binding incorrect", binding.getName().equals("int")); + } finally { + javaProject.setOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, old); + } + } + public void test0002() throws JavaModelException { + String contents = + "public class X {\n" + + " static enum Day {MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY, SATURDAY,SUNDAY}\n" + + " String aa(Day day) throws Exception {\n" + + " var today = \"\";\n" + + " switch (day) {\n" + + " case SATURDAY,SUNDAY ->\n" + + " today=\"Weekend\";\n" + + " case MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY ->\n" + + " today=\"Working\";\n" + + " default ->\n" + + " throw new Exception(\"Invalid day: \" + day.name());\n" + + " }\n" + + " return today;\n" + + " }\n" + + " \n" + + " String bb(Day day) throws Exception {\n" + + " var today = \"\";\n" + + " switch (day) {\n" + + " case SATURDAY,SUNDAY:\n" + + " today = \"Weekend day\";\n" + + " break;\n" + + " case MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY:\n" + + " today = \"Working day\";\n" + + " break;\n" + + " default:\n" + + " throw new Exception(\"Invalid day: \" + day.name());\n" + + " }\n" + + " return today;\n" + + " }\n" + + "}" ; + this.workingCopy = getWorkingCopy("/Converter12/src/X.java", true/*resolve*/); + IJavaProject javaProject = this.workingCopy.getJavaProject(); + String old = javaProject.getOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, true); + try { + javaProject.setOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, JavaCore.ENABLED); + javaProject.setOption(JavaCore.COMPILER_PB_REPORT_PREVIEW_FEATURES, JavaCore.IGNORE); + ASTNode node = buildAST( + contents, + this.workingCopy); + assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType()); + CompilationUnit compilationUnit = (CompilationUnit) node; + assertProblemsSize(compilationUnit, 0); + node = getASTNode(compilationUnit, 0, 1, 1); + assertEquals("Switch statement", node.getNodeType(), ASTNode.SWITCH_STATEMENT); + SwitchStatement switchStatement = (SwitchStatement) node; + checkSourceRange((Statement) switchStatement.statements().get(0), "case SATURDAY,SUNDAY ->", contents); + } finally { + javaProject.setOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, old); + } + } +} diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter15JLS4Test.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter15JLS4Test.java index dc6db31f4a..21383f0431 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter15JLS4Test.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter15JLS4Test.java @@ -4829,12 +4829,14 @@ public class ASTConverter15JLS4Test extends ConverterTestSetup { statement = (Statement) statements.get(0); assertEquals("Not a switch case statement", ASTNode.SWITCH_CASE, statement.getNodeType()); SwitchCase switchCase = (SwitchCase) statement; + @SuppressWarnings("deprecation") Expression expression = switchCase.getExpression(); assertNull("Got a constant", expression.resolveConstantExpressionValue()); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=88548 - public void test0152() throws CoreException { + @SuppressWarnings("deprecation") + public void test0152() throws CoreException { this.workingCopy = getWorkingCopy("/Converter15/src/X.java", true/*resolve*/); String contents = "public class X {\n" + diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter15JLS8Test.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter15JLS8Test.java index 32ef339415..546c5a585a 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter15JLS8Test.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter15JLS8Test.java @@ -4759,7 +4759,8 @@ public class ASTConverter15JLS8Test extends ConverterTestSetup { } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=88548 - public void test0151() throws CoreException { + @SuppressWarnings("deprecation") + public void test0151() throws CoreException { this.workingCopy = getWorkingCopy("/Converter15/src/X.java", true/*resolve*/); String contents = "public enum X {\n" + @@ -4822,7 +4823,8 @@ public class ASTConverter15JLS8Test extends ConverterTestSetup { } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=88548 - public void test0152() throws CoreException { + @SuppressWarnings("deprecation") + public void test0152() throws CoreException { this.workingCopy = getWorkingCopy("/Converter15/src/X.java", true/*resolve*/); String contents = "public class X {\n" + diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter15Test.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter15Test.java index 3a42702693..00cd53b3be 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter15Test.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter15Test.java @@ -4781,7 +4781,8 @@ public class ASTConverter15Test extends ConverterTestSetup { } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=88548 - public void test0151() throws CoreException { + @SuppressWarnings("deprecation") + public void test0151() throws CoreException { this.workingCopy = getWorkingCopy("/Converter15/src/X.java", true/*resolve*/); String contents = "public enum X {\n" + @@ -4844,7 +4845,8 @@ public class ASTConverter15Test extends ConverterTestSetup { } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=88548 - public void test0152() throws CoreException { + @SuppressWarnings("deprecation") + public void test0152() throws CoreException { this.workingCopy = getWorkingCopy("/Converter15/src/X.java", true/*resolve*/); String contents = "public class X {\n" + diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter9Test.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter9Test.java index 6321d365c7..e80eba3532 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter9Test.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter9Test.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2016, 2018 IBM Corporation and others. + * Copyright (c) 2016, 2019 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -8,6 +8,10 @@ * * SPDX-License-Identifier: EPL-2.0 * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ @@ -37,6 +41,7 @@ import org.eclipse.jdt.core.IPackageFragmentRoot; import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.core.JavaModelException; +import org.eclipse.jdt.core.compiler.IProblem; @SuppressWarnings({"rawtypes"}) public class ASTConverter9Test extends ConverterTestSetup { @@ -1414,5 +1419,93 @@ public class ASTConverter9Test extends ConverterTestSetup { deleteProject("Foo"); } } + // TODO: should probably start a new test class + public void testBug531714_015() throws CoreException { + // saw NPE in SwitchExpression.resolveType(SwitchExpression.java:423) + if (!isJRE12) { + System.err.println("Test "+getName()+" requires a JRE 12"); + return; + } + IJavaProject p = createJavaProject("Foo", new String[] {"src"}, new String[] {jcl9lib}, "bin", "12"); // FIXME jcl12? + p.setOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, JavaCore.ENABLED); + p.setOption(JavaCore.COMPILER_PB_REPORT_PREVIEW_FEATURES, JavaCore.IGNORE); + try { + String source = + "import java.util.*;\n" + + "public class X {\n" + + " void testForeach1(int i, List<String> list) {\n" + + " for (String s : switch(i) { case 1 -> list; default -> ; }) {\n" + + " \n" + + " }\n" + + " Throwable t = switch (i) {\n" + + " case 1 -> new Exception();\n" + + " case 2 -> new RuntimeException();\n" + // trigger !typeUniformAcrossAllArms + " default -> missing;\n" + + " };\n" + + " }\n" + + " void testForeach0(int i, List<String> list) {\n" + // errors in first arm + " for (String s : switch(i) { case 1 -> ; default -> list; }) {\n" + + " \n" + + " }\n" + + " Throwable t = switch (i) {\n" + + " case 0 -> missing;\n" + + " case 1 -> new Exception();\n" + + " default -> new RuntimeException();\n" + // trigger !typeUniformAcrossAllArms + " };\n" + + " }\n" + + " void testForeachAll(int i) {\n" + // only erroneous arms + " Throwable t = switch (i) {\n" + + " case 0 -> missing;\n" + + " default -> absent;\n" + + " };\n" + + " }\n" + + "}\n"; + createFile("Foo/src/X.java", source); + ICompilationUnit cuD = getCompilationUnit("/Foo/src/X.java"); + + ASTParser parser = ASTParser.newParser(AST_INTERNAL_JLS11); + parser.setProject(p); + parser.setSource(cuD); + parser.setResolveBindings(true); + parser.setStatementsRecovery(true); + parser.setBindingsRecovery(true); + org.eclipse.jdt.core.dom.CompilationUnit cuAST = (org.eclipse.jdt.core.dom.CompilationUnit) parser.createAST(null); + IProblem[] problems = cuAST.getProblems(); + assertProblems("Unexpected problems", + "1. ERROR in /Foo/src/X.java (at line 4)\n" + + " for (String s : switch(i) { case 1 -> list; default -> ; }) {\n" + + " ^^\n" + + "Syntax error on token \"->\", Expression expected after this token\n" + + "----------\n" + + "2. ERROR in /Foo/src/X.java (at line 10)\n" + + " default -> missing;\n" + + " ^^^^^^^\n" + + "missing cannot be resolved to a variable\n" + + "----------\n" + + "3. ERROR in /Foo/src/X.java (at line 14)\n" + + " for (String s : switch(i) { case 1 -> ; default -> list; }) {\n" + + " ^^\n" + + "Syntax error on token \"->\", Expression expected after this token\n" + + "----------\n" + + "4. ERROR in /Foo/src/X.java (at line 18)\n" + + " case 0 -> missing;\n" + + " ^^^^^^^\n" + + "missing cannot be resolved to a variable\n" + + "----------\n" + + "5. ERROR in /Foo/src/X.java (at line 25)\n" + + " case 0 -> missing;\n" + + " ^^^^^^^\n" + + "missing cannot be resolved to a variable\n" + + "----------\n" + + "6. ERROR in /Foo/src/X.java (at line 26)\n" + + " default -> absent;\n" + + " ^^^^^^\n" + + "absent cannot be resolved to a variable\n" + + "----------\n", + problems, source.toCharArray()); + } finally { + deleteProject(p); + } + } // Add new tests here } diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterAST3Test.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterAST3Test.java index addae41c47..f4d1f0ef49 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterAST3Test.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterAST3Test.java @@ -2088,6 +2088,7 @@ public class ASTConverterAST3Test extends ConverterTestSetup { /** * SwitchStatement ==> SwitchStatement */ + @SuppressWarnings("deprecation") public void test0097() throws JavaModelException { ICompilationUnit sourceUnit = getCompilationUnit("Converter" , "src", "test0097", "Test.java"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ char[] source = sourceUnit.getSource().toCharArray(); diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterAST4Test.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterAST4Test.java index 926d8a34bd..4b77b6e96a 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterAST4Test.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterAST4Test.java @@ -2088,6 +2088,7 @@ public class ASTConverterAST4Test extends ConverterTestSetup { /** * SwitchStatement ==> SwitchStatement */ + @SuppressWarnings("deprecation") public void test0097() throws JavaModelException { ICompilationUnit sourceUnit = getCompilationUnit("Converter" , "src", "test0097", "Test.java"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ char[] source = sourceUnit.getSource().toCharArray(); diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterAST8Test.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterAST8Test.java index 9c83e01fce..9e617b11bd 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterAST8Test.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterAST8Test.java @@ -2072,6 +2072,7 @@ public class ASTConverterAST8Test extends ConverterTestSetup { /** * SwitchStatement ==> SwitchStatement */ + @SuppressWarnings("deprecation") public void test0097() throws JavaModelException { ICompilationUnit sourceUnit = getCompilationUnit("Converter" , "src", "test0097", "Test.java"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ char[] source = sourceUnit.getSource().toCharArray(); diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterTest.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterTest.java index acbd8ddf23..dfafd6d6a9 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterTest.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterTest.java @@ -2177,6 +2177,7 @@ public class ASTConverterTest extends ConverterTestSetup { /** * SwitchStatement ==> SwitchStatement */ + @SuppressWarnings("deprecation") public void test0097() throws JavaModelException { ICompilationUnit sourceUnit = getCompilationUnit("Converter" , "src", "test0097", "Test.java"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ char[] source = sourceUnit.getSource().toCharArray(); diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTMatcherTest.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTMatcherTest.java index 04ca9bb6e8..6b421b9407 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTMatcherTest.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTMatcherTest.java @@ -1206,6 +1206,7 @@ public class ASTMatcherTest extends org.eclipse.jdt.core.tests.junit.extension.T x1.setName(this.N2); basicMatch(x1); } + @SuppressWarnings("deprecation") public void testSwitchCase() { SwitchCase x1 = this.ast.newSwitchCase(); x1.setExpression(this.E1); diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTTest.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTTest.java index 667df5dfb2..fb6493969f 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTTest.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2018 IBM Corporation and others. + * Copyright (c) 2000, 2019 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -8,6 +8,10 @@ * * SPDX-License-Identifier: EPL-2.0 * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ @@ -8868,6 +8872,7 @@ public class ASTTest extends org.eclipse.jdt.core.tests.junit.extension.TestCase ASTNode.USES_DIRECTIVE, ASTNode.PROVIDES_DIRECTIVE, ASTNode.MODULE_MODIFIER, + ASTNode.SWITCH_EXPRESSION, }; diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTVisitorTest.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTVisitorTest.java index 0407d10cc6..c5e62c6311 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTVisitorTest.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTVisitorTest.java @@ -2096,6 +2096,7 @@ public class ASTVisitorTest extends org.eclipse.jdt.core.tests.junit.extension.T String result = this.b.toString(); assertTrue(result.equals("[(eSMR"+this.N1S+this.N2S+"eSMR)]")); //$NON-NLS-1$ //$NON-NLS-2$ } + @SuppressWarnings("deprecation") public void testSwitchCase() { SwitchCase x1 = this.ast.newSwitchCase(); x1.setExpression(this.E1); diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/AbstractASTTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/AbstractASTTests.java index b6fafe483c..8b895c14be 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/AbstractASTTests.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/AbstractASTTests.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2018 IBM Corporation and others. + * Copyright (c) 2004, 2019 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -8,6 +8,10 @@ * * SPDX-License-Identifier: EPL-2.0 * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ @@ -493,7 +497,9 @@ public class AbstractASTTests extends ModifyingResourceTests implements DefaultM String option = cu.getJavaProject().getOption(JavaCore.COMPILER_COMPLIANCE, true); long jdkLevel = CompilerOptions.versionToJdkLevel(option); int JLSLevel = AST_INTERNAL_JLS3; - if (jdkLevel >= ClassFileConstants.getComplianceLevelForJavaVersion(ClassFileConstants.MAJOR_VERSION_11)) { + if (jdkLevel >= ClassFileConstants.getComplianceLevelForJavaVersion(ClassFileConstants.MAJOR_VERSION_12)) { + JLSLevel = AST_INTERNAL_JLS12; + } else if (jdkLevel >= ClassFileConstants.getComplianceLevelForJavaVersion(ClassFileConstants.MAJOR_VERSION_11)) { JLSLevel = AST_INTERNAL_JLS11; } else if (jdkLevel >= ClassFileConstants.JDK10) { JLSLevel = AST_INTERNAL_JLS10; diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ConverterTestSetup.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ConverterTestSetup.java index f34d73e568..513a512a7f 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ConverterTestSetup.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ConverterTestSetup.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2018 IBM Corporation and others. + * Copyright (c) 2000, 2019 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -8,6 +8,10 @@ * * SPDX-License-Identifier: EPL-2.0 * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ @@ -105,6 +109,7 @@ public abstract class ConverterTestSetup extends AbstractASTTests { this.deleteProject("Converter9"); //$NON-NLS-1$ this.deleteProject("Converter10"); //$NON-NLS-1$ this.deleteProject("Converter11"); //$NON-NLS-1$ + this.deleteProject("Converter12"); //$NON-NLS-1$ PROJECT_SETUP = false; } else { TEST_SUITES.remove(getClass()); @@ -117,6 +122,7 @@ public abstract class ConverterTestSetup extends AbstractASTTests { this.deleteProject("Converter9"); //$NON-NLS-1$ this.deleteProject("Converter10"); //$NON-NLS-1$ this.deleteProject("Converter11"); //$NON-NLS-1$ + this.deleteProject("Converter12"); //$NON-NLS-1$ PROJECT_SETUP = false; } } @@ -178,6 +184,14 @@ public abstract class ConverterTestSetup extends AbstractASTTests { new IPath[] {getConverterJCLPath("11"), getConverterJCLSourcePath("11"), getConverterJCLRootSourcePath()}, null); } + } else if ("12".equals(compliance)) { + if (JavaCore.getClasspathVariable("CONVERTER_JCL12_LIB") == null) { + setupExternalJCL("converterJclMin12"); + JavaCore.setClasspathVariables( + new String[] {"CONVERTER_JCL11_LIB", "CONVERTER_JCL11_SRC", "CONVERTER_JCL11_SRCROOT"}, + new IPath[] {getConverterJCLPath("12"), getConverterJCLSourcePath("12"), getConverterJCLRootSourcePath()}, + null); + } } else if (JavaCore.getClasspathVariable("CONVERTER_JCL_LIB") == null) { setupExternalJCL("converterJclMin"); JavaCore.setClasspathVariables( @@ -202,6 +216,7 @@ public abstract class ConverterTestSetup extends AbstractASTTests { setUpJavaProject("Converter9", "9"); //$NON-NLS-1$ //$NON-NLS-2$ setUpJavaProject("Converter10", "10"); //$NON-NLS-1$ //$NON-NLS-2$ setUpJavaProject("Converter11", "11"); //$NON-NLS-1$ //$NON-NLS-2$ + setUpJavaProject("Converter12", "12"); //$NON-NLS-1$ //$NON-NLS-2$ waitUntilIndexesReady(); // needed to find secondary types PROJECT_SETUP = true; } diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/RunConverterTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/RunConverterTests.java index 028e170023..f12cc67bab 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/RunConverterTests.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/RunConverterTests.java @@ -52,6 +52,7 @@ public static Class[] getAllTestClasses() { TypeAnnotationsConverterTest.class, ASTConverter18Test.class, ASTConverter9Test.class, + ASTConverter12Test.class, }; } public static Test suite() { diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AbstractJavaModelTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AbstractJavaModelTests.java index 72600309b7..59b92d6ea6 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AbstractJavaModelTests.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AbstractJavaModelTests.java @@ -8,6 +8,10 @@ * * SPDX-License-Identifier: EPL-2.0 * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ @@ -90,11 +94,10 @@ public abstract class AbstractJavaModelTests extends SuiteOfTestCases { } } long jdkLevel = CompilerOptions.versionToJdkLevel(javaVersion.length() > 3 ? javaVersion.substring(0, 3) : javaVersion); + if (jdkLevel >= ClassFileConstants.getLatestJDKLevel()) { + isJRE12 = true; + } if (jdkLevel >= ClassFileConstants.JDK11) { - if (CompilerOptions.versionToJdkLevel(javaVersion.length() > 3 ? javaVersion.substring(0, 3) : javaVersion, false) == 0) { - // version was capped to 11 during versionToJdkLevel(version, true) - isJRE12 = true; - } isJRE11 = true; } if (jdkLevel >= ClassFileConstants.JDK10) { @@ -114,7 +117,7 @@ public abstract class AbstractJavaModelTests extends SuiteOfTestCases { "jdk.packager,jdk.packager.services,jdk.plugin.dom," + // not present in OpenJDK "jdk.scripting.nashorn,jdk.sctp,jdk.security.auth,jdk.security.jgss,jdk.unsupported,jdk.xml.dom," + "oracle.desktop,oracle.net"; // not present in OpenJDK - } else if (vmName.contains("OpenJDK")) { + } else if (vmName.contains("OpenJDK") || vmName.contains("OpenJ9")) { DEFAULT_MODULES = "java.se," + "jdk.accessibility,jdk.attach,jdk.compiler,jdk.dynalink,jdk.httpserver," + "jdk.incubator.httpclient,jdk.jartool,jdk.javadoc,jdk.jconsole,jdk.jdi," + @@ -124,7 +127,7 @@ public abstract class AbstractJavaModelTests extends SuiteOfTestCases { System.out.println(System.getProperties()); fail("Unexpected java vm "+javaVersion+" "+vmName); } - System.out.println("Recognized Java 9 version '"+javaVersion+"' with vm.name '"+vmName+"'"); + System.out.println("Recognized Java version '"+javaVersion+"' with vm.name '"+vmName+"'"); } } @@ -142,11 +145,16 @@ public abstract class AbstractJavaModelTests extends SuiteOfTestCases { protected static final int AST_INTERNAL_JLS10 = AST.JLS10; /** + * Internal synonym for constant AST.JSL12 + * to alleviate deprecation warnings once AST.JLS12 is deprecated in future. + */ + protected static final int AST_INTERNAL_JLS12 = AST.JLS12; + + /** * Internal synonym for constant AST.JSL11 * to alleviate deprecation warnings once AST.JLS11 is deprecated in future. */ protected static final int AST_INTERNAL_JLS11 = AST.JLS11; - public static class BasicProblemRequestor implements IProblemRequestor { public void acceptProblem(IProblem problem) {} public void beginReporting() {} @@ -2044,6 +2052,12 @@ public abstract class AbstractJavaModelTests extends SuiteOfTestCases { options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_11); options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_11); javaProject.setOptions(options); + } else if ("12".equals(compliance)) { + Map options = new HashMap(); + options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_12); + options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_12); + options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_12); + javaProject.setOptions(options); } result[0] = javaProject; } @@ -3119,6 +3133,7 @@ public abstract class AbstractJavaModelTests extends SuiteOfTestCases { javaProject.setOption(JavaCore.COMPILER_PB_FIELD_HIDING, JavaCore.IGNORE); javaProject.setOption(JavaCore.COMPILER_PB_LOCAL_VARIABLE_HIDING, JavaCore.IGNORE); javaProject.setOption(JavaCore.COMPILER_PB_TYPE_PARAMETER_HIDING, JavaCore.IGNORE); +// javaProject.setOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, JavaCore.ENABLED); return javaProject; } protected void setUpProjectCompliance(IJavaProject javaProject, String compliance) throws JavaModelException, IOException { @@ -3136,7 +3151,10 @@ public abstract class AbstractJavaModelTests extends SuiteOfTestCases { newJclLibString = "JCL18_FULL"; newJclSrcString = "JCL18_SRC"; // Use the same source } else { - if (compliance.equals("11")) { + if (compliance.equals("12")) { + newJclLibString = "JCL12_LIB"; + newJclSrcString = "JCL12_SRC"; + } else if (compliance.equals("11")) { newJclLibString = "JCL11_LIB"; newJclSrcString = "JCL11_SRC"; } else if (compliance.equals("10")) { @@ -3193,10 +3211,11 @@ public abstract class AbstractJavaModelTests extends SuiteOfTestCases { IPath jcl9Lib = new Path("JCL19_LIB"); IPath jcl10Lib = new Path("JCL10_LIB"); IPath jcl11Lib = new Path("JCL11_LIB"); + IPath jcl12Lib = new Path("JCL12_LIB"); IPath jclFull = new Path("JCL18_FULL"); return path.equals(jclLib) || path.equals(jcl5Lib) || path.equals(jcl8Lib) || path.equals(jcl9Lib) - || path.equals(jcl10Lib) || path.equals(jcl11Lib) || path.equals(jclFull); + || path.equals(jcl10Lib) || path.equals(jcl11Lib) || path.equals(jcl12Lib) || path.equals(jclFull); } public void setUpJCLClasspathVariables(String compliance) throws JavaModelException, IOException { setUpJCLClasspathVariables(compliance, false); @@ -3259,6 +3278,14 @@ public abstract class AbstractJavaModelTests extends SuiteOfTestCases { new IPath[] {getExternalJCLPath("11"), getExternalJCLSourcePath("11"), getExternalJCLRootSourcePath()}, null); } + } else if ("12".equals(compliance)) { + if (JavaCore.getClasspathVariable("JCL12_LIB") == null) { + setupExternalJCL("jclMin12"); + JavaCore.setClasspathVariables( + new String[] {"JCL12_LIB", "JCL12_SRC", "JCL_SRCROOT"}, + new IPath[] {getExternalJCLPath("12"), getExternalJCLSourcePath("12"), getExternalJCLRootSourcePath()}, + null); + } } else { if (JavaCore.getClasspathVariable("JCL_LIB") == null) { setupExternalJCL("jclMin"); diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AllJavaModelTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AllJavaModelTests.java index 2f58097d50..5f37bc32c8 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AllJavaModelTests.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AllJavaModelTests.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2018 IBM Corporation and others. + * Copyright (c) 2000, 2019 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -102,6 +102,7 @@ private static Class[] getAllTestClasses() { ResolveTests2.class, ResolveTests_1_5.class, ResolveTests18.class, + ResolveTests12.class, SelectionJavadocModelTests.class, // Support for completion tests diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AttachSourceTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AttachSourceTests.java index a7d9e60fac..ba4462e602 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AttachSourceTests.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AttachSourceTests.java @@ -1903,6 +1903,7 @@ public void testModule2() throws CoreException, IOException { System.err.println(this.getClass().getName()+'.'+getName()+" needs a Java 9 JRE - skipped"); return; } + if (isJRE12) return; try { IJavaProject prj = createJava9Project("Test", new String[]{"src"}); String moduleSrc = diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests12.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests12.java new file mode 100644 index 0000000000..4fd1385939 --- /dev/null +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests12.java @@ -0,0 +1,860 @@ +/******************************************************************************* + * Copyright (c) 2019 IBM and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * + * SPDX-License-Identifier: EPL-2.0 + * + *******************************************************************************/ +package org.eclipse.jdt.core.tests.model; + +import org.eclipse.jdt.core.ICompilationUnit; +import org.eclipse.jdt.core.JavaModelException; +import org.eclipse.jdt.internal.codeassist.RelevanceConstants; + +import junit.framework.Test; + +public class CompletionTests12 extends AbstractJavaModelCompletionTests { + + static { +// TESTS_NAMES = new String[]{"test018e"}; + } + + public CompletionTests12(String name) { + super(name); + } + public void setUpSuite() throws Exception { + if (COMPLETION_PROJECT == null) { + COMPLETION_PROJECT = setUpJavaProject("Completion", "12"); + } else { + setUpProjectCompliance(COMPLETION_PROJECT, "12"); + } + super.setUpSuite(); + } + public static Test suite() { + return buildModelTestSuite(CompletionTests12.class); + } + public void test001() throws JavaModelException { + this.workingCopies = new ICompilationUnit[1]; + this.workingCopies[0] = getWorkingCopy( + "/Completion/src/Switch.java", + "public class Switch {\n" + + " public static void bar(MyDay day) {\n" + + " switch (day) {\n" + + " case SATURDAY, SUN ->\n" + + " System.out.println(day.toString());\n" + + " }\n" + + " }\n" + + " public static void main(String[] args) {\n" + + " bar(MyDay.SUNDAY);\n" + + " }\n" + + "}\n" + + "enum MyDay { SATURDAY, SUNDAY}"); + CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true); + requestor.allowAllRequiredProposals(); + String str = this.workingCopies[0].getSource(); + String completeBehind = "SATURDAY, SUN"; + int cursorLocation = str.indexOf(completeBehind) + completeBehind.length(); + this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner); + assertResults( + "SUNDAY[FIELD_REF]{SUNDAY, LMyDay;, LMyDay;, SUNDAY, null, "+ + (RelevanceConstants.R_DEFAULT + RelevanceConstants.R_RESOLVED + RelevanceConstants.R_INTERESTING+ + RelevanceConstants.R_CASE + RelevanceConstants.R_EXACT_EXPECTED_TYPE + + RelevanceConstants.R_ENUM + RelevanceConstants.R_ENUM_CONSTANT + + RelevanceConstants.R_UNQUALIFIED + RelevanceConstants.R_NON_RESTRICTED)+ "}", + requestor.getResults()); + } + public void test002() throws JavaModelException { + this.workingCopies = new ICompilationUnit[1]; + this.workingCopies[0] = getWorkingCopy( + "/Completion/src/Switch.java", + "public class Switch {\n" + + " public static void bar(MyDay day) {\n" + + " switch (day) {\n" + + " case SATURDAY, SUN :\n" + + " System.out.println(day.toString());\n" + + " }\n" + + " }\n" + + " public static void main(String[] args) {\n" + + " bar(MyDay.SUNDAY);\n" + + " }\n" + + "}\n" + + "enum MyDay { SATURDAY, SUNDAY}"); + CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true); + requestor.allowAllRequiredProposals(); + String str = this.workingCopies[0].getSource(); + String completeBehind = "SATURDAY, SUN"; + int cursorLocation = str.indexOf(completeBehind) + completeBehind.length(); + this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner); + assertResults( + "SUNDAY[FIELD_REF]{SUNDAY, LMyDay;, LMyDay;, SUNDAY, null, "+ + (RelevanceConstants.R_DEFAULT + RelevanceConstants.R_RESOLVED + RelevanceConstants.R_INTERESTING+ + RelevanceConstants.R_CASE + RelevanceConstants.R_EXACT_EXPECTED_TYPE + + RelevanceConstants.R_ENUM + RelevanceConstants.R_ENUM_CONSTANT + + RelevanceConstants.R_UNQUALIFIED + RelevanceConstants.R_NON_RESTRICTED)+ "}", + requestor.getResults()); + } + public void test003() throws JavaModelException { + this.workingCopies = new ICompilationUnit[1]; + this.workingCopies[0] = getWorkingCopy( + "/Completion/src/Switch.java", + "public class Switch {\n" + + " public static void bar(MyDay day) {\n" + + " switch (day) {\n" + + " case SATU -> \n" + + " System.out.println(day.toString());\n" + + " }\n" + + " }\n" + + " public static void main(String[] args) {\n" + + " bar(MyDay.SUNDAY);\n" + + " }\n" + + "}\n" + + "enum MyDay { SATURDAY, SUNDAY}"); + CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true); + requestor.allowAllRequiredProposals(); + String str = this.workingCopies[0].getSource(); + String completeBehind = "SATU"; + int cursorLocation = str.indexOf(completeBehind) + completeBehind.length(); + this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner); + assertResults( + "SATURDAY[FIELD_REF]{SATURDAY, LMyDay;, LMyDay;, SATURDAY, null, "+ + (RelevanceConstants.R_DEFAULT + RelevanceConstants.R_RESOLVED + RelevanceConstants.R_INTERESTING+ + RelevanceConstants.R_CASE + RelevanceConstants.R_EXACT_EXPECTED_TYPE + + RelevanceConstants.R_ENUM + RelevanceConstants.R_ENUM_CONSTANT + + RelevanceConstants.R_UNQUALIFIED + RelevanceConstants.R_NON_RESTRICTED)+ "}", + requestor.getResults()); + } + public void test004() throws JavaModelException { + this.workingCopies = new ICompilationUnit[1]; + this.workingCopies[0] = getWorkingCopy( + "/Completion/src/Switch.java", + "public class Switch {\n" + + " public static void bar(MyDay day) {\n" + + " switch (day) {\n" + + " case SATURDAY, SUNDAY, MOND -> \n" + + " System.out.println(day.toString());\n" + + " }\n" + + " }\n" + + " public static void main(String[] args) {\n" + + " bar(MyDay.SUNDAY);\n" + + " }\n" + + "}\n" + + "enum MyDay { SATURDAY, SUNDAY, MONDAY}"); + CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true); + requestor.allowAllRequiredProposals(); + String str = this.workingCopies[0].getSource(); + String completeBehind = "MOND"; + int cursorLocation = str.indexOf(completeBehind) + completeBehind.length(); + this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner); + assertResults( + "MONDAY[FIELD_REF]{MONDAY, LMyDay;, LMyDay;, MONDAY, null, "+ + (RelevanceConstants.R_DEFAULT + RelevanceConstants.R_RESOLVED + RelevanceConstants.R_INTERESTING+ + RelevanceConstants.R_CASE + RelevanceConstants.R_EXACT_EXPECTED_TYPE + + RelevanceConstants.R_ENUM + RelevanceConstants.R_ENUM_CONSTANT + + RelevanceConstants.R_UNQUALIFIED + RelevanceConstants.R_NON_RESTRICTED)+ "}", + requestor.getResults()); + } + public void test005() throws JavaModelException { + this.workingCopies = new ICompilationUnit[1]; + this.workingCopies[0] = getWorkingCopy( + "/Completion/src/Switch.java", + "public class Switch {\n" + + " public static void bar(MyDay day) {\n" + + " switch (day) {\n" + + " case SATURDAY, SUND, MONDAY -> \n" + + " System.out.println(day.toString());\n" + + " }\n" + + " }\n" + + " public static void main(String[] args) {\n" + + " bar(MyDay.SUNDAY);\n" + + " }\n" + + "}\n" + + "enum MyDay { SATURDAY, SUNDAY, MONDAY}"); + CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true); + requestor.allowAllRequiredProposals(); + String str = this.workingCopies[0].getSource(); + String completeBehind = "SUND"; + int cursorLocation = str.indexOf(completeBehind) + completeBehind.length(); + this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner); + assertResults( + "SUNDAY[FIELD_REF]{SUNDAY, LMyDay;, LMyDay;, SUNDAY, null, "+ + (RelevanceConstants.R_DEFAULT + RelevanceConstants.R_RESOLVED + RelevanceConstants.R_INTERESTING+ + RelevanceConstants.R_CASE + RelevanceConstants.R_EXACT_EXPECTED_TYPE + + RelevanceConstants.R_ENUM + RelevanceConstants.R_ENUM_CONSTANT + + RelevanceConstants.R_UNQUALIFIED + RelevanceConstants.R_NON_RESTRICTED)+ "}", + requestor.getResults()); + } + public void test005a() throws JavaModelException { + this.workingCopies = new ICompilationUnit[1]; + this.workingCopies[0] = getWorkingCopy( + "/Completion/src/Switch.java", + "public class Switch {\n" + + " public static void bar(MyDay day) {\n" + + " switch (day) {\n" + + " case SATURDAY, SUNDAY -> \n" + + " System.out.println(day.toString());\n" + + " case MON -> \n" + + " System.out.println(day.toString());\n" + + " }\n" + + " }\n" + + " public static void main(String[] args) {\n" + + " bar(MyDay.SUNDAY);\n" + + " }\n" + + "}\n" + + "enum MyDay { SATURDAY, SUNDAY, MONDAY}"); + CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true); + requestor.allowAllRequiredProposals(); + String str = this.workingCopies[0].getSource(); + String completeBehind = "case MON"; + int cursorLocation = str.indexOf(completeBehind) + completeBehind.length(); + this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner); + assertResults( + "MONDAY[FIELD_REF]{MONDAY, LMyDay;, LMyDay;, MONDAY, null, "+ + (RelevanceConstants.R_DEFAULT + RelevanceConstants.R_RESOLVED + RelevanceConstants.R_INTERESTING+ + RelevanceConstants.R_CASE + RelevanceConstants.R_EXACT_EXPECTED_TYPE + + RelevanceConstants.R_ENUM + RelevanceConstants.R_ENUM_CONSTANT + + RelevanceConstants.R_UNQUALIFIED + RelevanceConstants.R_NON_RESTRICTED)+ "}", + requestor.getResults()); + } + public void test006() throws JavaModelException { + this.workingCopies = new ICompilationUnit[1]; + this.workingCopies[0] = getWorkingCopy( + "/Completion/src/Switch.java", + "public class Switch {\n" + + " public static void bar(MyDay day) {\n" + + " switch (day.toS) {\n" + + " case \"SATURDAY\" -> \n" + + " System.out.println(day.toString());\n" + + " }\n" + + " }\n" + + " public static void main(String[] args) {\n" + + " bar(MyDay.SUNDAY);\n" + + " }\n" + + "}\n" + + "enum MyDay { SATURDAY, SUNDAY}"); + CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true); + requestor.allowAllRequiredProposals(); + String str = this.workingCopies[0].getSource(); + String completeBehind = "day.toS"; + int cursorLocation = str.indexOf(completeBehind) + completeBehind.length(); + this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner); + assertResults( + "toString[METHOD_REF]{toString(), Ljava.lang.Object;, ()Ljava.lang.String;, toString, null, 60}", + requestor.getResults()); + } + public void test007() throws JavaModelException { + this.workingCopies = new ICompilationUnit[1]; + this.workingCopies[0] = getWorkingCopy( + "/Completion/src/Switch.java", + "public class Switch {\n" + + " public static void bar(MyDay day) {\n" + + " switch (day.o) {\n" + + " case 0 -> \n" + + " System.out.println(day.toString());\n" + + " }\n" + + " }\n" + + " public static void main(String[] args) {\n" + + " bar(MyDay.SUNDAY);\n" + + " }\n" + + "}\n" + + "enum MyDay { SATURDAY, SUNDAY}"); + CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true); + requestor.allowAllRequiredProposals(); + String str = this.workingCopies[0].getSource(); + String completeBehind = "day.o"; + int cursorLocation = str.indexOf(completeBehind) + completeBehind.length(); + this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner); + assertResults( + "ordinal[METHOD_REF]{ordinal(), Ljava.lang.Enum<LMyDay;>;, ()I, ordinal, null, 60}", + requestor.getResults()); + } + public void test008() throws JavaModelException { + this.workingCopies = new ICompilationUnit[1]; + this.workingCopies[0] = getWorkingCopy( + "/Completion/src/Switch.java", + "public class Switch {\n" + + " public static void bar(MyDay day) {\n" + + " switch (1 + day.o) {\n" + + " case 0 -> \n" + + " System.out.println(day.toString());\n" + + " }\n" + + " }\n" + + " public static void main(String[] args) {\n" + + " bar(MyDay.SUNDAY);\n" + + " }\n" + + "}\n" + + "enum MyDay { SATURDAY, SUNDAY}"); + CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true); + requestor.allowAllRequiredProposals(); + String str = this.workingCopies[0].getSource(); + String completeBehind = "day.o"; + int cursorLocation = str.indexOf(completeBehind) + completeBehind.length(); + this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner); + assertResults( + "ordinal[METHOD_REF]{ordinal(), Ljava.lang.Enum<LMyDay;>;, ()I, ordinal, null, 90}", + requestor.getResults()); + } + public void test009() throws JavaModelException { + this.workingCopies = new ICompilationUnit[1]; + this.workingCopies[0] = getWorkingCopy( + "/Completion/src/Switch.java", + "public class Switch {\n" + + " public static void bar(MyDay day) {\n" + + " switch (1 + da) {\n" + + " case 0 -> \n" + + " System.out.println(day.toString());\n" + + " }\n" + + " }\n" + + " public static void main(String[] args) {\n" + + " bar(MyDay.SUNDAY);\n" + + " }\n" + + "}\n" + + "enum MyDay { SATURDAY, SUNDAY}"); + CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true); + requestor.allowAllRequiredProposals(); + String str = this.workingCopies[0].getSource(); + String completeBehind = "1 + da"; + int cursorLocation = str.indexOf(completeBehind) + completeBehind.length(); + this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner); + assertResults( + "day[LOCAL_VARIABLE_REF]{day, null, LMyDay;, day, null, 52}", + requestor.getResults()); + } + public void test010() throws JavaModelException { + this.workingCopies = new ICompilationUnit[1]; + this.workingCopies[0] = getWorkingCopy( + "/Completion/src/Switch.java", + "public class Switch {\n" + + " public static void bar(MyDay day) {\n" + + " switch (1 + da + 1) {\n" + + " case 0 -> \n" + + " System.out.println(day.toString());\n" + + " }\n" + + " }\n" + + " public static void main(String[] args) {\n" + + " bar(MyDay.SUNDAY);\n" + + " }\n" + + "}\n" + + "enum MyDay { SATURDAY, SUNDAY}"); + CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true); + requestor.allowAllRequiredProposals(); + String str = this.workingCopies[0].getSource(); + String completeBehind = "1 + da"; + int cursorLocation = str.indexOf(completeBehind) + completeBehind.length(); + this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner); + assertResults( + "day[LOCAL_VARIABLE_REF]{day, null, LMyDay;, day, null, 52}", + requestor.getResults()); + } + public void test011() throws JavaModelException { + this.workingCopies = new ICompilationUnit[1]; + this.workingCopies[0] = getWorkingCopy( + "/Completion/src/Switch.java", + "public class Switch {\n" + + " public static void bar(int arg0) {\n" + + " foo(\n" + + " switch (arg) {\n" + + " case 1 -> 1;\n" + + " default -> 0;\n" + + " }\n" + + " });\n" + + " public static void foo(int arg0) {\n" + + " bar(MyDay.SUNDAY);\n" + + " }\n" + + "}\n"); + CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true); + requestor.allowAllRequiredProposals(); + String str = this.workingCopies[0].getSource(); + String completeBehind = "switch (arg"; + int cursorLocation = str.indexOf(completeBehind) + completeBehind.length(); + this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner); + assertResults( + "arg0[LOCAL_VARIABLE_REF]{arg0, null, I, arg0, null, 52}", + requestor.getResults()); + } + public void test012() throws JavaModelException { + this.workingCopies = new ICompilationUnit[1]; + this.workingCopies[0] = getWorkingCopy( + "/Completion/src/Switch.java", + "public class Switch {\n" + + " public static void bar(int arg0) {\n" + + " foo(\n" + + " switch (arg0) {\n" + + " case 1 -> arg;\n" + + " default -> 0;\n" + + " }\n" + + " });\n" + + " public static void foo(int arg0) {\n" + + " bar(MyDay.SUNDAY);\n" + + " }\n" + + "}\n"); + CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true); + requestor.allowAllRequiredProposals(); + String str = this.workingCopies[0].getSource(); + String completeBehind = "-> arg"; + int cursorLocation = str.indexOf(completeBehind) + completeBehind.length(); + this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner); + assertResults( + "arg0[LOCAL_VARIABLE_REF]{arg0, null, I, arg0, null, 52}", + requestor.getResults()); + } + public void test013() throws JavaModelException { + this.workingCopies = new ICompilationUnit[1]; + this.workingCopies[0] = getWorkingCopy( + "/Completion/src/Switch.java", + "public class Switch {\n" + + " public static void bar(int arg0) {\n" + + " foo(\n" + + " switch (0 + arg) {\n" + + " case 1 -> 1;\n" + + " default -> 0;\n" + + " }\n" + + " });\n" + + " public static void foo(int arg0) {\n" + + " bar(MyDay.SUNDAY);\n" + + " }\n" + + "}\n"); + CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true); + requestor.allowAllRequiredProposals(); + String str = this.workingCopies[0].getSource(); + String completeBehind = "0 + arg"; + int cursorLocation = str.indexOf(completeBehind) + completeBehind.length(); + this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner); + assertResults( + "arg0[LOCAL_VARIABLE_REF]{arg0, null, I, arg0, null, 82}", + requestor.getResults()); + } + public void test014() throws JavaModelException { + this.workingCopies = new ICompilationUnit[1]; + this.workingCopies[0] = getWorkingCopy( + "/Completion/src/X.java", + "public class X {\n" + + " public static void bar(int arg0) {\n" + + " foo(\n" + + " swi);\n" + + " public static void foo(int arg0) {\n" + + " bar(MyDay.SUNDAY);\n" + + " }\n" + + "}\n"); + CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true); + requestor.allowAllRequiredProposals(); + String str = this.workingCopies[0].getSource(); + String completeBehind = "swi"; + int cursorLocation = str.indexOf(completeBehind) + completeBehind.length(); + this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner); + assertResults( + "switch[KEYWORD]{switch, null, null, switch, null, 49}", + requestor.getResults()); + } + public void _test015() throws JavaModelException { + this.workingCopies = new ICompilationUnit[1]; + this.workingCopies[0] = getWorkingCopy( + "/Completion/src/X.java", + "public class Switch {\n" + + " public static void bar(int arg0) {\n" + + " foo(\n" + + " switch (0 + arg0) {\n" + + " case 1 -> {break ar;}\n" + + " default -> 0;\n" + + " }\n" + + " });\n" + + " public static void foo(int arg0) {\n" + + " bar(MyDay.SUNDAY);\n" + + " }\n" + + "}\n"); + CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true); + requestor.allowAllRequiredProposals(); + String str = this.workingCopies[0].getSource(); + String completeBehind = "break ar"; + int cursorLocation = str.indexOf(completeBehind) + completeBehind.length(); + this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner); + assertResults( + "arg0[LOCAL_VARIABLE_REF]{arg0, null, I, arg0, null, 52}", + requestor.getResults()); + } + public void test016() throws JavaModelException { + this.workingCopies = new ICompilationUnit[1]; + this.workingCopies[0] = getWorkingCopy( + "/Completion/src/X.java", + "public class Switch {\n" + + " public static void bar(int arg0) {\n" + + " foo(\n" + + " switch (0 + arg0) {\n" + + " case 1 -> {break 1;}\n" + + " default -> ar;\n" + + " }\n" + + " });\n" + + " public static void foo(int arg0) {\n" + + " bar(MyDay.SUNDAY);\n" + + " }\n" + + "}\n"); + CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true); + requestor.allowAllRequiredProposals(); + String str = this.workingCopies[0].getSource(); + String completeBehind = "-> ar"; + int cursorLocation = str.indexOf(completeBehind) + completeBehind.length(); + this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner); + assertResults( + "arg0[LOCAL_VARIABLE_REF]{arg0, null, I, arg0, null, 52}", + requestor.getResults()); + } + public void _test017() throws JavaModelException { + this.workingCopies = new ICompilationUnit[1]; + this.workingCopies[0] = getWorkingCopy( + "/Completion/src/X.java", + "public class Switch {\n" + + " public static void bar(int arg0) {\n" + + " int arg1 = 0;\n" + + " foo(\n" + + " switch (0 + arg0) {\n" + + " case 1 -> 1;\n" + + " default -> {break ar;}\n" + + " }\n" + + " });\n" + + " public static void foo(int arg0) {\n" + + " bar(MyDay.SUNDAY);\n" + + " }\n" + + "}\n"); + CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true); + requestor.allowAllRequiredProposals(); + String str = this.workingCopies[0].getSource(); + String completeBehind = "break ar"; + int cursorLocation = str.indexOf(completeBehind) + completeBehind.length(); + this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner); + assertResults( + "arg0[LOCAL_VARIABLE_REF]{arg0, null, I, arg0, null, 52}", + requestor.getResults()); + } + public void _test017a() throws JavaModelException { + this.workingCopies = new ICompilationUnit[1]; + this.workingCopies[0] = getWorkingCopy( + "/Completion/src/X.java", + "public class Switch {\n" + + " public static void bar(int arg0) {\n" + + " foo(\n" + + " argLabel: switch (0 + arg0) {\n" + + " case 1 -> 1;\n" + + " default -> {break ar;}\n" + + " }\n" + + " });\n" + + " public static void foo(int arg0) {\n" + + " bar(MyDay.SUNDAY);\n" + + " }\n" + + "}\n"); + CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true); + requestor.allowAllRequiredProposals(); + String str = this.workingCopies[0].getSource(); + String completeBehind = "break ar"; + int cursorLocation = str.indexOf(completeBehind) + completeBehind.length(); + this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner); + assertResults( + "arg0[LOCAL_VARIABLE_REF]{arg0, null, I, arg0, null, 52}\n" + + "argLabel[LABEL_REF]{argLabel, null, null, argLabel, null, 49}", + requestor.getResults()); + } + public void test018a() throws JavaModelException { + this.workingCopies = new ICompilationUnit[1]; + this.workingCopies[0] = getWorkingCopy( + "/Completion/src/X.java", + "import org.eclipse.jdt.annotation.*;\n" + + "import java.util.function.*;\n" + + "interface IN0 {} \n" + + "interface IN1 extends IN0 {} \n" + + "interface IN2 extends IN0 {}\n" + + "public class X {\n" + + " @NonNull IN1 n_1() { return new IN1() {}; } \n" + + " IN2 n_2() { return null; } \n" + + " <M> void m(@NonNull Supplier<@NonNull M> m2) { } \n" + + " void testSw(int i) { \n" + + " m(switch(i) { \n" + + " case 1 -> this::n_; \n" + + " case 2 -> () -> n1(); \n" + + " case 3 -> null; \n" + + " case 4 -> () -> n2(); \n" + + " default -> this::n2; }); \n" + + " }\n" + + "}"); + CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true); + requestor.allowAllRequiredProposals(); + String str = this.workingCopies[0].getSource(); + String completeBehind = "this::n_"; + int cursorLocation = str.indexOf(completeBehind) + completeBehind.length(); + this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner); + assertResults( + "n_1[METHOD_NAME_REFERENCE]{n_1, LX;, ()LIN1;, n_1, null, 60}\n" + + "n_2[METHOD_NAME_REFERENCE]{n_2, LX;, ()LIN2;, n_2, null, 60}", + requestor.getResults()); + } + public void test018b() throws JavaModelException { + this.workingCopies = new ICompilationUnit[1]; + this.workingCopies[0] = getWorkingCopy( + "/Completion/src/X.java", + "import org.eclipse.jdt.annotation.*;\n" + + "interface IN0 {} \n" + + "interface IN1 extends IN0 {} \n" + + "interface IN2 extends IN0 {}\n" + + "public class X {\n" + + " @NonNull IN1 n_1() { return new IN1() {}; } \n" + + " IN2 n_2() { return null; } \n" + + " <M> void m(@NonNull Supplier<@NonNull M> m2) { } \n" + + " void testSw(int i) { \n" + + " m(switch(i) { \n" + + " case 2 -> () -> n_; \n" + + " }\n" + + "}\n" + + "interface Supplier<T> {\n" + + " T get();\n" + + "}"); + CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true); + requestor.allowAllRequiredProposals(); + String str = this.workingCopies[0].getSource(); + String completeBehind = "-> n_"; + int cursorLocation = str.indexOf(completeBehind) + completeBehind.length(); + this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner); + assertResults( + "n_1[METHOD_REF]{n_1(), LX;, ()LIN1;, n_1, null, 52}\n" + + "n_2[METHOD_REF]{n_2(), LX;, ()LIN2;, n_2, null, 52}", + requestor.getResults()); + } + public void test018c() throws JavaModelException { + this.workingCopies = new ICompilationUnit[1]; + this.workingCopies[0] = getWorkingCopy( + "/Completion/src/X.java", + "import org.eclipse.jdt.annotation.*;\n" + + "interface IN0 {} \n" + + "interface IN1 extends IN0 {} \n" + + "interface IN2 extends IN0 {}\n" + + "public class X {\n" + + " @NonNull IN1 n_1() { return new IN1() {}; } \n" + + " IN2 n_2() { return null; } \n" + + " <M> void m(@NonNull Supplier<@NonNull M> m2) { } \n" + + " void testSw(int i) { \n" + + " m(switch(i) { \n" + + " default -> this::n_; }); \n" + + " }\n" + + "}\n" + + "interface Supplier<T> {\n" + + " T get();\n" + + "}"); + CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true); + requestor.allowAllRequiredProposals(); + String str = this.workingCopies[0].getSource(); + String completeBehind = "this::n_"; + int cursorLocation = str.indexOf(completeBehind) + completeBehind.length(); + this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner); + assertResults( + "n_1[METHOD_NAME_REFERENCE]{n_1, LX;, ()LIN1;, n_1, null, 60}\n" + + "n_2[METHOD_NAME_REFERENCE]{n_2, LX;, ()LIN2;, n_2, null, 60}", + requestor.getResults()); + } + public void test018d() throws JavaModelException { + this.workingCopies = new ICompilationUnit[1]; + this.workingCopies[0] = getWorkingCopy( + "/Completion/src/X.java", + "import org.eclipse.jdt.annotation.*;\n" + + "interface IN0 {} \n" + + "interface IN1 extends IN0 {} \n" + + "interface IN2 extends IN0 {}\n" + + "public class X {\n" + + " @NonNull IN1 n_1() { return new IN1() {}; } \n" + + " IN2 n_2() { return null; } \n" + + " <M> void m(@NonNull Supplier<@NonNull M> m2) { } \n" + + " void testSw(int i) { \n" + + " m(switch(i) { \n" + + " default -> () -> n_; }); \n" + + " }\n" + + "}\n" + + "interface Supplier<T> {\n" + + " T get();\n" + + "}"); + CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true); + requestor.allowAllRequiredProposals(); + String str = this.workingCopies[0].getSource(); + String completeBehind = "() -> n_"; + int cursorLocation = str.indexOf(completeBehind) + completeBehind.length(); + this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner); + assertResults( + "n_1[METHOD_REF]{n_1(), LX;, ()LIN1;, n_1, null, 52}\n" + + "n_2[METHOD_REF]{n_2(), LX;, ()LIN2;, n_2, null, 52}", + requestor.getResults()); + } + public void test018e() throws JavaModelException { + this.workingCopies = new ICompilationUnit[1]; + this.workingCopies[0] = getWorkingCopy( + "/Completion/src/X.java", + "import org.eclipse.jdt.annotation.*;\n" + + "interface IN0 {} \n" + + "interface IN1 extends IN0 {} \n" + + "interface IN2 extends IN0 {}\n" + + "public class X {\n" + + " @NonNull IN1 n_1() { return new IN1() {}; } \n" + + " IN2 n_2() { return null; } \n" + + " <M> void m(@NonNull Supplier<@NonNull M> m2) { } \n" + + " void testSw(int i) { \n" + + " m(switch(i) { \n" + + " case 1 -> this::n_1; \n" + + " case 2 -> () -> n_; \n" + + " }\n" + + "}\n" + + "interface Supplier<T> {\n" + + " T get();\n" + + "}"); + CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true); + requestor.allowAllRequiredProposals(); + String str = this.workingCopies[0].getSource(); + String completeBehind = "() -> n_"; + int cursorLocation = str.indexOf(completeBehind) + completeBehind.length(); + this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner); + assertResults( + "n_1[LOCAL_VARIABLE_REF]{n_1, null, Ljava.lang.Object;, n_1, null, 51}\n" + + "n_1[METHOD_REF]{n_1(), LX;, ()LIN1;, n_1, null, 52}\n" + + "n_2[METHOD_REF]{n_2(), LX;, ()LIN2;, n_2, null, 52}", + requestor.getResults()); + } + public void test018f() throws JavaModelException { + this.workingCopies = new ICompilationUnit[1]; + this.workingCopies[0] = getWorkingCopy( + "/Completion/src/X.java", + "import org.eclipse.jdt.annotation.*;\n" + + "interface IN0 {} \n" + + "interface IN1 extends IN0 {} \n" + + "interface IN2 extends IN0 {}\n" + + "public class X {\n" + + " @NonNull IN1 n_1() { return new IN1() {}; } \n" + + " IN2 n_2() { return null; } \n" + + " <M> void m(@NonNull Supplier<@NonNull M> m2) { } \n" + + " void testSw(int i) { \n" + + " m(switch(i) { \n" + + " case 1 -> () -> n_1; \n" + + " case 2 -> this::n_; \n" + + " }\n" + + "}\n" + + "interface Supplier<T> {\n" + + " T get();\n" + + "}"); + CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true); + requestor.allowAllRequiredProposals(); + String str = this.workingCopies[0].getSource(); + String completeBehind = "this::n_"; + int cursorLocation = str.indexOf(completeBehind) + completeBehind.length(); + this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner); + assertResults( + "n_1[METHOD_NAME_REFERENCE]{n_1, LX;, ()LIN1;, n_1, null, 60}\n" + + "n_2[METHOD_NAME_REFERENCE]{n_2, LX;, ()LIN2;, n_2, null, 60}", + requestor.getResults()); + } + public void test019() throws JavaModelException { + this.workingCopies = new ICompilationUnit[1]; + this.workingCopies[0] = getWorkingCopy( + "/Completion/src/X.java", + "import org.eclipse.jdt.annotation.*;\n" + + " <M> void m(@NonNull Supplier<@NonNull M> m2) { } \n" + + "public class X {\n" + + " void testSw(int i) { \n" + + " m(swi);\n" + + "}\n" + + "interface Supplier<T> {\n" + + " T get();\n" + + "}"); + CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true); + requestor.allowAllRequiredProposals(); + String str = this.workingCopies[0].getSource(); + String completeBehind = "swi"; + int cursorLocation = str.indexOf(completeBehind) + completeBehind.length(); + this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner); + assertResults( + "switch[KEYWORD]{switch, null, null, switch, null, 49}", + requestor.getResults()); + } + public void test020() throws JavaModelException { + this.workingCopies = new ICompilationUnit[1]; + this.workingCopies[0] = getWorkingCopy( + "/Completion/src/X.java", + "public class X {\n" + + " static final String MONDAY = \"MONDAY\";\n" + + " static final String TUESDAY = \"TUESDAY\";\n" + + " static final String WEDNESDAY = \"WEDNESDAY\";\n" + + " static final String THURSDAY = \"THURSDAY\";\n" + + " static final String FRIDAY = \"FRIDAY\";\n" + + " static final String SATURDAY = \"SATURDAY\";\n" + + " static final String SUNDAY = \"SUNDAY\"; \n" + + " @SuppressWarnings(\"preview\")\n" + + " public static void main(String[] args) {\n" + + " String day = \"MONDAY\";\n" + + " switch (day) {\n" + + " case MONDAY, FRIDAY, SUNDAY -> System.out.println(6);\n" + + " case TUESDAY -> System.out.println(7);\n" + + " case THURSDAY, SATURDAY -> System.out.println(8);\n" + + " case WEDNESDAY -> System.out.println(9);\n" + + " }\n" + + " int k = switch (day) {\n" + + " case MONDAY -> throw new NullPointerException();\n" + + " case TUESDAY -> 1;\n" + + " case WEDNESDAY -> {break 10;}\n" + + " default -> {\n" + + " int g = day.h();\n" + + " int result = f(g);\n" + + " break result;\n" + + " }};\n" + + " }\n" + + " static int f(int k) {\n" + + " return k*k;\n" + + " }\n" + + "}"); + CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true); + requestor.allowAllRequiredProposals(); + String str = this.workingCopies[0].getSource(); + String completeBehind = "day.h"; + int cursorLocation = str.indexOf(completeBehind) + completeBehind.length(); + this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner); + assertResults( + "hashCode[METHOD_REF]{hashCode, Ljava.lang.Object;, ()I, hashCode, null, 90}", + requestor.getResults()); + } + public void test021() throws JavaModelException { + this.workingCopies = new ICompilationUnit[1]; + this.workingCopies[0] = getWorkingCopy( + "/Completion/src/X.java", + "public class X {\n" + + " static final String MONDAY = \"MONDAY\";\n" + + " static final String TUESDAY = \"TUESDAY\";\n" + + " static final String WEDNESDAY = \"WEDNESDAY\";\n" + + " static final String THURSDAY = \"THURSDAY\";\n" + + " static final String FRIDAY = \"FRIDAY\";\n" + + " static final String SATURDAY = \"SATURDAY\";\n" + + " static final String SUNDAY = \"SUNDAY\"; \n" + + " @SuppressWarnings(\"preview\")\n" + + " public static void main(String[] args) {\n" + + " String day = \"MONDAY\";\n" + + " int k = switch (day) {\n" + + " case MONDAY -> throw new NullPointerException();\n" + + " case TUESDAY -> 1;\n" + + " case WEDNESDAY -> {break 10;}\n" + + " default -> {\n" + + " int g = day.h();\n" + + " int result = f(g);\n" + + " break result;\n" + + " }};\n" + + " }\n" + + " static int f(int k) {\n" + + " return k*k;\n" + + " }\n" + + "}"); + CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true); + requestor.allowAllRequiredProposals(); + String str = this.workingCopies[0].getSource(); + String completeBehind = "day.h"; + int cursorLocation = str.indexOf(completeBehind) + completeBehind.length(); + this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner); + assertResults( + "hashCode[METHOD_REF]{hashCode, Ljava.lang.Object;, ()I, hashCode, null, 90}", + requestor.getResults()); + } +} diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaCoreOptionsTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaCoreOptionsTests.java index e5d2894558..b1dee23648 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaCoreOptionsTests.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaCoreOptionsTests.java @@ -6,6 +6,10 @@ * which accompanies this distribution, and is available at * https://www.eclipse.org/legal/epl-2.0/ * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * SPDX-License-Identifier: EPL-2.0 * * Contributors: @@ -120,10 +124,11 @@ public void test5() { assertTrue(JavaCore.compareJavaVersions("9", "1.8") > 0); assertTrue(JavaCore.compareJavaVersions("9.0.1", "9.1.2") == 0); assertTrue(JavaCore.compareJavaVersions("9", "9.1.2") == 0); + assertTrue(JavaCore.compareJavaVersions("12", "11") > 0); + assertTrue(JavaCore.compareJavaVersions("12", "1.5") > 0); String latest = JavaCore.latestSupportedJavaVersion(); String latestPlus = "" + (Integer.parseInt(latest) + 1); assertTrue(JavaCore.compareJavaVersions(latest, latestPlus) == 0); - } } diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugs12Tests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugs12Tests.java new file mode 100644 index 0000000000..ee0bf13582 --- /dev/null +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugs12Tests.java @@ -0,0 +1,630 @@ +/******************************************************************************* + * Copyright (c) 2019 IBM Corporation and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.core.tests.model; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.jdt.core.ICompilationUnit; +import org.eclipse.jdt.core.IJavaElement; +import org.eclipse.jdt.core.IJavaProject; +import org.eclipse.jdt.core.IPackageFragment; +import org.eclipse.jdt.core.IType; +import org.eclipse.jdt.core.JavaCore; +import org.eclipse.jdt.core.JavaModelException; +import org.eclipse.jdt.core.WorkingCopyOwner; +import org.eclipse.jdt.core.search.IJavaSearchScope; +import org.eclipse.jdt.core.search.ReferenceMatch; +import org.eclipse.jdt.core.search.SearchEngine; +import org.eclipse.jdt.core.search.SearchMatch; +import org.eclipse.jdt.core.search.TypeReferenceMatch; + +import junit.framework.Test; + +public class JavaSearchBugs12Tests extends AbstractJavaSearchTests { + + static { +// org.eclipse.jdt.internal.core.search.BasicSearchEngine.VERBOSE = true; +// TESTS_NUMBERS = new int[] { 19 }; +// TESTS_RANGE = new int[] { 1, -1 }; +// TESTS_NAMES = new String[] {"testBug542559_001"}; +} + +public JavaSearchBugs12Tests(String name) { + super(name); + this.endChar = ""; +} +public static Test suite() { + return buildModelTestSuite(JavaSearchBugs12Tests.class, BYTECODE_DECLARATION_ORDER); +} +class TestCollector extends JavaSearchResultCollector { + public void acceptSearchMatch(SearchMatch searchMatch) throws CoreException { + super.acceptSearchMatch(searchMatch); + } +} +class ReferenceCollector extends JavaSearchResultCollector { + protected void writeLine() throws CoreException { + super.writeLine(); + ReferenceMatch refMatch = (ReferenceMatch) this.match; + IJavaElement localElement = refMatch.getLocalElement(); + if (localElement != null) { + this.line.append("+["); + if (localElement.getElementType() == IJavaElement.ANNOTATION) { + this.line.append('@'); + this.line.append(localElement.getElementName()); + this.line.append(" on "); + this.line.append(localElement.getParent().getElementName()); + } else { + this.line.append(localElement.getElementName()); + } + this.line.append(']'); + } + } + +} +class TypeReferenceCollector extends ReferenceCollector { + protected void writeLine() throws CoreException { + super.writeLine(); + TypeReferenceMatch typeRefMatch = (TypeReferenceMatch) this.match; + IJavaElement[] others = typeRefMatch.getOtherElements(); + int length = others==null ? 0 : others.length; + if (length > 0) { + this.line.append("+["); + for (int i=0; i<length; i++) { + IJavaElement other = others[i]; + if (i>0) this.line.append(','); + if (other.getElementType() == IJavaElement.ANNOTATION) { + this.line.append('@'); + this.line.append(other.getElementName()); + this.line.append(" on "); + this.line.append(other.getParent().getElementName()); + } else { + this.line.append(other.getElementName()); + } + } + this.line.append(']'); + } + } +} + +IJavaSearchScope getJavaSearchScope() { + return SearchEngine.createJavaSearchScope(new IJavaProject[] {getJavaProject("JavaSearchBugs")}); +} +IJavaSearchScope getJavaSearchScopeBugs(String packageName, boolean addSubpackages) throws JavaModelException { + if (packageName == null) return getJavaSearchScope(); + return getJavaSearchPackageScope("JavaSearchBugs", packageName, addSubpackages); +} +public ICompilationUnit getWorkingCopy(String path, String source) throws JavaModelException { + if (this.wcOwner == null) { + this.wcOwner = new WorkingCopyOwner() {}; + } + return getWorkingCopy(path, source, this.wcOwner); +} +@Override +public void setUpSuite() throws Exception { + super.setUpSuite(); + JAVA_PROJECT = setUpJavaProject("JavaSearchBugs", "12"); +} +public void tearDownSuite() throws Exception { + deleteProject("JavaSearchBugs"); + super.tearDownSuite(); +} +protected void setUp () throws Exception { + super.setUp(); + this.resultCollector = new TestCollector(); + this.resultCollector.showAccuracy(true); +} + +public void testBug542559_001() throws CoreException { + this.workingCopies = new ICompilationUnit[1]; + this.workingCopies[0] = getWorkingCopy("/JavaSearchBugs/src/X.java", + "public class X {\n" + + " int switch_expr_field = 10;\n" + + " int twice(int i) {\n" + + " int tw = switch (i) {\n" + + " case 0 -> switch_expr_field * 0;\n" + + " case 1 -> 2;\n" + + " default -> 3;\n" + + " };\n" + + " return tw;\n" + + " }\n" + + " public static void main(String... args) {\n" + + " System.out.print(new X().twice(3));\n" + + " }\n" + + "}\n" + ); + IJavaProject javaProject = this.workingCopies[0].getJavaProject(); //assuming single project for all working copies + String old = javaProject.getOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, true); + try { + javaProject.setOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, JavaCore.ENABLED); + search("switch_expr_field", FIELD, REFERENCES); + assertSearchResults("src/X.java int X.twice(int) [switch_expr_field] EXACT_MATCH"); + } finally { + javaProject.setOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, old); + } +} +public void testBug542559_002() throws CoreException { + this.workingCopies = new ICompilationUnit[1]; + this.workingCopies[0] = getWorkingCopy("/JavaSearchBugs/src/X.java", + "public class X {\n" + + " int switch_expr_field = 10;\n" + + " int twice(int i) {\n" + + " int tw = switch (i) {\n" + + " case 0 -> switch_expr_field * 0;\n" + + " case 1 -> { break switch_expr_field; }\n" + + " default -> 3;\n" + + " };\n" + + " return tw;\n" + + " }\n" + + " public static void main(String... args) {\n" + + " System.out.print(new X().twice(3));\n" + + " }\n" + + "}\n" + ); + IJavaProject javaProject = this.workingCopies[0].getJavaProject(); //assuming single project for all working copies + String old = javaProject.getOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, true); + try { + javaProject.setOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, JavaCore.ENABLED); + search("switch_expr_field", FIELD, REFERENCES); + assertSearchResults( + "src/X.java int X.twice(int) [switch_expr_field] EXACT_MATCH\n" + + "src/X.java int X.twice(int) [switch_expr_field] EXACT_MATCH" + ); + } finally { + javaProject.setOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, old); + } +} +public void testBug542559_003() throws CoreException { + this.workingCopies = new ICompilationUnit[1]; + this.workingCopies[0] = getWorkingCopy("/JavaSearchBugs/src/X.java", + "public class X {\n" + + " int switch_expr_field = 10; \n" + + " int twice(int i) throws Exception { \n" + + " int tw = switch (i) { \n" + + " case 0 -> { break switch_expr_field; } \n" + + " case 4 -> throw new MyException(); \n" + + " default -> 3; \n" + + " }; \n" + + " return tw; \n" + + " } \n" + + " public static void main(String[] args) {\n" + + " try {\n" + + " System.out.print(new X().twice(3));\n" + + " } catch (Exception e) {\n" + + " // TODO Auto-generated catch block\n" + + " e.printStackTrace();\n" + + " }\n" + + " } \n" + + "}\n" + + "class MyException extends Exception {\n" + + " private static final long serialVersionUID = 3461899582505930474L;\n" + + " \n" + + "}\n" + ); + IJavaProject javaProject = this.workingCopies[0].getJavaProject(); //assuming single project for all working copies + String old = javaProject.getOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, true); + try { + javaProject.setOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, JavaCore.ENABLED); + IType type = this.workingCopies[0].getType("MyException"); + search(type, REFERENCES); + assertSearchResults( + "src/X.java int X.twice(int) [MyException] EXACT_MATCH" + ); + } finally { + javaProject.setOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, old); + } +} +/* + * java search reference for an integer in default block of switch expression + */ +public void testBug542559_004() throws CoreException { + this.workingCopies = new ICompilationUnit[1]; + this.workingCopies[0] = getWorkingCopy("/JavaSearchBugs/src/X.java", + "public class X {\n" + + " int switch_expr_field = 10;\n" + + " int twice(int i) {\n" + + " int tw = switch (i) {\n" + + " case 0 -> switch_expr_field * 0;\n" + + " case 1 -> 2;\n" + + " default ->{ \n" + + " switch_expr_field*9; \n" + + " }};\n" + + " return tw;\n" + + " }\n" + + " public static void main(String... args) {\n" + + " System.out.print(new X().twice(3));\n" + + " }\n" + + "}\n" + ); + IJavaProject javaProject = this.workingCopies[0].getJavaProject(); //assuming single project for all working copies + String old = javaProject.getOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, true); + try { + javaProject.setOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, JavaCore.ENABLED); + search("switch_expr_field", FIELD, REFERENCES); + assertSearchResults( + "src/X.java int X.twice(int) [switch_expr_field] EXACT_MATCH\n" + + "src/X.java int X.twice(int) [switch_expr_field] EXACT_MATCH" + ); + } finally { + javaProject.setOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, old); + } +} + +/* + * java search reference for an integer in default of switch expression + */ +public void testBug542559_005() throws CoreException { + this.workingCopies = new ICompilationUnit[1]; + this.workingCopies[0] = getWorkingCopy("/JavaSearchBugs/src/X.java", + "public class X {\n" + + " int switch_expr_field = 10;\n" + + " int twice(int i) {\n" + + " int tw = switch (i) {\n" + + " case 0 -> switch_expr_field * 0;\n" + + " case 1 -> 2;\n" + + " default -> switch_expr_field*9;\n" + + " };\n" + + " return tw;\n" + + " }\n" + + " public static void main(String... args) {\n" + + " System.out.print(new X().twice(3));\n" + + " }\n" + + "}\n" + ); + IJavaProject javaProject = this.workingCopies[0].getJavaProject(); //assuming single project for all working copies + String old = javaProject.getOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, true); + try { + javaProject.setOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, JavaCore.ENABLED); + search("switch_expr_field", FIELD, REFERENCES); + assertSearchResults( + "src/X.java int X.twice(int) [switch_expr_field] EXACT_MATCH\n" + + "src/X.java int X.twice(int) [switch_expr_field] EXACT_MATCH" + ); + } finally { + javaProject.setOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, old); + } +} + +/* + * java search reference for simple multi constant case statement for enum + */ +public void testBug542559_006() throws CoreException { + this.workingCopies = new ICompilationUnit[1]; + this.workingCopies[0] = getWorkingCopy("/JavaSearchBugs/src/X.java", + "public class X {\n" + + "enum Day { SATURDAY, SUNDAY, MONDAY;}\n" + + "public static void bar(Day day) {\n" + + " switch (day) {\n" + + " case SATURDAY, SUNDAY: \n" + + " System.out.println(Day.SUNDAY);\n" + + " break;\n" + + " case MONDAY : System.out.println(Day.MONDAY);\n" + + " break;\n" + + " }\n" + + " }" + + " public static void main(String[] args) {\n" + + " bar(Day.SATURDAY);\n" + + " }\n" + + + "}\n" + ); + IJavaProject javaProject = this.workingCopies[0].getJavaProject(); //assuming single project for all working copies + String old = javaProject.getOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, true); + try { + javaProject.setOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, JavaCore.ENABLED); + search("SATURDAY", FIELD, REFERENCES); + assertSearchResults( + "src/X.java void X.bar(Day) [SATURDAY] EXACT_MATCH\n"+ + "src/X.java void X.main(String[]) [SATURDAY] EXACT_MATCH" + ); + } finally { + javaProject.setOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, old); + } +} +/* + * java search reference for simple multi constant case statement for enum, 2nd case + */ +public void testBug542559_007() throws CoreException { + this.workingCopies = new ICompilationUnit[1]; + this.workingCopies[0] = getWorkingCopy("/JavaSearchBugs/src/X.java", + "public class X {\n" + + "enum Day { SATURDAY, SUNDAY, MONDAY;}\n" + + "public static void bar(Day day) {\n" + + " switch (day) {\n" + + " case SATURDAY, SUNDAY: \n" + + " System.out.println(Day.SUNDAY);\n" + + " break;\n" + + " case MONDAY : System.out.println(Day.MONDAY);\n" + + " break;\n" + + " }\n" + + " }" + + " public static void main(String[] args) {\n" + + " bar(Day.SATURDAY);\n" + + " }\n" + + + "}\n" + ); + IJavaProject javaProject = this.workingCopies[0].getJavaProject(); //assuming single project for all working copies + String old = javaProject.getOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, true); + try { + javaProject.setOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, JavaCore.ENABLED); + search("SUNDAY", FIELD, REFERENCES); + assertSearchResults( + "src/X.java void X.bar(Day) [SUNDAY] EXACT_MATCH\n"+ + "src/X.java void X.bar(Day) [SUNDAY] EXACT_MATCH" + ); + } finally { + javaProject.setOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, old); + } +} + +/* + * java search reference for class file reference in switch expression + */ +public void testBug542559_008() throws CoreException { + this.workingCopies = new ICompilationUnit[1]; + this.workingCopies[0] = getWorkingCopy("/JavaSearchBugs/src/X2.java", + "public class X2 {\n" + + " String s = new String(); \n" + + " int switch_expr_field = 10;\n" + + " int twice(int i) {\n" + + " int tw = switch (i) {\n" + + " case 0 -> switch_expr_field * 0;\n" + + " case 1 -> 2;\n" + + " default -> new X2().toString().length();\n" + + " };\n" + + " return tw;\n" + + " }\n" + + " public static void main(String... args) {\n" + + " System.out.print(new X2().twice(3));\n" + + " }\n" + + "}\n" + ); + IJavaProject javaProject = this.workingCopies[0].getJavaProject(); //assuming single project for all working copies + String old = javaProject.getOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, true); + try { + javaProject.setOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, JavaCore.ENABLED); + search("X2", CLASS, REFERENCES); + assertSearchResults( + "src/X2.java int X2.twice(int) [X2] EXACT_MATCH\n"+ + "src/X2.java void X2.main(String ...) [X2] EXACT_MATCH"); + } finally { + javaProject.setOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, old); + } +} + +/* + * java search reference for class file reference in case and default blocks + */ +public void testBug542559_009() throws CoreException { + this.workingCopies = new ICompilationUnit[1]; + this.workingCopies[0] = getWorkingCopy("/JavaSearchBugs/src/X.java", + "public class X {\n" + + " Integer abcd\n" + + " public static int foo(int i) {\n" + + " final int k;\n" + + "\n" + + " int it = switch (i) { \n" + + " case 1 -> {\n" + + " k = 1;\n" + + " abcd.toString();\n" + + " break k ;\n" + + " }\n" + + " case 2 -> {\n" + + " abcd.toString();\n" + + " break k ;\n" + + " }\n" + + " default -> {\n" + + " k = 3;\n" + + " abcd.toString();\n" + + " break k;\n" + + " }\n" + + " };\n" + + " return k;\n" + + " }\n" + + "\n" + + " public boolean bar() {\n" + + " return true;\n" + + " }\n" + + " public static void main(String[] args) {\n" + + " System.out.println(foo(3));\n" + + " }\n" + + "}\n" + ); + IJavaProject javaProject = this.workingCopies[0].getJavaProject(); //assuming single project for all working copies + String old = javaProject.getOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, true); + try { + javaProject.setOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, JavaCore.ENABLED); + search("abcd", FIELD, REFERENCES); + assertSearchResults( + "src/X.java int X.foo(int) [abcd] EXACT_MATCH\n" + + "src/X.java int X.foo(int) [abcd] EXACT_MATCH\n" + + "src/X.java int X.foo(int) [abcd] EXACT_MATCH" + ); + } finally { + javaProject.setOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, old); + } +} + +/* + * java search reference for string constant in switch expression and switch statement + */ +public void testBug542559_0010() throws CoreException { + this.workingCopies = new ICompilationUnit[1]; + this.workingCopies[0] = getWorkingCopy("/JavaSearchBugs/src/X.java", + "public class X {\n" + + " static final String MONDAY = \"MONDAY\";\n" + + " static final String TUESDAY = \"TUESDAY\";\n" + + " static final String WEDNESDAY = \"WEDNESDAY\";\n" + + " static final String THURSDAY = \"THURSDAY\";\n" + + " static final String FRIDAY = \"FRIDAY\";\n" + + " static final String SATURDAY = \"SATURDAY\";\n" + + " static final String SUNDAY = \"SUNDAY\"; \n" + + " @SuppressWarnings(\"preview\")\n" + + " public static void main(String[] args) {\n" + + " String day = \"MONDAY\";\n" + + " switch (day) {\n" + + " case MONDAY, FRIDAY, SUNDAY -> System.out.println(6);\n" + + " case TUESDAY -> System.out.println(7);\n" + + " case THURSDAY, SATURDAY -> System.out.println(8);\n" + + " case WEDNESDAY -> System.out.println(9);\n" + + " }\n" + + " int k = switch (day) {\n" + + " case SATURDAY -> throw new NullPointerException();\n" + + " case TUESDAY -> 1;\n" + + " case WEDNESDAY -> {break 10;}\n" + + " default -> {\n" + + " int g = day.h();\n" + + " int result = f(g);\n" + + " break result;\n" + + " }};\n" + + " }\n" + + " static int f(int k) {\n" + + " return k*k;\n" + + " }\n" + + "}\n" + ); + IJavaProject javaProject = this.workingCopies[0].getJavaProject(); //assuming single project for all working copies + String old = javaProject.getOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, true); + try { + javaProject.setOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, JavaCore.ENABLED); + search("SATURDAY", FIELD, REFERENCES); + assertSearchResults( + "src/X.java void X.main(String[]) [SATURDAY] EXACT_MATCH\n" + + "src/X.java void X.main(String[]) [SATURDAY] EXACT_MATCH" + ); + } finally { + javaProject.setOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, old); + } +} +/* + * java search a javatype reference from another java project if that is in switch expression + */ +public void testBug542559_0011() throws CoreException { + try { + + IJavaProject project1 = createJavaProject("JavaSearchBugs12", new String[] {"src"}, new String[] {"JCL12_LIB"}, "bin", "12"); + project1.open(null); + createFolder("/JavaSearchBugs12/src/pack1"); + createFile("/JavaSearchBugs12/src/pack1/X11.java", + "package pack1;\n" + + "public class X11 { \n" + + " static final String MONDAY = \"MONDAY\";\n" + + " static final String TUESDAY = \"TUESDAY\";\n" + + " static final String WEDNESDAY = \"WEDNESDAY\";\n" + + " static final String THURSDAY = \"THURSDAY\";\n" + + " static final String FRIDAY = \"FRIDAY\";\n" + + " static final String SATURDAY = \"SATURDAY\";\n" + + " static final String SUNDAY = \"SUNDAY\"; \n" + + " @SuppressWarnings(\"preview\")\n" + + " public static void main(String[] args) {\n" + + " String day = \"MONDAY\";\n" + + " switch (day) {\n" + + " case MONDAY, FRIDAY, SUNDAY -> System.out.println(6);\n" + + " case TUESDAY -> System.out.println(7);\n" + + " case THURSDAY, SATURDAY -> System.out.println(8);\n" + + " case WEDNESDAY -> System.out.println(9);\n" + + " }\n" + + " int k = switch (day) {\n" + + " case SATURDAY -> throw new NullPointerException();\n" + + " case TUESDAY -> 1;\n" + + " case WEDNESDAY -> {break 10;}\n" + + " default -> {\n" + + " pack2.X22.a2=99;\n" + + " int result = f(g);\n" + + " break result;\n" + + " }};\n" + + " }\n" + + " static int f(int k) {\n" + + " return k*k;\n" + + " }\n" + + "}\n"); + + IJavaProject project2 = createJavaProject("second", new String[] {"src"},new String[] {"JCL12_LIB"}, "bin", "12"); + project2.open(null); + createFolder("/second/src/pack2"); + createFile("/second/src/pack2/X22.java", + "package pack2;\n" + + "public class X22 {public static int a2=9;}\n"); + addClasspathEntry(project1, JavaCore.newProjectEntry(project2.getPath())); + project1.close(); // sync + project2.close(); + project2.open(null); + project1.open(null); + IPackageFragment pkg = getPackageFragment("second", "src", "pack2"); + + IJavaSearchScope scope = SearchEngine.createJavaSearchScope(new IJavaProject[] + {getJavaProject("JavaSearchBugs12")}); + + search( + pkg, + ALL_OCCURRENCES, + scope, + this.resultCollector); + String exp = "src/pack1/X11.java void pack1.X11.main(String[]) [pack2] EXACT_MATCH\n" + +"src/pack2 pack2 EXACT_MATCH"; + assertSearchResults( + exp, + this.resultCollector); + + } + finally { + deleteProject("JavaSearchBugs12"); + deleteProject("second"); + } + +} +/* + * java search a method reference in switch expression + */ +public void testBug542559_0012() throws CoreException { + this.workingCopies = new ICompilationUnit[1]; + this.workingCopies[0] = getWorkingCopy("/JavaSearchBugs/src/X.java", + "import java.util.function.Supplier;\n" + + "interface I0 { void i(); }\n" + + "interface I1 extends I0 {}\n" + + "interface I2 extends I0 {}\n" + + "public class X {\n" + + " I1 n1() { return null; }\n" + + " <I extends I2> I n2() { return null; }\n" + + " <M> M m(Supplier<M> m) { return m.get(); }\n" + + " void test(int i, boolean b) {\n" + + " m(switch (i) {\n" + + " case 1 -> this::n1;\n" + + " default -> this::n2;\n" + + " }).i(); \n" + + " }\n" + + " public static void main(String[] args) {\n" + + " try {\n" + + " new X().test(1, true);\n" + + " } catch (NullPointerException e) {\n" + + " System.out.println(\"NPE as expected\");\n" + + " }\n" + + " }\n" + + "}\n" + ); + IJavaProject javaProject = this.workingCopies[0].getJavaProject();//assuming single project for all working copies + String old = javaProject.getOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, true); + try { + javaProject.setOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, JavaCore.ENABLED); + search("n1", METHOD, REFERENCES); + assertSearchResults("src/X.java void X.test(int, boolean) [n1] EXACT_MATCH"); + } finally { + javaProject.setOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, old); + } +} + +}
\ No newline at end of file diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchTests.java index 8e5d3b4348..d257673445 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchTests.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchTests.java @@ -1,11 +1,15 @@ /******************************************************************************* - * Copyright (c) 2000, 2017 IBM Corporation and others. + * Copyright (c) 2000, 2019 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 * which accompanies this distribution, and is available at * https://www.eclipse.org/legal/epl-2.0/ * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * SPDX-License-Identifier: EPL-2.0 * * Contributors: diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ModuleBuilderTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ModuleBuilderTests.java index ddc65ad408..81d316fc7b 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ModuleBuilderTests.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ModuleBuilderTests.java @@ -8,6 +8,10 @@ * * SPDX-License-Identifier: EPL-2.0 * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ @@ -60,8 +64,8 @@ public class ModuleBuilderTests extends ModifyingResourceTests { } static { -// TESTS_NAMES = new String[] { "testBug522330" }; - } +// TESTS_NAMES = new String[] { "testReleaseOption8" }; + } private String sourceWorkspacePath = null; protected ProblemRequestor problemRequestor; public static Test suite() { @@ -6184,6 +6188,7 @@ public class ModuleBuilderTests extends ModifyingResourceTests { } public void testBug526054() throws Exception { + if (!isJRE9) return; ClasspathJrt.resetCaches(); try { // jdk.rmic is not be visible to code in an unnamed module, but using requires we can see the module. @@ -6807,6 +6812,7 @@ public class ModuleBuilderTests extends ModifyingResourceTests { } } public void testBug527569c() throws CoreException { + if (!isJRE9) return; IJavaProject p1 = createJava9Project("Bug527569", "1.7"); Map<String, String> options = new HashMap<>(); // Make sure the new options map doesn't reset. @@ -6856,6 +6862,7 @@ public class ModuleBuilderTests extends ModifyingResourceTests { } } public void testBug527569e() throws CoreException { + if (!isJRE9 || isJRE12) return; IJavaProject p1 = createJava9Project("Bug527569", "1.8"); Map<String, String> options = new HashMap<>(); // Make sure the new options map doesn't reset. @@ -7650,39 +7657,39 @@ public class ModuleBuilderTests extends ModifyingResourceTests { } } public void testBug543195() throws CoreException { - IJavaProject pj1 = createJava9Project("p1"); - IJavaProject pj2 = createJava9Project("p2"); + IJavaProject pj1 = createJava9Project("pj1"); + IJavaProject pj2 = createJava9Project("pj2"); IJavaProject ptest = createJava9Project("ptest"); try { addModularProjectEntry(pj2, pj1); addModularProjectEntry(ptest, pj2); - createFolder("p1/src/p"); - createFile("p1/src/p/Missing.java", + createFolder("pj1/src/p"); + createFile("pj1/src/p/Missing.java", "package p;\n" + "public class Missing {\n" + " public void miss() {}\n" + "}\n"); - createFile("p1/src/module-info.java", - "module p1 {\n" + + createFile("pj1/src/module-info.java", + "module pj1 {\n" + " exports p;\n" + "}\n"); - createFolder("p2/src/q"); - createFile("p2/src/q/API.java", + createFolder("pj2/src/q"); + createFile("pj2/src/q/API.java", "package q;\n" + "public class API extends p.Missing {}\n"); - createFile("p2/src/q/API2.java", + createFile("pj2/src/q/API2.java", "package q;\n" + "public class API2 extends API {}\n"); - createFile("p2/src/module-info.java", - "module p2 {\n" + - " requires p1;\n" + + createFile("pj2/src/module-info.java", + "module pj2 {\n" + + " requires pj1;\n" + " exports q;\n" + "}\n"); getWorkspace().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null); - deleteFile("p1/bin/p/Missing.class"); + deleteFile("pj1/bin/p/Missing.class"); pj1.getProject().close(null); createFolder("ptest/src/p/r"); diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ResolveTests12.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ResolveTests12.java new file mode 100644 index 0000000000..3440f5f466 --- /dev/null +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ResolveTests12.java @@ -0,0 +1,612 @@ +/******************************************************************************* + * Copyright (c) 2019 IBM Corporation and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ + +package org.eclipse.jdt.core.tests.model; + +import org.eclipse.jdt.core.ICompilationUnit; +import org.eclipse.jdt.core.IJavaElement; +import org.eclipse.jdt.core.JavaModelException; +import org.eclipse.jdt.core.WorkingCopyOwner; + +import junit.framework.Test; + +public class ResolveTests12 extends AbstractJavaModelTests { + ICompilationUnit wc = null; + +static { +// TESTS_NAMES = new String[] { "test018" }; + // TESTS_NUMBERS = new int[] { 124 }; + // TESTS_RANGE = new int[] { 16, -1 }; +} +public static Test suite() { + return buildModelTestSuite(ResolveTests12.class); +} +public ResolveTests12(String name) { + super(name); +} +public ICompilationUnit getWorkingCopy(String path, String source) throws JavaModelException { + return super.getWorkingCopy(path, source, this.wcOwner); +} +public void setUpSuite() throws Exception { + super.setUpSuite(); + setUpJavaProject("Resolve", "12", false); + waitUntilIndexesReady(); +} +protected void setUp() throws Exception { + super.setUp(); + this.wcOwner = new WorkingCopyOwner(){}; +} +public void tearDownSuite() throws Exception { + deleteProject("Resolve"); + super.tearDownSuite(); +} + +protected void tearDown() throws Exception { + if (this.wc != null) { + this.wc.discardWorkingCopy(); + } + super.tearDown(); +} +/* + * Multi constant case statement with ':', selection node is the string constant + */ +public void test001() throws JavaModelException { + this.wc = getWorkingCopy("/Resolve/src/X.java","public class X {\n" + + "static final String ONE=\"One\", TWO = \"Two\", THREE=\"Three\";\n" + + " public static void foo(String num) {\n" + + " switch (num) {\n" + + " case ONE, TWO, THREE:\n" + + " System.out.println(num);\n" + + " break;\n" + + " }" + + " }\n" + + "}\n"); + + String str = this.wc.getSource(); + String selection = "ONE"; + int start = str.lastIndexOf(selection); + int length = selection.length(); + IJavaElement[] elements = this.wc.codeSelect(start, length); + assertElementsEqual( + "Unexpected elements", + "ONE [in X [in [Working copy] X.java [in <default> [in src [in Resolve]]]]]", + elements + ); +} +/* + * Multi constant case statement with ':', selection node is the first enum constant + */ +public void test002() throws JavaModelException { + this.wc = getWorkingCopy("/Resolve/src/X.java","public class X {\n" + + " public static void foo(Num num) {\n" + + " switch (num) {\n" + + " case ONE, TWO, THREE:\n" + + " System.out.println(num);\n" + + " break;\n" + + " }" + + " }\n" + + " enum Num { ONE, TWO, THREE;}\n" + + "}\n"); + String str = this.wc.getSource(); + String selection = "ONE"; + int start = str.lastIndexOf(selection); + int length = selection.length(); + IJavaElement[] elements = this.wc.codeSelect(start, length); + assertElementsEqual( + "Unexpected elements", + "ONE [in Num [in X [in [Working copy] X.java [in <default> [in src [in Resolve]]]]]]", + elements + ); +} +/* + * Multi constant case statement with ':', selection node is the second string constant + */ +public void test003() throws JavaModelException { + this.wc = getWorkingCopy("/Resolve/src/X.java","public class X {\n" + + "static final String ONE=\"One\", TWO = \"Two\", THREE=\"Three\";\n" + + " public static void foo(String num) {\n" + + " switch (num) {\n" + + " case ONE, TWO, THREE:\n" + + " System.out.println(num);\n" + + " break;\n" + + " }" + + " }\n" + + "}\n"); + String str = this.wc.getSource(); + String selection = "TWO"; + int start = str.lastIndexOf(selection); + int length = selection.length(); + IJavaElement[] elements = this.wc.codeSelect(start, length); + assertElementsEqual( + "Unexpected elements", + "TWO [in X [in [Working copy] X.java [in <default> [in src [in Resolve]]]]]", + elements + ); +} +/* + * Multi constant case statement with ':', selection node is the second enum constant + */ +public void test004() throws JavaModelException { + this.wc = getWorkingCopy("/Resolve/src/X.java","public class X {\n" + + " public static void foo(Num num) {\n" + + " switch (num) {\n" + + " case ONE, TWO, THREE:\n" + + " System.out.println(num);\n" + + " break;\n" + + " }" + + " }\n" + + " enum Num { ONE, TWO, THREE;}\n" + + "}\n"); + String str = this.wc.getSource(); + String selection = "TWO"; + int start = str.lastIndexOf(selection); + int length = selection.length(); + IJavaElement[] elements = this.wc.codeSelect(start, length); + assertElementsEqual( + "Unexpected elements", + "TWO [in Num [in X [in [Working copy] X.java [in <default> [in src [in Resolve]]]]]]", + elements + ); +} +/* + * Multi constant case statement with '->', selection node is the string constant + */ +public void test005() throws JavaModelException { + this.wc = getWorkingCopy("/Resolve/src/X.java","public class X {\n" + + "static final String ONE=\"One\", TWO = \"Two\", THREE=\"Three\";\n" + + " public static void foo(String num) {\n" + + " switch (num) {\n" + + " case ONE, TWO, THREE ->\n" + + " System.out.println(num);\n" + + " }" + + " }\n" + + "}\n"); + String str = this.wc.getSource(); + String selection = "ONE"; + int start = str.lastIndexOf(selection); + int length = selection.length(); + IJavaElement[] elements = this.wc.codeSelect(start, length); + assertElementsEqual( + "Unexpected elements", + "ONE [in X [in [Working copy] X.java [in <default> [in src [in Resolve]]]]]", + elements + ); +} +/* + * Multi constant case statement with '->', selection node is the first enum constant + */ +public void test006() throws JavaModelException { + this.wc = getWorkingCopy("/Resolve/src/X.java","public class X {\n" + + " public static void foo(Num num) {\n" + + " switch (num) {\n" + + " case ONE, TWO, THREE ->\n" + + " System.out.println(num);\n" + + " break; // illegal, but should be ignored and shouldn't matter\n" + + " }" + + " }\n" + + " enum Num { ONE, TWO, THREE;}\n" + + "}\n"); + String str = this.wc.getSource(); + String selection = "ONE"; + int start = str.lastIndexOf(selection); + int length = selection.length(); + IJavaElement[] elements = this.wc.codeSelect(start, length); + assertElementsEqual( + "Unexpected elements", + "ONE [in Num [in X [in [Working copy] X.java [in <default> [in src [in Resolve]]]]]]", + elements + ); +} +/* + * Multi constant case statement with '->', selection node is the second string constant + */ +public void test007() throws JavaModelException { + this.wc = getWorkingCopy("/Resolve/src/X.java","public class X {\n" + + "static final String ONE=\"One\", TWO = \"Two\", THREE=\"Three\";\n" + + " public static void foo(String num) {\n" + + " switch (num) {\n" + + " case ONE, TWO, THREE ->\n" + + " System.out.println(num);\n" + + " break;\n" + + " }" + + " }\n" + + "}\n"); + String str = this.wc.getSource(); + String selection = "TWO"; + int start = str.lastIndexOf(selection); + int length = selection.length(); + IJavaElement[] elements = this.wc.codeSelect(start, length); + assertElementsEqual( + "Unexpected elements", + "TWO [in X [in [Working copy] X.java [in <default> [in src [in Resolve]]]]]", + elements + ); +} +/* + * Multi constant case statement with '->', selection node is the second enum constant + */ +public void test008() throws JavaModelException { + this.wc = getWorkingCopy("/Resolve/src/X.java","public class X {\n" + + " public static void foo(Num num) {\n" + + " switch (num) {\n" + + " case ONE, TWO, THREE ->\n" + + " System.out.println(num);\n" + + " break;\n" + + " }" + + " }\n" + + " enum Num { ONE, TWO, THREE;}\n" + + "}\n"); + String str = this.wc.getSource(); + String selection = "TWO"; + int start = str.lastIndexOf(selection); + int length = selection.length(); + IJavaElement[] elements = this.wc.codeSelect(start, length); + assertElementsEqual( + "Unexpected elements", + "TWO [in Num [in X [in [Working copy] X.java [in <default> [in src [in Resolve]]]]]]", + elements + ); +} +/* + * Multi constant case statement with '->', selection is a reference in the case block + * which same as the switch's expression + */ +public void test009() throws JavaModelException { + this.wc = getWorkingCopy("/Resolve/src/X.java","public class X {\n" + + " public static void foo(Num num_) {\n" + + " switch (num_) {\n" + + " case ONE, TWO, THREE ->\n" + + " System.out.println(num_);\n" + + " break;\n" + + " }" + + " }\n" + + " enum Num { ONE, TWO, THREE;}\n" + + "}\n"); + String str = this.wc.getSource(); + String selection = "num_"; + int start = str.lastIndexOf(selection); + int length = selection.length(); + IJavaElement[] elements = this.wc.codeSelect(start, length); + assertElementsEqual( + "Unexpected elements", + "num_ [in foo(Num) [in X [in [Working copy] X.java [in <default> [in src [in Resolve]]]]]]", + elements + ); +} +/* + * Multi constant case statement with '->', selection is a reference in the case block + * which is referencing a local variable defined in the case block + */ +public void test010() throws JavaModelException { + this.wc = getWorkingCopy("/Resolve/src/X.java","public class X {\n" + + " public static void foo(Num num_) {\n" + + " switch (num_) {\n" + + " case ONE, TWO, THREE -> {\n" + + " int i_j = 0;" + + " System.out.println(i_j);\n" + + " break;" + + " }\n" + + " }" + + " }\n" + + " enum Num { ONE, TWO, THREE;}\n" + + "}\n"); + String str = this.wc.getSource(); + String selection = "i_j"; + int start = str.lastIndexOf(selection); + int length = selection.length(); + IJavaElement[] elements = this.wc.codeSelect(start, length); + assertElementsEqual( + "Unexpected elements", + "i_j [in foo(Num) [in X [in [Working copy] X.java [in <default> [in src [in Resolve]]]]]]", + elements + ); +} +/* + * Multi constant case statement with '->', selection is a referenced name of type enum in switch expression + */ +public void test011() throws JavaModelException { + this.wc = getWorkingCopy("/Resolve/src/X.java","public class X {\n" + + " public static void foo(Num num_) {\n" + + " switch (num_) {\n" + + " case ONE, TWO, THREE -> {\n" + + " break;" + + " }\n" + + " }" + + " }\n" + + " enum Num { ONE, TWO, THREE;}\n" + + "}\n"); + String str = this.wc.getSource(); + String selection = "num_"; + int start = str.lastIndexOf(selection); + int length = selection.length(); + IJavaElement[] elements = this.wc.codeSelect(start, length); + assertElementsEqual( + "Unexpected elements", + "num_ [in foo(Num) [in X [in [Working copy] X.java [in <default> [in src [in Resolve]]]]]]", + elements + ); +} +/* + * Multi constant case statement with '->', selection is a referenced name of type int in switch expression + */ +public void test012() throws JavaModelException { + this.wc = getWorkingCopy("/Resolve/src/X.java","public class X {\n" + + " public static void foo(int num_) {\n" + + " switch (num_ + 1) {\n" + + " case 1, 2, 3 -> {\n" + + " break;" + + " }\n" + + " }" + + " }\n" + + "}\n"); + String str = this.wc.getSource(); + String selection = "num_"; + int start = str.lastIndexOf(selection); + int length = selection.length(); + IJavaElement[] elements = this.wc.codeSelect(start, length); + assertElementsEqual( + "Unexpected elements", + "num_ [in foo(int) [in X [in [Working copy] X.java [in <default> [in src [in Resolve]]]]]]", + elements + ); +} +/* + * Multi constant case statement with '->', selection is a referenced name of type int in switch expression + */ +public void test013() throws JavaModelException { + this.wc = getWorkingCopy("/Resolve/src/X.java","public class X {\n" + + " public static void foo(int num_) {\n" + + " int i = switch (num_) {\n" + + " case 1, 2, 3 -> (num_ + 1);\n" + + " default -> 0;\n" + + " }" + + " }\n" + + "}\n"); + String str = this.wc.getSource(); + String selection = "num_"; + int start = str.lastIndexOf(selection); + int length = selection.length(); + IJavaElement[] elements = this.wc.codeSelect(start, length); + assertElementsEqual( + "Unexpected elements", + "num_ [in foo(int) [in X [in [Working copy] X.java [in <default> [in src [in Resolve]]]]]]", + elements + ); +} +/* + * Multi constant case statement with '->', selection is a referenced name of type int in switch expression + */ +public void test014() throws JavaModelException { + this.wc = getWorkingCopy("/Resolve/src/X.java","public class X {\n" + + " public static void foo(int num_) {\n" + + " int i = switch (num_) {\n" + + " case 1, 2, 3 -> 0;\n" + + " default -> (num_ + 1);\n" + + " }" + + " }\n" + + "}\n"); + String str = this.wc.getSource(); + String selection = "num_"; + int start = str.lastIndexOf(selection); + int length = selection.length(); + IJavaElement[] elements = this.wc.codeSelect(start, length); + assertElementsEqual( + "Unexpected elements", + "num_ [in foo(int) [in X [in [Working copy] X.java [in <default> [in src [in Resolve]]]]]]", + elements + ); +} +/* + * Multi constant case statement with '->', selection is a referenced name of type int in switch expression + */ +public void test015() throws JavaModelException { + this.wc = getWorkingCopy("/Resolve/src/X.java","public class X {\n" + + " public static void foo(int num_) {\n" + + " int i = switch (num_) {\n" + + " case 1, 2, 3 -> 0;\n" + + " default -> (num_ + 1);\n" + + " }" + + " }\n" + + "}\n"); + String str = this.wc.getSource(); + String selection = "num_"; + int start = str.lastIndexOf(selection); + int length = selection.length(); + IJavaElement[] elements = this.wc.codeSelect(start, length); + assertElementsEqual( + "Unexpected elements", + "num_ [in foo(int) [in X [in [Working copy] X.java [in <default> [in src [in Resolve]]]]]]", + elements + ); +} +/* + * Multi constant case statement with '->', selection is a referenced name of type int in switch expression + */ +public void test016() throws JavaModelException { + this.wc = getWorkingCopy("/Resolve/src/X.java","public class X {\n" + + " public void bar(int s) {\n" + + " int i_j = switch (s) {\n" + + " case 1, 2, 3 -> (s+1);\n" + + " default -> i_j;\n" + + " };\n" + + " }\n" + + "}\n"); + String str = this.wc.getSource(); + String selection = "i_j"; + int start = str.lastIndexOf(selection); + int length = selection.length(); + IJavaElement[] elements = this.wc.codeSelect(start, length); + assertElementsEqual( + "Unexpected elements", + "i_j [in bar(int) [in X [in [Working copy] X.java [in <default> [in src [in Resolve]]]]]]", + elements + ); +} +public void test017() throws JavaModelException { + this.wc = getWorkingCopy("/Resolve/src/X.java","public class X {\n" + + " public void bar(int s) {\n" + + " int i_j = switch (s) {\n" + + " case 1, 2, 3 -> (s+1);\n" + + " default -> (1+i_j);\n" + + " };\n" + + " }\n" + + "}\n"); + String str = this.wc.getSource(); + String selection = "i_j"; + int start = str.lastIndexOf(selection); + int length = selection.length(); + IJavaElement[] elements = this.wc.codeSelect(start, length); + assertElementsEqual( + "Unexpected elements", + "i_j [in bar(int) [in X [in [Working copy] X.java [in <default> [in src [in Resolve]]]]]]", + elements + ); +} +public void test018() throws JavaModelException { + this.wc = getWorkingCopy("/Resolve/src/X.java", + "import java.util.function.*;\n" + + "interface IN0 {} \n" + + "interface IN1 extends IN0 {} \n" + + "interface IN2 extends IN0 {}\n" + + "public class X {\n" + + " IN1 n_1() { return new IN1() {}; } \n" + + " IN2 n_2() { return null; } \n" + + " <M> void m( Supplier< M> m2) { } \n" + + " void testSw(int i) { \n" + + " m(switch(i) { \n" + + " case 1 -> this::n_1; \n" + + " default -> this::n_2; }); \n" + + " }\n" + + "}\n"); + String str = this.wc.getSource(); + String selection = "n_1"; + int start = str.lastIndexOf(selection); + int length = selection.length(); + IJavaElement[] elements = this.wc.codeSelect(start, length); + assertElementsEqual( + "Unexpected elements", + "n_1() [in X [in [Working copy] X.java [in <default> [in src [in Resolve]]]]]", + elements + ); +} +public void test019() throws JavaModelException { + this.wc = getWorkingCopy("/Resolve/src/X.java", + "import java.util.function.*;\n" + + "interface IN0 {} \n" + + "interface IN1 extends IN0 {} \n" + + "interface IN2 extends IN0 {}\n" + + "public class X {\n" + + " IN1 n_1() { return new IN1() {}; } \n" + + " IN2 n_2() { return null; } \n" + + " <M> void m( Supplier< M> m2) { } \n" + + " void testSw(int i) { \n" + + " m(switch(i) { \n" + + " case 2 -> () -> n_1(); \n" + + " default -> this::n_2; }); \n" + + " }\n" + + "}\n"); + String str = this.wc.getSource(); + String selection = "n_1"; + int start = str.lastIndexOf(selection); + int length = selection.length(); + IJavaElement[] elements = this.wc.codeSelect(start, length); + assertElementsEqual( + "Unexpected elements", + "n_1() [in X [in [Working copy] X.java [in <default> [in src [in Resolve]]]]]", + elements + ); +} +public void test020() throws JavaModelException { + this.wc = getWorkingCopy("/Resolve/src/X.java", + "import java.util.function.*;\n" + + "interface IN0 {} \n" + + "interface IN1 extends IN0 {} \n" + + "interface IN2 extends IN0 {}\n" + + "public class X {\n" + + " IN1 n_1() { return new IN1() {}; } \n" + + " IN2 n_2() { return null; } \n" + + " <M> void m( Supplier< M> m2) { } \n" + + " void testSw(int i) { \n" + + " m(switch(i) { \n" + + " default -> this::n_2; }); \n" + + " }\n" + + "}\n"); + String str = this.wc.getSource(); + String selection = "n_2"; + int start = str.lastIndexOf(selection); + int length = selection.length(); + IJavaElement[] elements = this.wc.codeSelect(start, length); + assertElementsEqual( + "Unexpected elements", + "n_2() [in X [in [Working copy] X.java [in <default> [in src [in Resolve]]]]]", + elements + ); +} +public void test021() throws JavaModelException { + this.wc = getWorkingCopy("/Resolve/src/X.java", + "import java.util.function.*;\n" + + "interface IN0 {} \n" + + "interface IN1 extends IN0 {} \n" + + "interface IN2 extends IN0 {}\n" + + "public class X {\n" + + " IN1 n_1(int ijk) { return new IN1() {}; } \n" + + " IN2 n_2() { return null; } \n" + + " <M> void m( Supplier< M> m2) { } \n" + + " void testSw(int ijk) { \n" + + " m(switch(ijk) { \n" + + " default -> () -> n_1(ijk); }); \n" + + " }\n" + + "}\n"); + String str = this.wc.getSource(); + String selection = "n_1"; + int start = str.lastIndexOf(selection); + int length = selection.length(); + IJavaElement[] elements = this.wc.codeSelect(start, length); + assertElementsEqual( + "Unexpected elements", + "n_1(int) [in X [in [Working copy] X.java [in <default> [in src [in Resolve]]]]]", + elements + ); +} +public void test022() throws JavaModelException { + this.wc = getWorkingCopy("/Resolve/src/X.java", + "import java.util.function.*;\n" + + "interface IN0 {} \n" + + "interface IN1 extends IN0 {} \n" + + "interface IN2 extends IN0 {}\n" + + "public class X {\n" + + " IN1 n_1(int ijk) { return new IN1() {}; } \n" + + " IN2 n_2() { return null; } \n" + + " <M> void m( Supplier< M> m2) { } \n" + + " void testSw(int ijk) { \n" + + " m(switch(ijk) { \n" + + " default -> () -> n_1(ijk); }); \n" + + " }\n" + + "}\n"); + String str = this.wc.getSource(); + String selection = "ijk"; + int start = str.lastIndexOf(selection); + int length = selection.length(); + IJavaElement[] elements = this.wc.codeSelect(start, length); + assertElementsEqual( + "Unexpected elements", + "ijk [in testSw(int) [in X [in [Working copy] X.java [in <default> [in src [in Resolve]]]]]]", + elements + ); +} +} diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/RunCompletionModelTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/RunCompletionModelTests.java index dc7e1ac48e..348ad9ccb1 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/RunCompletionModelTests.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/RunCompletionModelTests.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2018 IBM Corporation and others. + * Copyright (c) 2000, 2019 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -41,6 +41,7 @@ public class RunCompletionModelTests extends junit.framework.TestCase { COMPLETION_SUITES.add(CompletionTests9.class); COMPLETION_SUITES.add(CompletionTests10.class); COMPLETION_SUITES.add(CompletionTests11.class); + COMPLETION_SUITES.add(CompletionTests12.class); COMPLETION_SUITES.add(CompletionContextTests.class); COMPLETION_SUITES.add(CompletionContextTests_1_5.class); COMPLETION_SUITES.add(CompletionWithMissingTypesTests.class); diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/rewrite/describing/ASTRewritingStatementsTest.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/rewrite/describing/ASTRewritingStatementsTest.java index 433b8554ca..1eb98c5065 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/rewrite/describing/ASTRewritingStatementsTest.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/rewrite/describing/ASTRewritingStatementsTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2016 IBM Corporation and others. + * Copyright (c) 2000, 2019 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -7,6 +7,10 @@ * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 + * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. * * Contributors: * IBM Corporation - initial API and implementation @@ -3562,6 +3566,7 @@ public class ASTRewritingStatementsTest extends ASTRewritingTest { } + @SuppressWarnings("deprecation") public void testSwitchStatement() throws Exception { IPackageFragment pack1= this.sourceFolder.createPackageFragment("test1", false, null); StringBuffer buf= new StringBuffer(); @@ -3606,12 +3611,19 @@ public class ASTRewritingStatementsTest extends ASTRewritingTest { assertTrue("Number of statements not 0", statements.size() == 0); SwitchCase caseStatement1= ast.newSwitchCase(); - caseStatement1.setExpression(ast.newNumberLiteral("1")); + if (this.apiLevel < AST.JLS12) { + caseStatement1.setExpression(ast.newNumberLiteral("1")); + } + else { + caseStatement1.expressions().add(ast.newNumberLiteral("1")); + } Statement statement1= ast.newReturnStatement(); SwitchCase caseStatement2= ast.newSwitchCase(); // default - caseStatement2.setExpression(null); + if (this.apiLevel < AST.JLS12) { + caseStatement2.setExpression(null); + } ListRewrite listRewrite= rewrite.getListRewrite(switchStatement, SwitchStatement.STATEMENTS_PROPERTY); listRewrite.insertLast(caseStatement1, null); @@ -3634,14 +3646,25 @@ public class ASTRewritingStatementsTest extends ASTRewritingTest { // change case statement SwitchCase caseStatement= (SwitchCase) statements.get(3); Expression newCaseExpression= ast.newNumberLiteral("10"); - rewrite.replace(caseStatement.getExpression(), newCaseExpression, null); + if (this.apiLevel < AST.JLS12) { + rewrite.replace(caseStatement.getExpression(), newCaseExpression, null); + } else { + List expressions = caseStatement.expressions(); + ListRewrite listRewrite= rewrite.getListRewrite(caseStatement, SwitchCase.EXPRESSIONS2_PROPERTY); + listRewrite.replace((Expression)expressions.get(0), newCaseExpression, null); + } ListRewrite listRewrite= rewrite.getListRewrite(switchStatement, SwitchStatement.STATEMENTS_PROPERTY); { // insert case statement SwitchCase caseStatement2= ast.newSwitchCase(); - caseStatement2.setExpression(ast.newNumberLiteral("11")); + if (this.apiLevel < AST.JLS12) { + caseStatement2.setExpression(ast.newNumberLiteral("11")); + } + else { + caseStatement2.expressions().add(ast.newNumberLiteral("11")); + } listRewrite.insertFirst(caseStatement2, null); // insert statement @@ -3652,7 +3675,12 @@ public class ASTRewritingStatementsTest extends ASTRewritingTest { { // insert case statement SwitchCase caseStatement2= ast.newSwitchCase(); - caseStatement2.setExpression(ast.newNumberLiteral("12")); + if (this.apiLevel < AST.JLS12) { + caseStatement2.setExpression(ast.newNumberLiteral("12")); + } + else { + caseStatement2.expressions().add(ast.newNumberLiteral("12")); + } listRewrite.insertLast(caseStatement2, null); // insert statement @@ -3691,6 +3719,7 @@ public class ASTRewritingStatementsTest extends ASTRewritingTest { } + @SuppressWarnings("deprecation") public void testSwitchStatement2() throws Exception { String previousValue = null; try { @@ -3741,12 +3770,19 @@ public class ASTRewritingStatementsTest extends ASTRewritingTest { assertTrue("Number of statements not 0", statements.size() == 0); SwitchCase caseStatement1= ast.newSwitchCase(); - caseStatement1.setExpression(ast.newNumberLiteral("1")); + if (this.apiLevel < AST.JLS12) { + caseStatement1.setExpression(ast.newNumberLiteral("1")); + } + else { + caseStatement1.expressions().add(ast.newNumberLiteral("1")); + } Statement statement1= ast.newReturnStatement(); SwitchCase caseStatement2= ast.newSwitchCase(); // default - caseStatement2.setExpression(null); + if (this.apiLevel < AST.JLS12) { + caseStatement2.setExpression(null); + } ListRewrite listRewrite= rewrite.getListRewrite(switchStatement, SwitchStatement.STATEMENTS_PROPERTY); listRewrite.insertLast(caseStatement1, null); @@ -3769,14 +3805,26 @@ public class ASTRewritingStatementsTest extends ASTRewritingTest { // change case statement SwitchCase caseStatement= (SwitchCase) statements.get(3); Expression newCaseExpression= ast.newNumberLiteral("10"); - rewrite.replace(caseStatement.getExpression(), newCaseExpression, null); + if (this.apiLevel < AST.JLS12) { + rewrite.replace(caseStatement.getExpression(), newCaseExpression, null); + } else { + List expressions = caseStatement.expressions(); + ListRewrite listRewrite2= rewrite.getListRewrite(caseStatement, SwitchCase.EXPRESSIONS2_PROPERTY); + listRewrite2.replace((Expression)expressions.get(0), newCaseExpression, null); + } ListRewrite listRewrite= rewrite.getListRewrite(switchStatement, SwitchStatement.STATEMENTS_PROPERTY); { // insert case statement SwitchCase caseStatement2= ast.newSwitchCase(); - caseStatement2.setExpression(ast.newNumberLiteral("11")); + if (this.apiLevel < AST.JLS12) { + caseStatement2.setExpression(ast.newNumberLiteral("11")); + } + else { + caseStatement2.expressions().add(ast.newNumberLiteral("11")); + + } listRewrite.insertFirst(caseStatement2, null); // insert statement @@ -3787,7 +3835,12 @@ public class ASTRewritingStatementsTest extends ASTRewritingTest { { // insert case statement SwitchCase caseStatement2= ast.newSwitchCase(); - caseStatement2.setExpression(ast.newNumberLiteral("12")); + if (this.apiLevel < AST.JLS12) { + caseStatement2.setExpression(ast.newNumberLiteral("12")); + } + else { + caseStatement2.expressions().add(ast.newNumberLiteral("12")); + } listRewrite.insertLast(caseStatement2, null); // insert statement @@ -4050,6 +4103,7 @@ public class ASTRewritingStatementsTest extends ASTRewritingTest { * https://bugs.eclipse.org/bugs/show_bug.cgi?id=246627 * Replace a statement preceded by an unchanged statement) */ + @SuppressWarnings("deprecation") public void testSwitchStatement7() throws Exception { String previousValue = null; try { @@ -4092,7 +4146,12 @@ public class ASTRewritingStatementsTest extends ASTRewritingTest { ExpressionStatement assignment = (ExpressionStatement)statements.get(1); // i= 1;: SwitchCase switchCase = ast.newSwitchCase(); - switchCase.setExpression(ast.newNumberLiteral("2")); + if (this.apiLevel < AST.JLS12) { + switchCase.setExpression(ast.newNumberLiteral("2")); + } + else { + switchCase.expressions().add(ast.newNumberLiteral("2")); + } ListRewrite listRewrite= rewrite.getListRewrite(switchStatement, SwitchStatement.STATEMENTS_PROPERTY); listRewrite.replace(assignment, switchCase, null); @@ -4192,6 +4251,7 @@ public class ASTRewritingStatementsTest extends ASTRewritingTest { * https://bugs.eclipse.org/bugs/show_bug.cgi?id=246627 * Remove a statement followed by an inserted statement) */ + @SuppressWarnings("deprecation") public void testSwitchStatement9() throws Exception { String previousValue = null; try { @@ -4234,7 +4294,12 @@ public class ASTRewritingStatementsTest extends ASTRewritingTest { ExpressionStatement assignment = (ExpressionStatement)statements.get(1); // i= 1; SwitchCase switchCase = ast.newSwitchCase(); - switchCase.setExpression(ast.newNumberLiteral("2")); + if (this.apiLevel < AST.JLS12) { + switchCase.setExpression(ast.newNumberLiteral("2")); + } + else { + switchCase.expressions().add(ast.newNumberLiteral("2")); + } ListRewrite listRewrite= rewrite.getListRewrite(switchStatement, SwitchStatement.STATEMENTS_PROPERTY); listRewrite.remove(assignment, null); diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/rewrite/describing/ASTRewritingSwitchExpressionsTest.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/rewrite/describing/ASTRewritingSwitchExpressionsTest.java new file mode 100644 index 0000000000..ea5df06850 --- /dev/null +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/rewrite/describing/ASTRewritingSwitchExpressionsTest.java @@ -0,0 +1,159 @@ +/******************************************************************************* + * Copyright (c) 2019 IBM Corporation and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.core.tests.rewrite.describing; + +import java.util.List; + +import org.eclipse.jdt.core.ICompilationUnit; +import org.eclipse.jdt.core.IPackageFragment; +import org.eclipse.jdt.core.dom.AST; +import org.eclipse.jdt.core.dom.ASTNode; +import org.eclipse.jdt.core.dom.Block; +import org.eclipse.jdt.core.dom.CompilationUnit; +import org.eclipse.jdt.core.dom.MethodDeclaration; +import org.eclipse.jdt.core.dom.SimpleName; +import org.eclipse.jdt.core.dom.Statement; +import org.eclipse.jdt.core.dom.SwitchCase; +import org.eclipse.jdt.core.dom.SwitchStatement; +import org.eclipse.jdt.core.dom.TypeDeclaration; +import org.eclipse.jdt.core.dom.rewrite.ASTRewrite; +import org.eclipse.jdt.core.dom.rewrite.ListRewrite; + +import junit.framework.Test; + +public class ASTRewritingSwitchExpressionsTest extends ASTRewritingTest { + + + public ASTRewritingSwitchExpressionsTest(String name) { + super(name, 12); + } + + public ASTRewritingSwitchExpressionsTest(String name, int apiLevel) { + super(name, apiLevel); + } + + public static Test suite() { + return createSuite(ASTRewritingSwitchExpressionsTest.class); + } + + @SuppressWarnings("rawtypes") + public void testSwitchExpressions_since_12() throws Exception { + IPackageFragment pack1= this.sourceFolder.createPackageFragment("test1", false, null); + StringBuffer buf= new StringBuffer(); + buf.append("package test1;\n"); + buf.append("public class E {\n"); + buf.append(" public void foo(int i) {\n"); + buf.append(" switch (i) {\n"); + buf.append(" }\n"); + buf.append(" switch (i) {\n"); + buf.append(" case 1, 2->\n"); + buf.append(" i= 1;\n"); + buf.append(" case 3->\n"); + buf.append(" i= 3;\n"); + buf.append(" default->\n"); + buf.append(" i= 4;\n"); + buf.append(" }\n"); + buf.append(" }\n"); + buf.append("}\n"); + ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null); + + CompilationUnit astRoot= createAST(cu); + ASTRewrite rewrite= ASTRewrite.create(astRoot.getAST()); + + AST ast= astRoot.getAST(); + + assertTrue("Parse errors", (astRoot.getFlags() & ASTNode.MALFORMED) == 0); + TypeDeclaration type= findTypeDeclaration(astRoot, "E"); + MethodDeclaration methodDecl= findMethodDeclaration(type, "foo"); + Block block= methodDecl.getBody(); + List blockStatements= block.statements(); + assertTrue("Number of statements not 2", blockStatements.size() == 2); + { // insert statements, replace expression + SwitchStatement switchStatement= (SwitchStatement) blockStatements.get(0); + + ASTNode expression= switchStatement.getExpression(); + SimpleName newExpression= ast.newSimpleName("x"); + rewrite.replace(expression, newExpression, null); + + List statements= switchStatement.statements(); + assertTrue("Number of statements not 0", statements.size() == 0); + + SwitchCase caseStatement1= ast.newSwitchCase(); + caseStatement1.setSwitchLabeledRule(true); + caseStatement1.expressions().add(ast.newNumberLiteral("1")); + caseStatement1.expressions().add(ast.newNumberLiteral("2")); + + + Statement statement1= ast.newReturnStatement(); + + SwitchCase caseStatement2= ast.newSwitchCase(); // default + caseStatement2.setSwitchLabeledRule(true); + + + ListRewrite listRewrite= rewrite.getListRewrite(switchStatement, SwitchStatement.STATEMENTS_PROPERTY); + listRewrite.insertLast(caseStatement1, null); + listRewrite.insertLast(statement1, null); + listRewrite.insertLast(caseStatement2, null); + } + + { // insert, remove, replace statements, change case statements + SwitchStatement switchStatement= (SwitchStatement) blockStatements.get(1); + + List statements= switchStatement.statements(); + assertTrue("Number of statements not 6", statements.size() == 6); + + // remove statements + + rewrite.remove((ASTNode) statements.get(0), null); + rewrite.remove((ASTNode) statements.get(1), null); + + // change case statement + SwitchCase caseStatement= (SwitchCase) statements.get(2); + ListRewrite listRewrite= rewrite.getListRewrite(caseStatement, SwitchCase.EXPRESSIONS2_PROPERTY); + + { + listRewrite.insertFirst(ast.newNumberLiteral("10"), null); + listRewrite.insertLast(ast.newNumberLiteral("12"), null); + + } + + } + + String preview= evaluateRewrite(cu, rewrite); + + buf= new StringBuffer(); + buf.append("package test1;\n"); + buf.append("public class E {\n"); + buf.append(" public void foo(int i) {\n"); + buf.append(" switch (x) {\n"); + buf.append(" case 1, 2->\n"); + buf.append(" return;\n"); + buf.append(" default->\n"); + buf.append(" }\n"); + buf.append(" switch (i) {\n"); + buf.append(" case 10, 3, 12->\n"); + buf.append(" i= 3;\n"); + buf.append(" default->\n"); + buf.append(" i= 4;\n"); + buf.append(" }\n"); + buf.append(" }\n"); + buf.append("}\n"); + assertEqualString(preview, buf.toString()); + } + +} diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/rewrite/describing/ASTRewritingTest.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/rewrite/describing/ASTRewritingTest.java index bf162e4e9c..c3ca55807c 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/rewrite/describing/ASTRewritingTest.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/rewrite/describing/ASTRewritingTest.java @@ -1,10 +1,14 @@ /******************************************************************************* - * Copyright (c) 2000, 2018 IBM Corporation and others. + * Copyright (c) 2000, 2019 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 * which accompanies this distribution, and is available at * https://www.eclipse.org/legal/epl-2.0/ + * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. * * SPDX-License-Identifier: EPL-2.0 * @@ -16,21 +20,33 @@ import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.util.List; -import junit.framework.Test; -import junit.framework.TestSuite; - import org.eclipse.core.runtime.CoreException; import org.eclipse.jdt.core.ICompilationUnit; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.IPackageFragmentRoot; import org.eclipse.jdt.core.JavaCore; -import org.eclipse.jdt.core.dom.*; +import org.eclipse.jdt.core.dom.AST; +import org.eclipse.jdt.core.dom.ASTParser; +import org.eclipse.jdt.core.dom.AbstractTypeDeclaration; +import org.eclipse.jdt.core.dom.BodyDeclaration; +import org.eclipse.jdt.core.dom.CompilationUnit; +import org.eclipse.jdt.core.dom.FieldDeclaration; +import org.eclipse.jdt.core.dom.MethodDeclaration; +import org.eclipse.jdt.core.dom.Modifier; +import org.eclipse.jdt.core.dom.PrimitiveType; +import org.eclipse.jdt.core.dom.SingleVariableDeclaration; +import org.eclipse.jdt.core.dom.Type; +import org.eclipse.jdt.core.dom.TypeDeclaration; +import org.eclipse.jdt.core.dom.VariableDeclarationFragment; import org.eclipse.jdt.core.dom.rewrite.ASTRewrite; import org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants; import org.eclipse.jdt.core.tests.model.AbstractJavaModelTests; import org.eclipse.jface.text.Document; import org.eclipse.text.edits.TextEdit; +import junit.framework.Test; +import junit.framework.TestSuite; + /** * Tests for ASTRewrite. Subclasses must have 2 constructors that forward to * constructors with the same signature as this class's constructors. @@ -70,8 +86,10 @@ public class ASTRewritingTest extends AbstractJavaModelTests { /** @deprecated using deprecated code */ private final static int JLS10_INTERNAL = AST.JLS10; + + private final static int JLS12_INTERNAL = AST.JLS12; - private final static int[] JLS_LEVELS = { JLS2_INTERNAL, JLS3_INTERNAL, JLS4_INTERNAL, JLS8_INTERNAL, JLS9_INTERNAL, JLS10_INTERNAL }; + private final static int[] JLS_LEVELS = { JLS2_INTERNAL, JLS3_INTERNAL, JLS4_INTERNAL, JLS8_INTERNAL, JLS9_INTERNAL, JLS10_INTERNAL, JLS12_INTERNAL }; private static final String ONLY_AST_STRING = "_only"; private static final String SINCE_AST_STRING = "_since"; @@ -108,26 +126,31 @@ public class ASTRewritingTest extends AbstractJavaModelTests { public static Test suite() { TestSuite suite= new TestSuite(ASTRewritingTest.class.getName()); - suite.addTest(ASTRewritingExpressionsTest.suite()); - suite.addTest(ASTRewritingInsertBoundTest.suite()); - suite.addTest(ASTRewritingMethodDeclTest.suite()); - suite.addTest(ASTRewritingMoveCodeTest.suite()); - suite.addTest(ASTRewritingStatementsTest.suite()); - suite.addTest(ASTRewritingTrackingTest.suite()); - suite.addTest(ASTRewritingJavadocTest.suite()); - suite.addTest(ASTRewritingTypeAnnotationsTest.suite()); - suite.addTest(ASTRewritingTypeDeclTest.suite()); - suite.addTest(ASTRewritingGroupNodeTest.suite()); - suite.addTest(ASTRewritingRevertTest.suite()); - suite.addTest(LineCommentOffsetsTest.suite()); - suite.addTest(ASTRewritingWithStatementsRecoveryTest.suite()); - suite.addTest(ASTRewritePropertyTest.suite()); - suite.addTest(ASTRewritingPackageDeclTest.suite()); - suite.addTest(ASTRewritingLambdaExpressionTest.suite()); - suite.addTest(ASTRewritingReferenceExpressionTest.suite()); - suite.addTest(SourceModifierTest.suite()); - suite.addTest(ImportRewriteTest.suite()); - suite.addTest(ImportRewrite18Test.suite()); + + + suite.addTest(ASTRewritingExpressionsTest.suite()); + suite.addTest(ASTRewritingInsertBoundTest.suite()); + suite.addTest(ASTRewritingMethodDeclTest.suite()); + suite.addTest(ASTRewritingMoveCodeTest.suite()); + suite.addTest(ASTRewritingStatementsTest.suite()); + suite.addTest(ASTRewritingSwitchExpressionsTest.suite()); + + suite.addTest(ASTRewritingTrackingTest.suite()); + suite.addTest(ASTRewritingJavadocTest.suite()); + suite.addTest(ASTRewritingTypeAnnotationsTest.suite()); + suite.addTest(ASTRewritingTypeDeclTest.suite()); + suite.addTest(ASTRewritingGroupNodeTest.suite()); + suite.addTest(ASTRewritingRevertTest.suite()); + suite.addTest(LineCommentOffsetsTest.suite()); + suite.addTest(ASTRewritingWithStatementsRecoveryTest.suite()); + suite.addTest(ASTRewritePropertyTest.suite()); + suite.addTest(ASTRewritingPackageDeclTest.suite()); + suite.addTest(ASTRewritingLambdaExpressionTest.suite()); + suite.addTest(ASTRewritingReferenceExpressionTest.suite()); + suite.addTest(SourceModifierTest.suite()); + suite.addTest(ImportRewriteTest.suite()); + suite.addTest(ImportRewrite18Test.suite()); + return suite; } diff --git a/org.eclipse.jdt.core.tests.model/workspace/Converter12/.classpath b/org.eclipse.jdt.core.tests.model/workspace/Converter12/.classpath new file mode 100644 index 0000000000..3522bc0c3f --- /dev/null +++ b/org.eclipse.jdt.core.tests.model/workspace/Converter12/.classpath @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="src" path="src"/> + <classpathentry kind="var" path="CONVERTER_JCL18_LIB" sourcepath="CONVERTER_JCL18_SRC" rootpath="CONVERTER_JCL_SRCROOT"/> + <classpathentry kind="output" path="bin"/> +</classpath> diff --git a/org.eclipse.jdt.core.tests.model/workspace/Converter12/.project b/org.eclipse.jdt.core.tests.model/workspace/Converter12/.project new file mode 100644 index 0000000000..663fb8d747 --- /dev/null +++ b/org.eclipse.jdt.core.tests.model/workspace/Converter12/.project @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>Converter18</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.jdt.core.javabuilder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.jdt.core.javanature</nature> + </natures> +</projectDescription> diff --git a/org.eclipse.jdt.core.tests.model/workspace/Converter12/src/X.java b/org.eclipse.jdt.core.tests.model/workspace/Converter12/src/X.java new file mode 100644 index 0000000000..5a1a8880f1 --- /dev/null +++ b/org.eclipse.jdt.core.tests.model/workspace/Converter12/src/X.java @@ -0,0 +1,4 @@ +public class X { + public void foo(X this) { + } +} diff --git a/org.eclipse.jdt.core/.settings/.api_filters b/org.eclipse.jdt.core/.settings/.api_filters new file mode 100644 index 0000000000..605b445376 --- /dev/null +++ b/org.eclipse.jdt.core/.settings/.api_filters @@ -0,0 +1,58 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<component id="org.eclipse.jdt.core" version="2"> + <resource path="META-INF/MANIFEST.MF"> + <filter id="924844039"> + <message_arguments> + <message_argument value="3.16.0"/> + <message_argument value="3.16.0"/> + </message_arguments> + </filter> + <filter comment="Address this while merging BETA_JAVA_12" id="924844039"> + <message_arguments> + <message_argument value="3.17.0"/> + <message_argument value="3.17.0"/> + </message_arguments> + </filter> + </resource> + <resource path="compiler/org/eclipse/jdt/core/compiler/CategorizedProblem.java" type="org.eclipse.jdt.core.compiler.CategorizedProblem"> + <filter comment="To be addressed while merging BETA_JAVA_12" id="336658481"> + <message_arguments> + <message_argument value="org.eclipse.jdt.core.compiler.CategorizedProblem"/> + <message_argument value="CAT_COMPLIANCE"/> + </message_arguments> + </filter> + </resource> + <resource path="compiler/org/eclipse/jdt/core/compiler/IProblem.java" type="org.eclipse.jdt.core.compiler.IProblem"> + <filter id="388194388"> + <message_arguments> + <message_argument value="org.eclipse.jdt.core.compiler.IProblem"/> + <message_argument value="IgnoreCategoriesMask"/> + <message_argument value="8388607"/> + </message_arguments> + </filter> + </resource> + <resource path="dom/org/eclipse/jdt/core/dom/BreakStatement.java" type="org.eclipse.jdt.core.dom.BreakStatement"> + <filter comment="For Java 12 support." id="336658481"> + <message_arguments> + <message_argument value="org.eclipse.jdt.core.dom.BreakStatement"/> + <message_argument value="EXPRESSION_PROPERTY"/> + </message_arguments> + </filter> + </resource> + <resource path="dom/org/eclipse/jdt/core/dom/SwitchCase.java" type="org.eclipse.jdt.core.dom.SwitchCase"> + <filter comment="For Java 12" id="336658481"> + <message_arguments> + <message_argument value="org.eclipse.jdt.core.dom.SwitchCase"/> + <message_argument value="EXPRESSIONS2_PROPERTY"/> + </message_arguments> + </filter> + </resource> + <resource path="model/org/eclipse/jdt/core/util/IClassFileReader.java" type="org.eclipse.jdt.core.util.IClassFileReader"> + <filter comment="default method added for getting nest members" id="404000815"> + <message_arguments> + <message_argument value="org.eclipse.jdt.core.util.IClassFileReader"/> + <message_argument value="getNestMembersAttribute()"/> + </message_arguments> + </filter> + </resource> +</component> diff --git a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathJep247.java b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathJep247.java index 8aad54669b..8dfa35f38c 100644 --- a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathJep247.java +++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathJep247.java @@ -5,6 +5,10 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v20.html * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ @@ -160,7 +164,7 @@ public class ClasspathJep247 extends ClasspathJrt { if (content == null) return FileVisitResult.CONTINUE; ClasspathJep247.this.acceptModule(content); - ClasspathJep247.this.moduleNamesCache.add(f.getFileName().toString()); + ClasspathJep247.this.moduleNamesCache.add(JRTUtil.sanitizedFileName(f)); } return FileVisitResult.CONTINUE; } @@ -217,7 +221,7 @@ public class ClasspathJep247 extends ClasspathJrt { List<String> sub = new ArrayList<>(); try (DirectoryStream<java.nio.file.Path> stream = Files.newDirectoryStream(this.releasePath)) { for (final java.nio.file.Path subdir: stream) { - String rel = subdir.getFileName().toString(); + String rel = JRTUtil.sanitizedFileName(subdir); if (rel.contains(this.releaseInHex)) { sub.add(rel); } else { diff --git a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathJep247Jdk12.java b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathJep247Jdk12.java index 52a83987cf..917fde6507 100644 --- a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathJep247Jdk12.java +++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathJep247Jdk12.java @@ -5,6 +5,10 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v20.html * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ @@ -70,7 +74,7 @@ public class ClasspathJep247Jdk12 extends ClasspathJep247 { Path p = this.fs.getPath(rel); try (DirectoryStream<java.nio.file.Path> stream = Files.newDirectoryStream(p)) { for (final java.nio.file.Path subdir: stream) { - Path f = this.fs.getPath(rel, subdir.getFileName().toString(), qualifiedBinaryFileName); + Path f = this.fs.getPath(rel, JRTUtil.sanitizedFileName(subdir), qualifiedBinaryFileName); if (Files.exists(f)) { content = JRTUtil.safeReadBytes(f); if (content != null) @@ -134,7 +138,7 @@ public class ClasspathJep247Jdk12 extends ClasspathJep247 { List<String> sub = new ArrayList<>(); try (DirectoryStream<java.nio.file.Path> stream = Files.newDirectoryStream(this.releasePath)) { for (final java.nio.file.Path subdir: stream) { - String rel = subdir.getFileName().toString(); + String rel = JRTUtil.sanitizedFileName(subdir); if (rel.contains(this.releaseInHex)) sub.add(rel); } @@ -157,7 +161,7 @@ public class ClasspathJep247Jdk12 extends ClasspathJep247 { if (this.modules == null) { try (DirectoryStream<java.nio.file.Path> stream = Files.newDirectoryStream(this.releasePath)) { for (final java.nio.file.Path subdir: stream) { - String rel = subdir.getFileName().toString(); + String rel = JRTUtil.sanitizedFileName(subdir); if (!rel.contains(this.releaseInHex)) { continue; } @@ -179,8 +183,9 @@ public class ClasspathJep247Jdk12 extends ClasspathJep247 { if (content == null) return FileVisitResult.CONTINUE; Path m = f.subpath(1, f.getNameCount() - 1); - ClasspathJep247Jdk12.this.acceptModule(m.getFileName().toString(), content); - ClasspathJep247Jdk12.this.moduleNamesCache.add(m.getFileName().toString()); + String name = JRTUtil.sanitizedFileName(m); + ClasspathJep247Jdk12.this.acceptModule(name, content); + ClasspathJep247Jdk12.this.moduleNamesCache.add(name); } return FileVisitResult.SKIP_SIBLINGS; } @@ -260,7 +265,7 @@ public class ClasspathJep247Jdk12 extends ClasspathJep247 { this.packageCache.add(Util.EMPTY_STRING); try (DirectoryStream<java.nio.file.Path> stream = Files.newDirectoryStream(this.releasePath)) { for (final java.nio.file.Path subdir: stream) { - String rel = subdir.getFileName().toString(); + String rel = JRTUtil.sanitizedFileName(subdir); if (!rel.contains(this.releaseInHex)) { continue; } diff --git a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathJrt.java b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathJrt.java index e76860d4d6..117ba4758f 100644 --- a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathJrt.java +++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathJrt.java @@ -156,10 +156,10 @@ public class ClasspathJrt extends ClasspathLocation implements IMultiModuleEntry } @Override - public FileVisitResult visitModule(java.nio.file.Path modPath) throws IOException { + public FileVisitResult visitModule(Path p, String name) throws IOException { if (moduleName == null) return FileVisitResult.CONTINUE; - if (!moduleName.equals(modPath.toString())) { + if (!moduleName.equals(name)) { return FileVisitResult.SKIP_SUBTREE; } return FileVisitResult.CONTINUE; @@ -219,10 +219,10 @@ public class ClasspathJrt extends ClasspathLocation implements IMultiModuleEntry } @Override - public FileVisitResult visitModule(Path mod) throws IOException { + public FileVisitResult visitModule(Path p, String name) throws IOException { try { - ClasspathJrt.this.acceptModule(JRTUtil.getClassfileContent(ClasspathJrt.this.file, IModule.MODULE_INFO_CLASS, mod.toString())); - ClasspathJrt.this.moduleNamesCache.add(mod.getFileName().toString()); + ClasspathJrt.this.acceptModule(JRTUtil.getClassfileContent(ClasspathJrt.this.file, IModule.MODULE_INFO_CLASS, name)); + ClasspathJrt.this.moduleNamesCache.add(name); } catch (ClassFormatException e) { e.printStackTrace(); } diff --git a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/FileSystem.java b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/FileSystem.java index 060351e20a..2e82e50c08 100644 --- a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/FileSystem.java +++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/FileSystem.java @@ -8,6 +8,10 @@ * * SPDX-License-Identifier: EPL-2.0 * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * IBM Corporation - initial API and implementation * Stephan Herrmann - Contribution for @@ -170,7 +174,7 @@ public class FileSystem implements IModuleAwareNameEnvironment, SuffixConstants Map<String,UpdatesByKind> moduleUpdates = new HashMap<>(); static final boolean isJRE12Plus; static { - isJRE12Plus = "12".equals(System.getProperty("java.specification.version")); //$NON-NLS-1$ //$NON-NLS-2$ + isJRE12Plus = CompilerOptions.VERSION_12.equals(System.getProperty("java.specification.version")); //$NON-NLS-1$ } /* diff --git a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/Main.java b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/Main.java index 18957eae3e..26e1fc9595 100644 --- a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/Main.java +++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/Main.java @@ -2179,6 +2179,16 @@ public void configure(String[] argv) { mode = DEFAULT; continue; } + if (currentArg.equals("-12") || currentArg.equals("-12.0")) { //$NON-NLS-1$ //$NON-NLS-2$ + if (didSpecifyCompliance) { + throw new IllegalArgumentException( + this.bind("configure.duplicateCompliance", currentArg)); //$NON-NLS-1$ + } + didSpecifyCompliance = true; + this.options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_12); + mode = DEFAULT; + continue; + } if (currentArg.equals("-d")) { //$NON-NLS-1$ if (this.destinationPath != null) { StringBuffer errorMessage = new StringBuffer(); @@ -2726,6 +2736,8 @@ public void configure(String[] argv) { this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_10); } else if (currentArg.equals("11") || currentArg.equals("11.0")) { //$NON-NLS-1$//$NON-NLS-2$ this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_11); + } else if (currentArg.equals("12") || currentArg.equals("12.0")) { //$NON-NLS-1$//$NON-NLS-2$ + this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_12); } else if (currentArg.equals("jsr14")) { //$NON-NLS-1$ this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_JSR14); @@ -2815,6 +2827,8 @@ public void configure(String[] argv) { this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_10); } else if (currentArg.equals("11") || currentArg.equals("11.0")) { //$NON-NLS-1$//$NON-NLS-2$ this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_11); + } else if (currentArg.equals("12") || currentArg.equals("12.0")) { //$NON-NLS-1$//$NON-NLS-2$ + this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_12); } else { throw new IllegalArgumentException(this.bind("configure.source", currentArg)); //$NON-NLS-1$ } diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionParser.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionParser.java index 0aa6f16a4b..60065a5b01 100644 --- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionParser.java +++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionParser.java @@ -1,11 +1,15 @@ /******************************************************************************* - * Copyright (c) 2000, 2018 IBM Corporation and others. + * Copyright (c) 2000, 2019 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 * which accompanies this distribution, and is available at * https://www.eclipse.org/legal/epl-2.0/ * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * SPDX-License-Identifier: EPL-2.0 * * Contributors: @@ -2512,6 +2516,14 @@ protected void consumeCompilationUnit() { super.consumeCompilationUnit(); } @Override +protected void consumeSwitchExpression() { + super.consumeSwitchExpression(); + if (this.assistNode != null) { + SwitchExpression expr = (SwitchExpression) this.expressionStack[this.expressionPtr]; + expr.resolveAll = true; + } +} +@Override protected void consumeConditionalExpression(int op) { popElement(K_CONDITIONAL_OPERATOR); super.consumeConditionalExpression(op); @@ -4268,6 +4280,16 @@ protected void consumeToken(int token) { pushOnElementStack(K_CONDITIONAL_OPERATOR, QUESTION); } break; + case TokenNameARROW: + switch (topKnownElementKind(COMPLETION_OR_ASSIST_PARSER)) { + case K_BETWEEN_CASE_AND_COLON: + popElement(K_BETWEEN_CASE_AND_COLON); + break; + case K_BETWEEN_DEFAULT_AND_COLON: + popElement(K_BETWEEN_DEFAULT_AND_COLON); + break; + } + break; case TokenNameCOLON: switch (topKnownElementKind(COMPLETION_OR_ASSIST_PARSER)) { case K_CONDITIONAL_OPERATOR: @@ -4314,6 +4336,17 @@ protected void consumeToken(int token) { case TokenNamecase : pushOnElementStack(K_BETWEEN_CASE_AND_COLON); break; + case TokenNameCOMMA : + switch (topKnownElementKind(COMPLETION_OR_ASSIST_PARSER)) { + // for multi constant case stmt + // case MONDAY, FRI + // if there's a comma, ignore the previous expression (constant) + // Which doesn't matter for completing the next constant + case K_BETWEEN_CASE_AND_COLON: + this.expressionPtr--; + this.expressionLengthStack[this.expressionLengthPtr]--; + } + break; case TokenNamedefault : pushOnElementStack(K_BETWEEN_DEFAULT_AND_COLON); break; @@ -4885,6 +4918,9 @@ public NameReference createSingleAssistNameReference(char[] assistName, long pos if (kind == K_LOCAL_INITIALIZER_DELIMITER && this.options.complianceLevel >= ClassFileConstants.JDK11) { keywords[count++]= Keywords.VAR; } + if (kind == K_SELECTOR_QUALIFIER && this.options.complianceLevel >= ClassFileConstants.JDK12) { + keywords[count++] = Keywords.SWITCH; + } keywords[count++]= Keywords.TRUE; keywords[count++]= Keywords.FALSE; keywords[count++]= Keywords.NULL; @@ -5090,6 +5126,15 @@ protected NameReference getUnspecifiedReference(boolean rejectTypeAnnotations) { return nameReference; } @Override +protected void consumePostfixExpression() { + // PostfixExpression ::= Name + if(this.topKnownElementKind(COMPLETION_OR_ASSIST_PARSER) == K_INSIDE_BREAK_STATEMENT) { + // Do nothing, just let checkLabelStatement() do the job + } else { + super.consumePostfixExpression(); + } +} +@Override protected NameReference getUnspecifiedReferenceOptimized() { if (this.identifierLengthStack[this.identifierLengthPtr] > 1) { // reducing a qualified name // potential receiver is being poped, so reset potential receiver diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistParser.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistParser.java index 08f7336442..4e35ca3ea9 100644 --- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistParser.java +++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistParser.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2018 IBM Corporation and others. + * Copyright (c) 2000, 2019 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -7,7 +7,11 @@ * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 - * + * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ @@ -508,6 +512,8 @@ protected boolean triggerRecoveryUponLambdaClosure(Statement statement, boolean if (this.elementKindStack[i] != K_LAMBDA_EXPRESSION_DELIMITER) continue; LambdaExpression expression = (LambdaExpression) this.elementObjectInfoStack[i]; + if (expression == null) + return false; if (expression.sourceStart >= statementStart && expression.sourceEnd <= statementEnd) { this.elementPtr = i - 1; lambdaClosed = true; @@ -1278,8 +1284,11 @@ private void adjustBracket(int token) { break; } } +private boolean lastArrowAssociatedWithCase = false; @Override protected void consumeToken(int token) { + if (TokenNameARROW == token) + this.lastArrowAssociatedWithCase = this.caseFlagSet; // remember the arrow association before reset. super.consumeToken(token); if(this.isFirst) { @@ -1312,7 +1321,7 @@ protected void consumeToken(int token) { } break; case TokenNameLBRACE: - if (this.previousToken == TokenNameARROW) { + if (this.previousToken == TokenNameARROW && !this.lastArrowAssociatedWithCase) { popElement(K_LAMBDA_EXPRESSION_DELIMITER); pushOnElementStack(K_LAMBDA_EXPRESSION_DELIMITER, BLOCK_BODY, this.previousObjectInfo); } diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionParser.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionParser.java index 1b4e6f64dc..404d3b3803 100644 --- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionParser.java +++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionParser.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2018 IBM Corporation and others. + * Copyright (c) 2000, 2019 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -7,7 +7,11 @@ * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 - * + * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * IBM Corporation - initial API and implementation * Jesper Steen Møller <jesper@selskabet.org> - contributions for: @@ -77,7 +81,7 @@ public class SelectionParser extends AssistParser { protected static final int SELECTION_OR_ASSIST_PARSER = ASSIST_PARSER + SELECTION_PARSER; // KIND : all values known by SelectionParser are between 1025 and 1549 - protected static final int K_BETWEEN_CASE_AND_COLON = SELECTION_PARSER + 1; // whether we are inside a block + protected static final int K_BETWEEN_CASE_AND_COLONORARROW = SELECTION_PARSER + 1; // whether we are inside a block protected static final int K_INSIDE_RETURN_STATEMENT = SELECTION_PARSER + 2; // whether we are between the keyword 'return' and the end of a return statement protected static final int K_CAST_STATEMENT = SELECTION_PARSER + 3; // whether we are between ')' and the end of a cast statement @@ -150,7 +154,7 @@ private void buildMoreCompletionContext(Expression expression) { if(kind != 0) { int info = topKnownElementInfo(SELECTION_OR_ASSIST_PARSER); nextElement : switch (kind) { - case K_BETWEEN_CASE_AND_COLON : + case K_BETWEEN_CASE_AND_COLONORARROW : if(this.expressionPtr > 0) { SwitchStatement switchStatement = new SwitchStatement(); switchStatement.expression = this.expressionStack[this.expressionPtr - 1]; @@ -1250,11 +1254,26 @@ protected void consumeToken(int token) { if (isInsideMethod() || isInsideFieldInitialization()) { switch (token) { case TokenNamecase : - pushOnElementStack(K_BETWEEN_CASE_AND_COLON); + pushOnElementStack(K_BETWEEN_CASE_AND_COLONORARROW); + break; + case TokenNameCOMMA : + switch (topKnownElementKind(SELECTION_OR_ASSIST_PARSER)) { + // for multi constant case stmt + // case MONDAY, FRIDAY + // if there's a comma, ignore the previous expression (constant) + // Which doesn't matter for the next constant + case K_BETWEEN_CASE_AND_COLONORARROW: + this.expressionPtr--; + this.expressionLengthStack[this.expressionLengthPtr]--; + } break; + case TokenNameARROW: + // TODO: Uncomment the line below + //if (this.options.sourceLevel < ClassFileConstants.JDK13) break; + // else FALL-THROUGH case TokenNameCOLON: - if(topKnownElementKind(SELECTION_OR_ASSIST_PARSER) == K_BETWEEN_CASE_AND_COLON) { - popElement(K_BETWEEN_CASE_AND_COLON); + if(topKnownElementKind(SELECTION_OR_ASSIST_PARSER) == K_BETWEEN_CASE_AND_COLONORARROW) { + popElement(K_BETWEEN_CASE_AND_COLONORARROW); } break; case TokenNamereturn: diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/CategorizedProblem.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/CategorizedProblem.java index 6b13fee0dc..55cb6c5b99 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/CategorizedProblem.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/CategorizedProblem.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2017 IBM Corporation and others. + * Copyright (c) 2000, 2019 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -8,6 +8,10 @@ * * SPDX-License-Identifier: EPL-2.0 * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ @@ -103,6 +107,10 @@ public abstract class CategorizedProblem implements IProblem { * @since 3.14 */ public static final int CAT_MODULE = 160; + /** + * @since 3.17 BETA_JAVA_12 + */ + public static final int CAT_COMPLIANCE = 170; /** * Returns an integer identifying the category of this problem. Categories, like problem IDs are diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/IProblem.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/IProblem.java index fff58835e4..fc4f419191 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/IProblem.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/IProblem.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2018 IBM Corporation and others. + * Copyright (c) 2000, 2019 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -8,6 +8,10 @@ * * SPDX-License-Identifier: EPL-2.0 * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * IBM Corporation - initial API and implementation * IBM Corporation - added the following constants @@ -373,11 +377,13 @@ void setSourceStart(int sourceStart); int Javadoc = 0x80000000; /** @since 3.14 */ int ModuleRelated = 0x00800000; + /** @since 3.17 BETA_JAVA_12 */ + int Compliance = 0x00400000; /** * Mask to use in order to filter out the category portion of the problem ID. */ - int IgnoreCategoriesMask = 0x7FFFFF; + int IgnoreCategoriesMask = 0x3FFFFF; /* * Below are listed all available problem IDs. Note that this list could be augmented in the future, @@ -2045,6 +2051,12 @@ void setSourceStart(int sourceStart); int LambdaShapeComputationError = 1101; /** @since 3.13 */ int ProblemNotAnalysed = 1102; + /** @since 3.17 BETA_JAVA_12 */ + int PreviewFeatureDisabled = Compliance + 1103; + /** @since 3.17 BETA_JAVA_12 */ + int PreviewFeatureUsed = Compliance + 1104; + /** @since 3.17 BETA_JAVA_12 */ + int PreviewFeatureNotSupported = Compliance + 1105; /** @since 3.13 */ int UnlikelyCollectionMethodArgumentType = 1200; @@ -2078,5 +2090,24 @@ void setSourceStart(int sourceStart); int VarIsNotAllowedHere = Syntax + 1511; // ''var'' is not allowed here /** @since 3.16 */ int VarCannotBeMixedWithNonVarParams = Syntax + 1512; // ''var'' cannot be mixed with explicit or implicit parameters - -} + /** @since 3.17 BETA_JAVA_12 */ + int SwitchExpressionsIncompatibleResultExpressionTypes = TypeRelated + 1600; + /** @since 3.17 BETA_JAVA_12 */ + int SwitchExpressionsEmptySwitchBlock = Internal + 1601; + /** @since 3.17 BETA_JAVA_12 */ + int SwitchExpressionsNoResultExpression = TypeRelated + 1602; + /** @since 3.17 BETA_JAVA_12 */ + int SwitchExpressionSwitchLabeledBlockCompletesNormally = Internal + 1603; + /** @since 3.17 BETA_JAVA_12 */ + int SwitchExpressionLastStatementCompletesNormally = Internal + 1604; + /** @since 3.17 BETA_JAVA_12 */ + int SwitchExpressionTrailingSwitchLabels = Internal + 1605; + /** @since 3.17 BETA_JAVA_12 */ + int switchMixedCase = Syntax + 1606; + /** @since 3.17 BETA_JAVA_12 */ + int SwitchExpressionMissingDefaultCase = Internal + 1607; + /** @since 3.17 BETA_JAVA_12 */ + int SwitchExpressionBreakMissingValue = Internal + 1610; + /** @since 3.17 BETA_JAVA_12 */ + int SwitchExpressionMissingEnumConstantCase = Internal + 1611; + } diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ASTVisitor.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ASTVisitor.java index 869dc489a9..c9cba847be 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ASTVisitor.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ASTVisitor.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2017 IBM Corporation and others. + * Copyright (c) 2000, 2018 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -7,7 +7,11 @@ * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 - * + * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ @@ -508,6 +512,9 @@ public abstract class ASTVisitor { public void endVisit(IntersectionCastTypeReference intersectionCastTypeReference, BlockScope scope) { // do nothing by default } + public void endVisit(SwitchExpression switchExpression, BlockScope scope) { + // do nothing by default + } public boolean visit( AllocationExpression allocationExpression, BlockScope scope) { @@ -999,4 +1006,7 @@ public abstract class ASTVisitor { public boolean visit(IntersectionCastTypeReference intersectionCastTypeReference, BlockScope scope) { return true; // do nothing by default, keep traversing } + public boolean visit(SwitchExpression switchExpression, BlockScope blockScope) { + return true; // do nothing by default, keep traversing + } } diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java index 78b31ccf23..9ec29d3e13 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java @@ -8,6 +8,10 @@ * * SPDX-License-Identifier: EPL-2.0 * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * IBM Corporation - initial API and implementation * Matt McCutchen - partial fix for https://bugs.eclipse.org/bugs/show_bug.cgi?id=122995 @@ -108,7 +112,7 @@ public abstract class ASTNode implements TypeConstants, TypeIds { public final static int Bit18 = 0x20000; // non null (expression) | onDemand (import reference) public final static int Bit19 = 0x40000; // didResolve (parameterized qualified type ref/parameterized single type ref) | empty (javadoc return statement) | needReceiverGenericCast (msg/fieldref) public final static int Bit20 = 0x80000; // contains syntax errors (method declaration, type declaration, field declarations, initializer), typeref: <> name ref: lambda capture) - public final static int Bit21 = 0x100000; + public final static int Bit21 = 0x100000; // for all declarations that can contain type references that have type annotations | insideExpressionStatement public final static int Bit22 = 0x200000; // parenthesis count (expression) | used (import reference) shadows outer local (local declarations) public final static int Bit23 = 0x400000; // parenthesis count (expression) | second or later declarator in declaration (local declarations) public final static int Bit24 = 0x800000; // parenthesis count (expression) @@ -325,7 +329,7 @@ public abstract class ASTNode implements TypeConstants, TypeIds { public static final int IsDiamond = Bit20; // this is only used for method invocation as the expression inside an expression statement - public static final int InsideExpressionStatement = Bit5; + public static final int InsideExpressionStatement = Bit21; // for annotation reference, signal if annotation was created from a default: public static final int IsSynthetic = ASTNode.Bit7; diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/BranchStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/BranchStatement.java index 08869f0104..ece451e2c2 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/BranchStatement.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/BranchStatement.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2009 IBM Corporation and others. + * Copyright (c) 2000, 2019 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -8,6 +8,10 @@ * * SPDX-License-Identifier: EPL-2.0 * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ @@ -32,6 +36,12 @@ public BranchStatement(char[] label, int sourceStart,int sourceEnd) { this.sourceEnd = sourceEnd; } +protected void generateExpressionResultCode(BlockScope currentScope, CodeStream codeStream) { + // do nothing here +} +protected void adjustStackSize(BlockScope currentScope, CodeStream codeStream) { + // do nothing here +} /** * Branch code generation * @@ -42,6 +52,7 @@ public void generateCode(BlockScope currentScope, CodeStream codeStream) { if ((this.bits & ASTNode.IsReachable) == 0) { return; } + generateExpressionResultCode(currentScope, codeStream); int pc = codeStream.position; // generation of code responsible for invoking the finally @@ -62,6 +73,7 @@ public void generateCode(BlockScope currentScope, CodeStream codeStream) { } } codeStream.goto_(this.targetLabel); + adjustStackSize(currentScope, codeStream); codeStream.recordPositionsFrom(pc, this.sourceStart); SubRoutineStatement.reenterAllExceptionHandlers(this.subroutines, -1, codeStream); if (this.initStateIndex != -1) { diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/BreakStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/BreakStatement.java index b17194ac06..7d1e82adab 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/BreakStatement.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/BreakStatement.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2012 IBM Corporation and others. + * Copyright (c) 2000, 2019 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -8,6 +8,10 @@ * * SPDX-License-Identifier: EPL-2.0 * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * IBM Corporation - initial API and implementation * Stephan Herrmann - Contribution for @@ -16,15 +20,19 @@ package org.eclipse.jdt.internal.compiler.ast; import org.eclipse.jdt.internal.compiler.ASTVisitor; +import org.eclipse.jdt.internal.compiler.codegen.CodeStream; import org.eclipse.jdt.internal.compiler.flow.*; import org.eclipse.jdt.internal.compiler.lookup.*; public class BreakStatement extends BranchStatement { + public Expression expression; + public SwitchExpression switchExpression; + public boolean isImplicit; + public BreakStatement(char[] label, int sourceStart, int e) { super(label, sourceStart, e); } - @Override public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) { @@ -40,11 +48,19 @@ public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, Fl if (this.label == null) { currentScope.problemReporter().invalidBreak(this); } else { - currentScope.problemReporter().undefinedLabel(this); + if (this.switchExpression == null) + currentScope.problemReporter().undefinedLabel(this); } return flowInfo; // pretend it did not break since no actual target } + if (this.switchExpression != null && this.expression != null) { + flowInfo = this.expression.analyseCode(currentScope, flowContext, flowInfo); + this.expression.checkNPEbyUnboxing(currentScope, flowContext, flowInfo); + if (flowInfo.reachMode() == FlowInfo.REACHABLE && currentScope.compilerOptions().isAnnotationBasedNullAnalysisEnabled) + checkAgainstNullAnnotation(currentScope, flowContext, flowInfo, this.expression); + } + targetContext.recordAbruptExit(); targetContext.expireNullCheckedFieldInfo(); @@ -89,17 +105,72 @@ public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, Fl } return FlowInfo.DEAD_END; } +@Override +protected void generateExpressionResultCode(BlockScope currentScope, CodeStream codeStream) { + if (this.label == null && this.expression != null) { + this.expression.generateCode(currentScope, codeStream, this.switchExpression != null); + } +} +@Override +protected void adjustStackSize(BlockScope currentScope, CodeStream codeStream) { + if (this.label == null && this.expression != null && this.switchExpression != null) { + TypeBinding postConversionType = this.expression.postConversionType(currentScope); + switch(postConversionType.id) { + case TypeIds.T_long : + case TypeIds.T_double : + codeStream.decrStackSize(2); + break; + case TypeIds.T_void : + break; + default : + codeStream.decrStackSize(1); + break; + } + } +} +@Override +public void resolve(BlockScope scope) { + super.resolve(scope); + if (this.expression != null && (this.switchExpression != null || this.isImplicit)) { + if (this.switchExpression == null && this.isImplicit && !this.expression.statementExpression()) { + if (scope.compilerOptions().enablePreviewFeatures) { + /* JLS 12 14.11.2 + Switch labeled rules in switch statements differ from those in switch expressions (15.28). + In switch statements they must be switch labeled statement expressions, ... */ + scope.problemReporter().invalidExpressionAsStatement(this.expression); + return; + } + } + this.expression.resolveType(scope); + } else if (this.expression == null && this.switchExpression != null) { + scope.problemReporter().switchExpressionBreakMissingValue(this); + } +} + +@Override +public TypeBinding resolveExpressionType(BlockScope scope) { + return this.expression != null ? this.expression.resolveType(scope) : null; +} @Override public StringBuffer printStatement(int tab, StringBuffer output) { - printIndent(tab, output).append("break"); //$NON-NLS-1$ - if (this.label != null) output.append(' ').append(this.label); + if (!this.isImplicit) // implicit for SwitchLabeledExpressions + printIndent(tab, output).append("break"); //$NON-NLS-1$ + if (this.label != null) + output.append(' ').append(this.label); + if (this.expression != null) { + output.append(' '); + this.expression.printExpression(tab, output); + } return output.append(';'); } @Override public void traverse(ASTVisitor visitor, BlockScope blockscope) { - visitor.visit(this, blockscope); + if (visitor.visit(this, blockscope)) { + if (this.expression != null) + this.expression.traverse(visitor, blockscope); + } visitor.endVisit(this, blockscope); } @Override diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CaseStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CaseStatement.java index 85e0f21105..5ad0916539 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CaseStatement.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CaseStatement.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2011 IBM Corporation and others. + * Copyright (c) 2000, 2019 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -8,11 +8,18 @@ * * SPDX-License-Identifier: EPL-2.0 * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.jdt.internal.compiler.ast; +import java.util.ArrayList; +import java.util.List; + import org.eclipse.jdt.internal.compiler.ASTVisitor; import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; import org.eclipse.jdt.internal.compiler.codegen.BranchLabel; @@ -21,6 +28,7 @@ import org.eclipse.jdt.internal.compiler.flow.FlowContext; import org.eclipse.jdt.internal.compiler.flow.FlowInfo; import org.eclipse.jdt.internal.compiler.impl.Constant; import org.eclipse.jdt.internal.compiler.impl.IntConstant; +//import org.eclipse.jdt.internal.compiler.impl.IntConstant; import org.eclipse.jdt.internal.compiler.lookup.Binding; import org.eclipse.jdt.internal.compiler.lookup.BlockScope; import org.eclipse.jdt.internal.compiler.lookup.FieldBinding; @@ -31,6 +39,8 @@ public class CaseStatement extends Statement { public Expression constantExpression; public BranchLabel targetLabel; + public Expression[] constantExpressions; // case with multiple expressions + public boolean isExpr = false; public CaseStatement(Expression constantExpression, int sourceEnd, int sourceStart) { this.constantExpression = constantExpression; @@ -43,13 +53,23 @@ public FlowInfo analyseCode( BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) { - - if (this.constantExpression != null) { - if (this.constantExpression.constant == Constant.NotAConstant - && !this.constantExpression.resolvedType.isEnum()) { - currentScope.problemReporter().caseExpressionMustBeConstant(this.constantExpression); + if (this.constantExpressions != null && this.constantExpressions.length > 1) { + for (Expression e : this.constantExpressions) { + if (e.constant == Constant.NotAConstant + && !e.resolvedType.isEnum()) { + currentScope.problemReporter().caseExpressionMustBeConstant(e); + } + this.constantExpression.analyseCode(currentScope, flowContext, flowInfo); + } + + } else { + if (this.constantExpression != null) { + if (this.constantExpression.constant == Constant.NotAConstant + && !this.constantExpression.resolvedType.isEnum()) { + currentScope.problemReporter().caseExpressionMustBeConstant(this.constantExpression); + } + this.constantExpression.analyseCode(currentScope, flowContext, flowInfo); } - this.constantExpression.analyseCode(currentScope, flowContext, flowInfo); } return flowInfo; } @@ -58,10 +78,19 @@ public FlowInfo analyseCode( public StringBuffer printStatement(int tab, StringBuffer output) { printIndent(tab, output); if (this.constantExpression == null) { - output.append("default :"); //$NON-NLS-1$ + output.append("default "); //$NON-NLS-1$ + output.append(this.isExpr ? "->" : ":"); //$NON-NLS-1$ //$NON-NLS-2$ } else { output.append("case "); //$NON-NLS-1$ - this.constantExpression.printExpression(0, output).append(" :"); //$NON-NLS-1$ + if (this.constantExpressions != null && this.constantExpressions.length > 0) { + for (int i = 0, l = this.constantExpressions.length; i < l; ++i) { + this.constantExpressions[i].printExpression(0, output); + if (i < l -1) output.append(','); + } + } else { + this.constantExpression.printExpression(0, output); + } + output.append(this.isExpr ? " ->" : " :"); //$NON-NLS-1$ //$NON-NLS-2$ } return output; } @@ -90,10 +119,10 @@ public void resolve(BlockScope scope) { /** * Returns the constant intValue or ordinal for enum constants. If constant is NotAConstant, then answers Float.MIN_VALUE - * @see org.eclipse.jdt.internal.compiler.ast.Statement#resolveCase(org.eclipse.jdt.internal.compiler.lookup.BlockScope, org.eclipse.jdt.internal.compiler.lookup.TypeBinding, org.eclipse.jdt.internal.compiler.ast.SwitchStatement) + * see org.eclipse.jdt.internal.compiler.ast.Statement#resolveCase(org.eclipse.jdt.internal.compiler.lookup.BlockScope, org.eclipse.jdt.internal.compiler.lookup.TypeBinding, org.eclipse.jdt.internal.compiler.ast.SwitchStatement) */ @Override -public Constant resolveCase(BlockScope scope, TypeBinding switchExpressionType, SwitchStatement switchStatement) { +public Constant[] resolveCase(BlockScope scope, TypeBinding switchExpressionType, SwitchStatement switchStatement) { // switchExpressionType maybe null in error case scope.enclosingCase = this; // record entering in a switch case block @@ -104,26 +133,55 @@ public Constant resolveCase(BlockScope scope, TypeBinding switchExpressionType, // on error the last default will be the selected one ... switchStatement.defaultCase = this; - return Constant.NotAConstant; + return Constant.NotAConstantList; } // add into the collection of cases of the associated switch statement switchStatement.cases[switchStatement.caseCount++] = this; - // tag constant name with enum type for privileged access to its members if (switchExpressionType != null && switchExpressionType.isEnum() && (this.constantExpression instanceof SingleNameReference)) { ((SingleNameReference) this.constantExpression).setActualReceiverType((ReferenceBinding)switchExpressionType); } TypeBinding caseType = this.constantExpression.resolveType(scope); - if (caseType == null || switchExpressionType == null) return Constant.NotAConstant; - if (this.constantExpression.isConstantValueOfTypeAssignableToType(caseType, switchExpressionType) + if (caseType == null || switchExpressionType == null) return Constant.NotAConstantList; + // tag constant name with enum type for privileged access to its members + + if (this.constantExpressions != null && this.constantExpressions.length > 1) { + List<Constant> cases = new ArrayList<>(); + for (Expression e : this.constantExpressions) { + if (e != this.constantExpression) { + if (switchExpressionType.isEnum() && (e instanceof SingleNameReference)) { + ((SingleNameReference) e).setActualReceiverType((ReferenceBinding)switchExpressionType); + } + e.resolveType(scope); + } + Constant con = resolveConstantExpression(scope, caseType, switchExpressionType, switchStatement, e); + if (con != Constant.NotAConstant) { + cases.add(con); + } + } + if (cases.size() > 0) { + return cases.toArray(new Constant[cases.size()]); + } + } else { + return new Constant[] { resolveConstantExpression(scope, caseType, switchExpressionType, switchStatement, this.constantExpression) }; + } + return Constant.NotAConstantList; +} +public Constant resolveConstantExpression(BlockScope scope, + TypeBinding caseType, + TypeBinding switchExpressionType, + SwitchStatement switchStatement, + Expression expression) { + + if (expression.isConstantValueOfTypeAssignableToType(caseType, switchExpressionType) || caseType.isCompatibleWith(switchExpressionType)) { if (caseType.isEnum()) { - if (((this.constantExpression.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT) != 0) { - scope.problemReporter().enumConstantsCannotBeSurroundedByParenthesis(this.constantExpression); + if (((expression.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT) != 0) { + scope.problemReporter().enumConstantsCannotBeSurroundedByParenthesis(expression); } - if (this.constantExpression instanceof NameReference - && (this.constantExpression.bits & ASTNode.RestrictiveFlagMASK) == Binding.FIELD) { - NameReference reference = (NameReference) this.constantExpression; + if (expression instanceof NameReference + && (expression.bits & ASTNode.RestrictiveFlagMASK) == Binding.FIELD) { + NameReference reference = (NameReference) expression; FieldBinding field = reference.fieldBinding(); if ((field.modifiers & ClassFileConstants.AccEnum) == 0) { scope.problemReporter().enumSwitchCannotTargetField(reference, field); @@ -133,11 +191,11 @@ public Constant resolveCase(BlockScope scope, TypeBinding switchExpressionType, return IntConstant.fromValue(field.original().id + 1); // (ordinal value + 1) zero should not be returned see bug 141810 } } else { - return this.constantExpression.constant; + return expression.constant; } - } else if (isBoxingCompatible(caseType, switchExpressionType, this.constantExpression, scope)) { + } else if (isBoxingCompatible(caseType, switchExpressionType, expression, scope)) { // constantExpression.computeConversion(scope, caseType, switchExpressionType); - do not report boxing/unboxing conversion - return this.constantExpression.constant; + return expression.constant; } scope.problemReporter().typeMismatchError(caseType, switchExpressionType, this.constantExpression, switchStatement.expression); return Constant.NotAConstant; @@ -146,7 +204,14 @@ public Constant resolveCase(BlockScope scope, TypeBinding switchExpressionType, @Override public void traverse(ASTVisitor visitor, BlockScope blockScope) { if (visitor.visit(this, blockScope)) { - if (this.constantExpression != null) this.constantExpression.traverse(visitor, blockScope); + if (this.constantExpressions != null && this.constantExpressions.length > 1) { + for (Expression e : this.constantExpressions) { + e.traverse(visitor, blockScope); + } + } else { + if (this.constantExpression != null) this.constantExpression.traverse(visitor, blockScope); + } + } visitor.endVisit(this, blockScope); } diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConditionalExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConditionalExpression.java index df72bd0422..00632c91e7 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConditionalExpression.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConditionalExpression.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2016 IBM Corporation and others. + * Copyright (c) 2000, 2019 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -8,6 +8,10 @@ * * SPDX-License-Identifier: EPL-2.0 * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * IBM Corporation - initial API and implementation * Stephen Herrmann <stephan@cs.tu-berlin.de> - Contributions for @@ -223,14 +227,8 @@ public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, // is there a chance of null (or non-null)? -> potentially null etc. // https://bugs.eclipse.org/bugs/show_bug.cgi?id=133125 - int status = 0; int combinedStatus = this.ifTrueNullStatus|this.ifFalseNullStatus; - if ((combinedStatus & (FlowInfo.NULL|FlowInfo.POTENTIALLY_NULL)) != 0) - status |= FlowInfo.POTENTIALLY_NULL; - if ((combinedStatus & (FlowInfo.NON_NULL|FlowInfo.POTENTIALLY_NON_NULL)) != 0) - status |= FlowInfo.POTENTIALLY_NON_NULL; - if ((combinedStatus & (FlowInfo.UNKNOWN|FlowInfo.POTENTIALLY_UNKNOWN)) != 0) - status |= FlowInfo.POTENTIALLY_UNKNOWN; + int status = Expression.computeNullStatus(0, combinedStatus); if (status > 0) this.nullStatus = status; } diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Expression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Expression.java index 56b6f8feaf..5b8054c57d 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Expression.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Expression.java @@ -8,6 +8,10 @@ * * SPDX-License-Identifier: EPL-2.0 * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * IBM Corporation - initial API and implementation * Stephan Herrmann - Contributions for @@ -732,6 +736,15 @@ public void computeConversion(Scope scope, TypeBinding runtimeType, TypeBinding } } +public static int computeNullStatus(int status, int combinedStatus) { + if ((combinedStatus & (FlowInfo.NULL|FlowInfo.POTENTIALLY_NULL)) != 0) + status |= FlowInfo.POTENTIALLY_NULL; + if ((combinedStatus & (FlowInfo.NON_NULL|FlowInfo.POTENTIALLY_NON_NULL)) != 0) + status |= FlowInfo.POTENTIALLY_NON_NULL; + if ((combinedStatus & (FlowInfo.UNKNOWN|FlowInfo.POTENTIALLY_UNKNOWN)) != 0) + status |= FlowInfo.POTENTIALLY_UNKNOWN; + return status; +} /** * Expression statements are plain expressions, however they generate like * normal expressions with no value required. @@ -1057,6 +1070,10 @@ public void resolve(BlockScope scope) { this.resolveType(scope); return; } +@Override +public TypeBinding resolveExpressionType(BlockScope scope) { + return resolveType(scope); +} /** * Resolve the type of this expression in the context of a blockScope @@ -1161,6 +1178,12 @@ public boolean forcedToBeRaw(ReferenceContext referenceContext) { if (ternary.valueIfTrue.forcedToBeRaw(referenceContext) || ternary.valueIfFalse.forcedToBeRaw(referenceContext)) { return true; } + } else if (this instanceof SwitchExpression) { + SwitchExpression se = (SwitchExpression) this; + for (Expression e : se.resultExpressions) { + if (e.forcedToBeRaw(referenceContext)) + return true; + } } return false; } diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FakedTrackingVariable.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FakedTrackingVariable.java index 8498b31c09..c42d4039ca 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FakedTrackingVariable.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FakedTrackingVariable.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2011, 2016 GK Software AG and others. + * Copyright (c) 2011, 2019 GK Software AG and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -8,6 +8,10 @@ * * SPDX-License-Identifier: EPL-2.0 * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * Stephan Herrmann - initial API and implementation * Nikolay Metchev (nikolaymetchev@gmail.com) - Contributions for @@ -180,6 +184,14 @@ public class FakedTrackingVariable extends LocalDeclaration { return falseTrackingVariable; } return getCloseTrackingVariable(((ConditionalExpression)expression).valueIfTrue, flowInfo, flowContext); + } else if (expression instanceof SwitchExpression) { + for (Expression re : ((SwitchExpression) expression).resultExpressions) { + FakedTrackingVariable fakedTrackingVariable = getCloseTrackingVariable(re, flowInfo, flowContext); + if (fakedTrackingVariable != null) { + return fakedTrackingVariable; + } + } + return null; } else break; @@ -242,12 +254,21 @@ public class FakedTrackingVariable extends LocalDeclaration { } } + private static boolean containsAllocation(SwitchExpression location) { + for (Expression re : location.resultExpressions) { + if (containsAllocation(re)) + return true; + } + return false; + } private static boolean containsAllocation(ASTNode location) { if (location instanceof AllocationExpression) return true; if (location instanceof ConditionalExpression) { ConditionalExpression conditional = (ConditionalExpression) location; return containsAllocation(conditional.valueIfTrue) || containsAllocation(conditional.valueIfFalse); + } else if (location instanceof SwitchExpression) { + return containsAllocation((SwitchExpression) location); } if (location instanceof CastExpression) return containsAllocation(((CastExpression) location).expression); @@ -260,6 +281,8 @@ public class FakedTrackingVariable extends LocalDeclaration { preConnectTrackerAcrossAssignment(location, local, flowInfo, (AllocationExpression) expression, closeTracker); } else if (expression instanceof ConditionalExpression) { preConnectTrackerAcrossAssignment(location, local, flowInfo, (ConditionalExpression) expression, closeTracker); + } else if (expression instanceof SwitchExpression) { + preConnectTrackerAcrossAssignment(location, local, flowInfo, (SwitchExpression) expression, closeTracker); } else if (expression instanceof CastExpression) { preConnectTrackerAcrossAssignment(location, local, ((CastExpression) expression).expression, flowInfo); } @@ -272,6 +295,13 @@ public class FakedTrackingVariable extends LocalDeclaration { } private static void preConnectTrackerAcrossAssignment(ASTNode location, LocalVariableBinding local, FlowInfo flowInfo, + SwitchExpression se, FakedTrackingVariable closeTracker) { + for (Expression re : se.resultExpressions) { + preConnectTrackerAcrossAssignment(location, local, flowInfo, closeTracker, re); + } + } + + private static void preConnectTrackerAcrossAssignment(ASTNode location, LocalVariableBinding local, FlowInfo flowInfo, AllocationExpression allocationExpression, FakedTrackingVariable closeTracker) { allocationExpression.closeTracker = closeTracker; if (allocationExpression.arguments != null && allocationExpression.arguments.length > 0) { @@ -456,7 +486,7 @@ public class FakedTrackingVariable extends LocalDeclaration { rhsTrackVar.globalClosingState &= ~(SHARED_WITH_OUTSIDE|OWNED_BY_OUTSIDE|FOREACH_ELEMENT_VAR); } } else { - if (rhs instanceof AllocationExpression || rhs instanceof ConditionalExpression) { + if (rhs instanceof AllocationExpression || rhs instanceof ConditionalExpression || rhs instanceof SwitchExpression) { if (rhsTrackVar == disconnectedTracker) return; // b.: self wrapper: res = new Wrap(res); -> done! if (local.closeTracker == rhsTrackVar diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LocalDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LocalDeclaration.java index 1cd7e21e71..b67c1a4af6 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LocalDeclaration.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LocalDeclaration.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2018 IBM Corporation and others. + * Copyright (c) 2000, 2019 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -7,7 +7,11 @@ * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 - * + * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * IBM Corporation - initial API and implementation * Stephan Herrmann <stephan@cs.tu-berlin.de> - Contributions for @@ -245,6 +249,14 @@ public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, Fl } if (candidate != null) return candidate; } + if (e instanceof SwitchExpression) { + SwitchExpression se = (SwitchExpression)e; + se.collectResultExpressions(); + for (Expression re : se.resultExpressions) { + Expression candidate = findPolyExpression(re); + if (candidate != null) return candidate; + } + } return null; } @@ -357,6 +369,7 @@ public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, Fl && variableType != null && variableType.isValidBinding()) { resolveAnnotationsEarly = this.initialization instanceof Invocation || this.initialization instanceof ConditionalExpression + || this.initialization instanceof SwitchExpression || this.initialization instanceof ArrayInitializer; } if (resolveAnnotationsEarly) { diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/NullAnnotationMatching.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/NullAnnotationMatching.java index 4c47725f64..41b38880cf 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/NullAnnotationMatching.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/NullAnnotationMatching.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2013, 2016 GK Software AG and others. + * Copyright (c) 2013, 2019 GK Software AG and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -8,6 +8,10 @@ * * SPDX-License-Identifier: EPL-2.0 * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * Stephan Herrmann - initial API and implementation * Till Brychcy - Contributions for @@ -159,6 +163,19 @@ public class NullAnnotationMatching { if (status1 == status2) return status1; return nullStatus; // if both branches disagree use the precomputed & merged nullStatus + } else if (expression instanceof SwitchExpression && expression.isPolyExpression()) { + // drill into all the branches: + SwitchExpression se = ((SwitchExpression) expression); + Expression[] resExprs = se.resultExpressions.toArray(new Expression[0]); + Expression re = resExprs[0]; + int status0 = NullAnnotationMatching.checkAssignment(currentScope, flowContext, var, flowInfo, re.nullStatus(flowInfo, flowContext), re, re.resolvedType); + boolean identicalStatus = true; + for (int i = 1, l = resExprs.length; i < l; ++i) { + re = resExprs[i]; + int otherStatus = NullAnnotationMatching.checkAssignment(currentScope, flowContext, var, flowInfo, re.nullStatus(flowInfo, flowContext), re, re.resolvedType); + identicalStatus &= status0 == otherStatus; + } + return identicalStatus ? status0 : nullStatus; // if not all branches agree use the precomputed & merged nullStatus } lhsTagBits = var.type.tagBits & TagBits.AnnotationNullMASK; NullAnnotationMatching annotationStatus = analyse(var.type, providedType, null, null, nullStatus, expression, CheckMode.COMPATIBLE); diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java index d5b9f6fea0..56b3ca3987 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java @@ -90,7 +90,7 @@ public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, Fl flowInfo = this.expression.analyseCode(currentScope, flowContext, flowInfo); this.expression.checkNPEbyUnboxing(currentScope, flowContext, flowInfo); if (flowInfo.reachMode() == FlowInfo.REACHABLE && currentScope.compilerOptions().isAnnotationBasedNullAnalysisEnabled) - checkAgainstNullAnnotation(currentScope, flowContext, flowInfo); + checkAgainstNullAnnotation(currentScope, flowContext, flowInfo, this.expression); if (currentScope.compilerOptions().analyseResourceLeaks) { FakedTrackingVariable trackingVariable = FakedTrackingVariable.getCloseTrackingVariable(this.expression, flowInfo, flowContext); if (trackingVariable != null) { @@ -182,29 +182,6 @@ public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, Fl public boolean doesNotCompleteNormally() { return true; } -void checkAgainstNullAnnotation(BlockScope scope, FlowContext flowContext, FlowInfo flowInfo) { - int nullStatus = this.expression.nullStatus(flowInfo, flowContext); - long tagBits; - MethodBinding methodBinding = null; - boolean useTypeAnnotations = scope.environment().usesNullTypeAnnotations(); - try { - methodBinding = scope.methodScope().referenceMethodBinding(); - tagBits = (useTypeAnnotations) ? methodBinding.returnType.tagBits : methodBinding.tagBits; - } catch (NullPointerException npe) { - // chain of references in try-block has several potential nulls; - // any null means we cannot perform the following check - return; - } - if (useTypeAnnotations) { - checkAgainstNullTypeAnnotation(scope, methodBinding.returnType, this.expression, flowContext, flowInfo); - } else if (nullStatus != FlowInfo.NON_NULL) { - // if we can't prove non-null check against declared null-ness of the enclosing method: - if ((tagBits & TagBits.AnnotationNonNull) != 0) { - flowContext.recordNullityMismatch(scope, this.expression, this.expression.resolvedType, methodBinding.returnType, flowInfo, nullStatus, null); - } - } -} - /** * Retrun statement code generation * diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java index 35967ab8fd..a4a9abb523 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java @@ -8,6 +8,10 @@ * * SPDX-License-Identifier: EPL-2.0 * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * IBM Corporation - initial API and implementation * Stephan Herrmann <stephan@cs.tu-berlin.de> - Contributions for @@ -63,6 +67,7 @@ public class SingleNameReference extends NameReference implements OperatorIds { public char[] token; public MethodBinding[] syntheticAccessors; // [0]=read accessor [1]=write accessor public TypeBinding genericCast; + public boolean isLabel;// flagging for break expression when expression is SwitchExpression - java 12 preview-feature public SingleNameReference(char[] source, long pos) { super(); diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Statement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Statement.java index 5bfb045288..56991a493b 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Statement.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Statement.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2017 IBM Corporation and others. + * Copyright (c) 2000, 2019 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -8,6 +8,10 @@ * * SPDX-License-Identifier: EPL-2.0 * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * IBM Corporation - initial API and implementation * Stephan Herrmann - Contributions for @@ -176,7 +180,16 @@ void analyseOneArgument18(BlockScope currentScope, FlowContext flowContext, Flow ce.internalAnalyseOneArgument18(currentScope, flowContext, expectedType, ce.valueIfTrue, flowInfo, ce.ifTrueNullStatus, expectedNonNullness, originalExpected); ce.internalAnalyseOneArgument18(currentScope, flowContext, expectedType, ce.valueIfFalse, flowInfo, ce.ifFalseNullStatus, expectedNonNullness, originalExpected); return; + } else if (argument instanceof SwitchExpression && argument.isPolyExpression()) { + SwitchExpression se = (SwitchExpression) argument; + for (int i = 0; i < se.resultExpressions.size(); i++) { + se.internalAnalyseOneArgument18(currentScope, flowContext, expectedType, + se.resultExpressions.get(i), flowInfo, + se.resultExpressionNullStatus.get(i), expectedNonNullness, originalExpected); + } + return; } + int nullStatus = argument.nullStatus(flowInfo, flowContext); internalAnalyseOneArgument18(currentScope, flowContext, expectedType, argument, flowInfo, nullStatus, expectedNonNullness, originalExpected); @@ -204,6 +217,28 @@ void internalAnalyseOneArgument18(BlockScope currentScope, FlowContext flowConte flowContext.recordNullityMismatch(currentScope, argument, argument.resolvedType, expectedType, flowInfo, nullStatus, annotationStatus); } } +/* package */ void checkAgainstNullAnnotation(BlockScope scope, FlowContext flowContext, FlowInfo flowInfo, Expression expr) { + int nullStatus = expr.nullStatus(flowInfo, flowContext); + long tagBits; + MethodBinding methodBinding = null; + boolean useTypeAnnotations = scope.environment().usesNullTypeAnnotations(); + try { + methodBinding = scope.methodScope().referenceMethodBinding(); + tagBits = (useTypeAnnotations) ? methodBinding.returnType.tagBits : methodBinding.tagBits; + } catch (NullPointerException npe) { + // chain of references in try-block has several potential nulls; + // any null means we cannot perform the following check + return; + } + if (useTypeAnnotations) { + checkAgainstNullTypeAnnotation(scope, methodBinding.returnType, expr, flowContext, flowInfo); + } else if (nullStatus != FlowInfo.NON_NULL) { + // if we can't prove non-null check against declared null-ness of the enclosing method: + if ((tagBits & TagBits.AnnotationNonNull) != 0) { + flowContext.recordNullityMismatch(scope, expr, expr.resolvedType, methodBinding.returnType, flowInfo, nullStatus, null); + } + } +} protected void checkAgainstNullTypeAnnotation(BlockScope scope, TypeBinding requiredType, Expression expression, FlowContext flowContext, FlowInfo flowInfo) { if (expression instanceof ConditionalExpression && expression.isPolyExpression()) { @@ -212,6 +247,14 @@ protected void checkAgainstNullTypeAnnotation(BlockScope scope, TypeBinding requ internalCheckAgainstNullTypeAnnotation(scope, requiredType, ce.valueIfTrue, ce.ifTrueNullStatus, flowContext, flowInfo); internalCheckAgainstNullTypeAnnotation(scope, requiredType, ce.valueIfFalse, ce.ifFalseNullStatus, flowContext, flowInfo); return; + } else if (expression instanceof SwitchExpression && expression.isPolyExpression()) { + SwitchExpression se = (SwitchExpression) expression; + for (int i = 0; i < se.resultExpressions.size(); i++) { + internalCheckAgainstNullTypeAnnotation(scope, requiredType, + se.resultExpressions.get(i), + se.resultExpressionNullStatus.get(i), flowContext, flowInfo); + } + return; } int nullStatus = expression.nullStatus(flowInfo, flowContext); internalCheckAgainstNullTypeAnnotation(scope, requiredType, expression, nullStatus, flowContext, flowInfo); @@ -423,11 +466,19 @@ public abstract void resolve(BlockScope scope); /** * Returns case constant associated to this statement (NotAConstant if none) + * parameter statement has to be either a SwitchStatement or a SwitchExpression */ -public Constant resolveCase(BlockScope scope, TypeBinding testType, SwitchStatement switchStatement) { +public Constant[] resolveCase(BlockScope scope, TypeBinding testType, SwitchStatement switchStatement) { // statement within a switch that are not case are treated as normal statement.... resolve(scope); - return Constant.NotAConstant; + return new Constant[] {Constant.NotAConstant}; +} +/** + * Returns the resolved expression if any associated to this statement - used + * parameter statement has to be either a SwitchStatement or a SwitchExpression + */ +public TypeBinding resolveExpressionType(BlockScope scope) { + return null; } /** * Implementation of {@link org.eclipse.jdt.internal.compiler.lookup.InvocationSite#invocationTargetType} diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SwitchExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SwitchExpression.java new file mode 100644 index 0000000000..0860ac3f0c --- /dev/null +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SwitchExpression.java @@ -0,0 +1,696 @@ +/******************************************************************************* + * Copyright (c) 2018, 2019 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.internal.compiler.ast; + +import static org.eclipse.jdt.internal.compiler.ast.ExpressionContext.ASSIGNMENT_CONTEXT; +import static org.eclipse.jdt.internal.compiler.ast.ExpressionContext.INVOCATION_CONTEXT; +import static org.eclipse.jdt.internal.compiler.ast.ExpressionContext.VANILLA_CONTEXT; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.Stack; +import java.util.stream.Collectors; + +import org.eclipse.jdt.internal.compiler.ASTVisitor; +import org.eclipse.jdt.internal.compiler.codegen.CodeStream; +import org.eclipse.jdt.internal.compiler.flow.FlowContext; +import org.eclipse.jdt.internal.compiler.flow.FlowInfo; +import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; +import org.eclipse.jdt.internal.compiler.impl.Constant; +import org.eclipse.jdt.internal.compiler.lookup.Binding; +import org.eclipse.jdt.internal.compiler.lookup.BlockScope; +import org.eclipse.jdt.internal.compiler.lookup.FieldBinding; +import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment; +import org.eclipse.jdt.internal.compiler.lookup.MethodBinding; +import org.eclipse.jdt.internal.compiler.lookup.PolyTypeBinding; +import org.eclipse.jdt.internal.compiler.lookup.Scope; +import org.eclipse.jdt.internal.compiler.lookup.TypeBinding; +import org.eclipse.jdt.internal.compiler.lookup.TypeIds; + +public class SwitchExpression extends SwitchStatement implements IPolyExpression { + + /* package */ TypeBinding expectedType; + private ExpressionContext expressionContext = VANILLA_CONTEXT; + private boolean isPolyExpression = false; + private TypeBinding[] originalValueResultExpressionTypes; + private TypeBinding[] finalValueResultExpressionTypes; + + private int nullStatus = FlowInfo.UNKNOWN; + public List<Expression> resultExpressions; + public boolean resolveAll; + /* package */ List<Integer> resultExpressionNullStatus; + private static Map<TypeBinding, TypeBinding[]> type_map; + + static { + type_map = new HashMap<TypeBinding, TypeBinding[]>(); + type_map.put(TypeBinding.CHAR, new TypeBinding[] {TypeBinding.CHAR, TypeBinding.BYTE, TypeBinding.INT}); + type_map.put(TypeBinding.SHORT, new TypeBinding[] {TypeBinding.SHORT, TypeBinding.BYTE, TypeBinding.INT}); + type_map.put(TypeBinding.BYTE, new TypeBinding[] {TypeBinding.BYTE, TypeBinding.INT}); + } + + @Override + public void setExpressionContext(ExpressionContext context) { + this.expressionContext = context; + } + + @Override + public void setExpectedType(TypeBinding expectedType) { + this.expectedType = expectedType; + } + + @Override + public ExpressionContext getExpressionContext() { + return this.expressionContext; + } + @Override + protected boolean ignoreMissingDefaultCase(CompilerOptions compilerOptions, boolean isEnumSwitch) { + return isEnumSwitch; // mandatory error if not enum in switch expressions + } + @Override + protected void reportMissingEnumConstantCase(BlockScope upperScope, FieldBinding enumConstant) { + upperScope.problemReporter().missingEnumConstantCase(this, enumConstant); + } + @Override + protected int getFallThroughState(Statement stmt, BlockScope blockScope) { + if (stmt instanceof Expression || stmt instanceof ThrowStatement) + return BREAKING; + if (this.switchLabeledRules // do this check for every block if '->' (Switch Labeled Rules) + && stmt instanceof Block) { + Block block = (Block) stmt; + if (block.doesNotCompleteNormally()) { + return BREAKING; + } + //JLS 12 15.28.1 Given a switch expression, if the switch block consists of switch labeled rules, + //then it is a compile-time error if any switch labeled block can complete normally. + blockScope.problemReporter().switchExpressionSwitchLabeledBlockCompletesNormally(block); + } + return FALLTHROUGH; + } + @Override + public boolean checkNPE(BlockScope skope, FlowContext flowContext, FlowInfo flowInfo, int ttlForFieldCheck) { + if ((this.nullStatus & FlowInfo.NULL) != 0) + skope.problemReporter().expressionNullReference(this); + else if ((this.nullStatus & FlowInfo.POTENTIALLY_NULL) != 0) + skope.problemReporter().expressionPotentialNullReference(this); + return true; // all checking done + } + + private void computeNullStatus(FlowInfo flowInfo, FlowContext flowContext) { + boolean precomputed = this.resultExpressionNullStatus.size() > 0; + if (!precomputed) + this.resultExpressionNullStatus.add(this.resultExpressions.get(0).nullStatus(flowInfo, flowContext)); int status = this.resultExpressions.get(0).nullStatus(flowInfo, flowContext); + int combinedStatus = status; + boolean identicalStatus = true; + for (int i = 1, l = this.resultExpressions.size(); i < l; ++i) { + if (!precomputed) + this.resultExpressionNullStatus.add(this.resultExpressions.get(i).nullStatus(flowInfo, flowContext)); + int tmp = this.resultExpressions.get(i).nullStatus(flowInfo, flowContext); + identicalStatus &= status == tmp; + combinedStatus |= tmp; + } + if (identicalStatus) { + this.nullStatus = status; + return; + } + status = Expression.computeNullStatus(0, combinedStatus); + if (status > 0) + this.nullStatus = status; + } + + @Override + protected void completeNormallyCheck(BlockScope blockScope) { + if (this.switchLabeledRules) return; // already taken care in getFallThroughState() + int sz = this.statements != null ? this.statements.length : 0; + if (sz == 0) return; + /* JLS 12 15.28.1 + * If, on the other hand, the switch block consists of switch labeled statement groups, then it is a + * compile-time error if either the last statement in the switch block can complete normally, or the + * switch block includes one or more switch labels at the end. + */ + Statement lastNonCaseStmt = null; + Statement firstTrailingCaseStmt = null; + for (int i = sz - 1; i >= 0; i--) { + Statement stmt = this.statements[sz - 1]; + if (stmt instanceof CaseStatement) + firstTrailingCaseStmt = stmt; + else { + lastNonCaseStmt = stmt; + break; + } + } + if (lastNonCaseStmt != null && !lastNonCaseStmt.doesNotCompleteNormally()) { + blockScope.problemReporter().switchExpressionLastStatementCompletesNormally(lastNonCaseStmt); + } + if (firstTrailingCaseStmt != null) { + blockScope.problemReporter().switchExpressionTrailingSwitchLabels(firstTrailingCaseStmt); + } + } + @Override + public Expression[] getPolyExpressions() { + List<Expression> polys = new ArrayList<>(); + for (Expression e : this.resultExpressions) { + Expression[] ea = e.getPolyExpressions(); + if (ea == null || ea.length ==0) continue; + polys.addAll(Arrays.asList(ea)); + } + return polys.toArray(new Expression[0]); + } + @Override + public boolean isPertinentToApplicability(TypeBinding targetType, MethodBinding method) { + for (Expression e : this.resultExpressions) { + if (!e.isPertinentToApplicability(targetType, method)) + return false; + } + return true; + } + @Override + public boolean isPotentiallyCompatibleWith(TypeBinding targetType, Scope scope1) { + for (Expression e : this.resultExpressions) { + if (!e.isPotentiallyCompatibleWith(targetType, scope1)) + return false; + } + return true; + } + @Override + public boolean isFunctionalType() { + for (Expression e : this.resultExpressions) { + if (e.isFunctionalType()) // return true even for one functional type + return true; + } + return false; + } + @Override + public int nullStatus(FlowInfo flowInfo, FlowContext flowContext) { + if ((this.implicitConversion & TypeIds.BOXING) != 0) + return FlowInfo.NON_NULL; + return this.nullStatus; + } + @Override + protected void statementGenerateCode(BlockScope currentScope, CodeStream codeStream, Statement statement) { + if (!(statement instanceof Expression) + || statement instanceof Assignment + || statement instanceof MessageSend + || (statement instanceof SwitchStatement && !(statement instanceof SwitchExpression))) { + super.statementGenerateCode(currentScope, codeStream, statement); + return; + } + Expression expression1 = (Expression) statement; + expression1.generateCode(currentScope, codeStream, true /* valueRequired */); + } + @Override + public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) { + super.generateCode(currentScope, codeStream); + if (!valueRequired) { + // switch expression is saved to a variable that is not used. We need to pop the generated value from the stack + switch(postConversionType(currentScope).id) { + case TypeIds.T_long : + case TypeIds.T_double : + codeStream.pop2(); + break; + case TypeIds.T_void : + break; + default : + codeStream.pop(); + break; + } + } + } + protected boolean computeConversions(BlockScope blockScope, TypeBinding targetType) { + boolean ok = true; + for (int i = 0, l = this.resultExpressions.size(); i < l; ++i) { + ok &= computeConversionsResultExpressions(blockScope, targetType, this.originalValueResultExpressionTypes[i], this.resultExpressions.get(i)); + } + return ok; + } + private boolean computeConversionsResultExpressions(BlockScope blockScope, TypeBinding targetType, TypeBinding resultExpressionType, + Expression resultExpression) { + if (resultExpressionType != null && resultExpressionType.isValidBinding()) { + if (resultExpression.isConstantValueOfTypeAssignableToType(resultExpressionType, targetType) + || resultExpressionType.isCompatibleWith(targetType)) { + + resultExpression.computeConversion(blockScope, targetType, resultExpressionType); + if (resultExpressionType.needsUncheckedConversion(targetType)) { + blockScope.problemReporter().unsafeTypeConversion(resultExpression, resultExpressionType, targetType); + } + if (resultExpression instanceof CastExpression + && (resultExpression.bits & (ASTNode.UnnecessaryCast|ASTNode.DisableUnnecessaryCastCheck)) == 0) { + CastExpression.checkNeedForAssignedCast(blockScope, targetType, (CastExpression) resultExpression); + } + } else if (isBoxingCompatible(resultExpressionType, targetType, resultExpression, blockScope)) { + resultExpression.computeConversion(blockScope, targetType, resultExpressionType); + if (resultExpression instanceof CastExpression + && (resultExpression.bits & (ASTNode.UnnecessaryCast|ASTNode.DisableUnnecessaryCastCheck)) == 0) { + CastExpression.checkNeedForAssignedCast(blockScope, targetType, (CastExpression) resultExpression); + } + } else { + blockScope.problemReporter().typeMismatchError(resultExpressionType, targetType, resultExpression, null); + return false; + } + } + return true; + } + /* package */ void collectResultExpressions() { + if (this.resultExpressions != null) + return; // already calculated. + + class ResultExpressionsCollector extends ASTVisitor { + Stack<SwitchExpression> targetSwitchExpressions; + public ResultExpressionsCollector(SwitchExpression se) { + if (this.targetSwitchExpressions == null) + this.targetSwitchExpressions = new Stack<>(); + this.targetSwitchExpressions.push(se); + } + @Override + public boolean visit(SwitchExpression switchExpression, BlockScope blockScope) { + if (switchExpression.resultExpressions == null) + switchExpression.resultExpressions = new ArrayList<>(0); + this.targetSwitchExpressions.push(switchExpression); + return true; + } + @Override + public void endVisit(SwitchExpression switchExpression, BlockScope blockScope) { + this.targetSwitchExpressions.pop(); + } + @Override + public boolean visit(BreakStatement breakStatement, BlockScope blockScope) { + SwitchExpression targetSwitchExpression = this.targetSwitchExpressions.peek(); + if (breakStatement.expression != null) { + targetSwitchExpression.resultExpressions.add(breakStatement.expression); + breakStatement.switchExpression = this.targetSwitchExpressions.peek(); + breakStatement.label = null; // not a label, but an expression + if (breakStatement.expression instanceof SingleNameReference) { + ((SingleNameReference) breakStatement.expression).isLabel = false; + } + } else { + // flag an error while resolving + breakStatement.switchExpression = targetSwitchExpression; + } + return true; + } + @Override + public boolean visit(DoStatement stmt, BlockScope blockScope) { + return false; + } + @Override + public boolean visit(ForStatement stmt, BlockScope blockScope) { + return false; + } + @Override + public boolean visit(ForeachStatement stmt, BlockScope blockScope) { + return false; + } + @Override + public boolean visit(SwitchStatement stmt, BlockScope blockScope) { + return false; + } + @Override + public boolean visit(TypeDeclaration stmt, BlockScope blockScope) { + return false; + } + @Override + public boolean visit(WhileStatement stmt, BlockScope blockScope) { + return false; + } + @Override + public boolean visit(CaseStatement caseStatement, BlockScope blockScope) { + return true; // do nothing by default, keep traversing + } + } + this.resultExpressions = new ArrayList<>(0); // indicates processed + int l = this.statements == null ? 0 : this.statements.length; + for (int i = 0; i < l; ++i) { + Statement stmt = this.statements[i]; + if (stmt instanceof CaseStatement) { + CaseStatement caseStatement = (CaseStatement) stmt; + if (!caseStatement.isExpr) continue; + stmt = this.statements[++i]; + if (stmt instanceof Expression) { + this.resultExpressions.add((Expression) stmt); + continue; + } else if (stmt instanceof ThrowStatement) { + // TODO: Throw Expression Processing. Anything to be done here for resolve? + continue; + } + } + // break statement and block statement of SwitchLabelRule or block statement of ':' + ResultExpressionsCollector reCollector = new ResultExpressionsCollector(this); + stmt.traverse(reCollector, this.scope); + } + } + @Override + public TypeBinding resolveType(BlockScope upperScope) { + try { + int resultExpressionsCount; + if (this.constant != Constant.NotAConstant) { + this.constant = Constant.NotAConstant; + + // tag break statements and (alongwith in the same pass) collect the result expressions + collectResultExpressions(); + + // A switch expression is a poly expression if it appears in an assignment context or an invocation context (5.2, 5.3). + // Otherwise, it is a standalone expression. + if (this.expressionContext == ASSIGNMENT_CONTEXT || this.expressionContext == INVOCATION_CONTEXT) { + for (Expression e : this.resultExpressions) { + //Where a poly switch expression appears in a context of a particular kind with target type T, + //its result expressions similarly appear in a context of the same kind with target type T. + e.setExpressionContext(this.expressionContext); + e.setExpectedType(this.expectedType); + } + } + + resolve(upperScope); + + if (this.statements == null || this.statements.length == 0) { + // Report Error JLS 12 15.28.1 The switch block must not be empty. + upperScope.problemReporter().switchExpressionEmptySwitchBlock(this); + return null; + } + + resultExpressionsCount = this.resultExpressions != null ? this.resultExpressions.size() : 0; + if (resultExpressionsCount == 0) { + // Report Error JLS 12 15.28.1 + // It is a compile-time error if a switch expression has no result expressions. + upperScope.problemReporter().switchExpressionNoResultExpressions(this); + return null; + } + + if (this.originalValueResultExpressionTypes == null) { + this.originalValueResultExpressionTypes = new TypeBinding[resultExpressionsCount]; + this.finalValueResultExpressionTypes = new TypeBinding[resultExpressionsCount]; + for (int i = 0; i < resultExpressionsCount; ++i) { + this.finalValueResultExpressionTypes[i] = this.originalValueResultExpressionTypes[i] = + this.resultExpressions.get(i).resolvedType; + } + } + if (isPolyExpression()) { //The type of a poly switch expression is the same as its target type. + if (this.expectedType == null || !this.expectedType.isProperType(true)) { + return new PolyTypeBinding(this); + } + return this.resolvedType = computeConversions(this.scope, this.expectedType) ? this.expectedType : null; + } + // fall through + } else { + // re-resolving of poly expression: + resultExpressionsCount = this.resultExpressions != null ? this.resultExpressions.size() : 0; + for (int i = 0; i < resultExpressionsCount; i++) { + Expression resultExpr = this.resultExpressions.get(i); + if (resultExpr.resolvedType == null || resultExpr.resolvedType.kind() == Binding.POLY_TYPE) { + this.finalValueResultExpressionTypes[i] = this.originalValueResultExpressionTypes[i] = + resultExpr.resolveTypeExpecting(upperScope, this.expectedType); + } + // This is a kludge and only way completion can tell this node to resolve all + // resultExpressions. Ideal solution is to remove all other expressions except + // the one that contain the completion node. + if (this.resolveAll) continue; + if (resultExpr.resolvedType == null || !resultExpr.resolvedType.isValidBinding()) + return this.resolvedType = null; + } + this.resolvedType = computeConversions(this.scope, this.expectedType) ? this.expectedType : null; + // fall through + } + + if (resultExpressionsCount == 1) + return this.resolvedType = this.originalValueResultExpressionTypes[0]; + + boolean typeUniformAcrossAllArms = true; + TypeBinding tmp = this.originalValueResultExpressionTypes[0]; + for (int i = 1, l = this.originalValueResultExpressionTypes.length; i < l; ++i) { + TypeBinding originalType = this.originalValueResultExpressionTypes[i]; + if (originalType != null && TypeBinding.notEquals(tmp, originalType)) { + typeUniformAcrossAllArms = false; + break; + } + } + // If the result expressions all have the same type (which may be the null type), + // then that is the type of the switch expression. + if (typeUniformAcrossAllArms) { + tmp = this.originalValueResultExpressionTypes[0]; + for (int i = 1; i < resultExpressionsCount; ++i) { + if (this.originalValueResultExpressionTypes[i] != null) + tmp = NullAnnotationMatching.moreDangerousType(tmp, this.originalValueResultExpressionTypes[i]); + } + return this.resolvedType = tmp; + } + + boolean typeBbolean = true; + for (TypeBinding t : this.originalValueResultExpressionTypes) { + if (t != null) + typeBbolean &= t.id == T_boolean || t.id == T_JavaLangBoolean; + } + LookupEnvironment env = this.scope.environment(); + /* + * Otherwise, if the type of each result expression is boolean or Boolean, + * an unboxing conversion (5.1.8) is applied to each result expression of type Boolean, + * and the switch expression has type boolean. + */ + if (typeBbolean) { + for (int i = 0; i < resultExpressionsCount; ++i) { + if (this.originalValueResultExpressionTypes[i].id == T_boolean) continue; + this.finalValueResultExpressionTypes[i] = env.computeBoxingType(this.originalValueResultExpressionTypes[i]); + this.resultExpressions.get(i).computeConversion(this.scope, this.finalValueResultExpressionTypes[i], this.originalValueResultExpressionTypes[i]); + } + return this.resolvedType = TypeBinding.BOOLEAN; + } + + /* + * Otherwise, if the type of each result expression is convertible to a numeric type (5.1.8), the type + * of the switch expression is given by numeric promotion (5.6.3) applied to the result expressions. + */ + boolean typeNumeric = true; + TypeBinding resultNumeric = null; + HashSet<TypeBinding> typeSet = new HashSet<>(); + /* JLS 12 5.6.3 Switch Numeric Promotion + * When a switch expression applies numeric promotion to a set of result expressions, each of which + * must denote a value that is convertible to a numeric type, the following rules apply, in order: + * If any result expression is of a reference type, it is subjected to unboxing conversion (5.1.8). + */ + for (int i = 0; i < resultExpressionsCount; ++i) { + TypeBinding originalType = this.originalValueResultExpressionTypes[i]; + if (originalType == null) continue; + tmp = originalType.isNumericType() ? originalType : env.computeBoxingType(originalType); + if (!tmp.isNumericType()) { + typeNumeric = false; + break; + } + typeSet.add(TypeBinding.wellKnownType(this.scope, tmp.id)); + } + if (typeNumeric) { + /* If any result expression is of type double, then other result expressions that are not of type double + * are widened to double. + * Otherwise, if any result expression is of type float, then other result expressions that are not of + * type float are widened to float. + * Otherwise, if any result expression is of type long, then other result expressions that are not of + * type long are widened to long. + */ + TypeBinding[] dfl = new TypeBinding[]{// do not change the order JLS 12 5.6.3 + TypeBinding.DOUBLE, + TypeBinding.FLOAT, + TypeBinding.LONG}; + for (TypeBinding binding : dfl) { + if (typeSet.contains(binding)) { + resultNumeric = binding; + break; + } + } + + /* Otherwise, if any result expression is of type int and is not a constant expression, the other + * result expressions that are not of type int are widened to int. + */ + resultNumeric = resultNumeric != null ? resultNumeric : check_nonconstant_int(); + + resultNumeric = resultNumeric != null ? resultNumeric : // one among the first few rules applied. + getResultNumeric(typeSet, this.originalValueResultExpressionTypes); // check the rest + typeSet = null; // hey gc! + for (int i = 0; i < resultExpressionsCount; ++i) { + // auto-unboxing and/or widening/narrrowing JLS 12 5.6.3 + this.resultExpressions.get(i).computeConversion(this.scope, + resultNumeric, this.originalValueResultExpressionTypes[i]); + this.finalValueResultExpressionTypes[i] = resultNumeric; + } + // After the conversion(s), if any, value set conversion (5.1.13) is then applied to each result expression. + return this.resolvedType = resultNumeric; + } + + /* Otherwise, boxing conversion (5.1.7) is applied to each result expression that has a primitive type, + * after which the type of the switch expression is the result of applying capture conversion (5.1.10) + * to the least upper bound (4.10.4) of the types of the result expressions. + */ + for (int i = 0; i < resultExpressionsCount; ++i) { + TypeBinding finalType = this.finalValueResultExpressionTypes[i]; + if (finalType != null && finalType.isBaseType()) + this.finalValueResultExpressionTypes[i] = env.computeBoxingType(finalType); + } + TypeBinding commonType = this.scope.lowerUpperBound(this.finalValueResultExpressionTypes); + if (commonType != null) { + for (int i = 0, l = this.resultExpressions.size(); i < l; ++i) { + if (this.originalValueResultExpressionTypes[i] == null) continue; + this.resultExpressions.get(i).computeConversion(this.scope, commonType, this.originalValueResultExpressionTypes[i]); + this.finalValueResultExpressionTypes[i] = commonType; + } + return this.resolvedType = commonType.capture(this.scope, this.sourceStart, this.sourceEnd); + } + this.scope.problemReporter().switchExpressionIncompatibleResultExpressions(this); + return null; + } finally { + if (this.scope != null) this.scope.enclosingCase = null; // no longer inside switch case block + } + } + private TypeBinding check_nonconstant_int() { + for (int i = 0, l = this.resultExpressions.size(); i < l; ++i) { + Expression e = this.resultExpressions.get(i); + TypeBinding type = this.originalValueResultExpressionTypes[i]; + if (type != null && type.id == T_int && e.constant == Constant.NotAConstant) + return TypeBinding.INT; + } + return null; + } + private boolean areAllIntegerResultExpressionsConvertibleToTargetType(TypeBinding targetType) { + for (int i = 0, l = this.resultExpressions.size(); i < l; ++i) { + Expression e = this.resultExpressions.get(i); + TypeBinding t = this.originalValueResultExpressionTypes[i]; + if (!TypeBinding.equalsEquals(t, TypeBinding.INT)) continue; + if (!e.isConstantValueOfTypeAssignableToType(t, targetType)) + return false; + } + return true; + } + @Override + public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) { + flowInfo = super.analyseCode(currentScope, flowContext, flowInfo); + this.resultExpressionNullStatus = new ArrayList<>(0); + final CompilerOptions compilerOptions = currentScope.compilerOptions(); + if (compilerOptions.enableSyntacticNullAnalysisForFields) { + for (Expression re : this.resultExpressions) { + this.resultExpressionNullStatus.add(re.nullStatus(flowInfo, flowContext)); + // wipe information that was meant only for this result expression: + flowContext.expireNullCheckedFieldInfo(); + } + } + computeNullStatus(flowInfo, flowContext); + return flowInfo; + } + private TypeBinding check_csb(Set<TypeBinding> typeSet, TypeBinding candidate) { + if (!typeSet.contains(candidate)) + return null; + + TypeBinding[] allowedTypes = SwitchExpression.type_map.get(candidate); + Set<TypeBinding> allowedSet = Arrays.stream(allowedTypes).collect(Collectors.toSet()); + + if (!allowedSet.containsAll(typeSet)) + return null; + + return areAllIntegerResultExpressionsConvertibleToTargetType(candidate) ? + candidate : null; + } + private TypeBinding getResultNumeric(Set<TypeBinding> typeSet, TypeBinding[] armTypes) { + // note: if an expression has a type integer, then it will be a constant + // since non-constant integers are already processed before reaching here. + + /* + * Otherwise, if any result expression is of type char, and every other result expression is either of + * type char, or of type byte, or a constant expression of type int with a value that is representable + * in the type char, then the byte results are widened to char and the int results are narrowed to char. + */ + + /* Otherwise, if any result expression is of type short, and every other result expression is either of + * type short, or of type byte, or a constant expression of type int with a value that is representable + * in the type short, then the byte results are widened to short and the int results are narrowed to + * short. + */ + /* Otherwise, if any result expression is of type byte, and every other result expression is either of + * type byte or a constant expression of type int with a value that is representable in the type byte, + * then the int results are narrowed to byte. + */ + + // DO NOT Change the order below [as per JLS 12 5.6.3 item 2, sub-items 5,6 and 7]. + TypeBinding[] csb = new TypeBinding[] {TypeBinding.CHAR, TypeBinding.SHORT, TypeBinding.BYTE}; + for (TypeBinding c : csb) { + TypeBinding result = check_csb(typeSet, c); + if (result != null) + return result; + } + /* Otherwise, all the result expressions that are not of type int are widened to int. */ + return TypeBinding.INT; + } + @Override + public boolean isPolyExpression() { + if (this.isPolyExpression) + return true; + // JLS 12 15.28.1 A switch expression is a poly expression if it appears in an assignment context or + // an invocation context (5.2, 5.3). Otherwise, it is a standalone expression. + return this.isPolyExpression = this.expressionContext == ASSIGNMENT_CONTEXT || + this.expressionContext == INVOCATION_CONTEXT; + } + @Override + public boolean isCompatibleWith(TypeBinding left, Scope skope) { + if (!isPolyExpression()) + return super.isCompatibleWith(left, skope); + + for (Expression e : this.resultExpressions) { + if (!e.isCompatibleWith(left, skope)) + return false; + } + return true; + } + @Override + public boolean isBoxingCompatibleWith(TypeBinding targetType, Scope skope) { + if (!isPolyExpression()) + return super.isBoxingCompatibleWith(targetType, skope); + + for (Expression e : this.resultExpressions) { + if (!(e.isCompatibleWith(targetType, skope) || e.isBoxingCompatibleWith(targetType, skope))) + return false; + } + return true; + } + @Override + public boolean sIsMoreSpecific(TypeBinding s, TypeBinding t, Scope skope) { + if (super.sIsMoreSpecific(s, t, skope)) + return true; + if (!isPolyExpression()) + return false; + for (Expression e : this.resultExpressions) { + if (!e.sIsMoreSpecific(s, t, skope)) + return false; + } + return true; + } + @Override + public TypeBinding expectedType() { + return this.expectedType; + } + @Override + public void traverse( + ASTVisitor visitor, + BlockScope blockScope) { + + if (visitor.visit(this, blockScope)) { + this.expression.traverse(visitor, blockScope); + if (this.statements != null) { + int statementsLength = this.statements.length; + for (int i = 0; i < statementsLength; i++) + this.statements[i].traverse(visitor, this.scope); + } + } + visitor.endVisit(this, blockScope); + } +}
\ No newline at end of file diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SwitchStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SwitchStatement.java index 15dbd6bfda..8670e38554 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SwitchStatement.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SwitchStatement.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2017 IBM Corporation and others. + * Copyright (c) 2000, 2019 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -8,6 +8,10 @@ * * SPDX-License-Identifier: EPL-2.0 * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * IBM Corporation - initial API and implementation * Stephan Herrmann - Contributions for @@ -43,7 +47,7 @@ import org.eclipse.jdt.internal.compiler.lookup.TypeIds; import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities; @SuppressWarnings("rawtypes") -public class SwitchStatement extends Statement { +public class SwitchStatement extends Expression { public Expression expression; public Statement[] statements; @@ -55,12 +59,15 @@ public class SwitchStatement extends Statement { public int blockStart; public int caseCount; int[] constants; + int[] constMapping; String[] stringConstants; + public boolean switchLabeledRules = false; // true if case ->, false if case : // fallthrough public final static int CASE = 0; public final static int FALLTHROUGH = 1; public final static int ESCAPING = 2; + public final static int BREAKING = 3; // for switch on strings private static final char[] SecretStringVariableName = " switchDispatchString".toCharArray(); //$NON-NLS-1$ @@ -76,6 +83,38 @@ public class SwitchStatement extends Statement { int duplicateCaseStatementsCounter = 0; private LocalVariableBinding dispatchStringCopy = null; + protected int getFallThroughState(Statement stmt, BlockScope blockScope) { + if (this.switchLabeledRules) { + if (stmt instanceof Expression || stmt instanceof ThrowStatement) + return BREAKING; + + if (stmt instanceof Block) { + Block block = (Block) stmt; + if (block.doesNotCompleteNormally()) { + return BREAKING; + } + // else add an implicit break + BreakStatement breakStatement = new BreakStatement(null, block.sourceEnd -1, block.sourceEnd); + breakStatement.isImplicit = true; + + int l = block.statements == null ? 0 : block.statements.length; + if (l == 0) { + block.statements = new Statement[] {breakStatement}; + block.scope = this.scope; // (upper scope) see Block.resolve() for similar + } else { + Statement[] newArray = new Statement[l + 1]; + System.arraycopy(block.statements, 0, newArray, 0, l); + newArray[l] = breakStatement; + block.statements = newArray; + } + return BREAKING; + } + } + return FALLTHROUGH; + } + protected void completeNormallyCheck(BlockScope blockScope) { + // do nothing + } @Override public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) { try { @@ -120,7 +159,7 @@ public class SwitchStatement extends Statement { complaintLevel = initialComplaintLevel; // reset complaint fallThroughState = CASE; } else { - fallThroughState = FALLTHROUGH; // reset below if needed + fallThroughState = getFallThroughState(statement, currentScope); // reset below if needed } if ((complaintLevel = statement.complainIfUnreachable(caseInits, this.scope, complaintLevel, true)) < Statement.COMPLAINED_UNREACHABLE) { caseInits = statement.analyseCode(this.scope, switchContext, caseInits); @@ -130,6 +169,7 @@ public class SwitchStatement extends Statement { switchContext.expireNullCheckedFieldInfo(); } } + completeNormallyCheck(currentScope); } final TypeBinding resolvedTypeBinding = this.expression.resolvedType; @@ -199,33 +239,60 @@ public class SwitchStatement extends Statement { "case " + this.hashCode + ":(" + this.string + ")\n"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } } - + /* + * With multi constant case statements, the number of case statements (hence branch labels) + * and number of constants (hence hashcode labels) could be different. For e.g: + + switch(s) { + case "FB", "c": + System.out.println("A/C"); + break; + case "Ea": + System.out.println("B"); + break; + + With the above code, we will have + 2 branch labels for FB and c + 3 stringCases for FB, c and Ea + 2 hashCodeCaseLabels one for FB, Ea and one for c + + Should produce something like this: + lookupswitch { // 2 + 99: 32 + 2236: 44 + default: 87 + + "FB" and "Ea" producing the same hashcode values, but still belonging in different case statements. + First, produce the two branch labels pertaining to the case statements + And the three string cases and use the this.constMapping to get the correct branch label. + */ final boolean hasCases = this.caseCount != 0; - - StringSwitchCase [] stringCases = new StringSwitchCase[this.caseCount]; // may have to shrink later if multiple strings hash to same code. + int constSize = hasCases ? this.stringConstants.length : 0; BranchLabel[] sourceCaseLabels = new BranchLabel[this.caseCount]; - CaseLabel [] hashCodeCaseLabels = new CaseLabel[this.caseCount]; - this.constants = new int[this.caseCount]; // hashCode() values. for (int i = 0, max = this.caseCount; i < max; i++) { this.cases[i].targetLabel = (sourceCaseLabels[i] = new BranchLabel(codeStream)); // A branch label, not a case label. sourceCaseLabels[i].tagBits |= BranchLabel.USED; - stringCases[i] = new StringSwitchCase(this.stringConstants[i].hashCode(), this.stringConstants[i], sourceCaseLabels[i]); + } + StringSwitchCase [] stringCases = new StringSwitchCase[constSize]; // may have to shrink later if multiple strings hash to same code. + CaseLabel [] hashCodeCaseLabels = new CaseLabel[constSize]; + this.constants = new int[constSize]; // hashCode() values. + for (int i = 0; i < constSize; i++) { + stringCases[i] = new StringSwitchCase(this.stringConstants[i].hashCode(), this.stringConstants[i], sourceCaseLabels[this.constMapping[i]]); hashCodeCaseLabels[i] = new CaseLabel(codeStream); hashCodeCaseLabels[i].tagBits |= BranchLabel.USED; - } Arrays.sort(stringCases); int uniqHashCount = 0; int lastHashCode = 0; - for (int i = 0, length = this.caseCount; i < length; ++i) { + for (int i = 0, length = constSize; i < length; ++i) { int hashCode = stringCases[i].hashCode; if (i == 0 || hashCode != lastHashCode) { lastHashCode = this.constants[uniqHashCount++] = hashCode; } } - if (uniqHashCount != this.caseCount) { // multiple keys hashed to the same value. + if (uniqHashCount != constSize) { // multiple keys hashed to the same value. System.arraycopy(this.constants, 0, this.constants = new int[uniqHashCount], 0, uniqHashCount); System.arraycopy(hashCodeCaseLabels, 0, hashCodeCaseLabels = new CaseLabel[uniqHashCount], 0, uniqHashCount); } @@ -252,7 +319,7 @@ public class SwitchStatement extends Statement { codeStream.invokeStringHashCode(); if (hasCases) { codeStream.lookupswitch(defaultCaseLabel, this.constants, sortedIndexes, hashCodeCaseLabels); - for (int i = 0, j = 0, max = this.caseCount; i < max; i++) { + for (int i = 0, j = 0, max = constSize; i < max; i++) { int hashCode = stringCases[i].hashCode; if (i == 0 || hashCode != lastHashCode) { lastHashCode = hashCode; @@ -291,7 +358,7 @@ public class SwitchStatement extends Statement { } } } - statement.generateCode(this.scope, codeStream); + statementGenerateCode(currentScope, codeStream, statement); } } @@ -312,6 +379,13 @@ public class SwitchStatement extends Statement { defaultCaseLabel.place(); defaultBranchLabel.place(); } + if (this.expectedType() != null) { + TypeBinding expectedType = this.expectedType().erasure(); + boolean optimizedGoto = codeStream.lastAbruptCompletion == -1; + // if the last bytecode was an optimized goto (value is already on the stack) or an enum switch without default case, then we need to adjust the + // stack depth to reflect the fact that there is an value on the stack (return type of the switch expression) + codeStream.recordExpressionType(expectedType, optimizedGoto ? 0 : 1, optimizedGoto); + } codeStream.recordPositionsFrom(pc, this.sourceStart); } finally { if (this.scope != null) this.scope.enclosingCase = null; // no longer inside switch case block @@ -339,6 +413,7 @@ public class SwitchStatement extends Statement { // prepare the labels and constants this.breakLabel.initialize(codeStream); + int constantCount = this.constants == null ? 0 : this.constants.length; CaseLabel[] caseLabels = new CaseLabel[this.caseCount]; for (int i = 0, max = this.caseCount; i < max; i++) { this.cases[i].targetLabel = (caseLabels[i] = new CaseLabel(codeStream)); @@ -351,19 +426,20 @@ public class SwitchStatement extends Statement { this.defaultCase.targetLabel = defaultLabel; } - final TypeBinding resolvedType = this.expression.resolvedType; + final TypeBinding resolvedType1 = this.expression.resolvedType; boolean valueRequired = false; - if (resolvedType.isEnum()) { + if (resolvedType1.isEnum()) { // go through the translation table codeStream.invoke(Opcodes.OPC_invokestatic, this.synthetic, null /* default declaringClass */); this.expression.generateCode(currentScope, codeStream, true); // get enum constant ordinal() - codeStream.invokeEnumOrdinal(resolvedType.constantPoolName()); + codeStream.invokeEnumOrdinal(resolvedType1.constantPoolName()); codeStream.iaload(); if (!hasCases) { // we can get rid of the generated ordinal value codeStream.pop(); } + valueRequired = hasCases; } else { valueRequired = this.expression.constant == Constant.NotAConstant || hasCases; // generate expression @@ -371,18 +447,18 @@ public class SwitchStatement extends Statement { } // generate the appropriate switch table/lookup bytecode if (hasCases) { - int[] sortedIndexes = new int[this.caseCount]; + int[] sortedIndexes = new int[constantCount]; // we sort the keys to be able to generate the code for tableswitch or lookupswitch - for (int i = 0; i < this.caseCount; i++) { + for (int i = 0; i < constantCount; i++) { sortedIndexes[i] = i; } int[] localKeysCopy; - System.arraycopy(this.constants, 0, (localKeysCopy = new int[this.caseCount]), 0, this.caseCount); - CodeStream.sort(localKeysCopy, 0, this.caseCount - 1, sortedIndexes); + System.arraycopy(this.constants, 0, (localKeysCopy = new int[constantCount]), 0, constantCount); + CodeStream.sort(localKeysCopy, 0, constantCount - 1, sortedIndexes); - int max = localKeysCopy[this.caseCount - 1]; + int max = localKeysCopy[constantCount - 1]; int min = localKeysCopy[0]; - if ((long) (this.caseCount * 2.5) > ((long) max - (long) min)) { + if ((long) (constantCount * 2.5) > ((long) max - (long) min)) { // work-around 1.3 VM bug, if max>0x7FFF0000, must use lookup bytecode // see http://dev.eclipse.org/bugs/show_bug.cgi?id=21557 @@ -396,6 +472,7 @@ public class SwitchStatement extends Statement { max, this.constants, sortedIndexes, + this.constMapping, caseLabels); } } else { @@ -411,7 +488,7 @@ public class SwitchStatement extends Statement { if (this.statements != null) { for (int i = 0, maxCases = this.statements.length; i < maxCases; i++) { Statement statement = this.statements[i]; - if ((caseIndex < this.caseCount) && (statement == this.cases[caseIndex])) { // statements[i] is a case + if ((caseIndex < constantCount) && (statement == this.cases[caseIndex])) { // statements[i] is a case this.scope.enclosingCase = this.cases[caseIndex]; // record entering in a switch case block if (this.preSwitchInitStateIndex != -1) { codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.preSwitchInitStateIndex); @@ -425,9 +502,30 @@ public class SwitchStatement extends Statement { } } } - statement.generateCode(this.scope, codeStream); + statementGenerateCode(currentScope, codeStream, statement); } } + boolean enumInSwitchExpression = resolvedType1.isEnum() && this instanceof SwitchExpression; + boolean isEnumSwitchWithoutDefaultCase = this.defaultCase == null && enumInSwitchExpression; + if (isEnumSwitchWithoutDefaultCase) { + // we want to force an line number entry to get an end position after the switch statement + if (this.preSwitchInitStateIndex != -1) { + codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.preSwitchInitStateIndex); + } + defaultLabel.place(); + /* a default case is not needed for enum if all enum values are used in the switch expression + * we need to handle the default case to throw an error (IncompatibleClassChangeError) in order + * to make the stack map consistent. All cases will return a value on the stack except the missing default + * case. + * There is no returned value for the default case so we handle it with an exception thrown. An + * IllegalClassChangeError seems legitimate as this would mean the enum type has been recompiled with more + * enum constants and the class that is using the switch on the enum has not been recompiled + */ + codeStream.newJavaLangIncompatibleClassChangeError(); + codeStream.dup(); + codeStream.invokeJavaLangIncompatibleClassChangeErrorDefaultConstructor(); + codeStream.athrow(); + } // May loose some local variable initializations : affecting the local variable attributes if (this.mergedInitStateIndex != -1) { codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.mergedInitStateIndex); @@ -438,18 +536,35 @@ public class SwitchStatement extends Statement { } // place the trailing labels (for break and default case) this.breakLabel.place(); - if (this.defaultCase == null) { + if (this.defaultCase == null && !enumInSwitchExpression) { // we want to force an line number entry to get an end position after the switch statement codeStream.recordPositionsFrom(codeStream.position, this.sourceEnd, true); defaultLabel.place(); } + if (this instanceof SwitchExpression) { + TypeBinding switchResolveType = this.resolvedType; + if (this.expectedType() != null) { + switchResolveType = this.expectedType().erasure(); + } + boolean optimizedGoto = codeStream.lastAbruptCompletion == -1; + // if the last bytecode was an optimized goto (value is already on the stack) or an enum switch without default case, then we need to adjust the + // stack depth to reflect the fact that there is an value on the stack (return type of the switch expression) + codeStream.recordExpressionType(switchResolveType, optimizedGoto ? 0 : 1, optimizedGoto || isEnumSwitchWithoutDefaultCase); + } codeStream.recordPositionsFrom(pc, this.sourceStart); } finally { if (this.scope != null) this.scope.enclosingCase = null; // no longer inside switch case block } } + protected void statementGenerateCode(BlockScope currentScope, CodeStream codeStream, Statement statement) { + statement.generateCode(this.scope, codeStream); + } @Override + public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) { + generateCode(currentScope, codeStream); // redirecting to statement part + } + @Override public StringBuffer printStatement(int indent, StringBuffer output) { printIndent(indent, output).append("switch ("); //$NON-NLS-1$ @@ -519,32 +634,52 @@ public class SwitchStatement extends Statement { this.cases = new CaseStatement[length = this.statements.length]; if (!isStringSwitch) { this.constants = new int[length]; + this.constMapping = new int[length]; } else { this.stringConstants = new String[length]; + this.constMapping = new int[length]; } int counter = 0; for (int i = 0; i < length; i++) { - Constant constant; + Constant[] constantsList; final Statement statement = this.statements[i]; - if ((constant = statement.resolveCase(this.scope, expressionType, this)) != Constant.NotAConstant) { - if (!isStringSwitch) { - int key = constant.intValue(); - //----check for duplicate case statement------------ - for (int j = 0; j < counter; j++) { - if (this.constants[j] == key) { - reportDuplicateCase((CaseStatement) statement, this.cases[j], length); + if (!(statement instanceof CaseStatement)) { + statement.resolve(this.scope); + continue; + } + if ((constantsList = statement.resolveCase(this.scope, expressionType, this)) != Constant.NotAConstantList) { + for (Constant con : constantsList) { + if (con == Constant.NotAConstant) + continue; + if (!isStringSwitch) { + int key = con.intValue(); + //----check for duplicate case statement------------ + for (int j = 0; j < counter; j++) { + if (this.constants[j] == key) { + reportDuplicateCase((CaseStatement) statement, this.cases[j], length); + } } - } - this.constants[counter++] = key; - } else { - String key = constant.stringValue(); - //----check for duplicate case statement------------ - for (int j = 0; j < counter; j++) { - if (this.stringConstants[j].equals(key)) { - reportDuplicateCase((CaseStatement) statement, this.cases[j], length); + if (this.constants.length == counter) { + System.arraycopy(this.constants, 0, this.constants = new int[counter+1], 0, counter); + System.arraycopy(this.constMapping, 0, this.constMapping = new int[counter+1], 0, counter); + } + this.constants[counter] = key; + this.constMapping[counter++] = this.caseCount - 1; + } else { + String key = con.stringValue(); + //----check for duplicate case statement------------ + for (int j = 0; j < counter; j++) { + if (this.stringConstants[j].equals(key)) { + reportDuplicateCase((CaseStatement) statement, this.cases[j], length); + } + } + if (this.stringConstants.length == counter) { + System.arraycopy(this.stringConstants, 0, this.stringConstants = new String[counter+1], 0, counter); + System.arraycopy(this.constMapping, 0, this.constMapping = new int[counter+1], 0, counter); } + this.stringConstants[counter] = key; + this.constMapping[counter++] = this.caseCount - 1; } - this.stringConstants[counter++] = key; } } } @@ -554,15 +689,17 @@ public class SwitchStatement extends Statement { } else { System.arraycopy(this.stringConstants, 0, this.stringConstants = new String[counter], 0, counter); } + System.arraycopy(this.constMapping, 0, this.constMapping = new int[counter], 0, counter); } } else { if ((this.bits & UndocumentedEmptyBlock) != 0) { upperScope.problemReporter().undocumentedEmptyBlock(this.blockStart, this.sourceEnd); } } + reportMixingCaseTypes(); // check default case for all kinds of switch: if (this.defaultCase == null) { - if (compilerOptions.getSeverity(CompilerOptions.MissingDefaultCase) == ProblemSeverities.Ignore) { + if (ignoreMissingDefaultCase(compilerOptions, isEnumSwitch)) { if (isEnumSwitch) { upperScope.methodScope().hasMissingSwitchDefault = true; } @@ -574,21 +711,21 @@ public class SwitchStatement extends Statement { if (isEnumSwitch && compilerOptions.complianceLevel >= ClassFileConstants.JDK1_5) { if (this.defaultCase == null || compilerOptions.reportMissingEnumCaseDespiteDefault) { int constantCount = this.constants == null ? 0 : this.constants.length; // could be null if no case statement - if (constantCount == this.caseCount - && this.caseCount != ((ReferenceBinding)expressionType).enumConstantCount()) { + if (constantCount >= this.caseCount + && constantCount != ((ReferenceBinding)expressionType).enumConstantCount()) { FieldBinding[] enumFields = ((ReferenceBinding)expressionType.erasure()).fields(); for (int i = 0, max = enumFields.length; i <max; i++) { FieldBinding enumConstant = enumFields[i]; if ((enumConstant.modifiers & ClassFileConstants.AccEnum) == 0) continue; findConstant : { - for (int j = 0; j < this.caseCount; j++) { + for (int j = 0; j < constantCount; j++) { if ((enumConstant.id + 1) == this.constants[j]) // zero should not be returned see bug 141810 break findConstant; } // enum constant did not get referenced from switch boolean suppress = (this.defaultCase != null && (this.defaultCase.bits & DocumentedCasesOmitted) != 0); if (!suppress) { - upperScope.problemReporter().missingEnumConstantCase(this, enumConstant); + reportMissingEnumConstantCase(upperScope, enumConstant); } } } @@ -599,7 +736,29 @@ public class SwitchStatement extends Statement { if (this.scope != null) this.scope.enclosingCase = null; // no longer inside switch case block } } + protected void reportMissingEnumConstantCase(BlockScope upperScope, FieldBinding enumConstant) { + upperScope.problemReporter().missingEnumConstantCase(this, enumConstant); + } + protected boolean ignoreMissingDefaultCase(CompilerOptions compilerOptions, boolean isEnumSwitch) { + return compilerOptions.getSeverity(CompilerOptions.MissingDefaultCase) == ProblemSeverities.Ignore; + } + private void reportMixingCaseTypes() { + if (this.caseCount == 0) { + this.switchLabeledRules = this.defaultCase != null ? this.defaultCase.isExpr : this.switchLabeledRules; + return; + } + boolean isExpr = this.switchLabeledRules = this.cases[0].isExpr; + for (int i = 1, l = this.caseCount; i < l; ++i) { + if (this.cases[i].isExpr != isExpr) { + this.scope.problemReporter().switchExpressionMixedCase(this.cases[i]); + return; + } + } + if (this.defaultCase != null && this.defaultCase.isExpr != isExpr) { + this.scope.problemReporter().switchExpressionMixedCase(this.defaultCase); + } + } private void reportDuplicateCase(final CaseStatement duplicate, final CaseStatement original, int length) { if (this.duplicateCaseStatements == null) { this.scope.problemReporter().duplicateCase(original); @@ -675,4 +834,9 @@ public class SwitchStatement extends Statement { } return false; } + + @Override + public StringBuffer printExpression(int indent, StringBuffer output) { + return printStatement(indent, output); + } } diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileConstants.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileConstants.java index bfcdf5e888..8093adc10c 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileConstants.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileConstants.java @@ -6,6 +6,10 @@ * which accompanies this distribution, and is available at * https://www.eclipse.org/legal/epl-2.0/ * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * SPDX-License-Identifier: EPL-2.0 * * Contributors: @@ -128,9 +132,10 @@ public interface ClassFileConstants { int MAJOR_VERSION_9 = 53; int MAJOR_VERSION_10 = 54; int MAJOR_VERSION_11 = 55; + int MAJOR_VERSION_12 = 56; int MAJOR_VERSION_0 = 44; - int MAJOR_LATEST_VERSION = MAJOR_VERSION_11; + int MAJOR_LATEST_VERSION = MAJOR_VERSION_12; int MINOR_VERSION_0 = 0; int MINOR_VERSION_1 = 1; @@ -152,6 +157,7 @@ public interface ClassFileConstants { long JDK9 = ((long)ClassFileConstants.MAJOR_VERSION_9 << 16) + ClassFileConstants.MINOR_VERSION_0; long JDK10 = ((long)ClassFileConstants.MAJOR_VERSION_10 << 16) + ClassFileConstants.MINOR_VERSION_0; long JDK11 = ((long)ClassFileConstants.MAJOR_VERSION_11 << 16) + ClassFileConstants.MINOR_VERSION_0; + long JDK12 = ((long)ClassFileConstants.MAJOR_VERSION_12 << 16) + ClassFileConstants.MINOR_VERSION_0; public static long getLatestJDKLevel() { return ((long)ClassFileConstants.MAJOR_LATEST_VERSION << 16) + ClassFileConstants.MINOR_VERSION_0; diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java index 0c43198eea..5f4cc19307 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java @@ -4567,7 +4567,16 @@ public void invokeJavaLangAssertionErrorDefaultConstructor() { ConstantPool.Init, ConstantPool.DefaultConstructorSignature); } - +public void invokeJavaLangIncompatibleClassChangeErrorDefaultConstructor() { + // invokespecial: java.lang.IncompatibleClassChangeError.<init>()V + invoke( + Opcodes.OPC_invokespecial, + 1, // receiverAndArgsSize + 0, // return type size + ConstantPool.JavaLangIncompatibleClassChangeErrorConstantPoolName, + ConstantPool.Init, + ConstantPool.DefaultConstructorSignature); +} public void invokeJavaLangClassDesiredAssertionStatus() { // invokevirtual: java.lang.Class.desiredAssertionStatus()Z; invoke( @@ -6142,7 +6151,19 @@ public void newJavaLangError() { this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_new; writeUnsignedShort(this.constantPool.literalIndexForType(ConstantPool.JavaLangErrorConstantPoolName)); } - +public void newJavaLangIncompatibleClassChangeError() { + // new: java.lang.Error + this.countLabels = 0; + this.stackDepth++; + if (this.stackDepth > this.stackMax) + this.stackMax = this.stackDepth; + if (this.classFileOffset + 2 >= this.bCodeStream.length) { + resizeByteArray(); + } + this.position++; + this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_new; + writeUnsignedShort(this.constantPool.literalIndexForType(ConstantPool.JavaLangIncompatibleClassChangeErrorConstantPoolName)); +} public void newNoClassDefFoundError() { // new: java.lang.NoClassDefFoundError this.countLabels = 0; @@ -6297,7 +6318,9 @@ public void record(LocalVariableBinding local) { public void recordExpressionType(TypeBinding typeBinding) { // nothing to do } - +public void recordExpressionType(TypeBinding typeBinding, int delta, boolean adjustStackDepth) { + // nothing to do +} public void recordPositionsFrom(int startPC, int sourcePos) { this.recordPositionsFrom(startPC, sourcePos, false); } @@ -6895,7 +6918,7 @@ public void swap() { this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_swap; } -public void tableswitch(CaseLabel defaultLabel, int low, int high, int[] keys, int[] sortedIndexes, CaseLabel[] casesLabel) { +public void tableswitch(CaseLabel defaultLabel, int low, int high, int[] keys, int[] sortedIndexes, int[] mapping, CaseLabel[] casesLabel) { this.countLabels = 0; this.stackDepth--; int length = casesLabel.length; @@ -6926,7 +6949,7 @@ public void tableswitch(CaseLabel defaultLabel, int low, int high, int[] keys, i int index; int key = keys[index = sortedIndexes[j - low]]; if (key == i) { - casesLabel[index].branch(); + casesLabel[mapping[index]].branch(); j++; if (i == high) break; // if high is maxint, then avoids wrapping to minint. } else { diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/ConstantPool.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/ConstantPool.java index 276c999ed2..700a70daa5 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/ConstantPool.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/ConstantPool.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2018 IBM Corporation and others. + * Copyright (c) 2000, 2019 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -167,6 +167,7 @@ public class ConstantPool implements ClassFileConstants, TypeIds { public static final char[] JavaLangDoubleConstantPoolName = "java/lang/Double".toCharArray(); //$NON-NLS-1$ public static final char[] JavaLangEnumConstantPoolName = "java/lang/Enum".toCharArray(); //$NON-NLS-1$ public static final char[] JavaLangErrorConstantPoolName = "java/lang/Error".toCharArray(); //$NON-NLS-1$ + public static final char[] JavaLangIncompatibleClassChangeErrorConstantPoolName = "java/lang/IncompatibleClassChangeError".toCharArray(); //$NON-NLS-1$ public static final char[] JavaLangExceptionConstantPoolName = "java/lang/Exception".toCharArray(); //$NON-NLS-1$ public static final char[] JavaLangFloatConstantPoolName = "java/lang/Float".toCharArray(); //$NON-NLS-1$ public static final char[] JavaLangIntegerConstantPoolName = "java/lang/Integer".toCharArray(); //$NON-NLS-1$ diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/StackMapFrameCodeStream.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/StackMapFrameCodeStream.java index 039f188d76..f49b793159 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/StackMapFrameCodeStream.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/StackMapFrameCodeStream.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006, 2016 IBM Corporation and others. + * Copyright (c) 2006, 2019 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -91,10 +91,17 @@ public class StackMapFrameCodeStream extends CodeStream { StringBuffer buffer = new StringBuffer(); buffer.append('(').append(this.pc).append(',').append(this.delta); if (this.typeBinding != null) { - buffer - .append(',') - .append(this.typeBinding.qualifiedPackageName()) - .append(this.typeBinding.qualifiedSourceName()); + if (this.typeBinding.isBaseType()) { + buffer + .append(',') + .append(this.typeBinding.qualifiedSourceName()); + } else { + buffer + .append(',') + .append(this.typeBinding.qualifiedPackageName()) + .append('.') + .append(this.typeBinding.qualifiedSourceName()); + } } buffer.append(')'); return String.valueOf(buffer); @@ -226,6 +233,7 @@ public void addFramePosition(int pc) { public void optimizeBranch(int oldPosition, BranchLabel lbl) { super.optimizeBranch(oldPosition, lbl); removeFramePosition(oldPosition); + removeStackMapMarkers(oldPosition); } public void removeFramePosition(int pc) { Integer entry = Integer.valueOf(pc); @@ -237,6 +245,17 @@ public void removeFramePosition(int pc) { } } } +public void removeStackMapMarkers(int markerOldPosition) { + if (this.stackDepthMarkers != null) { + for (int i = this.stackDepthMarkers.size() - 1; i >= 0; i--) { + StackDepthMarker marker = (StackDepthMarker) this.stackDepthMarkers.get(i); + if (marker.pc == markerOldPosition) { + this.stackDepthMarkers.remove(i); + break; + } + } + } +} @Override public void addVariable(LocalVariableBinding localBinding) { if (localBinding.initializationPCs == null) { @@ -284,6 +303,26 @@ public void decrStackSize(int offset) { public void recordExpressionType(TypeBinding typeBinding) { addStackDepthMarker(this.position, 0, typeBinding); } +@Override +public void recordExpressionType(TypeBinding typeBinding, int delta, boolean adjustStackDepth) { + addStackDepthMarker(this.position, delta, typeBinding); + if (adjustStackDepth) { + // optimized goto + // the break label already adjusted the stack depth (-1 or -2 depending on the return type) + // we need to adjust back to what it was + switch(typeBinding.id) { + case TypeIds.T_long : + case TypeIds.T_double : + this.stackDepth+=2; + break; + case TypeIds.T_void : + break; + default : + this.stackDepth++; + break; + } + } +} /** * Macro for building a class descriptor object */ diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java index 0aaaa13246..c23712a80a 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java @@ -6,6 +6,10 @@ * which accompanies this distribution, and is available at * https://www.eclipse.org/legal/epl-2.0/ * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * SPDX-License-Identifier: EPL-2.0 * * Contributors: @@ -202,7 +206,8 @@ public class CompilerOptions { public static final String OPTION_ReportAPILeak = "org.eclipse.jdt.core.compiler.problem.APILeak"; //$NON-NLS-1$ public static final String OPTION_ReportUnstableAutoModuleName = "org.eclipse.jdt.core.compiler.problem.unstableAutoModuleName"; //$NON-NLS-1$ - public static final String OPTION_EnablePreviews = "org.eclipse.jdt.core.compiler.problem.EnablePreviews"; //$NON-NLS-1$ + public static final String OPTION_EnablePreviews = "org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures"; //$NON-NLS-1$ + public static final String OPTION_ReportPreviewFeatures = "org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures"; //$NON-NLS-1$ /** * Possible values for configurable options @@ -224,6 +229,11 @@ public class CompilerOptions { public static final String VERSION_9 = "9"; //$NON-NLS-1$ public static final String VERSION_10 = "10"; //$NON-NLS-1$ public static final String VERSION_11 = "11"; //$NON-NLS-1$ + public static final String VERSION_12 = "12"; //$NON-NLS-1$ + /* + * Note: Whenever a new version is added, make sure getLatestVersion() + * is updated with it. + */ public static final String ERROR = "error"; //$NON-NLS-1$ public static final String WARNING = "warning"; //$NON-NLS-1$ public static final String INFO = "info"; //$NON-NLS-1$ @@ -333,8 +343,7 @@ public class CompilerOptions { public static final int UsingTerminallyDeprecatedAPI = IrritantSet.GROUP2 | ASTNode.Bit24; public static final int APILeak = IrritantSet.GROUP2 | ASTNode.Bit25; public static final int UnstableAutoModuleName = IrritantSet.GROUP2 | ASTNode.Bit26; - // Dummy feature, but - //public static final int DummyPreviewFeatureWarning = IrritantSet.GROUP2 | ASTNode.Bit27; + public static final int PreviewFeatureUsed = IrritantSet.GROUP2 | ASTNode.Bit27; // Severity level for handlers @@ -583,6 +592,12 @@ public class CompilerOptions { } /** + * Return the latest Java language version supported by the Eclipse compiler + */ + public static String getLatestVersion() { + return VERSION_12; + } + /** * Return the most specific option key controlling this irritant. Note that in some case, some irritant is controlled by * other master options (e.g. javadoc, deprecation, etc.). * This information is intended for grouping purpose (several problems governed by a rule) @@ -758,6 +773,8 @@ public class CompilerOptions { return OPTION_ReportAPILeak; case UnstableAutoModuleName: return OPTION_ReportUnstableAutoModuleName; + case PreviewFeatureUsed: + return OPTION_ReportPreviewFeatures; } return null; } @@ -998,6 +1015,7 @@ public class CompilerOptions { OPTION_ReportUnlikelyCollectionMethodArgumentType, OPTION_ReportUnlikelyEqualsArgumentType, OPTION_ReportAPILeak, + OPTION_ReportPreviewFeatures }; return result; } @@ -1099,8 +1117,8 @@ public class CompilerOptions { return "exports"; //$NON-NLS-1$ case UnstableAutoModuleName: return "module"; //$NON-NLS-1$ - //case DummyPreviewFeatureWarning: - // return "preview"; //$NON-NLS-1$ + case PreviewFeatureUsed: + return "preview"; //$NON-NLS-1$ } return null; } @@ -1351,6 +1369,7 @@ public class CompilerOptions { optionsMap.put(OPTION_ReportAPILeak, getSeverityString(APILeak)); optionsMap.put(OPTION_ReportUnstableAutoModuleName, getSeverityString(UnstableAutoModuleName)); optionsMap.put(OPTION_EnablePreviews, this.enablePreviewFeatures ? ENABLED : DISABLED); + optionsMap.put(OPTION_ReportPreviewFeatures, getSeverityString(PreviewFeatureUsed)); return optionsMap; } @@ -2070,6 +2089,8 @@ public class CompilerOptions { this.enablePreviewFeatures = false; } } + if ((optionValue = optionsMap.get(OPTION_ReportPreviewFeatures)) != null) + updateSeverity(PreviewFeatureUsed, optionValue); } private String[] stringToNameList(String optionValue) { diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/Constant.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/Constant.java index 3cda404aa0..29a45a3928 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/Constant.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/Constant.java @@ -21,6 +21,7 @@ import org.eclipse.jdt.internal.compiler.util.Messages; public abstract class Constant implements TypeIds, OperatorIds { public static final Constant NotAConstant = DoubleConstant.fromValue(Double.NaN); + public static final Constant[] NotAConstantList = new Constant[] {DoubleConstant.fromValue(Double.NaN)}; public boolean booleanValue() { throw new ShouldNotImplement(Messages.bind(Messages.constant_cannotCastedInto, new String[] { typeName(), "boolean" })); //$NON-NLS-1$ diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/IrritantSet.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/IrritantSet.java index 735f553600..a12103c4ab 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/IrritantSet.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/IrritantSet.java @@ -77,7 +77,7 @@ public class IrritantSet { public static final IrritantSet MODULE = new IrritantSet(CompilerOptions.UnstableAutoModuleName); public static final IrritantSet JAVADOC = new IrritantSet(CompilerOptions.InvalidJavadoc); - public static final IrritantSet PREVIEW = new IrritantSet(0); + public static final IrritantSet PREVIEW = new IrritantSet(CompilerOptions.PreviewFeatureUsed); public static final IrritantSet COMPILER_DEFAULT_ERRORS = new IrritantSet(0); // no optional error by default public static final IrritantSet COMPILER_DEFAULT_WARNINGS = new IrritantSet(0); // see static initializer below public static final IrritantSet COMPILER_DEFAULT_INFOS = new IrritantSet(0); // As of now, no default values @@ -135,7 +135,8 @@ public class IrritantSet { |CompilerOptions.UnlikelyCollectionMethodArgumentType |CompilerOptions.UsingTerminallyDeprecatedAPI |CompilerOptions.APILeak - |CompilerOptions.UnstableAutoModuleName); + |CompilerOptions.UnstableAutoModuleName + |CompilerOptions.PreviewFeatureUsed); // default errors IF AnnotationBasedNullAnalysis is enabled: COMPILER_DEFAULT_ERRORS.set( CompilerOptions.NullSpecViolation @@ -190,7 +191,6 @@ public class IrritantSet { UNLIKELY_ARGUMENT_TYPE .set(CompilerOptions.UnlikelyEqualsArgumentType); - //PREVIEW.set(CompilerOptions.DummyPreviewFeatureWarning); } // Internal state diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ConstraintExpressionFormula.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ConstraintExpressionFormula.java index 75717b1937..cb9dd27c90 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ConstraintExpressionFormula.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ConstraintExpressionFormula.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2013, 2017 GK Software AG. + * Copyright (c) 2013, 2019 GK Software AG. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -8,6 +8,10 @@ * * SPDX-License-Identifier: EPL-2.0 * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * Stephan Herrmann - initial API and implementation * Lars Vogel <Lars.Vogel@vogella.com> - Contributions for @@ -30,6 +34,7 @@ import org.eclipse.jdt.internal.compiler.ast.Invocation; import org.eclipse.jdt.internal.compiler.ast.LambdaExpression; import org.eclipse.jdt.internal.compiler.ast.MessageSend; import org.eclipse.jdt.internal.compiler.ast.ReferenceExpression; +import org.eclipse.jdt.internal.compiler.ast.SwitchExpression; import org.eclipse.jdt.internal.compiler.ast.Wildcard; import org.eclipse.jdt.internal.compiler.lookup.InferenceContext18.SuspendedInferenceRecord; @@ -144,6 +149,14 @@ class ConstraintExpressionFormula extends ConstraintFormula { new ConstraintExpressionFormula(conditional.valueIfTrue, this.right, this.relation, this.isSoft), new ConstraintExpressionFormula(conditional.valueIfFalse, this.right, this.relation, this.isSoft) }; + } else if (this.left instanceof SwitchExpression) { + SwitchExpression se = (SwitchExpression) this.left; + ConstraintFormula[] cfs = new ConstraintFormula[se.resultExpressions.size()]; + int i = 0; + for (Expression re : se.resultExpressions) { + cfs[i++] = new ConstraintExpressionFormula(re, this.right, this.relation, this.isSoft); + } + return cfs; } else if (this.left instanceof LambdaExpression) { LambdaExpression lambda = (LambdaExpression) this.left; BlockScope scope = lambda.enclosingScope; @@ -522,6 +535,13 @@ class ConstraintExpressionFormula extends ConstraintFormula { variables.addAll(new ConstraintExpressionFormula(expr.valueIfTrue, this.right, COMPATIBLE).inputVariables(context)); variables.addAll(new ConstraintExpressionFormula(expr.valueIfFalse, this.right, COMPATIBLE).inputVariables(context)); return variables; + } else if (this.left instanceof SwitchExpression && this.left.isPolyExpression()) { + SwitchExpression expr = (SwitchExpression) this.left; + Set<InferenceVariable> variables = new HashSet<>(); + for (Expression re : expr.resultExpressions) { + variables.addAll(new ConstraintExpressionFormula(re, this.right, COMPATIBLE).inputVariables(context)); + } + return variables; } return EMPTY_VARIABLE_LIST; } diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InferenceContext18.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InferenceContext18.java index f65f5f4319..563081f03a 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InferenceContext18.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InferenceContext18.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2013, 2018 GK Software AG, and others. + * Copyright (c) 2013, 2019 GK Software AG, and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -8,6 +8,10 @@ * * SPDX-License-Identifier: EPL-2.0 * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * Stephan Herrmann - initial API and implementation * IBM Corporation - Bug fixes @@ -32,6 +36,7 @@ import org.eclipse.jdt.internal.compiler.ast.FunctionalExpression; import org.eclipse.jdt.internal.compiler.ast.Invocation; import org.eclipse.jdt.internal.compiler.ast.LambdaExpression; import org.eclipse.jdt.internal.compiler.ast.ReferenceExpression; +import org.eclipse.jdt.internal.compiler.ast.SwitchExpression; import org.eclipse.jdt.internal.compiler.ast.Wildcard; import org.eclipse.jdt.internal.compiler.lookup.TypeConstants.BoundCheckStatus; import org.eclipse.jdt.internal.compiler.util.Sorting; @@ -573,6 +578,15 @@ public class InferenceContext18 { if (addJDK_8153748ConstraintsFromExpression(ce.valueIfTrue, parameter, method, substitution) == ReductionResult.FALSE) return ReductionResult.FALSE; return addJDK_8153748ConstraintsFromExpression(ce.valueIfFalse, parameter, method, substitution); + } else if (argument instanceof SwitchExpression) { + SwitchExpression se = (SwitchExpression) argument; + ReductionResult result = ReductionResult.FALSE; + for (Expression re : se.resultExpressions) { + result = addJDK_8153748ConstraintsFromExpression(re, parameter, method, substitution); + if (result == ReductionResult.FALSE) + break; + } + return result; } return null; } @@ -709,6 +723,13 @@ public class InferenceContext18 { ConditionalExpression ce = (ConditionalExpression) expri; return addConstraintsToC_OneExpr(ce.valueIfTrue, c, fsi, substF, method) && addConstraintsToC_OneExpr(ce.valueIfFalse, c, fsi, substF, method); + } else if (expri instanceof SwitchExpression) { + SwitchExpression se = (SwitchExpression) expri; + for (Expression re : se.resultExpressions) { + if (!addConstraintsToC_OneExpr(re, c, fsi, substF, method)) + return false; + } + return true; } return true; } @@ -950,6 +971,13 @@ public class InferenceContext18 { } else if (expri instanceof ConditionalExpression) { ConditionalExpression cond = (ConditionalExpression) expri; return checkExpression(cond.valueIfTrue, u, r1, v, r2) && checkExpression(cond.valueIfFalse, u, r1, v, r2); + } else if (expri instanceof SwitchExpression) { + SwitchExpression se = (SwitchExpression) expri; + for (Expression re : se.resultExpressions) { + if (!checkExpression(re, u, r1, v, r2)) + return false; + } + return true; } else { return false; } diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/JavadocParser.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/JavadocParser.java index 3817b6db1a..373a684717 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/JavadocParser.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/JavadocParser.java @@ -8,6 +8,10 @@ * * SPDX-License-Identifier: EPL-2.0 * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ @@ -640,6 +644,9 @@ public class JavadocParser extends AbstractCommentParser { } else if (length == TAG_SINCE_LENGTH && CharOperation.equals(TAG_SINCE, tagName, 0, length)) { this.tagValue = TAG_SINCE_VALUE; this.tagWaitingForDescription = this.tagValue; + } else if (length == TAG_SYSTEM_PROPERTY_LENGTH && CharOperation.equals(TAG_SYSTEM_PROPERTY, tagName, 0, length)) { + this.tagValue = TAG_SYSTEM_PROPERTY_VALUE; + this.tagWaitingForDescription = this.tagValue; } break; case 't': diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/JavadocTagConstants.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/JavadocTagConstants.java index 10f540e36f..1e92374e21 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/JavadocTagConstants.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/JavadocTagConstants.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2018 IBM Corporation and others. + * Copyright (c) 2000, 2019 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -8,6 +8,10 @@ * * SPDX-License-Identifier: EPL-2.0 * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ @@ -44,6 +48,7 @@ public interface JavadocTagConstants { public static final char[] TAG_SINCE = "since".toCharArray(); //$NON-NLS-1$ public static final char[] TAG_VERSION = "version".toCharArray(); //$NON-NLS-1$ public static final char[] TAG_CATEGORY = "category".toCharArray(); //$NON-NLS-1$ + public static final char[] TAG_SYSTEM_PROPERTY = "systemProperty".toCharArray(); //$NON-NLS-1$ public static final char[] TAG_USES = "uses".toCharArray(); //$NON-NLS-1$ public static final char[] TAG_PROVIDES = "provides".toCharArray(); //$NON-NLS-1$ @@ -68,6 +73,7 @@ public interface JavadocTagConstants { public static final int TAG_CODE_LENGTH = TAG_CODE.length; public static final int TAG_LITERAL_LENGTH = TAG_LITERAL.length; public static final int TAG_DOC_ROOT_LENGTH = TAG_DOC_ROOT.length; + public static final int TAG_SYSTEM_PROPERTY_LENGTH = TAG_SYSTEM_PROPERTY.length; public static final int TAG_USES_LENGTH = TAG_USES.length; public static final int TAG_PROVIDES_LENGTH = TAG_PROVIDES.length; @@ -93,6 +99,7 @@ public interface JavadocTagConstants { public static final int TAG_CODE_VALUE = 18; public static final int TAG_LITERAL_VALUE = 19; public static final int TAG_DOC_ROOT_VALUE = 20; + public static final int TAG_SYSTEM_PROPERTY_VALUE=21; public static final int TAG_USES_VALUE=21; public static final int TAG_PROVIDES_VALUE=22; public static final int TAG_OTHERS_VALUE = 100; @@ -119,6 +126,7 @@ public interface JavadocTagConstants { TAG_CODE, /* 18 */ TAG_LITERAL, /* 19 */ TAG_DOC_ROOT, /* 20 */ + TAG_SYSTEM_PROPERTY /* 21 */ }; // tags expected positions @@ -162,6 +170,8 @@ public interface JavadocTagConstants { // since 10 {}, // since 11 + {}, + //since 12 {} }; public static final char[][][] INLINE_TAGS = { @@ -188,7 +198,9 @@ public interface JavadocTagConstants { // since 10 {}, // since 11 - {} + {}, + //since 12 + {TAG_SYSTEM_PROPERTY} }; public final static int INLINE_TAGS_LENGTH = INLINE_TAGS.length; public final static int BLOCK_TAGS_LENGTH = BLOCK_TAGS.length; @@ -197,7 +209,6 @@ public interface JavadocTagConstants { public final static short TAG_TYPE_NONE = 0; public final static short TAG_TYPE_INLINE = 1; public final static short TAG_TYPE_BLOCK = 2; - public static final short[] JAVADOC_TAG_TYPE = { TAG_TYPE_NONE, // NO_TAG_VALUE = 0; TAG_TYPE_BLOCK, // TAG_DEPRECATED_VALUE = 1; @@ -219,7 +230,8 @@ public interface JavadocTagConstants { TAG_TYPE_BLOCK, // TAG_VERSION_VALUE = 17; TAG_TYPE_INLINE, // TAG_CODE_VALUE = 18; TAG_TYPE_INLINE, // TAG_LITERAL_VALUE = 19; - TAG_TYPE_INLINE // TAG_DOC_ROOT_VALUE = 20; + TAG_TYPE_INLINE, // TAG_DOC_ROOT_VALUE = 20; + TAG_TYPE_INLINE // TAG_DOC_ROOT_VALUE = 21 }; /* * Tags usage @@ -235,6 +247,7 @@ public interface JavadocTagConstants { TAG_LINKPLAIN, TAG_DOC_ROOT, TAG_VALUE, + TAG_SYSTEM_PROPERTY }; public static final char[][] COMPILATION_UNIT_TAGS = {}; public static final char[][] CLASS_TAGS = { @@ -251,7 +264,8 @@ public interface JavadocTagConstants { TAG_DOC_ROOT, TAG_VALUE, TAG_CODE, - TAG_LITERAL + TAG_LITERAL, + TAG_SYSTEM_PROPERTY }; public static final char[][] FIELD_TAGS = { TAG_SEE, @@ -265,7 +279,8 @@ public interface JavadocTagConstants { TAG_DOC_ROOT, TAG_VALUE, TAG_CODE, - TAG_LITERAL + TAG_LITERAL, + TAG_SYSTEM_PROPERTY }; public static final char[][] METHOD_TAGS = { TAG_SEE, @@ -283,7 +298,8 @@ public interface JavadocTagConstants { TAG_DOC_ROOT, TAG_VALUE, TAG_CODE, - TAG_LITERAL + TAG_LITERAL, + TAG_SYSTEM_PROPERTY }; public static final char[][] MODULE_TAGS = { TAG_SEE, diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java index a9e213965a..63c98f070d 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java @@ -7,7 +7,11 @@ * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 - * + * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * IBM Corporation - initial API and implementation * Tom Tromey - patch for readTable(String) as described in http://bugs.eclipse.org/bugs/show_bug.cgi?id=32196 @@ -52,6 +56,7 @@ import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; import org.eclipse.jdt.internal.compiler.codegen.ConstantPool; import org.eclipse.jdt.internal.compiler.env.ICompilationUnit; import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; +import org.eclipse.jdt.internal.compiler.impl.IrritantSet; import org.eclipse.jdt.internal.compiler.impl.ReferenceContext; import org.eclipse.jdt.internal.compiler.lookup.Binding; import org.eclipse.jdt.internal.compiler.lookup.BlockScope; @@ -941,6 +946,7 @@ protected int valueLambdaNestDepth = -1; private int stateStackLengthStack[] = new int[0]; protected boolean parsingJava8Plus; protected boolean parsingJava9Plus; +protected boolean parsingJava12Plus; protected boolean parsingJava11Plus; protected int unstackedAct = ERROR_ACTION; private boolean haltOnSyntaxError = false; @@ -960,6 +966,7 @@ public Parser(ProblemReporter problemReporter, boolean optimizeStringLiterals) { initializeScanner(); this.parsingJava8Plus = this.options.sourceLevel >= ClassFileConstants.JDK1_8; this.parsingJava9Plus = this.options.sourceLevel >= ClassFileConstants.JDK9; + this.parsingJava12Plus = this.options.sourceLevel >= ClassFileConstants.JDK12; this.parsingJava11Plus = this.options.sourceLevel >= ClassFileConstants.JDK11; this.astLengthStack = new int[50]; this.expressionLengthStack = new int[30]; @@ -2198,10 +2205,30 @@ protected void consumeBlockStatements() { concatNodeLists(); } protected void consumeCaseLabel() { - // SwitchLabel ::= 'case' ConstantExpression ':' - this.expressionLengthPtr--; - Expression expression = this.expressionStack[this.expressionPtr--]; - CaseStatement caseStatement = new CaseStatement(expression, expression.sourceEnd, this.intStack[this.intPtr--]); +// // SwitchLabel ::= 'case' ConstantExpression ':' +// this.expressionLengthPtr--; +// Expression expression = this.expressionStack[this.expressionPtr--]; +// CaseStatement caseStatement = new CaseStatement(expression, expression.sourceEnd, this.intStack[this.intPtr--]); +// // Look for $fall-through$ tag in leading comment for case statement +// if (hasLeadingTagComment(FALL_THROUGH_TAG, caseStatement.sourceStart)) { +// caseStatement.bits |= ASTNode.DocumentedFallthrough; +// } +// pushOnAstStack(caseStatement); + Expression[] constantExpressions = null; + int length = 0; + if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) { + this.expressionPtr -= length; + System.arraycopy( + this.expressionStack, + this.expressionPtr + 1, + constantExpressions = new Expression[length], + 0, + length); + } else { + // TODO : ERROR + } + CaseStatement caseStatement = new CaseStatement(constantExpressions[0], constantExpressions[length - 1].sourceEnd, this.intStack[this.intPtr--]); + caseStatement.constantExpressions = constantExpressions; // Look for $fall-through$ tag in leading comment for case statement if (hasLeadingTagComment(FALL_THROUGH_TAG, caseStatement.sourceStart)) { caseStatement.bits |= ASTNode.DocumentedFallthrough; @@ -7167,1319 +7194,1359 @@ protected void consumeRule(int act) { consumeSwitchBlockStatements() ; break; - case 388 : if (DEBUG) { System.out.println("SwitchBlockStatement ::= SwitchLabels BlockStatements"); } //$NON-NLS-1$ + case 389 : if (DEBUG) { System.out.println("SwitchBlockStatement ::= SwitchLabels BlockStatements"); } //$NON-NLS-1$ consumeSwitchBlockStatement() ; break; - case 390 : if (DEBUG) { System.out.println("SwitchLabels ::= SwitchLabels SwitchLabel"); } //$NON-NLS-1$ + case 391 : if (DEBUG) { System.out.println("SwitchLabels ::= SwitchLabels SwitchLabel"); } //$NON-NLS-1$ consumeSwitchLabels() ; break; - case 391 : if (DEBUG) { System.out.println("SwitchLabel ::= case ConstantExpression COLON"); } //$NON-NLS-1$ + case 392 : if (DEBUG) { System.out.println("SwitchLabel ::= SwitchLabelCaseLhs COLON"); } //$NON-NLS-1$ consumeCaseLabel(); break; - case 392 : if (DEBUG) { System.out.println("SwitchLabel ::= default COLON"); } //$NON-NLS-1$ + case 393 : if (DEBUG) { System.out.println("SwitchLabel ::= default COLON"); } //$NON-NLS-1$ consumeDefaultLabel(); break; - case 393 : if (DEBUG) { System.out.println("WhileStatement ::= while LPAREN Expression RPAREN..."); } //$NON-NLS-1$ + case 396 : if (DEBUG) { System.out.println("SwitchExpression ::= switch LPAREN Expression RPAREN..."); } //$NON-NLS-1$ + consumeSwitchExpression() ; + break; + + case 399 : if (DEBUG) { System.out.println("SwitchLabeledRule ::= SwitchLabeledThrowStatement"); } //$NON-NLS-1$ + consumeSwitchLabeledRule(); + break; + + case 400 : if (DEBUG) { System.out.println("SwitchLabeledExpression ::= SwitchLabelExpr Expression"); } //$NON-NLS-1$ + consumeSwitchLabeledExpression(); + break; + + case 401 : if (DEBUG) { System.out.println("SwitchLabeledBlock ::= SwitchLabelExpr Block"); } //$NON-NLS-1$ + consumeSwitchLabeledBlock(); + break; + + case 402 : if (DEBUG) { System.out.println("SwitchLabeledThrowStatement ::= SwitchLabelExpr..."); } //$NON-NLS-1$ + consumeSwitchLabeledThrowStatement(); + break; + + case 403 : if (DEBUG) { System.out.println("SwitchLabelExpr ::= default ARROW"); } //$NON-NLS-1$ + consumeDefaultLabelExpr(); + break; + + case 404 : if (DEBUG) { System.out.println("SwitchLabelExpr ::= SwitchLabelCaseLhs BeginCaseExpr..."); } //$NON-NLS-1$ + consumeCaseLabelExpr(); + break; + + case 405 : if (DEBUG) { System.out.println("SwitchLabelCaseLhs ::= case ConstantExpressions"); } //$NON-NLS-1$ + consumeSwitchLabelCaseLhs(); + break; + + case 406 : if (DEBUG) { System.out.println("WhileStatement ::= while LPAREN Expression RPAREN..."); } //$NON-NLS-1$ consumeStatementWhile() ; break; - case 394 : if (DEBUG) { System.out.println("WhileStatementNoShortIf ::= while LPAREN Expression..."); } //$NON-NLS-1$ + case 407 : if (DEBUG) { System.out.println("WhileStatementNoShortIf ::= while LPAREN Expression..."); } //$NON-NLS-1$ consumeStatementWhile() ; break; - case 395 : if (DEBUG) { System.out.println("DoStatement ::= do Statement while LPAREN Expression..."); } //$NON-NLS-1$ + case 408 : if (DEBUG) { System.out.println("DoStatement ::= do Statement while LPAREN Expression..."); } //$NON-NLS-1$ consumeStatementDo() ; break; - case 396 : if (DEBUG) { System.out.println("ForStatement ::= for LPAREN ForInitopt SEMICOLON..."); } //$NON-NLS-1$ + case 409 : if (DEBUG) { System.out.println("ForStatement ::= for LPAREN ForInitopt SEMICOLON..."); } //$NON-NLS-1$ consumeStatementFor() ; break; - case 397 : if (DEBUG) { System.out.println("ForStatementNoShortIf ::= for LPAREN ForInitopt..."); } //$NON-NLS-1$ + case 410 : if (DEBUG) { System.out.println("ForStatementNoShortIf ::= for LPAREN ForInitopt..."); } //$NON-NLS-1$ consumeStatementFor() ; break; - case 398 : if (DEBUG) { System.out.println("ForInit ::= StatementExpressionList"); } //$NON-NLS-1$ + case 411 : if (DEBUG) { System.out.println("ForInit ::= StatementExpressionList"); } //$NON-NLS-1$ consumeForInit() ; break; - case 402 : if (DEBUG) { System.out.println("StatementExpressionList ::= StatementExpressionList..."); } //$NON-NLS-1$ + case 415 : if (DEBUG) { System.out.println("StatementExpressionList ::= StatementExpressionList..."); } //$NON-NLS-1$ consumeStatementExpressionList() ; break; - case 403 : if (DEBUG) { System.out.println("AssertStatement ::= assert Expression SEMICOLON"); } //$NON-NLS-1$ + case 416 : if (DEBUG) { System.out.println("AssertStatement ::= assert Expression SEMICOLON"); } //$NON-NLS-1$ consumeSimpleAssertStatement() ; break; - case 404 : if (DEBUG) { System.out.println("AssertStatement ::= assert Expression COLON Expression"); } //$NON-NLS-1$ + case 417 : if (DEBUG) { System.out.println("AssertStatement ::= assert Expression COLON Expression"); } //$NON-NLS-1$ consumeAssertStatement() ; break; - case 405 : if (DEBUG) { System.out.println("BreakStatement ::= break SEMICOLON"); } //$NON-NLS-1$ + case 418 : if (DEBUG) { System.out.println("BreakStatement ::= break SEMICOLON"); } //$NON-NLS-1$ consumeStatementBreak() ; break; - case 406 : if (DEBUG) { System.out.println("BreakStatement ::= break Identifier SEMICOLON"); } //$NON-NLS-1$ + case 419 : if (DEBUG) { System.out.println("BreakStatement ::= break Expression SEMICOLON"); } //$NON-NLS-1$ consumeStatementBreakWithLabel() ; break; - case 407 : if (DEBUG) { System.out.println("ContinueStatement ::= continue SEMICOLON"); } //$NON-NLS-1$ + case 420 : if (DEBUG) { System.out.println("ContinueStatement ::= continue SEMICOLON"); } //$NON-NLS-1$ consumeStatementContinue() ; break; - case 408 : if (DEBUG) { System.out.println("ContinueStatement ::= continue Identifier SEMICOLON"); } //$NON-NLS-1$ + case 421 : if (DEBUG) { System.out.println("ContinueStatement ::= continue Identifier SEMICOLON"); } //$NON-NLS-1$ consumeStatementContinueWithLabel() ; break; - case 409 : if (DEBUG) { System.out.println("ReturnStatement ::= return Expressionopt SEMICOLON"); } //$NON-NLS-1$ + case 422 : if (DEBUG) { System.out.println("ReturnStatement ::= return Expressionopt SEMICOLON"); } //$NON-NLS-1$ consumeStatementReturn() ; break; - case 410 : if (DEBUG) { System.out.println("ThrowStatement ::= throw Expression SEMICOLON"); } //$NON-NLS-1$ + case 423 : if (DEBUG) { System.out.println("ThrowStatement ::= throw Expression SEMICOLON"); } //$NON-NLS-1$ consumeStatementThrow(); break; - case 411 : if (DEBUG) { System.out.println("SynchronizedStatement ::= OnlySynchronized LPAREN..."); } //$NON-NLS-1$ + case 424 : if (DEBUG) { System.out.println("ThrowExpression ::= throw Expression"); } //$NON-NLS-1$ + consumeThrowExpression() ; + break; + + case 425 : if (DEBUG) { System.out.println("SynchronizedStatement ::= OnlySynchronized LPAREN..."); } //$NON-NLS-1$ consumeStatementSynchronized(); break; - case 412 : if (DEBUG) { System.out.println("OnlySynchronized ::= synchronized"); } //$NON-NLS-1$ + case 426 : if (DEBUG) { System.out.println("OnlySynchronized ::= synchronized"); } //$NON-NLS-1$ consumeOnlySynchronized(); break; - case 413 : if (DEBUG) { System.out.println("TryStatement ::= try TryBlock Catches"); } //$NON-NLS-1$ + case 427 : if (DEBUG) { System.out.println("TryStatement ::= try TryBlock Catches"); } //$NON-NLS-1$ consumeStatementTry(false, false); break; - case 414 : if (DEBUG) { System.out.println("TryStatement ::= try TryBlock Catchesopt Finally"); } //$NON-NLS-1$ + case 428 : if (DEBUG) { System.out.println("TryStatement ::= try TryBlock Catchesopt Finally"); } //$NON-NLS-1$ consumeStatementTry(true, false); break; - case 415 : if (DEBUG) { System.out.println("TryStatementWithResources ::= try ResourceSpecification"); } //$NON-NLS-1$ + case 429 : if (DEBUG) { System.out.println("TryStatementWithResources ::= try ResourceSpecification"); } //$NON-NLS-1$ consumeStatementTry(false, true); break; - case 416 : if (DEBUG) { System.out.println("TryStatementWithResources ::= try ResourceSpecification"); } //$NON-NLS-1$ + case 430 : if (DEBUG) { System.out.println("TryStatementWithResources ::= try ResourceSpecification"); } //$NON-NLS-1$ consumeStatementTry(true, true); break; - case 417 : if (DEBUG) { System.out.println("ResourceSpecification ::= LPAREN Resources ;opt RPAREN"); } //$NON-NLS-1$ + case 431 : if (DEBUG) { System.out.println("ResourceSpecification ::= LPAREN Resources ;opt RPAREN"); } //$NON-NLS-1$ consumeResourceSpecification(); break; - case 418 : if (DEBUG) { System.out.println(";opt ::="); } //$NON-NLS-1$ + case 432 : if (DEBUG) { System.out.println(";opt ::="); } //$NON-NLS-1$ consumeResourceOptionalTrailingSemiColon(false); break; - case 419 : if (DEBUG) { System.out.println(";opt ::= SEMICOLON"); } //$NON-NLS-1$ + case 433 : if (DEBUG) { System.out.println(";opt ::= SEMICOLON"); } //$NON-NLS-1$ consumeResourceOptionalTrailingSemiColon(true); break; - case 420 : if (DEBUG) { System.out.println("Resources ::= Resource"); } //$NON-NLS-1$ + case 434 : if (DEBUG) { System.out.println("Resources ::= Resource"); } //$NON-NLS-1$ consumeSingleResource(); break; - case 421 : if (DEBUG) { System.out.println("Resources ::= Resources TrailingSemiColon Resource"); } //$NON-NLS-1$ + case 435 : if (DEBUG) { System.out.println("Resources ::= Resources TrailingSemiColon Resource"); } //$NON-NLS-1$ consumeMultipleResources(); break; - case 422 : if (DEBUG) { System.out.println("TrailingSemiColon ::= SEMICOLON"); } //$NON-NLS-1$ + case 436 : if (DEBUG) { System.out.println("TrailingSemiColon ::= SEMICOLON"); } //$NON-NLS-1$ consumeResourceOptionalTrailingSemiColon(true); break; - case 423 : if (DEBUG) { System.out.println("Resource ::= Type PushModifiers VariableDeclaratorId..."); } //$NON-NLS-1$ + case 437 : if (DEBUG) { System.out.println("Resource ::= Type PushModifiers VariableDeclaratorId..."); } //$NON-NLS-1$ consumeResourceAsLocalVariableDeclaration(); break; - case 424 : if (DEBUG) { System.out.println("Resource ::= Modifiers Type PushRealModifiers..."); } //$NON-NLS-1$ + case 438 : if (DEBUG) { System.out.println("Resource ::= Modifiers Type PushRealModifiers..."); } //$NON-NLS-1$ consumeResourceAsLocalVariableDeclaration(); break; - case 425 : if (DEBUG) { System.out.println("Resource ::= Name"); } //$NON-NLS-1$ + case 439 : if (DEBUG) { System.out.println("Resource ::= Name"); } //$NON-NLS-1$ consumeResourceAsLocalVariable(); break; - case 426 : if (DEBUG) { System.out.println("Resource ::= FieldAccess"); } //$NON-NLS-1$ + case 440 : if (DEBUG) { System.out.println("Resource ::= FieldAccess"); } //$NON-NLS-1$ consumeResourceAsFieldAccess(); break; - case 428 : if (DEBUG) { System.out.println("ExitTryBlock ::="); } //$NON-NLS-1$ + case 442 : if (DEBUG) { System.out.println("ExitTryBlock ::="); } //$NON-NLS-1$ consumeExitTryBlock(); break; - case 430 : if (DEBUG) { System.out.println("Catches ::= Catches CatchClause"); } //$NON-NLS-1$ + case 444 : if (DEBUG) { System.out.println("Catches ::= Catches CatchClause"); } //$NON-NLS-1$ consumeCatches(); break; - case 431 : if (DEBUG) { System.out.println("CatchClause ::= catch LPAREN CatchFormalParameter RPAREN"); } //$NON-NLS-1$ + case 445 : if (DEBUG) { System.out.println("CatchClause ::= catch LPAREN CatchFormalParameter RPAREN"); } //$NON-NLS-1$ consumeStatementCatch() ; break; - case 433 : if (DEBUG) { System.out.println("PushLPAREN ::= LPAREN"); } //$NON-NLS-1$ + case 447 : if (DEBUG) { System.out.println("PushLPAREN ::= LPAREN"); } //$NON-NLS-1$ consumeLeftParen(); break; - case 434 : if (DEBUG) { System.out.println("PushRPAREN ::= RPAREN"); } //$NON-NLS-1$ + case 448 : if (DEBUG) { System.out.println("PushRPAREN ::= RPAREN"); } //$NON-NLS-1$ consumeRightParen(); break; - case 439 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= this"); } //$NON-NLS-1$ + case 453 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= this"); } //$NON-NLS-1$ consumePrimaryNoNewArrayThis(); break; - case 440 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= PushLPAREN Expression_NotName..."); } //$NON-NLS-1$ + case 454 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= PushLPAREN Expression_NotName..."); } //$NON-NLS-1$ consumePrimaryNoNewArray(); break; - case 441 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= PushLPAREN Name PushRPAREN"); } //$NON-NLS-1$ + case 455 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= PushLPAREN Name PushRPAREN"); } //$NON-NLS-1$ consumePrimaryNoNewArrayWithName(); break; - case 444 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= Name DOT this"); } //$NON-NLS-1$ + case 458 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= Name DOT this"); } //$NON-NLS-1$ consumePrimaryNoNewArrayNameThis(); break; - case 445 : if (DEBUG) { System.out.println("QualifiedSuperReceiver ::= Name DOT super"); } //$NON-NLS-1$ + case 459 : if (DEBUG) { System.out.println("QualifiedSuperReceiver ::= Name DOT super"); } //$NON-NLS-1$ consumeQualifiedSuperReceiver(); break; - case 446 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= Name DOT class"); } //$NON-NLS-1$ + case 460 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= Name DOT class"); } //$NON-NLS-1$ consumePrimaryNoNewArrayName(); break; - case 447 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= Name Dims DOT class"); } //$NON-NLS-1$ + case 461 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= Name Dims DOT class"); } //$NON-NLS-1$ consumePrimaryNoNewArrayArrayType(); break; - case 448 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= PrimitiveType Dims DOT class"); } //$NON-NLS-1$ + case 462 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= PrimitiveType Dims DOT class"); } //$NON-NLS-1$ consumePrimaryNoNewArrayPrimitiveArrayType(); break; - case 449 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= PrimitiveType DOT class"); } //$NON-NLS-1$ + case 463 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= PrimitiveType DOT class"); } //$NON-NLS-1$ consumePrimaryNoNewArrayPrimitiveType(); break; - case 455 : if (DEBUG) { System.out.println("ReferenceExpressionTypeArgumentsAndTrunk0 ::=..."); } //$NON-NLS-1$ + case 469 : if (DEBUG) { System.out.println("ReferenceExpressionTypeArgumentsAndTrunk0 ::=..."); } //$NON-NLS-1$ consumeReferenceExpressionTypeArgumentsAndTrunk(false); break; - case 456 : if (DEBUG) { System.out.println("ReferenceExpressionTypeArgumentsAndTrunk0 ::=..."); } //$NON-NLS-1$ + case 470 : if (DEBUG) { System.out.println("ReferenceExpressionTypeArgumentsAndTrunk0 ::=..."); } //$NON-NLS-1$ consumeReferenceExpressionTypeArgumentsAndTrunk(true); break; - case 457 : if (DEBUG) { System.out.println("ReferenceExpression ::= PrimitiveType Dims COLON_COLON"); } //$NON-NLS-1$ + case 471 : if (DEBUG) { System.out.println("ReferenceExpression ::= PrimitiveType Dims COLON_COLON"); } //$NON-NLS-1$ consumeReferenceExpressionTypeForm(true); break; - case 458 : if (DEBUG) { System.out.println("ReferenceExpression ::= Name Dimsopt COLON_COLON..."); } //$NON-NLS-1$ + case 472 : if (DEBUG) { System.out.println("ReferenceExpression ::= Name Dimsopt COLON_COLON..."); } //$NON-NLS-1$ consumeReferenceExpressionTypeForm(false); break; - case 459 : if (DEBUG) { System.out.println("ReferenceExpression ::= Name BeginTypeArguments..."); } //$NON-NLS-1$ + case 473 : if (DEBUG) { System.out.println("ReferenceExpression ::= Name BeginTypeArguments..."); } //$NON-NLS-1$ consumeReferenceExpressionGenericTypeForm(); break; - case 460 : if (DEBUG) { System.out.println("ReferenceExpression ::= Primary COLON_COLON..."); } //$NON-NLS-1$ + case 474 : if (DEBUG) { System.out.println("ReferenceExpression ::= Primary COLON_COLON..."); } //$NON-NLS-1$ consumeReferenceExpressionPrimaryForm(); break; - case 461 : if (DEBUG) { System.out.println("ReferenceExpression ::= QualifiedSuperReceiver..."); } //$NON-NLS-1$ + case 475 : if (DEBUG) { System.out.println("ReferenceExpression ::= QualifiedSuperReceiver..."); } //$NON-NLS-1$ consumeReferenceExpressionPrimaryForm(); break; - case 462 : if (DEBUG) { System.out.println("ReferenceExpression ::= super COLON_COLON..."); } //$NON-NLS-1$ + case 476 : if (DEBUG) { System.out.println("ReferenceExpression ::= super COLON_COLON..."); } //$NON-NLS-1$ consumeReferenceExpressionSuperForm(); break; - case 463 : if (DEBUG) { System.out.println("NonWildTypeArgumentsopt ::="); } //$NON-NLS-1$ + case 477 : if (DEBUG) { System.out.println("NonWildTypeArgumentsopt ::="); } //$NON-NLS-1$ consumeEmptyTypeArguments(); break; - case 465 : if (DEBUG) { System.out.println("IdentifierOrNew ::= Identifier"); } //$NON-NLS-1$ + case 479 : if (DEBUG) { System.out.println("IdentifierOrNew ::= Identifier"); } //$NON-NLS-1$ consumeIdentifierOrNew(false); break; - case 466 : if (DEBUG) { System.out.println("IdentifierOrNew ::= new"); } //$NON-NLS-1$ + case 480 : if (DEBUG) { System.out.println("IdentifierOrNew ::= new"); } //$NON-NLS-1$ consumeIdentifierOrNew(true); break; - case 467 : if (DEBUG) { System.out.println("LambdaExpression ::= LambdaParameters ARROW LambdaBody"); } //$NON-NLS-1$ + case 481 : if (DEBUG) { System.out.println("LambdaExpression ::= LambdaParameters ARROW LambdaBody"); } //$NON-NLS-1$ consumeLambdaExpression(); break; - case 468 : if (DEBUG) { System.out.println("NestedLambda ::="); } //$NON-NLS-1$ + case 482 : if (DEBUG) { System.out.println("NestedLambda ::="); } //$NON-NLS-1$ consumeNestedLambda(); break; - case 469 : if (DEBUG) { System.out.println("LambdaParameters ::= Identifier NestedLambda"); } //$NON-NLS-1$ + case 483 : if (DEBUG) { System.out.println("LambdaParameters ::= Identifier NestedLambda"); } //$NON-NLS-1$ consumeTypeElidedLambdaParameter(false); break; - case 475 : if (DEBUG) { System.out.println("TypeElidedFormalParameterList ::=..."); } //$NON-NLS-1$ + case 489 : if (DEBUG) { System.out.println("TypeElidedFormalParameterList ::=..."); } //$NON-NLS-1$ consumeFormalParameterList(); break; - case 476 : if (DEBUG) { System.out.println("TypeElidedFormalParameter ::= Modifiersopt Identifier"); } //$NON-NLS-1$ + case 490 : if (DEBUG) { System.out.println("TypeElidedFormalParameter ::= Modifiersopt Identifier"); } //$NON-NLS-1$ consumeTypeElidedLambdaParameter(true); break; - case 479 : if (DEBUG) { System.out.println("ElidedLeftBraceAndReturn ::="); } //$NON-NLS-1$ + case 493 : if (DEBUG) { System.out.println("ElidedLeftBraceAndReturn ::="); } //$NON-NLS-1$ consumeElidedLeftBraceAndReturn(); break; - case 480 : if (DEBUG) { System.out.println("AllocationHeader ::= new ClassType LPAREN..."); } //$NON-NLS-1$ + case 494 : if (DEBUG) { System.out.println("AllocationHeader ::= new ClassType LPAREN..."); } //$NON-NLS-1$ consumeAllocationHeader(); break; - case 481 : if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::= new..."); } //$NON-NLS-1$ + case 495 : if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::= new..."); } //$NON-NLS-1$ consumeClassInstanceCreationExpressionWithTypeArguments(); break; - case 482 : if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::= new ClassType..."); } //$NON-NLS-1$ + case 496 : if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::= new ClassType..."); } //$NON-NLS-1$ consumeClassInstanceCreationExpression(); break; - case 483 : if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::= Primary DOT new..."); } //$NON-NLS-1$ + case 497 : if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::= Primary DOT new..."); } //$NON-NLS-1$ consumeClassInstanceCreationExpressionQualifiedWithTypeArguments() ; break; - case 484 : if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::= Primary DOT new..."); } //$NON-NLS-1$ + case 498 : if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::= Primary DOT new..."); } //$NON-NLS-1$ consumeClassInstanceCreationExpressionQualified() ; break; - case 485 : if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::=..."); } //$NON-NLS-1$ + case 499 : if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::=..."); } //$NON-NLS-1$ consumeClassInstanceCreationExpressionQualified() ; break; - case 486 : if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::=..."); } //$NON-NLS-1$ + case 500 : if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::=..."); } //$NON-NLS-1$ consumeClassInstanceCreationExpressionQualifiedWithTypeArguments() ; break; - case 487 : if (DEBUG) { System.out.println("EnterInstanceCreationArgumentList ::="); } //$NON-NLS-1$ + case 501 : if (DEBUG) { System.out.println("EnterInstanceCreationArgumentList ::="); } //$NON-NLS-1$ consumeEnterInstanceCreationArgumentList(); break; - case 488 : if (DEBUG) { System.out.println("ClassInstanceCreationExpressionName ::= Name DOT new"); } //$NON-NLS-1$ + case 502 : if (DEBUG) { System.out.println("ClassInstanceCreationExpressionName ::= Name DOT new"); } //$NON-NLS-1$ consumeClassInstanceCreationExpressionName() ; break; - case 489 : if (DEBUG) { System.out.println("UnqualifiedClassBodyopt ::="); } //$NON-NLS-1$ + case 503 : if (DEBUG) { System.out.println("UnqualifiedClassBodyopt ::="); } //$NON-NLS-1$ consumeClassBodyopt(); break; - case 491 : if (DEBUG) { System.out.println("UnqualifiedEnterAnonymousClassBody ::="); } //$NON-NLS-1$ + case 505 : if (DEBUG) { System.out.println("UnqualifiedEnterAnonymousClassBody ::="); } //$NON-NLS-1$ consumeEnterAnonymousClassBody(false); break; - case 492 : if (DEBUG) { System.out.println("QualifiedClassBodyopt ::="); } //$NON-NLS-1$ + case 506 : if (DEBUG) { System.out.println("QualifiedClassBodyopt ::="); } //$NON-NLS-1$ consumeClassBodyopt(); break; - case 494 : if (DEBUG) { System.out.println("QualifiedEnterAnonymousClassBody ::="); } //$NON-NLS-1$ + case 508 : if (DEBUG) { System.out.println("QualifiedEnterAnonymousClassBody ::="); } //$NON-NLS-1$ consumeEnterAnonymousClassBody(true); break; - case 496 : if (DEBUG) { System.out.println("ArgumentList ::= ArgumentList COMMA Expression"); } //$NON-NLS-1$ + case 510 : if (DEBUG) { System.out.println("ArgumentList ::= ArgumentList COMMA Expression"); } //$NON-NLS-1$ consumeArgumentList(); break; - case 497 : if (DEBUG) { System.out.println("ArrayCreationHeader ::= new PrimitiveType..."); } //$NON-NLS-1$ + case 511 : if (DEBUG) { System.out.println("ArrayCreationHeader ::= new PrimitiveType..."); } //$NON-NLS-1$ consumeArrayCreationHeader(); break; - case 498 : if (DEBUG) { System.out.println("ArrayCreationHeader ::= new ClassOrInterfaceType..."); } //$NON-NLS-1$ + case 512 : if (DEBUG) { System.out.println("ArrayCreationHeader ::= new ClassOrInterfaceType..."); } //$NON-NLS-1$ consumeArrayCreationHeader(); break; - case 499 : if (DEBUG) { System.out.println("ArrayCreationWithoutArrayInitializer ::= new..."); } //$NON-NLS-1$ + case 513 : if (DEBUG) { System.out.println("ArrayCreationWithoutArrayInitializer ::= new..."); } //$NON-NLS-1$ consumeArrayCreationExpressionWithoutInitializer(); break; - case 500 : if (DEBUG) { System.out.println("ArrayCreationWithArrayInitializer ::= new PrimitiveType"); } //$NON-NLS-1$ + case 514 : if (DEBUG) { System.out.println("ArrayCreationWithArrayInitializer ::= new PrimitiveType"); } //$NON-NLS-1$ consumeArrayCreationExpressionWithInitializer(); break; - case 501 : if (DEBUG) { System.out.println("ArrayCreationWithoutArrayInitializer ::= new..."); } //$NON-NLS-1$ + case 515 : if (DEBUG) { System.out.println("ArrayCreationWithoutArrayInitializer ::= new..."); } //$NON-NLS-1$ consumeArrayCreationExpressionWithoutInitializer(); break; - case 502 : if (DEBUG) { System.out.println("ArrayCreationWithArrayInitializer ::= new..."); } //$NON-NLS-1$ + case 516 : if (DEBUG) { System.out.println("ArrayCreationWithArrayInitializer ::= new..."); } //$NON-NLS-1$ consumeArrayCreationExpressionWithInitializer(); break; - case 504 : if (DEBUG) { System.out.println("DimWithOrWithOutExprs ::= DimWithOrWithOutExprs..."); } //$NON-NLS-1$ + case 518 : if (DEBUG) { System.out.println("DimWithOrWithOutExprs ::= DimWithOrWithOutExprs..."); } //$NON-NLS-1$ consumeDimWithOrWithOutExprs(); break; - case 506 : if (DEBUG) { System.out.println("DimWithOrWithOutExpr ::= TypeAnnotationsopt LBRACKET..."); } //$NON-NLS-1$ + case 520 : if (DEBUG) { System.out.println("DimWithOrWithOutExpr ::= TypeAnnotationsopt LBRACKET..."); } //$NON-NLS-1$ consumeDimWithOrWithOutExpr(); break; - case 507 : if (DEBUG) { System.out.println("Dims ::= DimsLoop"); } //$NON-NLS-1$ + case 521 : if (DEBUG) { System.out.println("Dims ::= DimsLoop"); } //$NON-NLS-1$ consumeDims(); break; - case 510 : if (DEBUG) { System.out.println("OneDimLoop ::= LBRACKET RBRACKET"); } //$NON-NLS-1$ + case 524 : if (DEBUG) { System.out.println("OneDimLoop ::= LBRACKET RBRACKET"); } //$NON-NLS-1$ consumeOneDimLoop(false); break; - case 511 : if (DEBUG) { System.out.println("OneDimLoop ::= TypeAnnotations LBRACKET RBRACKET"); } //$NON-NLS-1$ + case 525 : if (DEBUG) { System.out.println("OneDimLoop ::= TypeAnnotations LBRACKET RBRACKET"); } //$NON-NLS-1$ consumeOneDimLoop(true); break; - case 512 : if (DEBUG) { System.out.println("FieldAccess ::= Primary DOT Identifier"); } //$NON-NLS-1$ + case 526 : if (DEBUG) { System.out.println("FieldAccess ::= Primary DOT Identifier"); } //$NON-NLS-1$ consumeFieldAccess(false); break; - case 513 : if (DEBUG) { System.out.println("FieldAccess ::= super DOT Identifier"); } //$NON-NLS-1$ + case 527 : if (DEBUG) { System.out.println("FieldAccess ::= super DOT Identifier"); } //$NON-NLS-1$ consumeFieldAccess(true); break; - case 514 : if (DEBUG) { System.out.println("FieldAccess ::= QualifiedSuperReceiver DOT Identifier"); } //$NON-NLS-1$ + case 528 : if (DEBUG) { System.out.println("FieldAccess ::= QualifiedSuperReceiver DOT Identifier"); } //$NON-NLS-1$ consumeFieldAccess(false); break; - case 515 : if (DEBUG) { System.out.println("MethodInvocation ::= Name LPAREN ArgumentListopt RPAREN"); } //$NON-NLS-1$ + case 529 : if (DEBUG) { System.out.println("MethodInvocation ::= Name LPAREN ArgumentListopt RPAREN"); } //$NON-NLS-1$ consumeMethodInvocationName(); break; - case 516 : if (DEBUG) { System.out.println("MethodInvocation ::= Name DOT OnlyTypeArguments..."); } //$NON-NLS-1$ + case 530 : if (DEBUG) { System.out.println("MethodInvocation ::= Name DOT OnlyTypeArguments..."); } //$NON-NLS-1$ consumeMethodInvocationNameWithTypeArguments(); break; - case 517 : if (DEBUG) { System.out.println("MethodInvocation ::= Primary DOT OnlyTypeArguments..."); } //$NON-NLS-1$ + case 531 : if (DEBUG) { System.out.println("MethodInvocation ::= Primary DOT OnlyTypeArguments..."); } //$NON-NLS-1$ consumeMethodInvocationPrimaryWithTypeArguments(); break; - case 518 : if (DEBUG) { System.out.println("MethodInvocation ::= Primary DOT Identifier LPAREN..."); } //$NON-NLS-1$ + case 532 : if (DEBUG) { System.out.println("MethodInvocation ::= Primary DOT Identifier LPAREN..."); } //$NON-NLS-1$ consumeMethodInvocationPrimary(); break; - case 519 : if (DEBUG) { System.out.println("MethodInvocation ::= QualifiedSuperReceiver DOT..."); } //$NON-NLS-1$ + case 533 : if (DEBUG) { System.out.println("MethodInvocation ::= QualifiedSuperReceiver DOT..."); } //$NON-NLS-1$ consumeMethodInvocationPrimary(); break; - case 520 : if (DEBUG) { System.out.println("MethodInvocation ::= QualifiedSuperReceiver DOT..."); } //$NON-NLS-1$ + case 534 : if (DEBUG) { System.out.println("MethodInvocation ::= QualifiedSuperReceiver DOT..."); } //$NON-NLS-1$ consumeMethodInvocationPrimaryWithTypeArguments(); break; - case 521 : if (DEBUG) { System.out.println("MethodInvocation ::= super DOT OnlyTypeArguments..."); } //$NON-NLS-1$ + case 535 : if (DEBUG) { System.out.println("MethodInvocation ::= super DOT OnlyTypeArguments..."); } //$NON-NLS-1$ consumeMethodInvocationSuperWithTypeArguments(); break; - case 522 : if (DEBUG) { System.out.println("MethodInvocation ::= super DOT Identifier LPAREN..."); } //$NON-NLS-1$ + case 536 : if (DEBUG) { System.out.println("MethodInvocation ::= super DOT Identifier LPAREN..."); } //$NON-NLS-1$ consumeMethodInvocationSuper(); break; - case 523 : if (DEBUG) { System.out.println("ArrayAccess ::= Name LBRACKET Expression RBRACKET"); } //$NON-NLS-1$ + case 537 : if (DEBUG) { System.out.println("ArrayAccess ::= Name LBRACKET Expression RBRACKET"); } //$NON-NLS-1$ consumeArrayAccess(true); break; - case 524 : if (DEBUG) { System.out.println("ArrayAccess ::= PrimaryNoNewArray LBRACKET Expression..."); } //$NON-NLS-1$ + case 538 : if (DEBUG) { System.out.println("ArrayAccess ::= PrimaryNoNewArray LBRACKET Expression..."); } //$NON-NLS-1$ consumeArrayAccess(false); break; - case 525 : if (DEBUG) { System.out.println("ArrayAccess ::= ArrayCreationWithArrayInitializer..."); } //$NON-NLS-1$ + case 539 : if (DEBUG) { System.out.println("ArrayAccess ::= ArrayCreationWithArrayInitializer..."); } //$NON-NLS-1$ consumeArrayAccess(false); break; - case 527 : if (DEBUG) { System.out.println("PostfixExpression ::= Name"); } //$NON-NLS-1$ + case 541 : if (DEBUG) { System.out.println("PostfixExpression ::= Name"); } //$NON-NLS-1$ consumePostfixExpression(); break; - case 530 : if (DEBUG) { System.out.println("PostIncrementExpression ::= PostfixExpression PLUS_PLUS"); } //$NON-NLS-1$ + case 544 : if (DEBUG) { System.out.println("PostIncrementExpression ::= PostfixExpression PLUS_PLUS"); } //$NON-NLS-1$ consumeUnaryExpression(OperatorIds.PLUS,true); break; - case 531 : if (DEBUG) { System.out.println("PostDecrementExpression ::= PostfixExpression..."); } //$NON-NLS-1$ + case 545 : if (DEBUG) { System.out.println("PostDecrementExpression ::= PostfixExpression..."); } //$NON-NLS-1$ consumeUnaryExpression(OperatorIds.MINUS,true); break; - case 532 : if (DEBUG) { System.out.println("PushPosition ::="); } //$NON-NLS-1$ + case 546 : if (DEBUG) { System.out.println("PushPosition ::="); } //$NON-NLS-1$ consumePushPosition(); break; - case 535 : if (DEBUG) { System.out.println("UnaryExpression ::= PLUS PushPosition UnaryExpression"); } //$NON-NLS-1$ + case 549 : if (DEBUG) { System.out.println("UnaryExpression ::= PLUS PushPosition UnaryExpression"); } //$NON-NLS-1$ consumeUnaryExpression(OperatorIds.PLUS); break; - case 536 : if (DEBUG) { System.out.println("UnaryExpression ::= MINUS PushPosition UnaryExpression"); } //$NON-NLS-1$ + case 550 : if (DEBUG) { System.out.println("UnaryExpression ::= MINUS PushPosition UnaryExpression"); } //$NON-NLS-1$ consumeUnaryExpression(OperatorIds.MINUS); break; - case 538 : if (DEBUG) { System.out.println("PreIncrementExpression ::= PLUS_PLUS PushPosition..."); } //$NON-NLS-1$ + case 552 : if (DEBUG) { System.out.println("PreIncrementExpression ::= PLUS_PLUS PushPosition..."); } //$NON-NLS-1$ consumeUnaryExpression(OperatorIds.PLUS,false); break; - case 539 : if (DEBUG) { System.out.println("PreDecrementExpression ::= MINUS_MINUS PushPosition..."); } //$NON-NLS-1$ + case 553 : if (DEBUG) { System.out.println("PreDecrementExpression ::= MINUS_MINUS PushPosition..."); } //$NON-NLS-1$ consumeUnaryExpression(OperatorIds.MINUS,false); break; - case 541 : if (DEBUG) { System.out.println("UnaryExpressionNotPlusMinus ::= TWIDDLE PushPosition..."); } //$NON-NLS-1$ + case 555 : if (DEBUG) { System.out.println("UnaryExpressionNotPlusMinus ::= TWIDDLE PushPosition..."); } //$NON-NLS-1$ consumeUnaryExpression(OperatorIds.TWIDDLE); break; - case 542 : if (DEBUG) { System.out.println("UnaryExpressionNotPlusMinus ::= NOT PushPosition..."); } //$NON-NLS-1$ + case 556 : if (DEBUG) { System.out.println("UnaryExpressionNotPlusMinus ::= NOT PushPosition..."); } //$NON-NLS-1$ consumeUnaryExpression(OperatorIds.NOT); break; - case 544 : if (DEBUG) { System.out.println("CastExpression ::= PushLPAREN PrimitiveType Dimsopt..."); } //$NON-NLS-1$ + case 558 : if (DEBUG) { System.out.println("CastExpression ::= PushLPAREN PrimitiveType Dimsopt..."); } //$NON-NLS-1$ consumeCastExpressionWithPrimitiveType(); break; - case 545 : if (DEBUG) { System.out.println("CastExpression ::= PushLPAREN Name..."); } //$NON-NLS-1$ + case 559 : if (DEBUG) { System.out.println("CastExpression ::= PushLPAREN Name..."); } //$NON-NLS-1$ consumeCastExpressionWithGenericsArray(); break; - case 546 : if (DEBUG) { System.out.println("CastExpression ::= PushLPAREN Name..."); } //$NON-NLS-1$ + case 560 : if (DEBUG) { System.out.println("CastExpression ::= PushLPAREN Name..."); } //$NON-NLS-1$ consumeCastExpressionWithQualifiedGenericsArray(); break; - case 547 : if (DEBUG) { System.out.println("CastExpression ::= PushLPAREN Name PushRPAREN..."); } //$NON-NLS-1$ + case 561 : if (DEBUG) { System.out.println("CastExpression ::= PushLPAREN Name PushRPAREN..."); } //$NON-NLS-1$ consumeCastExpressionLL1(); break; - case 548 : if (DEBUG) { System.out.println("CastExpression ::= BeginIntersectionCast PushLPAREN..."); } //$NON-NLS-1$ + case 562 : if (DEBUG) { System.out.println("CastExpression ::= BeginIntersectionCast PushLPAREN..."); } //$NON-NLS-1$ consumeCastExpressionLL1WithBounds(); break; - case 549 : if (DEBUG) { System.out.println("CastExpression ::= PushLPAREN Name Dims..."); } //$NON-NLS-1$ + case 563 : if (DEBUG) { System.out.println("CastExpression ::= PushLPAREN Name Dims..."); } //$NON-NLS-1$ consumeCastExpressionWithNameArray(); break; - case 550 : if (DEBUG) { System.out.println("AdditionalBoundsListOpt ::="); } //$NON-NLS-1$ + case 564 : if (DEBUG) { System.out.println("AdditionalBoundsListOpt ::="); } //$NON-NLS-1$ consumeZeroAdditionalBounds(); break; - case 554 : if (DEBUG) { System.out.println("OnlyTypeArgumentsForCastExpression ::= OnlyTypeArguments"); } //$NON-NLS-1$ + case 568 : if (DEBUG) { System.out.println("OnlyTypeArgumentsForCastExpression ::= OnlyTypeArguments"); } //$NON-NLS-1$ consumeOnlyTypeArgumentsForCastExpression(); break; - case 555 : if (DEBUG) { System.out.println("InsideCastExpression ::="); } //$NON-NLS-1$ + case 569 : if (DEBUG) { System.out.println("InsideCastExpression ::="); } //$NON-NLS-1$ consumeInsideCastExpression(); break; - case 556 : if (DEBUG) { System.out.println("InsideCastExpressionLL1 ::="); } //$NON-NLS-1$ + case 570 : if (DEBUG) { System.out.println("InsideCastExpressionLL1 ::="); } //$NON-NLS-1$ consumeInsideCastExpressionLL1(); break; - case 557 : if (DEBUG) { System.out.println("InsideCastExpressionLL1WithBounds ::="); } //$NON-NLS-1$ + case 571 : if (DEBUG) { System.out.println("InsideCastExpressionLL1WithBounds ::="); } //$NON-NLS-1$ consumeInsideCastExpressionLL1WithBounds (); break; - case 558 : if (DEBUG) { System.out.println("InsideCastExpressionWithQualifiedGenerics ::="); } //$NON-NLS-1$ + case 572 : if (DEBUG) { System.out.println("InsideCastExpressionWithQualifiedGenerics ::="); } //$NON-NLS-1$ consumeInsideCastExpressionWithQualifiedGenerics(); break; - case 560 : if (DEBUG) { System.out.println("MultiplicativeExpression ::= MultiplicativeExpression..."); } //$NON-NLS-1$ + case 574 : if (DEBUG) { System.out.println("MultiplicativeExpression ::= MultiplicativeExpression..."); } //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.MULTIPLY); break; - case 561 : if (DEBUG) { System.out.println("MultiplicativeExpression ::= MultiplicativeExpression..."); } //$NON-NLS-1$ + case 575 : if (DEBUG) { System.out.println("MultiplicativeExpression ::= MultiplicativeExpression..."); } //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.DIVIDE); break; - case 562 : if (DEBUG) { System.out.println("MultiplicativeExpression ::= MultiplicativeExpression..."); } //$NON-NLS-1$ + case 576 : if (DEBUG) { System.out.println("MultiplicativeExpression ::= MultiplicativeExpression..."); } //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.REMAINDER); break; - case 564 : if (DEBUG) { System.out.println("AdditiveExpression ::= AdditiveExpression PLUS..."); } //$NON-NLS-1$ + case 578 : if (DEBUG) { System.out.println("AdditiveExpression ::= AdditiveExpression PLUS..."); } //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.PLUS); break; - case 565 : if (DEBUG) { System.out.println("AdditiveExpression ::= AdditiveExpression MINUS..."); } //$NON-NLS-1$ + case 579 : if (DEBUG) { System.out.println("AdditiveExpression ::= AdditiveExpression MINUS..."); } //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.MINUS); break; - case 567 : if (DEBUG) { System.out.println("ShiftExpression ::= ShiftExpression LEFT_SHIFT..."); } //$NON-NLS-1$ + case 581 : if (DEBUG) { System.out.println("ShiftExpression ::= ShiftExpression LEFT_SHIFT..."); } //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.LEFT_SHIFT); break; - case 568 : if (DEBUG) { System.out.println("ShiftExpression ::= ShiftExpression RIGHT_SHIFT..."); } //$NON-NLS-1$ + case 582 : if (DEBUG) { System.out.println("ShiftExpression ::= ShiftExpression RIGHT_SHIFT..."); } //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.RIGHT_SHIFT); break; - case 569 : if (DEBUG) { System.out.println("ShiftExpression ::= ShiftExpression UNSIGNED_RIGHT_SHIFT"); } //$NON-NLS-1$ + case 583 : if (DEBUG) { System.out.println("ShiftExpression ::= ShiftExpression UNSIGNED_RIGHT_SHIFT"); } //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.UNSIGNED_RIGHT_SHIFT); break; - case 571 : if (DEBUG) { System.out.println("RelationalExpression ::= RelationalExpression LESS..."); } //$NON-NLS-1$ + case 585 : if (DEBUG) { System.out.println("RelationalExpression ::= RelationalExpression LESS..."); } //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.LESS); break; - case 572 : if (DEBUG) { System.out.println("RelationalExpression ::= RelationalExpression GREATER..."); } //$NON-NLS-1$ + case 586 : if (DEBUG) { System.out.println("RelationalExpression ::= RelationalExpression GREATER..."); } //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.GREATER); break; - case 573 : if (DEBUG) { System.out.println("RelationalExpression ::= RelationalExpression LESS_EQUAL"); } //$NON-NLS-1$ + case 587 : if (DEBUG) { System.out.println("RelationalExpression ::= RelationalExpression LESS_EQUAL"); } //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.LESS_EQUAL); break; - case 574 : if (DEBUG) { System.out.println("RelationalExpression ::= RelationalExpression..."); } //$NON-NLS-1$ + case 588 : if (DEBUG) { System.out.println("RelationalExpression ::= RelationalExpression..."); } //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.GREATER_EQUAL); break; - case 576 : if (DEBUG) { System.out.println("InstanceofExpression ::= InstanceofExpression instanceof"); } //$NON-NLS-1$ + case 590 : if (DEBUG) { System.out.println("InstanceofExpression ::= InstanceofExpression instanceof"); } //$NON-NLS-1$ consumeInstanceOfExpression(); break; - case 578 : if (DEBUG) { System.out.println("EqualityExpression ::= EqualityExpression EQUAL_EQUAL..."); } //$NON-NLS-1$ + case 592 : if (DEBUG) { System.out.println("EqualityExpression ::= EqualityExpression EQUAL_EQUAL..."); } //$NON-NLS-1$ consumeEqualityExpression(OperatorIds.EQUAL_EQUAL); break; - case 579 : if (DEBUG) { System.out.println("EqualityExpression ::= EqualityExpression NOT_EQUAL..."); } //$NON-NLS-1$ + case 593 : if (DEBUG) { System.out.println("EqualityExpression ::= EqualityExpression NOT_EQUAL..."); } //$NON-NLS-1$ consumeEqualityExpression(OperatorIds.NOT_EQUAL); break; - case 581 : if (DEBUG) { System.out.println("AndExpression ::= AndExpression AND EqualityExpression"); } //$NON-NLS-1$ + case 595 : if (DEBUG) { System.out.println("AndExpression ::= AndExpression AND EqualityExpression"); } //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.AND); break; - case 583 : if (DEBUG) { System.out.println("ExclusiveOrExpression ::= ExclusiveOrExpression XOR..."); } //$NON-NLS-1$ + case 597 : if (DEBUG) { System.out.println("ExclusiveOrExpression ::= ExclusiveOrExpression XOR..."); } //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.XOR); break; - case 585 : if (DEBUG) { System.out.println("InclusiveOrExpression ::= InclusiveOrExpression OR..."); } //$NON-NLS-1$ + case 599 : if (DEBUG) { System.out.println("InclusiveOrExpression ::= InclusiveOrExpression OR..."); } //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.OR); break; - case 587 : if (DEBUG) { System.out.println("ConditionalAndExpression ::= ConditionalAndExpression..."); } //$NON-NLS-1$ + case 601 : if (DEBUG) { System.out.println("ConditionalAndExpression ::= ConditionalAndExpression..."); } //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.AND_AND); break; - case 589 : if (DEBUG) { System.out.println("ConditionalOrExpression ::= ConditionalOrExpression..."); } //$NON-NLS-1$ + case 603 : if (DEBUG) { System.out.println("ConditionalOrExpression ::= ConditionalOrExpression..."); } //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.OR_OR); break; - case 591 : if (DEBUG) { System.out.println("ConditionalExpression ::= ConditionalOrExpression..."); } //$NON-NLS-1$ + case 605 : if (DEBUG) { System.out.println("ConditionalExpression ::= ConditionalOrExpression..."); } //$NON-NLS-1$ consumeConditionalExpression(OperatorIds.QUESTIONCOLON) ; break; - case 594 : if (DEBUG) { System.out.println("Assignment ::= PostfixExpression AssignmentOperator..."); } //$NON-NLS-1$ + case 608 : if (DEBUG) { System.out.println("Assignment ::= PostfixExpression AssignmentOperator..."); } //$NON-NLS-1$ consumeAssignment(); break; - case 596 : if (DEBUG) { System.out.println("Assignment ::= InvalidArrayInitializerAssignement"); } //$NON-NLS-1$ + case 610 : if (DEBUG) { System.out.println("Assignment ::= InvalidArrayInitializerAssignement"); } //$NON-NLS-1$ ignoreExpressionAssignment(); break; - case 597 : if (DEBUG) { System.out.println("AssignmentOperator ::= EQUAL"); } //$NON-NLS-1$ + case 611 : if (DEBUG) { System.out.println("AssignmentOperator ::= EQUAL"); } //$NON-NLS-1$ consumeAssignmentOperator(EQUAL); break; - case 598 : if (DEBUG) { System.out.println("AssignmentOperator ::= MULTIPLY_EQUAL"); } //$NON-NLS-1$ + case 612 : if (DEBUG) { System.out.println("AssignmentOperator ::= MULTIPLY_EQUAL"); } //$NON-NLS-1$ consumeAssignmentOperator(MULTIPLY); break; - case 599 : if (DEBUG) { System.out.println("AssignmentOperator ::= DIVIDE_EQUAL"); } //$NON-NLS-1$ + case 613 : if (DEBUG) { System.out.println("AssignmentOperator ::= DIVIDE_EQUAL"); } //$NON-NLS-1$ consumeAssignmentOperator(DIVIDE); break; - case 600 : if (DEBUG) { System.out.println("AssignmentOperator ::= REMAINDER_EQUAL"); } //$NON-NLS-1$ + case 614 : if (DEBUG) { System.out.println("AssignmentOperator ::= REMAINDER_EQUAL"); } //$NON-NLS-1$ consumeAssignmentOperator(REMAINDER); break; - case 601 : if (DEBUG) { System.out.println("AssignmentOperator ::= PLUS_EQUAL"); } //$NON-NLS-1$ + case 615 : if (DEBUG) { System.out.println("AssignmentOperator ::= PLUS_EQUAL"); } //$NON-NLS-1$ consumeAssignmentOperator(PLUS); break; - case 602 : if (DEBUG) { System.out.println("AssignmentOperator ::= MINUS_EQUAL"); } //$NON-NLS-1$ + case 616 : if (DEBUG) { System.out.println("AssignmentOperator ::= MINUS_EQUAL"); } //$NON-NLS-1$ consumeAssignmentOperator(MINUS); break; - case 603 : if (DEBUG) { System.out.println("AssignmentOperator ::= LEFT_SHIFT_EQUAL"); } //$NON-NLS-1$ + case 617 : if (DEBUG) { System.out.println("AssignmentOperator ::= LEFT_SHIFT_EQUAL"); } //$NON-NLS-1$ consumeAssignmentOperator(LEFT_SHIFT); break; - case 604 : if (DEBUG) { System.out.println("AssignmentOperator ::= RIGHT_SHIFT_EQUAL"); } //$NON-NLS-1$ + case 618 : if (DEBUG) { System.out.println("AssignmentOperator ::= RIGHT_SHIFT_EQUAL"); } //$NON-NLS-1$ consumeAssignmentOperator(RIGHT_SHIFT); break; - case 605 : if (DEBUG) { System.out.println("AssignmentOperator ::= UNSIGNED_RIGHT_SHIFT_EQUAL"); } //$NON-NLS-1$ + case 619 : if (DEBUG) { System.out.println("AssignmentOperator ::= UNSIGNED_RIGHT_SHIFT_EQUAL"); } //$NON-NLS-1$ consumeAssignmentOperator(UNSIGNED_RIGHT_SHIFT); break; - case 606 : if (DEBUG) { System.out.println("AssignmentOperator ::= AND_EQUAL"); } //$NON-NLS-1$ + case 620 : if (DEBUG) { System.out.println("AssignmentOperator ::= AND_EQUAL"); } //$NON-NLS-1$ consumeAssignmentOperator(AND); break; - case 607 : if (DEBUG) { System.out.println("AssignmentOperator ::= XOR_EQUAL"); } //$NON-NLS-1$ + case 621 : if (DEBUG) { System.out.println("AssignmentOperator ::= XOR_EQUAL"); } //$NON-NLS-1$ consumeAssignmentOperator(XOR); break; - case 608 : if (DEBUG) { System.out.println("AssignmentOperator ::= OR_EQUAL"); } //$NON-NLS-1$ + case 622 : if (DEBUG) { System.out.println("AssignmentOperator ::= OR_EQUAL"); } //$NON-NLS-1$ consumeAssignmentOperator(OR); break; - case 609 : if (DEBUG) { System.out.println("Expression ::= AssignmentExpression"); } //$NON-NLS-1$ + case 623 : if (DEBUG) { System.out.println("Expression ::= AssignmentExpression"); } //$NON-NLS-1$ consumeExpression(); break; - case 612 : if (DEBUG) { System.out.println("Expressionopt ::="); } //$NON-NLS-1$ + case 626 : if (DEBUG) { System.out.println("Expressionopt ::="); } //$NON-NLS-1$ consumeEmptyExpression(); break; - case 617 : if (DEBUG) { System.out.println("ClassBodyDeclarationsopt ::="); } //$NON-NLS-1$ + case 629 : if (DEBUG) { System.out.println("ConstantExpressions ::= ConstantExpressions COMMA..."); } //$NON-NLS-1$ + consumeConstantExpressions(); + break; + + case 633 : if (DEBUG) { System.out.println("ClassBodyDeclarationsopt ::="); } //$NON-NLS-1$ consumeEmptyClassBodyDeclarationsopt(); break; - case 618 : if (DEBUG) { System.out.println("ClassBodyDeclarationsopt ::= NestedType..."); } //$NON-NLS-1$ + case 634 : if (DEBUG) { System.out.println("ClassBodyDeclarationsopt ::= NestedType..."); } //$NON-NLS-1$ consumeClassBodyDeclarationsopt(); break; - case 619 : if (DEBUG) { System.out.println("Modifiersopt ::="); } //$NON-NLS-1$ + case 635 : if (DEBUG) { System.out.println("Modifiersopt ::="); } //$NON-NLS-1$ consumeDefaultModifiers(); break; - case 620 : if (DEBUG) { System.out.println("Modifiersopt ::= Modifiers"); } //$NON-NLS-1$ + case 636 : if (DEBUG) { System.out.println("Modifiersopt ::= Modifiers"); } //$NON-NLS-1$ consumeModifiers(); break; - case 621 : if (DEBUG) { System.out.println("BlockStatementsopt ::="); } //$NON-NLS-1$ + case 637 : if (DEBUG) { System.out.println("BlockStatementsopt ::="); } //$NON-NLS-1$ consumeEmptyBlockStatementsopt(); break; - case 623 : if (DEBUG) { System.out.println("Dimsopt ::="); } //$NON-NLS-1$ + case 639 : if (DEBUG) { System.out.println("Dimsopt ::="); } //$NON-NLS-1$ consumeEmptyDimsopt(); break; - case 625 : if (DEBUG) { System.out.println("ArgumentListopt ::="); } //$NON-NLS-1$ + case 641 : if (DEBUG) { System.out.println("ArgumentListopt ::="); } //$NON-NLS-1$ consumeEmptyArgumentListopt(); break; - case 629 : if (DEBUG) { System.out.println("FormalParameterListopt ::="); } //$NON-NLS-1$ + case 645 : if (DEBUG) { System.out.println("FormalParameterListopt ::="); } //$NON-NLS-1$ consumeFormalParameterListopt(); break; - case 633 : if (DEBUG) { System.out.println("InterfaceMemberDeclarationsopt ::="); } //$NON-NLS-1$ + case 649 : if (DEBUG) { System.out.println("InterfaceMemberDeclarationsopt ::="); } //$NON-NLS-1$ consumeEmptyInterfaceMemberDeclarationsopt(); break; - case 634 : if (DEBUG) { System.out.println("InterfaceMemberDeclarationsopt ::= NestedType..."); } //$NON-NLS-1$ + case 650 : if (DEBUG) { System.out.println("InterfaceMemberDeclarationsopt ::= NestedType..."); } //$NON-NLS-1$ consumeInterfaceMemberDeclarationsopt(); break; - case 635 : if (DEBUG) { System.out.println("NestedType ::="); } //$NON-NLS-1$ + case 651 : if (DEBUG) { System.out.println("NestedType ::="); } //$NON-NLS-1$ consumeNestedType(); break; - case 636 : if (DEBUG) { System.out.println("ForInitopt ::="); } //$NON-NLS-1$ + case 652 : if (DEBUG) { System.out.println("ForInitopt ::="); } //$NON-NLS-1$ consumeEmptyForInitopt(); break; - case 638 : if (DEBUG) { System.out.println("ForUpdateopt ::="); } //$NON-NLS-1$ + case 654 : if (DEBUG) { System.out.println("ForUpdateopt ::="); } //$NON-NLS-1$ consumeEmptyForUpdateopt(); break; - case 642 : if (DEBUG) { System.out.println("Catchesopt ::="); } //$NON-NLS-1$ + case 658 : if (DEBUG) { System.out.println("Catchesopt ::="); } //$NON-NLS-1$ consumeEmptyCatchesopt(); break; - case 644 : if (DEBUG) { System.out.println("EnumDeclaration ::= EnumHeader EnumBody"); } //$NON-NLS-1$ + case 660 : if (DEBUG) { System.out.println("EnumDeclaration ::= EnumHeader EnumBody"); } //$NON-NLS-1$ consumeEnumDeclaration(); break; - case 645 : if (DEBUG) { System.out.println("EnumHeader ::= EnumHeaderName ClassHeaderImplementsopt"); } //$NON-NLS-1$ + case 661 : if (DEBUG) { System.out.println("EnumHeader ::= EnumHeaderName ClassHeaderImplementsopt"); } //$NON-NLS-1$ consumeEnumHeader(); break; - case 646 : if (DEBUG) { System.out.println("EnumHeaderName ::= Modifiersopt enum Identifier"); } //$NON-NLS-1$ + case 662 : if (DEBUG) { System.out.println("EnumHeaderName ::= Modifiersopt enum Identifier"); } //$NON-NLS-1$ consumeEnumHeaderName(); break; - case 647 : if (DEBUG) { System.out.println("EnumHeaderName ::= Modifiersopt enum Identifier..."); } //$NON-NLS-1$ + case 663 : if (DEBUG) { System.out.println("EnumHeaderName ::= Modifiersopt enum Identifier..."); } //$NON-NLS-1$ consumeEnumHeaderNameWithTypeParameters(); break; - case 648 : if (DEBUG) { System.out.println("EnumBody ::= LBRACE EnumBodyDeclarationsopt RBRACE"); } //$NON-NLS-1$ + case 664 : if (DEBUG) { System.out.println("EnumBody ::= LBRACE EnumBodyDeclarationsopt RBRACE"); } //$NON-NLS-1$ consumeEnumBodyNoConstants(); break; - case 649 : if (DEBUG) { System.out.println("EnumBody ::= LBRACE COMMA EnumBodyDeclarationsopt..."); } //$NON-NLS-1$ + case 665 : if (DEBUG) { System.out.println("EnumBody ::= LBRACE COMMA EnumBodyDeclarationsopt..."); } //$NON-NLS-1$ consumeEnumBodyNoConstants(); break; - case 650 : if (DEBUG) { System.out.println("EnumBody ::= LBRACE EnumConstants COMMA..."); } //$NON-NLS-1$ + case 666 : if (DEBUG) { System.out.println("EnumBody ::= LBRACE EnumConstants COMMA..."); } //$NON-NLS-1$ consumeEnumBodyWithConstants(); break; - case 651 : if (DEBUG) { System.out.println("EnumBody ::= LBRACE EnumConstants..."); } //$NON-NLS-1$ + case 667 : if (DEBUG) { System.out.println("EnumBody ::= LBRACE EnumConstants..."); } //$NON-NLS-1$ consumeEnumBodyWithConstants(); break; - case 653 : if (DEBUG) { System.out.println("EnumConstants ::= EnumConstants COMMA EnumConstant"); } //$NON-NLS-1$ + case 669 : if (DEBUG) { System.out.println("EnumConstants ::= EnumConstants COMMA EnumConstant"); } //$NON-NLS-1$ consumeEnumConstants(); break; - case 654 : if (DEBUG) { System.out.println("EnumConstantHeaderName ::= Modifiersopt Identifier"); } //$NON-NLS-1$ + case 670 : if (DEBUG) { System.out.println("EnumConstantHeaderName ::= Modifiersopt Identifier"); } //$NON-NLS-1$ consumeEnumConstantHeaderName(); break; - case 655 : if (DEBUG) { System.out.println("EnumConstantHeader ::= EnumConstantHeaderName..."); } //$NON-NLS-1$ + case 671 : if (DEBUG) { System.out.println("EnumConstantHeader ::= EnumConstantHeaderName..."); } //$NON-NLS-1$ consumeEnumConstantHeader(); break; - case 656 : if (DEBUG) { System.out.println("EnumConstant ::= EnumConstantHeader ForceNoDiet..."); } //$NON-NLS-1$ + case 672 : if (DEBUG) { System.out.println("EnumConstant ::= EnumConstantHeader ForceNoDiet..."); } //$NON-NLS-1$ consumeEnumConstantWithClassBody(); break; - case 657 : if (DEBUG) { System.out.println("EnumConstant ::= EnumConstantHeader"); } //$NON-NLS-1$ + case 673 : if (DEBUG) { System.out.println("EnumConstant ::= EnumConstantHeader"); } //$NON-NLS-1$ consumeEnumConstantNoClassBody(); break; - case 658 : if (DEBUG) { System.out.println("Arguments ::= LPAREN ArgumentListopt RPAREN"); } //$NON-NLS-1$ + case 674 : if (DEBUG) { System.out.println("Arguments ::= LPAREN ArgumentListopt RPAREN"); } //$NON-NLS-1$ consumeArguments(); break; - case 659 : if (DEBUG) { System.out.println("Argumentsopt ::="); } //$NON-NLS-1$ + case 675 : if (DEBUG) { System.out.println("Argumentsopt ::="); } //$NON-NLS-1$ consumeEmptyArguments(); break; - case 661 : if (DEBUG) { System.out.println("EnumDeclarations ::= SEMICOLON ClassBodyDeclarationsopt"); } //$NON-NLS-1$ + case 677 : if (DEBUG) { System.out.println("EnumDeclarations ::= SEMICOLON ClassBodyDeclarationsopt"); } //$NON-NLS-1$ consumeEnumDeclarations(); break; - case 662 : if (DEBUG) { System.out.println("EnumBodyDeclarationsopt ::="); } //$NON-NLS-1$ + case 678 : if (DEBUG) { System.out.println("EnumBodyDeclarationsopt ::="); } //$NON-NLS-1$ consumeEmptyEnumDeclarations(); break; - case 664 : if (DEBUG) { System.out.println("EnhancedForStatement ::= EnhancedForStatementHeader..."); } //$NON-NLS-1$ + case 680 : if (DEBUG) { System.out.println("EnhancedForStatement ::= EnhancedForStatementHeader..."); } //$NON-NLS-1$ consumeEnhancedForStatement(); break; - case 665 : if (DEBUG) { System.out.println("EnhancedForStatementNoShortIf ::=..."); } //$NON-NLS-1$ + case 681 : if (DEBUG) { System.out.println("EnhancedForStatementNoShortIf ::=..."); } //$NON-NLS-1$ consumeEnhancedForStatement(); break; - case 666 : if (DEBUG) { System.out.println("EnhancedForStatementHeaderInit ::= for LPAREN Type..."); } //$NON-NLS-1$ + case 682 : if (DEBUG) { System.out.println("EnhancedForStatementHeaderInit ::= for LPAREN Type..."); } //$NON-NLS-1$ consumeEnhancedForStatementHeaderInit(false); break; - case 667 : if (DEBUG) { System.out.println("EnhancedForStatementHeaderInit ::= for LPAREN Modifiers"); } //$NON-NLS-1$ + case 683 : if (DEBUG) { System.out.println("EnhancedForStatementHeaderInit ::= for LPAREN Modifiers"); } //$NON-NLS-1$ consumeEnhancedForStatementHeaderInit(true); break; - case 668 : if (DEBUG) { System.out.println("EnhancedForStatementHeader ::=..."); } //$NON-NLS-1$ + case 684 : if (DEBUG) { System.out.println("EnhancedForStatementHeader ::=..."); } //$NON-NLS-1$ consumeEnhancedForStatementHeader(); break; - case 669 : if (DEBUG) { System.out.println("SingleStaticImportDeclaration ::=..."); } //$NON-NLS-1$ + case 685 : if (DEBUG) { System.out.println("SingleStaticImportDeclaration ::=..."); } //$NON-NLS-1$ consumeImportDeclaration(); break; - case 670 : if (DEBUG) { System.out.println("SingleStaticImportDeclarationName ::= import static Name"); } //$NON-NLS-1$ + case 686 : if (DEBUG) { System.out.println("SingleStaticImportDeclarationName ::= import static Name"); } //$NON-NLS-1$ consumeSingleStaticImportDeclarationName(); break; - case 671 : if (DEBUG) { System.out.println("StaticImportOnDemandDeclaration ::=..."); } //$NON-NLS-1$ + case 687 : if (DEBUG) { System.out.println("StaticImportOnDemandDeclaration ::=..."); } //$NON-NLS-1$ consumeImportDeclaration(); break; - case 672 : if (DEBUG) { System.out.println("StaticImportOnDemandDeclarationName ::= import static..."); } //$NON-NLS-1$ + case 688 : if (DEBUG) { System.out.println("StaticImportOnDemandDeclarationName ::= import static..."); } //$NON-NLS-1$ consumeStaticImportOnDemandDeclarationName(); break; - case 673 : if (DEBUG) { System.out.println("TypeArguments ::= LESS TypeArgumentList1"); } //$NON-NLS-1$ + case 689 : if (DEBUG) { System.out.println("TypeArguments ::= LESS TypeArgumentList1"); } //$NON-NLS-1$ consumeTypeArguments(); break; - case 674 : if (DEBUG) { System.out.println("OnlyTypeArguments ::= LESS TypeArgumentList1"); } //$NON-NLS-1$ + case 690 : if (DEBUG) { System.out.println("OnlyTypeArguments ::= LESS TypeArgumentList1"); } //$NON-NLS-1$ consumeOnlyTypeArguments(); break; - case 676 : if (DEBUG) { System.out.println("TypeArgumentList1 ::= TypeArgumentList COMMA..."); } //$NON-NLS-1$ + case 692 : if (DEBUG) { System.out.println("TypeArgumentList1 ::= TypeArgumentList COMMA..."); } //$NON-NLS-1$ consumeTypeArgumentList1(); break; - case 678 : if (DEBUG) { System.out.println("TypeArgumentList ::= TypeArgumentList COMMA TypeArgument"); } //$NON-NLS-1$ + case 694 : if (DEBUG) { System.out.println("TypeArgumentList ::= TypeArgumentList COMMA TypeArgument"); } //$NON-NLS-1$ consumeTypeArgumentList(); break; - case 679 : if (DEBUG) { System.out.println("TypeArgument ::= ReferenceType"); } //$NON-NLS-1$ + case 695 : if (DEBUG) { System.out.println("TypeArgument ::= ReferenceType"); } //$NON-NLS-1$ consumeTypeArgument(); break; - case 683 : if (DEBUG) { System.out.println("ReferenceType1 ::= ReferenceType GREATER"); } //$NON-NLS-1$ + case 699 : if (DEBUG) { System.out.println("ReferenceType1 ::= ReferenceType GREATER"); } //$NON-NLS-1$ consumeReferenceType1(); break; - case 684 : if (DEBUG) { System.out.println("ReferenceType1 ::= ClassOrInterface LESS..."); } //$NON-NLS-1$ + case 700 : if (DEBUG) { System.out.println("ReferenceType1 ::= ClassOrInterface LESS..."); } //$NON-NLS-1$ consumeTypeArgumentReferenceType1(); break; - case 686 : if (DEBUG) { System.out.println("TypeArgumentList2 ::= TypeArgumentList COMMA..."); } //$NON-NLS-1$ + case 702 : if (DEBUG) { System.out.println("TypeArgumentList2 ::= TypeArgumentList COMMA..."); } //$NON-NLS-1$ consumeTypeArgumentList2(); break; - case 689 : if (DEBUG) { System.out.println("ReferenceType2 ::= ReferenceType RIGHT_SHIFT"); } //$NON-NLS-1$ + case 705 : if (DEBUG) { System.out.println("ReferenceType2 ::= ReferenceType RIGHT_SHIFT"); } //$NON-NLS-1$ consumeReferenceType2(); break; - case 690 : if (DEBUG) { System.out.println("ReferenceType2 ::= ClassOrInterface LESS..."); } //$NON-NLS-1$ + case 706 : if (DEBUG) { System.out.println("ReferenceType2 ::= ClassOrInterface LESS..."); } //$NON-NLS-1$ consumeTypeArgumentReferenceType2(); break; - case 692 : if (DEBUG) { System.out.println("TypeArgumentList3 ::= TypeArgumentList COMMA..."); } //$NON-NLS-1$ + case 708 : if (DEBUG) { System.out.println("TypeArgumentList3 ::= TypeArgumentList COMMA..."); } //$NON-NLS-1$ consumeTypeArgumentList3(); break; - case 695 : if (DEBUG) { System.out.println("ReferenceType3 ::= ReferenceType UNSIGNED_RIGHT_SHIFT"); } //$NON-NLS-1$ + case 711 : if (DEBUG) { System.out.println("ReferenceType3 ::= ReferenceType UNSIGNED_RIGHT_SHIFT"); } //$NON-NLS-1$ consumeReferenceType3(); break; - case 696 : if (DEBUG) { System.out.println("Wildcard ::= TypeAnnotationsopt QUESTION"); } //$NON-NLS-1$ + case 712 : if (DEBUG) { System.out.println("Wildcard ::= TypeAnnotationsopt QUESTION"); } //$NON-NLS-1$ consumeWildcard(); break; - case 697 : if (DEBUG) { System.out.println("Wildcard ::= TypeAnnotationsopt QUESTION WildcardBounds"); } //$NON-NLS-1$ + case 713 : if (DEBUG) { System.out.println("Wildcard ::= TypeAnnotationsopt QUESTION WildcardBounds"); } //$NON-NLS-1$ consumeWildcardWithBounds(); break; - case 698 : if (DEBUG) { System.out.println("WildcardBounds ::= extends ReferenceType"); } //$NON-NLS-1$ + case 714 : if (DEBUG) { System.out.println("WildcardBounds ::= extends ReferenceType"); } //$NON-NLS-1$ consumeWildcardBoundsExtends(); break; - case 699 : if (DEBUG) { System.out.println("WildcardBounds ::= super ReferenceType"); } //$NON-NLS-1$ + case 715 : if (DEBUG) { System.out.println("WildcardBounds ::= super ReferenceType"); } //$NON-NLS-1$ consumeWildcardBoundsSuper(); break; - case 700 : if (DEBUG) { System.out.println("Wildcard1 ::= TypeAnnotationsopt QUESTION GREATER"); } //$NON-NLS-1$ + case 716 : if (DEBUG) { System.out.println("Wildcard1 ::= TypeAnnotationsopt QUESTION GREATER"); } //$NON-NLS-1$ consumeWildcard1(); break; - case 701 : if (DEBUG) { System.out.println("Wildcard1 ::= TypeAnnotationsopt QUESTION..."); } //$NON-NLS-1$ + case 717 : if (DEBUG) { System.out.println("Wildcard1 ::= TypeAnnotationsopt QUESTION..."); } //$NON-NLS-1$ consumeWildcard1WithBounds(); break; - case 702 : if (DEBUG) { System.out.println("WildcardBounds1 ::= extends ReferenceType1"); } //$NON-NLS-1$ + case 718 : if (DEBUG) { System.out.println("WildcardBounds1 ::= extends ReferenceType1"); } //$NON-NLS-1$ consumeWildcardBounds1Extends(); break; - case 703 : if (DEBUG) { System.out.println("WildcardBounds1 ::= super ReferenceType1"); } //$NON-NLS-1$ + case 719 : if (DEBUG) { System.out.println("WildcardBounds1 ::= super ReferenceType1"); } //$NON-NLS-1$ consumeWildcardBounds1Super(); break; - case 704 : if (DEBUG) { System.out.println("Wildcard2 ::= TypeAnnotationsopt QUESTION RIGHT_SHIFT"); } //$NON-NLS-1$ + case 720 : if (DEBUG) { System.out.println("Wildcard2 ::= TypeAnnotationsopt QUESTION RIGHT_SHIFT"); } //$NON-NLS-1$ consumeWildcard2(); break; - case 705 : if (DEBUG) { System.out.println("Wildcard2 ::= TypeAnnotationsopt QUESTION..."); } //$NON-NLS-1$ + case 721 : if (DEBUG) { System.out.println("Wildcard2 ::= TypeAnnotationsopt QUESTION..."); } //$NON-NLS-1$ consumeWildcard2WithBounds(); break; - case 706 : if (DEBUG) { System.out.println("WildcardBounds2 ::= extends ReferenceType2"); } //$NON-NLS-1$ + case 722 : if (DEBUG) { System.out.println("WildcardBounds2 ::= extends ReferenceType2"); } //$NON-NLS-1$ consumeWildcardBounds2Extends(); break; - case 707 : if (DEBUG) { System.out.println("WildcardBounds2 ::= super ReferenceType2"); } //$NON-NLS-1$ + case 723 : if (DEBUG) { System.out.println("WildcardBounds2 ::= super ReferenceType2"); } //$NON-NLS-1$ consumeWildcardBounds2Super(); break; - case 708 : if (DEBUG) { System.out.println("Wildcard3 ::= TypeAnnotationsopt QUESTION..."); } //$NON-NLS-1$ + case 724 : if (DEBUG) { System.out.println("Wildcard3 ::= TypeAnnotationsopt QUESTION..."); } //$NON-NLS-1$ consumeWildcard3(); break; - case 709 : if (DEBUG) { System.out.println("Wildcard3 ::= TypeAnnotationsopt QUESTION..."); } //$NON-NLS-1$ + case 725 : if (DEBUG) { System.out.println("Wildcard3 ::= TypeAnnotationsopt QUESTION..."); } //$NON-NLS-1$ consumeWildcard3WithBounds(); break; - case 710 : if (DEBUG) { System.out.println("WildcardBounds3 ::= extends ReferenceType3"); } //$NON-NLS-1$ + case 726 : if (DEBUG) { System.out.println("WildcardBounds3 ::= extends ReferenceType3"); } //$NON-NLS-1$ consumeWildcardBounds3Extends(); break; - case 711 : if (DEBUG) { System.out.println("WildcardBounds3 ::= super ReferenceType3"); } //$NON-NLS-1$ + case 727 : if (DEBUG) { System.out.println("WildcardBounds3 ::= super ReferenceType3"); } //$NON-NLS-1$ consumeWildcardBounds3Super(); break; - case 712 : if (DEBUG) { System.out.println("TypeParameterHeader ::= TypeAnnotationsopt Identifier"); } //$NON-NLS-1$ + case 728 : if (DEBUG) { System.out.println("TypeParameterHeader ::= TypeAnnotationsopt Identifier"); } //$NON-NLS-1$ consumeTypeParameterHeader(); break; - case 713 : if (DEBUG) { System.out.println("TypeParameters ::= LESS TypeParameterList1"); } //$NON-NLS-1$ + case 729 : if (DEBUG) { System.out.println("TypeParameters ::= LESS TypeParameterList1"); } //$NON-NLS-1$ consumeTypeParameters(); break; - case 715 : if (DEBUG) { System.out.println("TypeParameterList ::= TypeParameterList COMMA..."); } //$NON-NLS-1$ + case 731 : if (DEBUG) { System.out.println("TypeParameterList ::= TypeParameterList COMMA..."); } //$NON-NLS-1$ consumeTypeParameterList(); break; - case 717 : if (DEBUG) { System.out.println("TypeParameter ::= TypeParameterHeader extends..."); } //$NON-NLS-1$ + case 733 : if (DEBUG) { System.out.println("TypeParameter ::= TypeParameterHeader extends..."); } //$NON-NLS-1$ consumeTypeParameterWithExtends(); break; - case 718 : if (DEBUG) { System.out.println("TypeParameter ::= TypeParameterHeader extends..."); } //$NON-NLS-1$ + case 734 : if (DEBUG) { System.out.println("TypeParameter ::= TypeParameterHeader extends..."); } //$NON-NLS-1$ consumeTypeParameterWithExtendsAndBounds(); break; - case 720 : if (DEBUG) { System.out.println("AdditionalBoundList ::= AdditionalBoundList..."); } //$NON-NLS-1$ + case 736 : if (DEBUG) { System.out.println("AdditionalBoundList ::= AdditionalBoundList..."); } //$NON-NLS-1$ consumeAdditionalBoundList(); break; - case 721 : if (DEBUG) { System.out.println("AdditionalBound ::= AND ReferenceType"); } //$NON-NLS-1$ + case 737 : if (DEBUG) { System.out.println("AdditionalBound ::= AND ReferenceType"); } //$NON-NLS-1$ consumeAdditionalBound(); break; - case 723 : if (DEBUG) { System.out.println("TypeParameterList1 ::= TypeParameterList COMMA..."); } //$NON-NLS-1$ + case 739 : if (DEBUG) { System.out.println("TypeParameterList1 ::= TypeParameterList COMMA..."); } //$NON-NLS-1$ consumeTypeParameterList1(); break; - case 724 : if (DEBUG) { System.out.println("TypeParameter1 ::= TypeParameterHeader GREATER"); } //$NON-NLS-1$ + case 740 : if (DEBUG) { System.out.println("TypeParameter1 ::= TypeParameterHeader GREATER"); } //$NON-NLS-1$ consumeTypeParameter1(); break; - case 725 : if (DEBUG) { System.out.println("TypeParameter1 ::= TypeParameterHeader extends..."); } //$NON-NLS-1$ + case 741 : if (DEBUG) { System.out.println("TypeParameter1 ::= TypeParameterHeader extends..."); } //$NON-NLS-1$ consumeTypeParameter1WithExtends(); break; - case 726 : if (DEBUG) { System.out.println("TypeParameter1 ::= TypeParameterHeader extends..."); } //$NON-NLS-1$ + case 742 : if (DEBUG) { System.out.println("TypeParameter1 ::= TypeParameterHeader extends..."); } //$NON-NLS-1$ consumeTypeParameter1WithExtendsAndBounds(); break; - case 728 : if (DEBUG) { System.out.println("AdditionalBoundList1 ::= AdditionalBoundList..."); } //$NON-NLS-1$ + case 744 : if (DEBUG) { System.out.println("AdditionalBoundList1 ::= AdditionalBoundList..."); } //$NON-NLS-1$ consumeAdditionalBoundList1(); break; - case 729 : if (DEBUG) { System.out.println("AdditionalBound1 ::= AND ReferenceType1"); } //$NON-NLS-1$ + case 745 : if (DEBUG) { System.out.println("AdditionalBound1 ::= AND ReferenceType1"); } //$NON-NLS-1$ consumeAdditionalBound1(); break; - case 735 : if (DEBUG) { System.out.println("UnaryExpression_NotName ::= PLUS PushPosition..."); } //$NON-NLS-1$ + case 751 : if (DEBUG) { System.out.println("UnaryExpression_NotName ::= PLUS PushPosition..."); } //$NON-NLS-1$ consumeUnaryExpression(OperatorIds.PLUS); break; - case 736 : if (DEBUG) { System.out.println("UnaryExpression_NotName ::= MINUS PushPosition..."); } //$NON-NLS-1$ + case 752 : if (DEBUG) { System.out.println("UnaryExpression_NotName ::= MINUS PushPosition..."); } //$NON-NLS-1$ consumeUnaryExpression(OperatorIds.MINUS); break; - case 739 : if (DEBUG) { System.out.println("UnaryExpressionNotPlusMinus_NotName ::= TWIDDLE..."); } //$NON-NLS-1$ + case 755 : if (DEBUG) { System.out.println("UnaryExpressionNotPlusMinus_NotName ::= TWIDDLE..."); } //$NON-NLS-1$ consumeUnaryExpression(OperatorIds.TWIDDLE); break; - case 740 : if (DEBUG) { System.out.println("UnaryExpressionNotPlusMinus_NotName ::= NOT PushPosition"); } //$NON-NLS-1$ + case 756 : if (DEBUG) { System.out.println("UnaryExpressionNotPlusMinus_NotName ::= NOT PushPosition"); } //$NON-NLS-1$ consumeUnaryExpression(OperatorIds.NOT); break; - case 743 : if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::=..."); } //$NON-NLS-1$ + case 759 : if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::=..."); } //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.MULTIPLY); break; - case 744 : if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::= Name MULTIPLY..."); } //$NON-NLS-1$ + case 760 : if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::= Name MULTIPLY..."); } //$NON-NLS-1$ consumeBinaryExpressionWithName(OperatorIds.MULTIPLY); break; - case 745 : if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::=..."); } //$NON-NLS-1$ + case 761 : if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::=..."); } //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.DIVIDE); break; - case 746 : if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::= Name DIVIDE..."); } //$NON-NLS-1$ + case 762 : if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::= Name DIVIDE..."); } //$NON-NLS-1$ consumeBinaryExpressionWithName(OperatorIds.DIVIDE); break; - case 747 : if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::=..."); } //$NON-NLS-1$ + case 763 : if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::=..."); } //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.REMAINDER); break; - case 748 : if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::= Name REMAINDER..."); } //$NON-NLS-1$ + case 764 : if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::= Name REMAINDER..."); } //$NON-NLS-1$ consumeBinaryExpressionWithName(OperatorIds.REMAINDER); break; - case 750 : if (DEBUG) { System.out.println("AdditiveExpression_NotName ::=..."); } //$NON-NLS-1$ + case 766 : if (DEBUG) { System.out.println("AdditiveExpression_NotName ::=..."); } //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.PLUS); break; - case 751 : if (DEBUG) { System.out.println("AdditiveExpression_NotName ::= Name PLUS..."); } //$NON-NLS-1$ + case 767 : if (DEBUG) { System.out.println("AdditiveExpression_NotName ::= Name PLUS..."); } //$NON-NLS-1$ consumeBinaryExpressionWithName(OperatorIds.PLUS); break; - case 752 : if (DEBUG) { System.out.println("AdditiveExpression_NotName ::=..."); } //$NON-NLS-1$ + case 768 : if (DEBUG) { System.out.println("AdditiveExpression_NotName ::=..."); } //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.MINUS); break; - case 753 : if (DEBUG) { System.out.println("AdditiveExpression_NotName ::= Name MINUS..."); } //$NON-NLS-1$ + case 769 : if (DEBUG) { System.out.println("AdditiveExpression_NotName ::= Name MINUS..."); } //$NON-NLS-1$ consumeBinaryExpressionWithName(OperatorIds.MINUS); break; - case 755 : if (DEBUG) { System.out.println("ShiftExpression_NotName ::= ShiftExpression_NotName..."); } //$NON-NLS-1$ + case 771 : if (DEBUG) { System.out.println("ShiftExpression_NotName ::= ShiftExpression_NotName..."); } //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.LEFT_SHIFT); break; - case 756 : if (DEBUG) { System.out.println("ShiftExpression_NotName ::= Name LEFT_SHIFT..."); } //$NON-NLS-1$ + case 772 : if (DEBUG) { System.out.println("ShiftExpression_NotName ::= Name LEFT_SHIFT..."); } //$NON-NLS-1$ consumeBinaryExpressionWithName(OperatorIds.LEFT_SHIFT); break; - case 757 : if (DEBUG) { System.out.println("ShiftExpression_NotName ::= ShiftExpression_NotName..."); } //$NON-NLS-1$ + case 773 : if (DEBUG) { System.out.println("ShiftExpression_NotName ::= ShiftExpression_NotName..."); } //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.RIGHT_SHIFT); break; - case 758 : if (DEBUG) { System.out.println("ShiftExpression_NotName ::= Name RIGHT_SHIFT..."); } //$NON-NLS-1$ + case 774 : if (DEBUG) { System.out.println("ShiftExpression_NotName ::= Name RIGHT_SHIFT..."); } //$NON-NLS-1$ consumeBinaryExpressionWithName(OperatorIds.RIGHT_SHIFT); break; - case 759 : if (DEBUG) { System.out.println("ShiftExpression_NotName ::= ShiftExpression_NotName..."); } //$NON-NLS-1$ + case 775 : if (DEBUG) { System.out.println("ShiftExpression_NotName ::= ShiftExpression_NotName..."); } //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.UNSIGNED_RIGHT_SHIFT); break; - case 760 : if (DEBUG) { System.out.println("ShiftExpression_NotName ::= Name UNSIGNED_RIGHT_SHIFT..."); } //$NON-NLS-1$ + case 776 : if (DEBUG) { System.out.println("ShiftExpression_NotName ::= Name UNSIGNED_RIGHT_SHIFT..."); } //$NON-NLS-1$ consumeBinaryExpressionWithName(OperatorIds.UNSIGNED_RIGHT_SHIFT); break; - case 762 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::= ShiftExpression_NotName"); } //$NON-NLS-1$ + case 778 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::= ShiftExpression_NotName"); } //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.LESS); break; - case 763 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::= Name LESS..."); } //$NON-NLS-1$ + case 779 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::= Name LESS..."); } //$NON-NLS-1$ consumeBinaryExpressionWithName(OperatorIds.LESS); break; - case 764 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::= ShiftExpression_NotName"); } //$NON-NLS-1$ + case 780 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::= ShiftExpression_NotName"); } //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.GREATER); break; - case 765 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::= Name GREATER..."); } //$NON-NLS-1$ + case 781 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::= Name GREATER..."); } //$NON-NLS-1$ consumeBinaryExpressionWithName(OperatorIds.GREATER); break; - case 766 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::=..."); } //$NON-NLS-1$ + case 782 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::=..."); } //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.LESS_EQUAL); break; - case 767 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::= Name LESS_EQUAL..."); } //$NON-NLS-1$ + case 783 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::= Name LESS_EQUAL..."); } //$NON-NLS-1$ consumeBinaryExpressionWithName(OperatorIds.LESS_EQUAL); break; - case 768 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::=..."); } //$NON-NLS-1$ + case 784 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::=..."); } //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.GREATER_EQUAL); break; - case 769 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::= Name GREATER_EQUAL..."); } //$NON-NLS-1$ + case 785 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::= Name GREATER_EQUAL..."); } //$NON-NLS-1$ consumeBinaryExpressionWithName(OperatorIds.GREATER_EQUAL); break; - case 771 : if (DEBUG) { System.out.println("InstanceofExpression_NotName ::= Name instanceof..."); } //$NON-NLS-1$ + case 787 : if (DEBUG) { System.out.println("InstanceofExpression_NotName ::= Name instanceof..."); } //$NON-NLS-1$ consumeInstanceOfExpressionWithName(); break; - case 772 : if (DEBUG) { System.out.println("InstanceofExpression_NotName ::=..."); } //$NON-NLS-1$ + case 788 : if (DEBUG) { System.out.println("InstanceofExpression_NotName ::=..."); } //$NON-NLS-1$ consumeInstanceOfExpression(); break; - case 774 : if (DEBUG) { System.out.println("EqualityExpression_NotName ::=..."); } //$NON-NLS-1$ + case 790 : if (DEBUG) { System.out.println("EqualityExpression_NotName ::=..."); } //$NON-NLS-1$ consumeEqualityExpression(OperatorIds.EQUAL_EQUAL); break; - case 775 : if (DEBUG) { System.out.println("EqualityExpression_NotName ::= Name EQUAL_EQUAL..."); } //$NON-NLS-1$ + case 791 : if (DEBUG) { System.out.println("EqualityExpression_NotName ::= Name EQUAL_EQUAL..."); } //$NON-NLS-1$ consumeEqualityExpressionWithName(OperatorIds.EQUAL_EQUAL); break; - case 776 : if (DEBUG) { System.out.println("EqualityExpression_NotName ::=..."); } //$NON-NLS-1$ + case 792 : if (DEBUG) { System.out.println("EqualityExpression_NotName ::=..."); } //$NON-NLS-1$ consumeEqualityExpression(OperatorIds.NOT_EQUAL); break; - case 777 : if (DEBUG) { System.out.println("EqualityExpression_NotName ::= Name NOT_EQUAL..."); } //$NON-NLS-1$ + case 793 : if (DEBUG) { System.out.println("EqualityExpression_NotName ::= Name NOT_EQUAL..."); } //$NON-NLS-1$ consumeEqualityExpressionWithName(OperatorIds.NOT_EQUAL); break; - case 779 : if (DEBUG) { System.out.println("AndExpression_NotName ::= AndExpression_NotName AND..."); } //$NON-NLS-1$ + case 795 : if (DEBUG) { System.out.println("AndExpression_NotName ::= AndExpression_NotName AND..."); } //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.AND); break; - case 780 : if (DEBUG) { System.out.println("AndExpression_NotName ::= Name AND EqualityExpression"); } //$NON-NLS-1$ + case 796 : if (DEBUG) { System.out.println("AndExpression_NotName ::= Name AND EqualityExpression"); } //$NON-NLS-1$ consumeBinaryExpressionWithName(OperatorIds.AND); break; - case 782 : if (DEBUG) { System.out.println("ExclusiveOrExpression_NotName ::=..."); } //$NON-NLS-1$ + case 798 : if (DEBUG) { System.out.println("ExclusiveOrExpression_NotName ::=..."); } //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.XOR); break; - case 783 : if (DEBUG) { System.out.println("ExclusiveOrExpression_NotName ::= Name XOR AndExpression"); } //$NON-NLS-1$ + case 799 : if (DEBUG) { System.out.println("ExclusiveOrExpression_NotName ::= Name XOR AndExpression"); } //$NON-NLS-1$ consumeBinaryExpressionWithName(OperatorIds.XOR); break; - case 785 : if (DEBUG) { System.out.println("InclusiveOrExpression_NotName ::=..."); } //$NON-NLS-1$ + case 801 : if (DEBUG) { System.out.println("InclusiveOrExpression_NotName ::=..."); } //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.OR); break; - case 786 : if (DEBUG) { System.out.println("InclusiveOrExpression_NotName ::= Name OR..."); } //$NON-NLS-1$ + case 802 : if (DEBUG) { System.out.println("InclusiveOrExpression_NotName ::= Name OR..."); } //$NON-NLS-1$ consumeBinaryExpressionWithName(OperatorIds.OR); break; - case 788 : if (DEBUG) { System.out.println("ConditionalAndExpression_NotName ::=..."); } //$NON-NLS-1$ + case 804 : if (DEBUG) { System.out.println("ConditionalAndExpression_NotName ::=..."); } //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.AND_AND); break; - case 789 : if (DEBUG) { System.out.println("ConditionalAndExpression_NotName ::= Name AND_AND..."); } //$NON-NLS-1$ + case 805 : if (DEBUG) { System.out.println("ConditionalAndExpression_NotName ::= Name AND_AND..."); } //$NON-NLS-1$ consumeBinaryExpressionWithName(OperatorIds.AND_AND); break; - case 791 : if (DEBUG) { System.out.println("ConditionalOrExpression_NotName ::=..."); } //$NON-NLS-1$ + case 807 : if (DEBUG) { System.out.println("ConditionalOrExpression_NotName ::=..."); } //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.OR_OR); break; - case 792 : if (DEBUG) { System.out.println("ConditionalOrExpression_NotName ::= Name OR_OR..."); } //$NON-NLS-1$ + case 808 : if (DEBUG) { System.out.println("ConditionalOrExpression_NotName ::= Name OR_OR..."); } //$NON-NLS-1$ consumeBinaryExpressionWithName(OperatorIds.OR_OR); break; - case 794 : if (DEBUG) { System.out.println("ConditionalExpression_NotName ::=..."); } //$NON-NLS-1$ + case 810 : if (DEBUG) { System.out.println("ConditionalExpression_NotName ::=..."); } //$NON-NLS-1$ consumeConditionalExpression(OperatorIds.QUESTIONCOLON) ; break; - case 795 : if (DEBUG) { System.out.println("ConditionalExpression_NotName ::= Name QUESTION..."); } //$NON-NLS-1$ + case 811 : if (DEBUG) { System.out.println("ConditionalExpression_NotName ::= Name QUESTION..."); } //$NON-NLS-1$ consumeConditionalExpressionWithName(OperatorIds.QUESTIONCOLON) ; break; - case 799 : if (DEBUG) { System.out.println("AnnotationTypeDeclarationHeaderName ::= Modifiers AT..."); } //$NON-NLS-1$ + case 815 : if (DEBUG) { System.out.println("AnnotationTypeDeclarationHeaderName ::= Modifiers AT..."); } //$NON-NLS-1$ consumeAnnotationTypeDeclarationHeaderName() ; break; - case 800 : if (DEBUG) { System.out.println("AnnotationTypeDeclarationHeaderName ::= Modifiers AT..."); } //$NON-NLS-1$ + case 816 : if (DEBUG) { System.out.println("AnnotationTypeDeclarationHeaderName ::= Modifiers AT..."); } //$NON-NLS-1$ consumeAnnotationTypeDeclarationHeaderNameWithTypeParameters() ; break; - case 801 : if (DEBUG) { System.out.println("AnnotationTypeDeclarationHeaderName ::= AT..."); } //$NON-NLS-1$ + case 817 : if (DEBUG) { System.out.println("AnnotationTypeDeclarationHeaderName ::= AT..."); } //$NON-NLS-1$ consumeAnnotationTypeDeclarationHeaderNameWithTypeParameters() ; break; - case 802 : if (DEBUG) { System.out.println("AnnotationTypeDeclarationHeaderName ::= AT..."); } //$NON-NLS-1$ + case 818 : if (DEBUG) { System.out.println("AnnotationTypeDeclarationHeaderName ::= AT..."); } //$NON-NLS-1$ consumeAnnotationTypeDeclarationHeaderName() ; break; - case 803 : if (DEBUG) { System.out.println("AnnotationTypeDeclarationHeader ::=..."); } //$NON-NLS-1$ + case 819 : if (DEBUG) { System.out.println("AnnotationTypeDeclarationHeader ::=..."); } //$NON-NLS-1$ consumeAnnotationTypeDeclarationHeader() ; break; - case 804 : if (DEBUG) { System.out.println("AnnotationTypeDeclaration ::=..."); } //$NON-NLS-1$ + case 820 : if (DEBUG) { System.out.println("AnnotationTypeDeclaration ::=..."); } //$NON-NLS-1$ consumeAnnotationTypeDeclaration() ; break; - case 806 : if (DEBUG) { System.out.println("AnnotationTypeMemberDeclarationsopt ::="); } //$NON-NLS-1$ + case 822 : if (DEBUG) { System.out.println("AnnotationTypeMemberDeclarationsopt ::="); } //$NON-NLS-1$ consumeEmptyAnnotationTypeMemberDeclarationsopt() ; break; - case 807 : if (DEBUG) { System.out.println("AnnotationTypeMemberDeclarationsopt ::= NestedType..."); } //$NON-NLS-1$ + case 823 : if (DEBUG) { System.out.println("AnnotationTypeMemberDeclarationsopt ::= NestedType..."); } //$NON-NLS-1$ consumeAnnotationTypeMemberDeclarationsopt() ; break; - case 809 : if (DEBUG) { System.out.println("AnnotationTypeMemberDeclarations ::=..."); } //$NON-NLS-1$ + case 825 : if (DEBUG) { System.out.println("AnnotationTypeMemberDeclarations ::=..."); } //$NON-NLS-1$ consumeAnnotationTypeMemberDeclarations() ; break; - case 810 : if (DEBUG) { System.out.println("AnnotationMethodHeaderName ::= Modifiersopt..."); } //$NON-NLS-1$ + case 826 : if (DEBUG) { System.out.println("AnnotationMethodHeaderName ::= Modifiersopt..."); } //$NON-NLS-1$ consumeMethodHeaderNameWithTypeParameters(true); break; - case 811 : if (DEBUG) { System.out.println("AnnotationMethodHeaderName ::= Modifiersopt Type..."); } //$NON-NLS-1$ + case 827 : if (DEBUG) { System.out.println("AnnotationMethodHeaderName ::= Modifiersopt Type..."); } //$NON-NLS-1$ consumeMethodHeaderName(true); break; - case 812 : if (DEBUG) { System.out.println("AnnotationMethodHeaderDefaultValueopt ::="); } //$NON-NLS-1$ + case 828 : if (DEBUG) { System.out.println("AnnotationMethodHeaderDefaultValueopt ::="); } //$NON-NLS-1$ consumeEmptyMethodHeaderDefaultValue() ; break; - case 813 : if (DEBUG) { System.out.println("AnnotationMethodHeaderDefaultValueopt ::= DefaultValue"); } //$NON-NLS-1$ + case 829 : if (DEBUG) { System.out.println("AnnotationMethodHeaderDefaultValueopt ::= DefaultValue"); } //$NON-NLS-1$ consumeMethodHeaderDefaultValue(); break; - case 814 : if (DEBUG) { System.out.println("AnnotationMethodHeader ::= AnnotationMethodHeaderName..."); } //$NON-NLS-1$ + case 830 : if (DEBUG) { System.out.println("AnnotationMethodHeader ::= AnnotationMethodHeaderName..."); } //$NON-NLS-1$ consumeMethodHeader(); break; - case 815 : if (DEBUG) { System.out.println("AnnotationTypeMemberDeclaration ::=..."); } //$NON-NLS-1$ + case 831 : if (DEBUG) { System.out.println("AnnotationTypeMemberDeclaration ::=..."); } //$NON-NLS-1$ consumeAnnotationTypeMemberDeclaration() ; break; - case 823 : if (DEBUG) { System.out.println("AnnotationName ::= AT UnannotatableName"); } //$NON-NLS-1$ + case 839 : if (DEBUG) { System.out.println("AnnotationName ::= AT UnannotatableName"); } //$NON-NLS-1$ consumeAnnotationName() ; break; - case 824 : if (DEBUG) { System.out.println("NormalAnnotation ::= AnnotationName LPAREN..."); } //$NON-NLS-1$ + case 840 : if (DEBUG) { System.out.println("NormalAnnotation ::= AnnotationName LPAREN..."); } //$NON-NLS-1$ consumeNormalAnnotation(false) ; break; - case 825 : if (DEBUG) { System.out.println("MemberValuePairsopt ::="); } //$NON-NLS-1$ + case 841 : if (DEBUG) { System.out.println("MemberValuePairsopt ::="); } //$NON-NLS-1$ consumeEmptyMemberValuePairsopt() ; break; - case 828 : if (DEBUG) { System.out.println("MemberValuePairs ::= MemberValuePairs COMMA..."); } //$NON-NLS-1$ + case 844 : if (DEBUG) { System.out.println("MemberValuePairs ::= MemberValuePairs COMMA..."); } //$NON-NLS-1$ consumeMemberValuePairs() ; break; - case 829 : if (DEBUG) { System.out.println("MemberValuePair ::= SimpleName EQUAL EnterMemberValue..."); } //$NON-NLS-1$ + case 845 : if (DEBUG) { System.out.println("MemberValuePair ::= SimpleName EQUAL EnterMemberValue..."); } //$NON-NLS-1$ consumeMemberValuePair() ; break; - case 830 : if (DEBUG) { System.out.println("EnterMemberValue ::="); } //$NON-NLS-1$ + case 846 : if (DEBUG) { System.out.println("EnterMemberValue ::="); } //$NON-NLS-1$ consumeEnterMemberValue() ; break; - case 831 : if (DEBUG) { System.out.println("ExitMemberValue ::="); } //$NON-NLS-1$ + case 847 : if (DEBUG) { System.out.println("ExitMemberValue ::="); } //$NON-NLS-1$ consumeExitMemberValue() ; break; - case 833 : if (DEBUG) { System.out.println("MemberValue ::= Name"); } //$NON-NLS-1$ + case 849 : if (DEBUG) { System.out.println("MemberValue ::= Name"); } //$NON-NLS-1$ consumeMemberValueAsName() ; break; - case 836 : if (DEBUG) { System.out.println("MemberValueArrayInitializer ::=..."); } //$NON-NLS-1$ + case 852 : if (DEBUG) { System.out.println("MemberValueArrayInitializer ::=..."); } //$NON-NLS-1$ consumeMemberValueArrayInitializer() ; break; - case 837 : if (DEBUG) { System.out.println("MemberValueArrayInitializer ::=..."); } //$NON-NLS-1$ + case 853 : if (DEBUG) { System.out.println("MemberValueArrayInitializer ::=..."); } //$NON-NLS-1$ consumeMemberValueArrayInitializer() ; break; - case 838 : if (DEBUG) { System.out.println("MemberValueArrayInitializer ::=..."); } //$NON-NLS-1$ + case 854 : if (DEBUG) { System.out.println("MemberValueArrayInitializer ::=..."); } //$NON-NLS-1$ consumeEmptyMemberValueArrayInitializer() ; break; - case 839 : if (DEBUG) { System.out.println("MemberValueArrayInitializer ::=..."); } //$NON-NLS-1$ + case 855 : if (DEBUG) { System.out.println("MemberValueArrayInitializer ::=..."); } //$NON-NLS-1$ consumeEmptyMemberValueArrayInitializer() ; break; - case 840 : if (DEBUG) { System.out.println("EnterMemberValueArrayInitializer ::="); } //$NON-NLS-1$ + case 856 : if (DEBUG) { System.out.println("EnterMemberValueArrayInitializer ::="); } //$NON-NLS-1$ consumeEnterMemberValueArrayInitializer() ; break; - case 842 : if (DEBUG) { System.out.println("MemberValues ::= MemberValues COMMA MemberValue"); } //$NON-NLS-1$ + case 858 : if (DEBUG) { System.out.println("MemberValues ::= MemberValues COMMA MemberValue"); } //$NON-NLS-1$ consumeMemberValues() ; break; - case 843 : if (DEBUG) { System.out.println("MarkerAnnotation ::= AnnotationName"); } //$NON-NLS-1$ + case 859 : if (DEBUG) { System.out.println("MarkerAnnotation ::= AnnotationName"); } //$NON-NLS-1$ consumeMarkerAnnotation(false) ; break; - case 844 : if (DEBUG) { System.out.println("SingleMemberAnnotationMemberValue ::= MemberValue"); } //$NON-NLS-1$ + case 860 : if (DEBUG) { System.out.println("SingleMemberAnnotationMemberValue ::= MemberValue"); } //$NON-NLS-1$ consumeSingleMemberAnnotationMemberValue() ; break; - case 845 : if (DEBUG) { System.out.println("SingleMemberAnnotation ::= AnnotationName LPAREN..."); } //$NON-NLS-1$ + case 861 : if (DEBUG) { System.out.println("SingleMemberAnnotation ::= AnnotationName LPAREN..."); } //$NON-NLS-1$ consumeSingleMemberAnnotation(false) ; break; - case 846 : if (DEBUG) { System.out.println("RecoveryMethodHeaderName ::= Modifiersopt TypeParameters"); } //$NON-NLS-1$ + case 862 : if (DEBUG) { System.out.println("RecoveryMethodHeaderName ::= Modifiersopt TypeParameters"); } //$NON-NLS-1$ consumeRecoveryMethodHeaderNameWithTypeParameters(); break; - case 847 : if (DEBUG) { System.out.println("RecoveryMethodHeaderName ::= Modifiersopt Type..."); } //$NON-NLS-1$ + case 863 : if (DEBUG) { System.out.println("RecoveryMethodHeaderName ::= Modifiersopt Type..."); } //$NON-NLS-1$ consumeRecoveryMethodHeaderName(); break; - case 848 : if (DEBUG) { System.out.println("RecoveryMethodHeaderName ::= ModifiersWithDefault..."); } //$NON-NLS-1$ + case 864 : if (DEBUG) { System.out.println("RecoveryMethodHeaderName ::= ModifiersWithDefault..."); } //$NON-NLS-1$ consumeRecoveryMethodHeaderNameWithTypeParameters(); break; - case 849 : if (DEBUG) { System.out.println("RecoveryMethodHeaderName ::= ModifiersWithDefault Type"); } //$NON-NLS-1$ + case 865 : if (DEBUG) { System.out.println("RecoveryMethodHeaderName ::= ModifiersWithDefault Type"); } //$NON-NLS-1$ consumeRecoveryMethodHeaderName(); break; - case 850 : if (DEBUG) { System.out.println("RecoveryMethodHeader ::= RecoveryMethodHeaderName..."); } //$NON-NLS-1$ + case 866 : if (DEBUG) { System.out.println("RecoveryMethodHeader ::= RecoveryMethodHeaderName..."); } //$NON-NLS-1$ consumeMethodHeader(); break; - case 851 : if (DEBUG) { System.out.println("RecoveryMethodHeader ::= RecoveryMethodHeaderName..."); } //$NON-NLS-1$ + case 867 : if (DEBUG) { System.out.println("RecoveryMethodHeader ::= RecoveryMethodHeaderName..."); } //$NON-NLS-1$ consumeMethodHeader(); break; @@ -9015,12 +9082,21 @@ protected void consumeStatementBreakWithLabel() { // BreakStatement ::= 'break' Identifier ';' // break pushs a position on this.intStack in case there is no label - pushOnAstStack( - new BreakStatement( - this.identifierStack[this.identifierPtr--], - this.intStack[this.intPtr--], - this.endStatementPosition)); - this.identifierLengthPtr--; + // add the compliance check + if (this.expressionLengthStack[this.expressionLengthPtr--] != 0) { + Expression expr = this.expressionStack[this.expressionPtr--]; + char[] labelOrExpr = expr instanceof Literal ? + ((Literal) expr).source() : expr instanceof SingleNameReference ? ((SingleNameReference) expr).token : null; + BreakStatement breakStatement = new BreakStatement( + labelOrExpr, + this.intStack[this.intPtr--], + this.endStatementPosition); + pushOnAstStack(breakStatement); + breakStatement.expression = expr; // need to figure out later whether this is a label or an expression. + if (expr instanceof SingleNameReference) { + ((SingleNameReference) expr).isLabel = true; + } + } } protected void consumeStatementCatch() { // CatchClause ::= 'catch' '(' FormalParameter ')' Block @@ -9198,25 +9274,25 @@ protected void consumeStatementReturn() { pushOnAstStack(new ReturnStatement(null, this.intStack[this.intPtr--], this.endStatementPosition)); } } -protected void consumeStatementSwitch() { - // SwitchStatement ::= 'switch' OpenBlock '(' Expression ')' SwitchBlock - +private void createSwitchStatementOrExpression(boolean isStmt) { + //OpenBlock just makes the semantic action blockStart() //the block is inlined but a scope need to be created //if some declaration occurs. + this.nestedType--; int length; - SwitchStatement switchStatement = new SwitchStatement(); + SwitchStatement switchStatement = isStmt ? new SwitchStatement() : new SwitchExpression(); this.expressionLengthPtr--; switchStatement.expression = this.expressionStack[this.expressionPtr--]; if ((length = this.astLengthStack[this.astLengthPtr--]) != 0) { this.astPtr -= length; System.arraycopy( - this.astStack, - this.astPtr + 1, - switchStatement.statements = new Statement[length], - 0, - length); + this.astStack, + this.astPtr + 1, + switchStatement.statements = new Statement[length], + 0, + length); } switchStatement.explicitDeclarations = this.realBlockStack[this.realBlockPtr--]; pushOnAstStack(switchStatement); @@ -9225,7 +9301,11 @@ protected void consumeStatementSwitch() { switchStatement.sourceEnd = this.endStatementPosition; if (length == 0 && !containsComment(switchStatement.blockStart, switchStatement.sourceEnd)) { switchStatement.bits |= ASTNode.UndocumentedEmptyBlock; - } + } +} +protected void consumeStatementSwitch() { + // SwitchStatement ::= 'switch' OpenBlock '(' Expression ')' SwitchBlock + createSwitchStatementOrExpression(true); } protected void consumeStatementSynchronized() { // SynchronizedStatement ::= OnlySynchronized '(' Expression ')' Block @@ -9422,6 +9502,7 @@ protected void consumeStaticOnly() { protected void consumeSwitchBlock() { // SwitchBlock ::= '{' SwitchBlockStatements SwitchLabels '}' concatNodeLists(); + } protected void consumeSwitchBlockStatement() { // SwitchBlockStatement ::= SwitchLabels BlockStatements @@ -9435,6 +9516,109 @@ protected void consumeSwitchLabels() { // SwitchLabels ::= SwitchLabels SwitchLabel optimizedConcatNodeLists(); } +protected void consumeSwitchLabelCaseLhs() { +// System.out.println("consumeSwitchLabelCaseLhs"); +} +protected void consumeCaseLabelExpr() { +// SwitchLabelExpr ::= SwitchLabelCaseLhs BeginCaseExpr '->' + consumeCaseLabel(); + CaseStatement caseStatement = (CaseStatement) this.astStack[this.astPtr]; + if (!this.parsingJava12Plus) { +// problemReporter().caseStatementWithArrowNotBelow12(caseStatement); + problemReporter().previewFeatureNotSupported(caseStatement.sourceStart, caseStatement.sourceEnd, "Case Labels with '->'", CompilerOptions.VERSION_12); //$NON-NLS-1$ + } else if (!this.options.enablePreviewFeatures){ + problemReporter().previewFeatureNotEnabled(caseStatement.sourceStart, caseStatement.sourceEnd, "Case Labels with '->'"); //$NON-NLS-1$ + } else { + if (this.options.isAnyEnabled(IrritantSet.PREVIEW)) { + problemReporter().previewFeatureUsed(caseStatement.sourceStart, caseStatement.sourceEnd); + } + } + caseStatement.isExpr = true; +} +protected void consumeDefaultLabelExpr() { +// SwitchLabelDefaultExpr ::= 'default' '->' + consumeDefaultLabel(); + CaseStatement defaultStatement = (CaseStatement) this.astStack[this.astPtr]; + if (!this.parsingJava12Plus) { +// problemReporter().caseStatementWithArrowNotBelow12(defaultStatement); + problemReporter().previewFeatureNotSupported(defaultStatement.sourceStart, defaultStatement.sourceEnd, "Case Labels with '->'", CompilerOptions.VERSION_12); //$NON-NLS-1$ + } else if (!this.options.enablePreviewFeatures){ + problemReporter().previewFeatureNotEnabled(defaultStatement.sourceStart, defaultStatement.sourceEnd, "Case Labels with '->'"); //$NON-NLS-1$ + } else { + if (this.options.isAnyEnabled(IrritantSet.PREVIEW)) { + problemReporter().previewFeatureUsed(defaultStatement.sourceStart, defaultStatement.sourceEnd); + } + } + defaultStatement.isExpr = true; +} +protected void consumeSwitchExpression() { +// SwitchExpression ::= 'switch' '(' Expression ')' OpenBlock SwitchExpressionBlock + createSwitchStatementOrExpression(false); + if (this.astLengthStack[this.astLengthPtr--] != 0) { + SwitchExpression s = (SwitchExpression) this.astStack[this.astPtr--]; + + if (!this.parsingJava12Plus) { + problemReporter().previewFeatureNotSupported(s.sourceStart, s.sourceEnd, "Switch Expressions", CompilerOptions.VERSION_12); //$NON-NLS-1$ + } else if (!this.options.enablePreviewFeatures) { + problemReporter().previewFeatureNotEnabled(s.sourceStart, s.sourceEnd, "Switch Expressions"); //$NON-NLS-1$ + } else { + if (this.options.isAnyEnabled(IrritantSet.PREVIEW)) { + problemReporter().previewFeatureUsed(s.sourceStart, s.sourceEnd); + } + } + + pushOnExpressionStack(s); + } +} +protected void consumeSwitchExprThrowDefaultArm() { +// SwitchExprThrowDefaultArm ::= SwitchLabelDefaultExpr Expression ';' + consumeStatementThrow(); +// pushSwitchLabeledRule(SwitchLabeledRule.RULE_KIND.DEFAULT_THROW); +} +protected void consumeConstantExpression() { + // do nothing for now. +} +protected void consumeConstantExpressions() { + concatExpressionLists(); +} +protected void consumeSwitchLabeledRules() { + concatNodeLists(); +} +protected void consumeSwitchLabeledRule() { +// SwitchLabeledRule ::= SwitchLabeledExpression +// SwitchLabeledRule ::= SwitchLabeledBlock +// SwitchLabeledRule ::= SwitchLabeledThrowStatement +// concatNodeLists(); + + // do nothing explicit here +} +protected void consumeSwitchLabeledRuleToBlockStatement() { + // do nothing +} +protected void consumeSwitchLabeledExpression() { + consumeExpressionStatement(); + Expression expr = (Expression) this.astStack[this.astPtr]; + BreakStatement breakStatement = new BreakStatement( + null, + expr.sourceStart, + this.endStatementPosition); + breakStatement.isImplicit = true; + breakStatement.expression = expr; + this.astStack[this.astPtr] = breakStatement; + concatNodeLists(); +} +protected void consumeSwitchLabeledBlock() { + concatNodeLists(); +} +protected void consumeSwitchLabeledThrowStatement() { + // TODO: Semicolon not there - so we call this early + consumeStatementThrow(); + concatNodeLists(); +} +protected void consumeThrowExpression() { + // do nothing +} +protected boolean caseFlagSet = false; protected void consumeToken(int type) { /* remember the last consumed value */ /* try to minimize the number of build values */ @@ -9458,11 +9642,16 @@ protected void consumeToken(int type) { //System.out.println(this.scanner.toStringAction(type)); switch (type) { case TokenNameARROW: - consumeLambdaHeader(); + if (!this.caseFlagSet && this.scanner.lookBack[0] != TokenNamedefault) + consumeLambdaHeader(); + this.caseFlagSet = false; break; case TokenNameCOLON_COLON: this.colonColonStart = this.scanner.currentPosition - 2; break; + case TokenNameBeginCaseExpr: + this.caseFlagSet = true; + break; case TokenNameBeginLambda: flushCommentsDefinedPriorTo(this.scanner.currentPosition); break; @@ -9674,7 +9863,6 @@ protected void consumeToken(int type) { case TokenNamethrow : case TokenNamedo : case TokenNameif : - case TokenNameswitch : case TokenNametry : case TokenNamewhile : case TokenNamebreak : @@ -9689,6 +9877,11 @@ protected void consumeToken(int type) { case TokenNameprovides: pushOnIntStack(this.scanner.startPosition); break; + case TokenNameswitch : + consumeNestedType(); + this.nestedMethod[this.nestedType] ++; + pushOnIntStack(this.scanner.startPosition); + break; case TokenNamenew : // https://bugs.eclipse.org/bugs/show_bug.cgi?id=40954 resetModifiers(); diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/ParserBasicInformation.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/ParserBasicInformation.java index 20d477f5c0..da927b5490 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/ParserBasicInformation.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/ParserBasicInformation.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2014 IBM Corporation and others. + * Copyright (c) 2000, 2018 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -7,7 +7,11 @@ * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 - * + * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ @@ -19,22 +23,22 @@ public interface ParserBasicInformation { public final static int - ERROR_SYMBOL = 128, + ERROR_SYMBOL = 129, MAX_NAME_LENGTH = 41, - NUM_STATES = 1152, + NUM_STATES = 1166, - NT_OFFSET = 128, - SCOPE_UBOUND = 290, - SCOPE_SIZE = 291, - LA_STATE_OFFSET = 16451, + NT_OFFSET = 129, + SCOPE_UBOUND = 297, + SCOPE_SIZE = 298, + LA_STATE_OFFSET = 16966, MAX_LA = 1, - NUM_RULES = 851, - NUM_TERMINALS = 128, - NUM_NON_TERMINALS = 388, - NUM_SYMBOLS = 516, - START_STATE = 895, - EOFT_SYMBOL = 60, - EOLT_SYMBOL = 60, - ACCEPT_ACTION = 16450, - ERROR_ACTION = 16451; + NUM_RULES = 867, + NUM_TERMINALS = 129, + NUM_NON_TERMINALS = 397, + NUM_SYMBOLS = 526, + START_STATE = 1124, + EOFT_SYMBOL = 61, + EOLT_SYMBOL = 61, + ACCEPT_ACTION = 16965, + ERROR_ACTION = 16966; } diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Scanner.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Scanner.java index 43e2477015..05fd504e2d 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Scanner.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Scanner.java @@ -8,6 +8,10 @@ * * SPDX-License-Identifier: EPL-2.0 * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * IBM Corporation - initial API and implementation * Stephan Herrmann - Contribution for bug 186342 - [compiler][null] Using annotations for null checking @@ -106,6 +110,7 @@ public class Scanner implements TerminalTokens { public boolean wasAcr = false; public boolean fakeInModule = false; + boolean inCase = false; /** * The current context of the scanner w.r.t restricted keywords * @@ -1158,7 +1163,12 @@ public void ungetToken(int unambiguousToken) { } this.nextToken = unambiguousToken; } - +private void updateCase(int token) { + if (token == TokenNamecase) + this.inCase = true; + if (token == TokenNameCOLON || token == TokenNameARROW) + this.inCase = false; +} public int getNextToken() throws InvalidInputException { int token; @@ -1179,13 +1189,14 @@ public int getNextToken() throws InvalidInputException { if (this.activeParser == null) { // anybody interested in the grammatical structure of the program should have registered. return token; } - if (token == TokenNameLPAREN || token == TokenNameLESS || token == TokenNameAT) { + if (token == TokenNameLPAREN || token == TokenNameLESS || token == TokenNameAT || token == TokenNameARROW) { token = disambiguatedToken(token); } else if (token == TokenNameELLIPSIS) { this.consumingEllipsisAnnotations = false; } this.lookBack[0] = this.lookBack[1]; this.lookBack[1] = token; + updateCase(token); return token; } protected int getNextToken0() throws InvalidInputException { @@ -4824,7 +4835,11 @@ int disambiguatedRestrictedKeyword(int restrictedKeywordToken) { } int disambiguatedToken(int token) { final VanguardParser parser = getVanguardParser(); - if (token == TokenNameLPAREN && maybeAtLambdaOrCast()) { + if (token == TokenNameARROW && this.inCase) { + this.nextToken = TokenNameARROW; + this.inCase = false; + return TokenNameBeginCaseExpr; + } else if (token == TokenNameLPAREN && maybeAtLambdaOrCast()) { if (parser.parse(Goal.LambdaParameterListGoal) == VanguardParser.SUCCESS) { this.nextToken = TokenNameLPAREN; return TokenNameBeginLambda; diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/ScannerHelper.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/ScannerHelper.java index c9bf5ce3bc..d20a4d224c 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/ScannerHelper.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/ScannerHelper.java @@ -47,6 +47,7 @@ public class ScannerHelper { private static long[][][] Tables8; private static long[][][] Tables9; private static long[][][] Tables11; + private static long[][][] Tables12; public final static int MAX_OBVIOUS = 128; public final static int[] OBVIOUS_IDENT_CHAR_NATURES = new int[MAX_OBVIOUS]; @@ -151,6 +152,9 @@ static void initializeTable19() { static void initializeTableJava11() { Tables11 = initializeTables("unicode10"); //$NON-NLS-1$ } +static void initializeTableJava12() { + Tables12 = initializeTables("unicode11"); //$NON-NLS-1$ +} static long[][][] initializeTables(String unicode_path) { long[][][] tempTable = new long[2][][]; tempTable[START_INDEX] = new long[3][]; @@ -290,12 +294,18 @@ public static boolean isJavaIdentifierPart(long complianceLevel, int codePoint) initializeTable19(); } return isJavaIdentifierPart0(codePoint, Tables9); - } else { + } else if (complianceLevel <= ClassFileConstants.JDK11) { // java 11 supports Unicode 10 if (Tables11 == null) { initializeTableJava11(); } return isJavaIdentifierPart0(codePoint, Tables11); + } else { + // java 12 supports Unicode 11 + if (Tables12 == null) { + initializeTableJava12(); + } + return isJavaIdentifierPart0(codePoint, Tables12); } } public static boolean isJavaIdentifierPart(long complianceLevel, char high, char low) { @@ -351,12 +361,19 @@ public static boolean isJavaIdentifierStart(long complianceLevel, int codePoint) initializeTable19(); } return isJavaIdentifierStart0(codePoint, Tables9); - } else { + } else if (complianceLevel <= ClassFileConstants.JDK11) { // java 11 supports Unicode 10 if (Tables11 == null) { initializeTableJava11(); } return isJavaIdentifierStart0(codePoint, Tables11); + } else { + + // java 12 supports Unicode 11 + if (Tables12 == null) { + initializeTableJava12(); + } + return isJavaIdentifierStart0(codePoint, Tables12); } } private static int toCodePoint(char high, char low) { diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/TerminalTokens.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/TerminalTokens.java index e7f6bb9d22..12c16dba22 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/TerminalTokens.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/TerminalTokens.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2013 IBM Corporation and others. + * Copyright (c) 2000, 2018 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -8,6 +8,9 @@ * * SPDX-License-Identifier: EPL-2.0 * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. * * Contributors: * IBM Corporation - initial API and implementation @@ -39,75 +42,75 @@ public interface TerminalTokens { TokenNameCOMMENT_JAVADOC = 1003; int TokenNameIdentifier = 22, - TokenNameabstract = 51, - TokenNameassert = 73, - TokenNameboolean = 97, - TokenNamebreak = 74, - TokenNamebyte = 98, - TokenNamecase = 99, - TokenNamecatch = 100, - TokenNamechar = 101, - TokenNameclass = 66, - TokenNamecontinue = 75, - TokenNameconst = 126, - TokenNamedefault = 71, - TokenNamedo = 76, - TokenNamedouble = 102, - TokenNameelse = 111, - TokenNameenum = 69, - TokenNameextends = 85, - TokenNamefalse = 39, - TokenNamefinal = 52, - TokenNamefinally = 109, - TokenNamefloat = 103, - TokenNamefor = 77, - TokenNamegoto = 127, - TokenNameif = 78, - TokenNameimplements = 122, - TokenNameimport = 104, + TokenNameabstract = 52, + TokenNameassert = 76, + TokenNameboolean = 99, + TokenNamebreak = 77, + TokenNamebyte = 100, + TokenNamecase = 101, + TokenNamecatch = 102, + TokenNamechar = 103, + TokenNameclass = 67, + TokenNamecontinue = 78, + TokenNameconst = 127, + TokenNamedefault = 73, + TokenNamedo = 79, + TokenNamedouble = 104, + TokenNameelse = 112, + TokenNameenum = 71, + TokenNameextends = 86, + TokenNamefalse = 38, + TokenNamefinal = 53, + TokenNamefinally = 111, + TokenNamefloat = 105, + TokenNamefor = 80, + TokenNamegoto = 128, + TokenNameif = 81, + TokenNameimplements = 123, + TokenNameimport = 106, TokenNameinstanceof = 17, - TokenNameint = 105, - TokenNameinterface = 68, - TokenNamelong = 106, - TokenNamenative = 53, + TokenNameint = 107, + TokenNameinterface = 70, + TokenNamelong = 108, + TokenNamenative = 54, TokenNamenew = 36, - TokenNamenull = 40, - TokenNamepackage = 84, - TokenNameprivate = 54, - TokenNameprotected = 55, - TokenNamepublic = 56, - TokenNamereturn = 79, - TokenNameshort = 107, - TokenNamestatic = 38, - TokenNamestrictfp = 57, + TokenNamenull = 39, + TokenNamepackage = 85, + TokenNameprivate = 55, + TokenNameprotected = 56, + TokenNamepublic = 57, + TokenNamereturn = 82, + TokenNameshort = 109, + TokenNamestatic = 48, + TokenNamestrictfp = 58, TokenNamesuper = 34, - TokenNameswitch = 80, + TokenNameswitch = 51, TokenNamesynchronized = 50, TokenNamethis = 35, - TokenNamethrow = 81, - TokenNamethrows = 119, - TokenNametransient = 58, - TokenNametrue = 41, - TokenNametry = 82, - TokenNamevoid = 108, - TokenNamevolatile = 59, - TokenNamewhile = 72, - TokenNamemodule = 112, - TokenNameopen = 113, - TokenNamerequires = 114, - TokenNametransitive = 120, - TokenNameexports = 115, - TokenNameopens = 116, - TokenNameto = 123, - TokenNameuses = 117, - TokenNameprovides = 118, - TokenNamewith = 124, - TokenNameIntegerLiteral = 42, - TokenNameLongLiteral = 43, - TokenNameFloatingPointLiteral = 44, - TokenNameDoubleLiteral = 45, - TokenNameCharacterLiteral = 46, - TokenNameStringLiteral = 47, + TokenNamethrow = 74, + TokenNamethrows = 120, + TokenNametransient = 59, + TokenNametrue = 40, + TokenNametry = 83, + TokenNamevoid = 110, + TokenNamevolatile = 60, + TokenNamewhile = 75, + TokenNamemodule = 113, + TokenNameopen = 114, + TokenNamerequires = 115, + TokenNametransitive = 121, + TokenNameexports = 116, + TokenNameopens = 117, + TokenNameto = 124, + TokenNameuses = 118, + TokenNameprovides = 119, + TokenNamewith = 125, + TokenNameIntegerLiteral = 41, + TokenNameLongLiteral = 42, + TokenNameFloatingPointLiteral = 43, + TokenNameDoubleLiteral = 44, + TokenNameCharacterLiteral = 45, + TokenNameStringLiteral = 46, TokenNamePLUS_PLUS = 2, TokenNameMINUS_MINUS = 3, TokenNameEQUAL_EQUAL = 19, @@ -117,53 +120,54 @@ public interface TerminalTokens { TokenNameLEFT_SHIFT = 18, TokenNameRIGHT_SHIFT = 14, TokenNameUNSIGNED_RIGHT_SHIFT = 16, - TokenNamePLUS_EQUAL = 86, - TokenNameMINUS_EQUAL = 87, - TokenNameMULTIPLY_EQUAL = 88, - TokenNameDIVIDE_EQUAL = 89, - TokenNameAND_EQUAL = 90, - TokenNameOR_EQUAL = 91, - TokenNameXOR_EQUAL = 92, - TokenNameREMAINDER_EQUAL = 93, - TokenNameLEFT_SHIFT_EQUAL = 94, - TokenNameRIGHT_SHIFT_EQUAL = 95, - TokenNameUNSIGNED_RIGHT_SHIFT_EQUAL = 96, + TokenNamePLUS_EQUAL = 87, + TokenNameMINUS_EQUAL = 88, + TokenNameMULTIPLY_EQUAL = 89, + TokenNameDIVIDE_EQUAL = 90, + TokenNameAND_EQUAL = 91, + TokenNameOR_EQUAL = 92, + TokenNameXOR_EQUAL = 93, + TokenNameREMAINDER_EQUAL = 94, + TokenNameLEFT_SHIFT_EQUAL = 95, + TokenNameRIGHT_SHIFT_EQUAL = 96, + TokenNameUNSIGNED_RIGHT_SHIFT_EQUAL = 97, TokenNameOR_OR = 31, TokenNameAND_AND = 30, TokenNamePLUS = 4, TokenNameMINUS = 5, - TokenNameNOT = 62, + TokenNameNOT = 63, TokenNameREMAINDER = 9, - TokenNameXOR = 23, + TokenNameXOR = 24, TokenNameAND = 21, TokenNameMULTIPLY = 8, - TokenNameOR = 27, - TokenNameTWIDDLE = 63, + TokenNameOR = 28, + TokenNameTWIDDLE = 64, TokenNameDIVIDE = 10, TokenNameGREATER = 15, TokenNameLESS = 11, - TokenNameLPAREN = 24, + TokenNameLPAREN = 23, TokenNameRPAREN = 25, - TokenNameLBRACE = 48, + TokenNameLBRACE = 49, TokenNameRBRACE = 33, TokenNameLBRACKET = 6, - TokenNameRBRACKET = 64, + TokenNameRBRACKET = 66, TokenNameSEMICOLON = 26, TokenNameQUESTION = 29, - TokenNameCOLON = 61, + TokenNameCOLON = 62, TokenNameCOMMA = 32, TokenNameDOT = 1, - TokenNameEQUAL = 70, + TokenNameEQUAL = 72, TokenNameAT = 37, - TokenNameELLIPSIS = 121, - TokenNameARROW = 110, + TokenNameELLIPSIS = 122, + TokenNameARROW = 98, TokenNameCOLON_COLON = 7, - TokenNameBeginLambda = 49, + TokenNameBeginLambda = 47, TokenNameBeginIntersectionCast = 65, - TokenNameBeginTypeArguments = 83, - TokenNameElidedSemicolonAndRightBrace = 67, - TokenNameAT308 = 28, - TokenNameAT308DOTDOTDOT = 125, - TokenNameEOF = 60, - TokenNameERROR = 128; + TokenNameBeginTypeArguments = 84, + TokenNameElidedSemicolonAndRightBrace = 68, + TokenNameAT308 = 27, + TokenNameAT308DOTDOTDOT = 126, + TokenNameBeginCaseExpr = 69, + TokenNameEOF = 61, + TokenNameERROR = 129; } diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser1.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser1.rsc Binary files differindex 274fa5063e..2bd646ecc7 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser1.rsc +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser1.rsc diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser10.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser10.rsc Binary files differindex 4865baaaa5..a49d7119ed 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser10.rsc +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser10.rsc diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser11.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser11.rsc Binary files differindex 37144d48aa..ef79d1de51 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser11.rsc +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser11.rsc diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser12.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser12.rsc Binary files differindex 867a099f38..e9fa8cd3c9 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser12.rsc +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser12.rsc diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser13.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser13.rsc Binary files differindex 2c1fbd338b..4af7a4ffad 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser13.rsc +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser13.rsc diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser14.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser14.rsc Binary files differindex 07b4bf6bbf..24432a187f 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser14.rsc +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser14.rsc diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser15.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser15.rsc Binary files differindex 56d678fa71..b84e8bb579 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser15.rsc +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser15.rsc diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser16.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser16.rsc Binary files differindex 9e8f5966ee..c5f0e8a576 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser16.rsc +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser16.rsc diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser17.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser17.rsc Binary files differindex 353090ba35..3cf316c2f2 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser17.rsc +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser17.rsc diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser18.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser18.rsc Binary files differindex 266bf1bcf6..f25fe9aa0d 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser18.rsc +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser18.rsc diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser19.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser19.rsc index df3f4df043..68c3b12f49 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser19.rsc +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser19.rsc @@ -1,2 +1,2 @@ -ooF!!m yF!!@@@@00m!!!!=== y##""!!Cd=!!!#!c =}H0II000lab
-U EFFnDGBU=E%%S"#
\ No newline at end of file +ppH!!o zH!!BBBB11o!!!!>>> z##""!!Df!!!#!e >~K1LL1>11ncd
+V GHHbEJFICV>G%%T"#
\ No newline at end of file diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser2.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser2.rsc Binary files differindex 3a3cedb52a..7ae8abeab0 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser2.rsc +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser2.rsc diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser20.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser20.rsc Binary files differindex 8bdb123d8b..87ff0c441f 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser20.rsc +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser20.rsc diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser21.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser21.rsc Binary files differindex 3031ff9f42..05ba22c1de 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser21.rsc +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser21.rsc diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser22.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser22.rsc Binary files differindex 518ee2acf0..ad9e312e73 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser22.rsc +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser22.rsc diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser23.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser23.rsc Binary files differindex c8dd03c345..76da0d61db 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser23.rsc +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser23.rsc diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser24.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser24.rsc Binary files differindex ec7d7e618c..5b4675f3c8 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser24.rsc +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser24.rsc diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser3.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser3.rsc Binary files differindex 95008983e9..add45284a4 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser3.rsc +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser3.rsc diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser4.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser4.rsc Binary files differindex a1145dcb17..aa09c17fd2 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser4.rsc +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser4.rsc diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser5.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser5.rsc Binary files differindex f56c662a2d..b4b627b5f6 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser5.rsc +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser5.rsc diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser6.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser6.rsc Binary files differindex 28c6b22efb..ed603bb9f3 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser6.rsc +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser6.rsc diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser7.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser7.rsc Binary files differindex 30e76fa77b..379d8cdd01 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser7.rsc +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser7.rsc diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser8.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser8.rsc Binary files differindex e594f6b593..4e9607b325 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser8.rsc +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser8.rsc diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser9.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser9.rsc Binary files differindex 4b693991e9..9670813691 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser9.rsc +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser9.rsc diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/readableNames.props b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/readableNames.props index 5268fd66d3..64eb6d9eba 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/readableNames.props +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/readableNames.props @@ -84,6 +84,7 @@ ConditionalOrExpression=Expression ConditionalOrExpression_NotName=Expression ConstantDeclaration=ConstantDeclaration ConstantExpression=ConstantExpression +ConstantExpressions=ConstantExpressions ConstructorDeclaration=ConstructorDeclaration ConstructorHeader=ConstructorDeclaration ConstructorHeaderName=ConstructorHeaderName @@ -296,10 +297,18 @@ StaticOnly=StaticOnly SwitchBlock=SwitchBlock SwitchBlockStatement=SwitchBlockStatement SwitchBlockStatements=SwitchBlockStatements +SwitchExpression=SwitchExpression SwitchLabel=SwitchLabel +SwitchLabelCaseLhs=SwitchLabelCaseLhs +SwitchLabelExpr=SwitchLabelDefaultExpr +SwitchLabeledBlock=SwitchLabeledBlock +SwitchLabeledExpression=SwitchLabeledExpression +SwitchLabeledRule=SwitchLabeledRule +SwitchLabeledThrowStatement=SwitchLabeledThrowStatement SwitchLabels=SwitchLabels SwitchStatement=SwitchStatement SynchronizedStatement=SynchronizedStatement +ThrowExpression=ThrowExpression ThrowStatement=ThrowStatement TrailingSemiColon=; TryBlock=Block diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode11/part0.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode11/part0.rsc Binary files differnew file mode 100644 index 0000000000..f434660ef0 --- /dev/null +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode11/part0.rsc diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode11/part1.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode11/part1.rsc Binary files differnew file mode 100644 index 0000000000..abb590ba3d --- /dev/null +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode11/part1.rsc diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode11/part14.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode11/part14.rsc Binary files differnew file mode 100644 index 0000000000..c8241e80d5 --- /dev/null +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode11/part14.rsc diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode11/part2.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode11/part2.rsc Binary files differnew file mode 100644 index 0000000000..ab6b33ed48 --- /dev/null +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode11/part2.rsc diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode11/start0.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode11/start0.rsc Binary files differnew file mode 100644 index 0000000000..1cd786208c --- /dev/null +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode11/start0.rsc diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode11/start1.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode11/start1.rsc Binary files differnew file mode 100644 index 0000000000..2ca6b51f99 --- /dev/null +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode11/start1.rsc diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode11/start2.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode11/start2.rsc Binary files differnew file mode 100644 index 0000000000..ab6b33ed48 --- /dev/null +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode11/start2.rsc diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java index 1a47e1d8c2..d9361bf5db 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java @@ -7,7 +7,11 @@ * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 - * + * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * IBM Corporation - initial API and implementation * Benjamin Muskalla - Contribution for bug 239066 @@ -154,6 +158,7 @@ import org.eclipse.jdt.internal.compiler.ast.ReferenceExpression; import org.eclipse.jdt.internal.compiler.ast.ReturnStatement; import org.eclipse.jdt.internal.compiler.ast.SingleNameReference; import org.eclipse.jdt.internal.compiler.ast.Statement; +import org.eclipse.jdt.internal.compiler.ast.SwitchExpression; import org.eclipse.jdt.internal.compiler.ast.SwitchStatement; import org.eclipse.jdt.internal.compiler.ast.ThisReference; import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration; @@ -662,6 +667,8 @@ public static int getIrritant(int problemID) { return CompilerOptions.APILeak; case IProblem.UnstableAutoModuleName: return CompilerOptions.UnstableAutoModuleName; + case IProblem.PreviewFeatureUsed: + return CompilerOptions.PreviewFeatureUsed; } return 0; } @@ -806,6 +813,8 @@ public static int getProblemCategory(int severity, int problemID) { return CategorizedProblem.CAT_MEMBER; if ((problemID & IProblem.ModuleRelated) != 0) return CategorizedProblem.CAT_MODULE; + if ((problemID & IProblem.Compliance) != 0) + return CategorizedProblem.CAT_COMPLIANCE; } return CategorizedProblem.CAT_INTERNAL; } @@ -6060,7 +6069,8 @@ public boolean expressionNonNullComparison(Expression expr, boolean checkForNull || expr instanceof ThisReference) { // fall through to bottom } else if (expr instanceof Literal - || expr instanceof ConditionalExpression) { + || expr instanceof ConditionalExpression + || expr instanceof SwitchExpression) { if (expr instanceof NullLiteral) { needImplementation(location); // reported as nonnull?? return false; @@ -6479,13 +6489,28 @@ public void notAFunctionalInterface(TypeDeclaration type) { type.sourceStart, type.sourceEnd); } + public void missingEnumConstantCase(SwitchStatement switchStatement, FieldBinding enumConstant) { + missingEnumConstantCase(switchStatement.defaultCase, enumConstant, switchStatement.expression); +} +public void missingEnumConstantCase(SwitchExpression switchExpression, FieldBinding enumConstant) { + missingSwitchExpressionEnumConstantCase(switchExpression.defaultCase, enumConstant, switchExpression.expression); +} +private void missingSwitchExpressionEnumConstantCase(CaseStatement defaultCase, FieldBinding enumConstant, ASTNode expression) { + this.handle( + IProblem.SwitchExpressionMissingEnumConstantCase, + new String[] {new String(enumConstant.declaringClass.readableName()), new String(enumConstant.name) }, + new String[] {new String(enumConstant.declaringClass.shortReadableName()), new String(enumConstant.name) }, + expression.sourceStart, + expression.sourceEnd); +} +private void missingEnumConstantCase(CaseStatement defaultCase, FieldBinding enumConstant, ASTNode expression) { this.handle( - switchStatement.defaultCase == null ? IProblem.MissingEnumConstantCase : IProblem.MissingEnumConstantCaseDespiteDefault, - new String[] {new String(enumConstant.declaringClass.readableName()), new String(enumConstant.name) }, - new String[] {new String(enumConstant.declaringClass.shortReadableName()), new String(enumConstant.name) }, - switchStatement.expression.sourceStart, - switchStatement.expression.sourceEnd); + defaultCase == null ? IProblem.MissingEnumConstantCase : IProblem.MissingEnumConstantCaseDespiteDefault, + new String[] {new String(enumConstant.declaringClass.readableName()), new String(enumConstant.name) }, + new String[] {new String(enumConstant.declaringClass.shortReadableName()), new String(enumConstant.name) }, + expression.sourceStart, + expression.sourceEnd); } public void missingDefaultCase(SwitchStatement switchStatement, boolean isEnumSwitch, TypeBinding expressionType) { if (isEnumSwitch) { @@ -6497,7 +6522,8 @@ public void missingDefaultCase(SwitchStatement switchStatement, boolean isEnumSw switchStatement.expression.sourceEnd); } else { this.handle( - IProblem.MissingDefaultCase, + switchStatement instanceof SwitchExpression ? + IProblem.SwitchExpressionMissingDefaultCase : IProblem.MissingDefaultCase, NoArgument, NoArgument, switchStatement.expression.sourceStart, @@ -9249,6 +9275,32 @@ public void problemNotAnalysed(Expression token, String optionKey) { token.sourceStart, token.sourceEnd); } +public void previewFeatureNotEnabled(int sourceStart, int sourceEnd, String featureName) { + String[] args = new String[] {featureName}; + this.handle( + IProblem.PreviewFeatureDisabled, + args, + args, + sourceStart, + sourceEnd); +} +public void previewFeatureUsed(int sourceStart, int sourceEnd) { + this.handle( + IProblem.PreviewFeatureUsed, + NoArgument, + NoArgument, + sourceStart, + sourceEnd); +} +public void previewFeatureNotSupported(int sourceStart, int sourceEnd, String featureName, String sourceLevel) { + String[] args = new String[] {featureName, sourceLevel}; + this.handle( + IProblem.PreviewFeatureNotSupported, + args, + args, + sourceStart, + sourceEnd); +} public void useAssertAsAnIdentifier(int sourceStart, int sourceEnd) { this.handle( IProblem.UseAssertAsAnIdentifier, @@ -10989,4 +11041,69 @@ public void autoModuleWithUnstableName(ModuleReference moduleReference) { moduleReference.sourceStart, moduleReference.sourceEnd); } +public void switchExpressionIncompatibleResultExpressions(SwitchExpression expression) { + TypeBinding type = expression.resultExpressions.get(0).resolvedType; + this.handle( + IProblem.SwitchExpressionsIncompatibleResultExpressionTypes, + new String[] {new String(type.readableName())}, + new String[] {new String(type.shortReadableName())}, + expression.sourceStart, + expression.sourceEnd); +} +public void switchExpressionEmptySwitchBlock(SwitchExpression expression) { + this.handle( + IProblem.SwitchExpressionsEmptySwitchBlock, + NoArgument, + NoArgument, + expression.sourceStart, + expression.sourceEnd); +} +public void switchExpressionNoResultExpressions(SwitchExpression expression) { + this.handle( + IProblem.SwitchExpressionsNoResultExpression, + NoArgument, + NoArgument, + expression.sourceStart, + expression.sourceEnd); +} +public void switchExpressionSwitchLabeledBlockCompletesNormally(Block block) { + this.handle( + IProblem.SwitchExpressionSwitchLabeledBlockCompletesNormally, + NoArgument, + NoArgument, + block.sourceStart, + block.sourceEnd); +} +public void switchExpressionLastStatementCompletesNormally(Statement stmt) { + this.handle( + IProblem.SwitchExpressionSwitchLabeledBlockCompletesNormally, + NoArgument, + NoArgument, + stmt.sourceStart, + stmt.sourceEnd); +} +public void switchExpressionTrailingSwitchLabels(Statement stmt) { + this.handle( + IProblem.SwitchExpressionTrailingSwitchLabels, + NoArgument, + NoArgument, + stmt.sourceStart, + stmt.sourceEnd); +} +public void switchExpressionMixedCase(ASTNode statement) { + this.handle( + IProblem.switchMixedCase, + NoArgument, + NoArgument, + statement.sourceStart, + statement.sourceEnd); +} +public void switchExpressionBreakMissingValue(ASTNode statement) { + this.handle( + IProblem.SwitchExpressionBreakMissingValue, + NoArgument, + NoArgument, + statement.sourceStart, + statement.sourceEnd); +} } diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties index b4a85c9569..37dff5d64c 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties @@ -1,5 +1,5 @@ ############################################################################### -# Copyright (c) 2000, 2018 IBM Corporation and others. +# Copyright (c) 2000, 2019 IBM Corporation and others. # # This program and the accompanying materials # are made available under the terms of the Eclipse Public License 2.0 @@ -7,7 +7,10 @@ # https://www.eclipse.org/legal/epl-2.0/ # # SPDX-License-Identifier: EPL-2.0 -# +# +# This is an implementation of an early-draft specification developed under the Java +# Community Process (JCP) and is made available for testing and evaluation purposes +# only. The code is not compatible with any specification of the JCP. # # Contributors: # IBM Corporation - initial API and implementation @@ -879,6 +882,9 @@ 1100 = Problem detected during type inference: {0} #1101 is already used up but deprecated 1102 = At least one of the problems in category ''{0}'' is not analysed due to a compiler option being ignored +1103 = {0} is a preview feature and disabled by default. Use --enable-preview to enable +1104 = You are using a preview language feature that may or may not be supported in a future release +1105 = The preview feature {0} is only available with source level {1} and above # more programming problems: 1200 = Unlikely argument type {0} for {1} on a {2} @@ -967,6 +973,20 @@ 1511 = 'var' is not allowed here 1512 = 'var' cannot be mixed with non-var parameters +# Switch-Expressions +1600 = Incompatible switch results expressions {0} +1601 = A switch expression should have a non-empty switch block +1602 = A switch expression should have at least one result expression +1603 = A switch labeled block in a switch expression should not complete normally +1604 = The last statement of a switch block in a switch expression should not complete normally +1605 = Trailing switch labels are not allowed in a switch expression. +1606 = Mixing of different kinds of case statements '->' and ':' is not allowed within a switch +1607 = A switch expression should have a default case +1608 = Switch expressions are allowed only at source level 12 or above +1609 = Switch Case Labels with '->' are allowed only at source level 12 or above +1610 = Break of a switch expression should have a value +1611 = A Switch expression should cover all possible values + ### ELABORATIONS ## Access restrictions 78592 = The type ''{1}'' is not API (restriction on classpath entry ''{0}'') diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/JRTUtil.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/JRTUtil.java index 51bfc33171..5d9b78bb81 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/JRTUtil.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/JRTUtil.java @@ -8,6 +8,10 @@ * * SPDX-License-Identifier: EPL-2.0 * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ @@ -75,7 +79,7 @@ public class JRTUtil { * how the JRT needs to be processed, for e.g., clients can skip a particular module * by returning FileVisitResult.SKIP_SUBTREE */ - public FileVisitResult visitModule(T mod) throws IOException; + public FileVisitResult visitModule(T path, String name) throws IOException; } static abstract class AbstractFileVisitor<T> implements FileVisitor<T> { @@ -180,6 +184,16 @@ public class JRTUtil { public static boolean hasCompilationUnit(File jrt, String qualifiedPackageName, String moduleName) { return getJrtSystem(jrt).hasClassFile(qualifiedPackageName, moduleName); } + /* + * Returns only the file name after removing trailing '/' if any for folders + */ + public static String sanitizedFileName(Path path) { + String p = path.getFileName().toString(); + if (p.length() > 1 && p.charAt(p.length() - 1) == '/') { + return p.substring(0, p.length() - 1); + } + return p; + } /** * Tries to read all bytes of the file denoted by path, * returns null if the file could not be found or if the read was interrupted. @@ -253,10 +267,7 @@ class JrtFileSystemWithOlderRelease extends JrtFileSystem { List<String> sub = new ArrayList<>(); try (DirectoryStream<java.nio.file.Path> stream = Files.newDirectoryStream(releasePath)) { for (final java.nio.file.Path subdir: stream) { - String r = subdir.getFileName().toString(); - if (r.endsWith("/")) { //$NON-NLS-1$ - r = r.substring(0, r.length() - 1); - } + String r = JRTUtil.sanitizedFileName(subdir); if (r.contains(this.releaseInHex)) { sub.add(r); } else { @@ -292,7 +303,7 @@ class JrtFileSystemWithOlderRelease extends JrtFileSystem { return FileVisitResult.SKIP_SUBTREE; } return ((notify & JRTUtil.NOTIFY_MODULES) == 0) ? FileVisitResult.CONTINUE - : visitor.visitModule(dir); + : visitor.visitModule(dir, JRTUtil.sanitizedFileName(mod)); } if ((notify & JRTUtil.NOTIFY_PACKAGES) == 0) { // client is not interested in packages @@ -466,7 +477,7 @@ class JrtFileSystem { byte[] getClassfileContent(String fileName, String module) throws IOException, ClassFormatException { byte[] content = null; if (module != null) { - content = getClassfileBytes(fileName, new String(module.toCharArray())); + content = getClassfileBytes(fileName, module); } else { String[] modules = getModules(fileName); for (String mod : modules) { @@ -543,7 +554,7 @@ class JrtFileSystem { return FileVisitResult.SKIP_SUBTREE; } return ((notify & JRTUtil.NOTIFY_MODULES) == 0) ? - FileVisitResult.CONTINUE : visitor.visitModule(mod); + FileVisitResult.CONTINUE : visitor.visitModule(dir, JRTUtil.sanitizedFileName(mod)); } if ((notify & JRTUtil.NOTIFY_PACKAGES) == 0) { // We are dealing with a module or not client is not interested in packages diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AST.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AST.java index ce3f49443b..6004f8005a 100644 --- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AST.java +++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AST.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2018 IBM Corporation and others. + * Copyright (c) 2000, 2019 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -7,6 +7,10 @@ * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 + * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. * * Contributors: * IBM Corporation - initial API and implementation @@ -270,6 +274,28 @@ public final class AST { * @since 3.14 */ /*package*/ static final int JLS11_INTERNAL = JLS11; + + /** + * Constant for indicating the AST API that handles JLS12. + * <p> + * This API is capable of handling all constructs in the + * Java language as described in the Java Language + * Specification, Java SE 12 Edition (JLS12). + * JLS12 is a superset of all earlier versions of the + * Java language, and the JLS12 API can be used to manipulate + * programs written in all versions of the Java language + * up to and including Java SE 12 (aka JDK 12). + * </p> + * + * @since 3.17 BETA_JAVA_12 + */ + public static final int JLS12 = 12; + /** + * Internal synonym for {@link #JLS11}. Use to alleviate + * deprecation warnings once JLS11 is deprecated + * @since 3.16 + */ + static final int JLS12_INTERNAL = JLS12; /* * Must not collide with a value for ICompilationUnit constants @@ -850,7 +876,21 @@ public final class AST { null/*taskTag*/, null/*taskPriorities*/, true/*taskCaseSensitive*/); - break; + break; + case JLS12_INTERNAL : + this.apiLevel = level; + // initialize a scanner + compliance = ClassFileConstants.getComplianceLevelForJavaVersion(ClassFileConstants.MAJOR_VERSION_12); + this.scanner = new Scanner( + true /*comment*/, + true /*whitespace*/, + false /*nls*/, + compliance /*sourceLevel*/, + compliance /*complianceLevel*/, + null/*taskTag*/, + null/*taskPriorities*/, + true/*taskCaseSensitive*/); + break; default: throw new IllegalArgumentException("Unsupported JLS level"); //$NON-NLS-1$ } @@ -2539,6 +2579,19 @@ public final class AST { } /** + * Creates and returns a new unparented switch expression node + * owned by this AST. By default, the expression is unspecified, but legal, + * and there are no statements or switch cases. + * + * @return a new unparented labeled switch expression node + * @since 3.17 BETA_JAVA_12 + */ + public SwitchExpression newSwitchExpression() { + SwitchExpression result = new SwitchExpression(this); + return result; + } + + /** * Creates a new unparented switch case statement node owned by * this AST. By default, the expression is unspecified, but legal. * @@ -2548,7 +2601,6 @@ public final class AST { return new SwitchCase(this); } - /** * Creates a new unparented switch statement node owned by this AST. * By default, the expression is unspecified, but legal, and there are diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTConverter.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTConverter.java index 87340a1389..6d0a464a10 100644 --- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTConverter.java +++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTConverter.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2018 IBM Corporation and others. + * Copyright (c) 2000, 2019 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -8,6 +8,10 @@ * * SPDX-License-Identifier: EPL-2.0 * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * IBM Corporation - initial API and implementation * Stephan Herrmann - Contribution for @@ -360,7 +364,15 @@ class ASTConverter { spanningNode.setFlags(spanningNode.getFlags() | ASTNode.MALFORMED); } } - + /** + * Internal access method to SwitchCase#setExpression() for avoiding deprecated warnings + * @param switchCase + * @param exp + * @deprecated + */ + private static void internalSetExpression(SwitchCase switchCase, Expression exp) { + switchCase.setExpression(exp); + } /** * Internal access method to SingleVariableDeclaration#setExtraDimensions() for avoiding deprecated warnings * @@ -1285,20 +1297,42 @@ class ASTConverter { retrieveIdentifierAndSetPositions(statement.sourceStart, statement.sourceEnd, name); breakStatement.setLabel(name); } + else if (statement.expression != null && this.ast.apiLevel >= AST.JLS12_INTERNAL) { + final Expression expression= convert(statement.expression); + breakStatement.setExpression(expression); + } return breakStatement; } public SwitchCase convert(org.eclipse.jdt.internal.compiler.ast.CaseStatement statement) { SwitchCase switchCase = new SwitchCase(this.ast); - org.eclipse.jdt.internal.compiler.ast.Expression constantExpression = statement.constantExpression; - if (constantExpression == null) { - switchCase.setExpression(null); + if (this.ast.apiLevel >= AST.JLS12_INTERNAL) { + org.eclipse.jdt.internal.compiler.ast.Expression[] expressions = statement.constantExpressions; + if (expressions == null || expressions.length == 0) { + switchCase.expressions().clear(); + } else { + for (org.eclipse.jdt.internal.compiler.ast.Expression expression : expressions) { + switchCase.expressions().add(convert(expression)); + } + } } else { - switchCase.setExpression(convert(constantExpression)); + org.eclipse.jdt.internal.compiler.ast.Expression constantExpression = statement.constantExpression; + if (constantExpression == null) { + internalSetExpression(switchCase, null); + } else { + internalSetExpression(switchCase, convert(constantExpression)); + } + } + if (this.ast.apiLevel >= AST.JLS12_INTERNAL) { + switchCase.setSwitchLabeledRule(statement.isExpr); } switchCase.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1); - retrieveColonPosition(switchCase); + if (statement.isExpr) { + retrieveArrowPosition(switchCase); + } else { + retrieveColonPosition(switchCase); + } return switchCase; } @@ -1842,6 +1876,9 @@ class ASTConverter { if (expression instanceof org.eclipse.jdt.internal.compiler.ast.ReferenceExpression) { return convert((org.eclipse.jdt.internal.compiler.ast.ReferenceExpression) expression); } + if (expression instanceof org.eclipse.jdt.internal.compiler.ast.SwitchExpression) { + return convert((org.eclipse.jdt.internal.compiler.ast.SwitchExpression) expression); + } return null; } @@ -2686,6 +2723,7 @@ class ASTConverter { return result; } + public ReturnStatement convert(org.eclipse.jdt.internal.compiler.ast.ReturnStatement statement) { final ReturnStatement returnStatement = new ReturnStatement(this.ast); returnStatement.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1); @@ -2827,6 +2865,33 @@ class ASTConverter { return literal; } + public Expression convert(org.eclipse.jdt.internal.compiler.ast.SwitchExpression expression) { + if (this.ast.apiLevel < AST.JLS12_INTERNAL) { + return createFakeNullLiteral(expression); + } + SwitchExpression switchExpression = new SwitchExpression(this.ast); + if (this.resolveBindings) { + recordNodes(switchExpression, expression); + } + switchExpression.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1); + switchExpression.setExpression(convert(expression.expression)); + org.eclipse.jdt.internal.compiler.ast.Statement[] statements = expression.statements; + if (statements != null) { + int statementsLength = statements.length; + for (int i = 0; i < statementsLength; i++) { + if (statements[i] instanceof org.eclipse.jdt.internal.compiler.ast.LocalDeclaration) { + checkAndAddMultipleLocalDeclaration(statements, i, switchExpression.statements()); + } else { + final Statement currentStatement = convert(statements[i]); + if (currentStatement != null) { + switchExpression.statements().add(currentStatement); + } + } + } + } + return switchExpression; + } + public SwitchStatement convert(org.eclipse.jdt.internal.compiler.ast.SwitchStatement statement) { SwitchStatement switchStatement = new SwitchStatement(this.ast); switchStatement.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1); @@ -4226,7 +4291,7 @@ class ASTConverter { * Warning: Callers of this method must ensure that the fake literal node is not recorded in * {@link #recordNodes(ASTNode, org.eclipse.jdt.internal.compiler.ast.ASTNode)}, see bug 403444! */ - protected Expression createFakeNullLiteral(org.eclipse.jdt.internal.compiler.ast.FunctionalExpression expression) { + protected Expression createFakeNullLiteral(org.eclipse.jdt.internal.compiler.ast.Expression expression) { if (this.referenceContext != null) { this.referenceContext.setFlags(this.referenceContext.getFlags() | ASTNode.MALFORMED); } @@ -4795,6 +4860,17 @@ class ASTConverter { * This method fixes the length of the corresponding node. */ protected void retrieveColonPosition(ASTNode node) { + setNodeSourceEndPosition(node, TerminalTokens.TokenNameCOLON); + } + /** + * This method is used to set the right end position for switch labeled rules ie with '->' + * The actual AST nodes don't include the trailing semicolon. + * This method fixes the length of the corresponding node. + */ + private void retrieveArrowPosition(ASTNode node) { + setNodeSourceEndPosition(node, TerminalTokens.TokenNameARROW); + } + private void setNodeSourceEndPosition(ASTNode node, int expectedToken) { int start = node.getStartPosition(); int length = node.getLength(); int end = start + length; @@ -4802,8 +4878,7 @@ class ASTConverter { try { int token; while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) { - switch(token) { - case TerminalTokens.TokenNameCOLON: + if (token == expectedToken) { node.setSourceRange(start, this.scanner.currentPosition - start); return; } diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTMatcher.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTMatcher.java index ff2d234843..1e0259ef5f 100644 --- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTMatcher.java +++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTMatcher.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2017 IBM Corporation and others. + * Copyright (c) 2000, 2019 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -7,6 +7,10 @@ * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 + * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. * * Contributors: * IBM Corporation - initial API and implementation @@ -484,7 +488,9 @@ public class ASTMatcher { return false; } BreakStatement o = (BreakStatement) other; - return safeSubtreeMatch(node.getLabel(), o.getLabel()); + return ( node.getAST().apiLevel >= AST.JLS12_INTERNAL && node.getExpression() != null + ? safeSubtreeMatch(node.getExpression(), o.getExpression()) + : safeSubtreeMatch(node.getLabel(), o.getLabel())); } /** @@ -2267,7 +2273,43 @@ public class ASTMatcher { return false; } SwitchCase o = (SwitchCase) other; - return safeSubtreeMatch(node.getExpression(), o.getExpression()); + return ( node.getAST().apiLevel >= AST.JLS12_INTERNAL + ? safeSubtreeListMatch(node.expressions(), o.expressions()) + : compareDeprecatedSwitchExpression(node, o)); + } + + /** + * Return whether the deprecated comment strings of the given java doc are equals. + * <p> + * Note the only purpose of this method is to hide deprecated warnings. + * @deprecated mark deprecated to hide deprecated usage + */ + private boolean compareDeprecatedSwitchExpression(SwitchCase first, SwitchCase second) { + return safeSubtreeMatch(first.getExpression(), second.getExpression()); + } + + /** + * Returns whether the given node and the other object match. + * <p> + * The default implementation provided by this class tests whether the + * other object is a node of the same type with structurally isomorphic + * child subtrees. Subclasses may override this method as needed. + * </p> + * + * @param node the node + * @param other the other object, or <code>null</code> + * @return <code>true</code> if the subtree matches, or + * <code>false</code> if they do not match or the other object has a + * different node type or is <code>null</code> + * @since 3.17 BETA_JAVA_12 + */ + public boolean match(SwitchExpression node, Object other) { + if (!(other instanceof SwitchExpression)) { + return false; + } + SwitchExpression o = (SwitchExpression) other; + return safeSubtreeMatch(node.getExpression(), o.getExpression()) + && safeSubtreeListMatch(node.statements(), o.statements()); } /** diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTNode.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTNode.java index ac6d7103a7..11135b6f45 100644 --- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTNode.java +++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTNode.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2018 IBM Corporation and others. + * Copyright (c) 2000, 2019 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -7,6 +7,10 @@ * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 + * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. * * Contributors: * IBM Corporation - initial API and implementation @@ -954,6 +958,14 @@ public abstract class ASTNode { * @since 3.14 */ public static final int MODULE_MODIFIER = 99; + + /** + * Node type constant indicating a node of type + * <code>SwitchExpression</code>. + * @see SwitchExpression + * @since 3.17 BETA_JAVA_12 + */ + public static final int SWITCH_EXPRESSION = 100; /** * Returns the node class for the corresponding node type. @@ -1129,6 +1141,8 @@ public abstract class ASTNode { return SwitchCase.class; case SWITCH_STATEMENT : return SwitchStatement.class; + case SWITCH_EXPRESSION : + return SwitchExpression.class; case SYNCHRONIZED_STATEMENT : return SynchronizedStatement.class; case TAG_ELEMENT : @@ -2071,6 +2085,22 @@ public abstract class ASTNode { throw new UnsupportedOperationException("Operation only supported in ASTs with level JLS11 and above"); //$NON-NLS-1$ } } + + /** + * Checks that this AST operation is not used when + * building JLS2, JLS3, JLS4, JLS8, JLS9,JLS10 or JLS11 level ASTs. + * <p> + * Use this method to prevent access to new properties that have been added in JLS12 + * </p> + * + * @exception UnsupportedOperationException if this operation is used below JLS12 + * @since 3.16 + */ + final void unsupportedBelow12() { + if (this.ast.apiLevel < AST.JLS12_INTERNAL) { + throw new UnsupportedOperationException("Operation only supported in ASTs with level JLS12 and above"); //$NON-NLS-1$ + } + } /** * Checks that this AST operation is only used when * building JLS2 level ASTs. diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTParser.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTParser.java index c202eb295a..af3682f5fa 100644 --- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTParser.java +++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTParser.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2018 IBM Corporation and others. + * Copyright (c) 2004, 2019 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -7,6 +7,10 @@ * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 + * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. * * Contributors: * IBM Corporation - initial API and implementation @@ -234,6 +238,7 @@ public class ASTParser { case AST.JLS9_INTERNAL: case AST.JLS10_INTERNAL: case AST.JLS11_INTERNAL: + case AST.JLS12_INTERNAL: break; default: throw new IllegalArgumentException(); diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTVisitor.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTVisitor.java index b31c3a7c82..b88b354bab 100644 --- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTVisitor.java +++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTVisitor.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2017 IBM Corporation and others. + * Copyright (c) 2000, 2019 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -7,6 +7,10 @@ * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 + * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. * * Contributors: * IBM Corporation - initial API and implementation @@ -1521,7 +1525,24 @@ public abstract class ASTVisitor { public boolean visit(SwitchCase node) { return true; } - + + /** + * Visits the given type-specific AST node. + * <p> + * The default implementation does nothing and return true. + * Subclasses may reimplement. + * </p> + * + * @param node the node to visit + * @return <code>true</code> if the children of this node should be + * visited, and <code>false</code> if the children of this node should + * be skipped + * @since 3.17 BETA_JAVA_12 + */ + public boolean visit(SwitchExpression node) { + return true; + } + /** * Visits the given type-specific AST node. * <p> @@ -2355,7 +2376,7 @@ public abstract class ASTVisitor { public void endVisit(LambdaExpression node) { // default implementation: do nothing } - + /** * End of visit the given type-specific AST node. * <p> @@ -2830,6 +2851,19 @@ public abstract class ASTVisitor { * </p> * * @param node the node to visit + * @since 3.17 BETA_JAVA_12 + */ + public void endVisit(SwitchExpression node) { + // default implementation: do nothing + } + + /** + * End of visit the given type-specific AST node. + * <p> + * The default implementation does nothing. Subclasses may reimplement. + * </p> + * + * @param node the node to visit */ public void endVisit(SwitchStatement node) { // default implementation: do nothing diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/BreakStatement.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/BreakStatement.java index 4cebdc6ca0..2441ce01dd 100644 --- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/BreakStatement.java +++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/BreakStatement.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2013 IBM Corporation and others. + * Copyright (c) 2000, 2019 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -7,6 +7,10 @@ * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 + * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. * * Contributors: * IBM Corporation - initial API and implementation @@ -23,6 +27,9 @@ import java.util.List; * <pre> * BreakStatement: * <b>break</b> [ Identifier ] <b>;</b> + * + * Break statement allows expression as part of Java 12 preview feature (JEP 325) + * <b>break</b> <b>{ Identifier | Expression }</b> * </pre> * * @since 2.0 @@ -37,6 +44,13 @@ public class BreakStatement extends Statement { */ public static final ChildPropertyDescriptor LABEL_PROPERTY = new ChildPropertyDescriptor(BreakStatement.class, "label", SimpleName.class, OPTIONAL, NO_CYCLE_RISK); //$NON-NLS-1$ + + /** + * The "expression" structural property of this node type (child type: {@link Expression}). (added in JEP 325). + * @since 3.17 BETA_JAVA_12 + */ + public static final ChildPropertyDescriptor EXPRESSION_PROPERTY = + new ChildPropertyDescriptor(BreakStatement.class, "expression", Expression.class, OPTIONAL, NO_CYCLE_RISK); //$NON-NLS-1$); /** * A list of property descriptors (element type: @@ -44,12 +58,25 @@ public class BreakStatement extends Statement { * or null if uninitialized. */ private static final List PROPERTY_DESCRIPTORS; + + /** + * A list of property descriptors (element type: + * {@link StructuralPropertyDescriptor}), + * or null if uninitialized. + */ + private static final List PROPERTY_DESCRIPTORS_12; static { List properyList = new ArrayList(2); createPropertyList(BreakStatement.class, properyList); addProperty(LABEL_PROPERTY, properyList); PROPERTY_DESCRIPTORS = reapPropertyList(properyList); + + List properyList_12 = new ArrayList(2); + createPropertyList(BreakStatement.class, properyList_12); + addProperty(LABEL_PROPERTY, properyList_12); + addProperty(EXPRESSION_PROPERTY, properyList_12); + PROPERTY_DESCRIPTORS_12 = reapPropertyList(properyList_12); } /** @@ -64,6 +91,9 @@ public class BreakStatement extends Statement { * @since 3.0 */ public static List propertyDescriptors(int apiLevel) { + if (apiLevel >= AST.JLS12_INTERNAL) { + return PROPERTY_DESCRIPTORS_12; + } return PROPERTY_DESCRIPTORS; } @@ -71,6 +101,11 @@ public class BreakStatement extends Statement { * The label, or <code>null</code> if none; none by default. */ private SimpleName optionalLabel = null; + + /** + * The expression; <code>null</code> for none + */ + private Expression optionalExpression = null; /** * Creates a new unparented break statement node owned by the given @@ -99,6 +134,14 @@ public class BreakStatement extends Statement { setLabel((SimpleName) child); return null; } + } + if (property == EXPRESSION_PROPERTY) { + if (get) { + return getExpression(); + } else { + setExpression((Expression) child); + return null; + } } // allow default implementation to flag the error return super.internalGetSetChildProperty(property, get, child); @@ -115,6 +158,9 @@ public class BreakStatement extends Statement { result.setSourceRange(getStartPosition(), getLength()); result.copyLeadingComment(this); result.setLabel((SimpleName) ASTNode.copySubtree(target, getLabel())); + if (this.ast.apiLevel >= AST.JLS12_INTERNAL) { + result.setExpression((Expression) ASTNode.copySubtree(target, getLabel())); + } return result; } @@ -128,6 +174,9 @@ public class BreakStatement extends Statement { void accept0(ASTVisitor visitor) { boolean visitChildren = visitor.visit(this); if (visitChildren) { + if (this.ast.apiLevel >= AST.JLS12_INTERNAL) { + acceptChild(visitor, getExpression()); + } acceptChild(visitor, getLabel()); } visitor.endVisit(this); @@ -160,17 +209,53 @@ public class BreakStatement extends Statement { this.optionalLabel = label; postReplaceChild(oldChild, label, LABEL_PROPERTY); } + + /** + * Returns the expression of this break statement, or <code>null</code> if + * there is none. + * + * @return the expression, or <code>null</code> if there is none + * @exception UnsupportedOperationException if this operation is used below JLS12 + * @since 3.17 BETA_JAVA_12 + */ + public Expression getExpression() { + // optionalExpression can be null + unsupportedBelow12(); + return this.optionalExpression; + } + + /** + * Sets or clears the expression of this break statement. + * + * @param expression the expression, or <code>null</code> if + * there is none + * @exception IllegalArgumentException if: + * <ul> + * <li>the node belongs to a different AST</li> + * <li>the node already has a parent</li> + * </ul> + * @exception UnsupportedOperationException if this operation is used below JLS12 + * @since 3.17 BETA_JAVA_12 + */ + public void setExpression(Expression expression) { + unsupportedBelow12(); + ASTNode oldChild = this.optionalExpression; + preReplaceChild(oldChild, expression, EXPRESSION_PROPERTY); + this.optionalExpression = expression; + postReplaceChild(oldChild, expression, EXPRESSION_PROPERTY); + } @Override int memSize() { - return super.memSize() + 1 * 4; + return super.memSize() + 2 * 4; } @Override int treeSize() { return memSize() - + (this.optionalLabel == null ? 0 : getLabel().treeSize()); + + (this.optionalLabel == null ? 0 : getLabel().treeSize()) + + (this.optionalExpression == null ? 0 : getExpression().treeSize()); } } diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultASTVisitor.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultASTVisitor.java index e50e553ef8..f926654178 100644 --- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultASTVisitor.java +++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultASTVisitor.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2017 IBM Corporation and others. + * Copyright (c) 2000, 2019 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -8,6 +8,9 @@ * * SPDX-License-Identifier: EPL-2.0 * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ @@ -334,6 +337,10 @@ class DefaultASTVisitor extends ASTVisitor { endVisitNode(node); } @Override + public void endVisit(SwitchExpression node) { + endVisitNode(node); + } + @Override public void endVisit(SwitchCase node) { endVisitNode(node); } @@ -731,6 +738,11 @@ class DefaultASTVisitor extends ASTVisitor { public boolean visit(SwitchCase node) { return visitNode(node); } + + @Override + public boolean visit(SwitchExpression node) { + return visitNode(node); + } @Override public boolean visit(SwitchStatement node) { diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultBindingResolver.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultBindingResolver.java index 341e16ea7a..851500e532 100644 --- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultBindingResolver.java +++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultBindingResolver.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2018 IBM Corporation and others. + * Copyright (c) 2000, 2019 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -7,6 +7,10 @@ * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 + * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. * * Contributors: * IBM Corporation - initial API and implementation @@ -742,6 +746,7 @@ class DefaultBindingResolver extends BindingResolver { case ASTNode.METHOD_INVOCATION : case ASTNode.SUPER_METHOD_INVOCATION : case ASTNode.CONDITIONAL_EXPRESSION : + case ASTNode.SWITCH_EXPRESSION : case ASTNode.MARKER_ANNOTATION : case ASTNode.NORMAL_ANNOTATION : case ASTNode.SINGLE_MEMBER_ANNOTATION : diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Expression.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Expression.java index 13d96883a7..de760b945a 100644 --- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Expression.java +++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Expression.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2013 IBM Corporation and others. + * Copyright (c) 2000, 2019 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -7,6 +7,10 @@ * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 + * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. * * Contributors: * IBM Corporation - initial API and implementation @@ -48,6 +52,7 @@ package org.eclipse.jdt.core.dom; * {@link SuperFieldAccess}, * {@link SuperMethodInvocation}, * {@link SuperMethodReference}, + * {@link SwitchExpression}, * {@link ThisExpression}, * {@link TypeLiteral}, * {@link TypeMethodReference}, diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SwitchCase.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SwitchCase.java index c805ceac10..6e430a15a7 100644 --- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SwitchCase.java +++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SwitchCase.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2013 IBM Corporation and others. + * Copyright (c) 2000, 2019 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -8,6 +8,10 @@ * * SPDX-License-Identifier: EPL-2.0 * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ @@ -23,8 +27,12 @@ import java.util.List; * <p> * <pre> * SwitchCase: - * <b>case</b> Expression <b>:</b> - * <b>default</b> <b>:</b> + * <b>case</b> Expression <b>:</b> + * <b>default</b> <b>:</b> + * + * Switch case allows multiple expressions and '->' as part of Java 12 preview feature (JEP 325) + * <b>case</b> [ Expression { <b>,</b> Expression } ] <b>{ : | ->}</b> + * <b>default</b> <b>{ : | ->}</b> * </pre> * </p> * @@ -37,22 +45,43 @@ public class SwitchCase extends Statement { /** * The "expression" structural property of this node type (child type: {@link Expression}). * @since 3.0 + * @deprecated In the JLS 12 15.28.1 API, this property is replaced by {@link #EXPRESSIONS2_PROPERTY }. */ public static final ChildPropertyDescriptor EXPRESSION_PROPERTY = new ChildPropertyDescriptor(SwitchCase.class, "expression", Expression.class, OPTIONAL, CYCLE_RISK); //$NON-NLS-1$ /** + * The "expression" structural property of this node type (child type: {@link Expression}). (added in JEP 325). + * @since 3.17 BETA_JAVA_12 + */ + public static final ChildListPropertyDescriptor EXPRESSIONS2_PROPERTY = + new ChildListPropertyDescriptor(SwitchCase.class, "expression", Expression.class, CYCLE_RISK); //$NON-NLS-1$); + + + /** * A list of property descriptors (element type: * {@link StructuralPropertyDescriptor}), * or null if uninitialized. */ private static final List PROPERTY_DESCRIPTORS; + + /** + * A list of property descriptors (element type: + * {@link StructuralPropertyDescriptor}), + * or null if uninitialized. + */ + private static final List PROPERTY_DESCRIPTORS_12; static { List propertyList = new ArrayList(2); createPropertyList(SwitchCase.class, propertyList); addProperty(EXPRESSION_PROPERTY, propertyList); PROPERTY_DESCRIPTORS = reapPropertyList(propertyList); + + propertyList = new ArrayList(2); + createPropertyList(SwitchCase.class, propertyList); + addProperty(EXPRESSIONS2_PROPERTY , propertyList); + PROPERTY_DESCRIPTORS_12 = reapPropertyList(propertyList); } /** @@ -66,6 +95,9 @@ public class SwitchCase extends Statement { * @since 3.0 */ public static List propertyDescriptors(int apiLevel) { + if (apiLevel >= AST.JLS12_INTERNAL) { + return PROPERTY_DESCRIPTORS_12; + } return PROPERTY_DESCRIPTORS; } @@ -75,6 +107,17 @@ public class SwitchCase extends Statement { * @see #expressionInitialized */ private Expression optionalExpression = null; + + /** + * <code>true</code> indicates "->" and <code>false</code> indicates ":". + */ + private boolean switchLabeledRule = false; + + + /** + * The expression; <code>empty</code> for none; + */ + private ASTNode.NodeList expressions = null; /** * Indicates whether <code>optionalExpression</code> has been initialized. @@ -89,6 +132,9 @@ public class SwitchCase extends Statement { */ SwitchCase(AST ast) { super(ast); + if (ast.apiLevel >= AST.JLS12_INTERNAL) { + this.expressions = new ASTNode.NodeList(EXPRESSIONS2_PROPERTY ); + } } @Override @@ -111,17 +157,32 @@ public class SwitchCase extends Statement { } @Override + final List internalGetChildListProperty(ChildListPropertyDescriptor property) { + if (property == EXPRESSIONS2_PROPERTY ) { + return expressions(); + } + // allow default implementation to flag the error + return super.internalGetChildListProperty(property); + } + + @Override final int getNodeType0() { return SWITCH_CASE; } + @SuppressWarnings("unchecked") @Override ASTNode clone0(AST target) { SwitchCase result = new SwitchCase(target); result.setSourceRange(getStartPosition(), getLength()); result.copyLeadingComment(this); - result.setExpression( - (Expression) ASTNode.copySubtree(target, getExpression())); + if (this.ast.apiLevel >= AST.JLS12_INTERNAL) { + result.expressions().addAll( + ASTNode.copySubtrees(target, expressions())); + } else { + result.setExpression( + (Expression) ASTNode.copySubtree(target, getExpression())); + } return result; } @@ -135,7 +196,11 @@ public class SwitchCase extends Statement { void accept0(ASTVisitor visitor) { boolean visitChildren = visitor.visit(this); if (visitChildren) { - acceptChild(visitor, getExpression()); + if (this.ast.apiLevel >= AST.JLS12_INTERNAL) { + acceptChildren(visitor, this.expressions); + } else { + acceptChild(visitor, getExpression()); + } } visitor.endVisit(this); } @@ -145,6 +210,7 @@ public class SwitchCase extends Statement { * <code>null</code> if there is none (the "default:" case). * * @return the expression node, or <code>null</code> if there is none + * @deprecated use getExpressions() (see JLS 12) */ public Expression getExpression() { if (!this.expressionInitialized) { @@ -160,6 +226,21 @@ public class SwitchCase extends Statement { } return this.optionalExpression; } + + /** + * Returns the list of expressions of this switch case, or + * <code>empty</code> if there is none (the "default:" case). + * + * @return the expression node, or <code>expression</code> if there is none + * @exception UnsupportedOperationException if this operation is used below JLS12 + * @since 3.17 BETA_JAVA_12 + */ + public List expressions() { + if (this.expressions == null) { + unsupportedBelow12(); + } + return this.expressions; + } /** * Sets the expression of this switch case, or clears it (turns it into @@ -173,6 +254,7 @@ public class SwitchCase extends Statement { * <li>the node already has a parent</li> * <li>a cycle in would be created</li> * </ul> + * @deprecated see JLS 12 */ public void setExpression(Expression expression) { ASTNode oldChild = this.optionalExpression; @@ -181,18 +263,47 @@ public class SwitchCase extends Statement { this.expressionInitialized = true; postReplaceChild(oldChild, expression, EXPRESSION_PROPERTY); } + + /** + * Sets the switchLabeledRule of this switch case as <code>true</code> or <code>false</code>. + * <code>true</code> indicates "->" and <code>false</code> indicates ":". + + * @param switchLabeledRule <code>true</code> or </false> + * @exception UnsupportedOperationException if this operation is used below JLS12 + * @since 3.17 BETA_JAVA_12 + */ + public void setSwitchLabeledRule(boolean switchLabeledRule) { + unsupportedBelow12(); + this.switchLabeledRule = switchLabeledRule; + } + + /** + * Gets the switchLabeledRule of this switch case as <code>true</code> or <code>false</code>. + *<code>true</code> indicates "->" and <code>false</code> indicates ":". + * + * @return switchLabeledRule <code>true</code> or </false> + * @exception UnsupportedOperationException if this operation is used below JLS12 + * @since 3.17 BETA_JAVA_12 + */ + public boolean isSwitchLabeledRule() { + unsupportedBelow12(); + return this.switchLabeledRule; + } /** * Returns whether this switch case represents the "default:" case. * <p> * This convenience method is equivalent to - * <code>getExpression() == null</code>. + * <code>getExpression() == null</code> or <code>getExpressions().isEmpty()</code>. * </p> * * @return <code>true</code> if this is the default switch case, and * <code>false</code> if this is a non-default switch case */ public boolean isDefault() { + if (this.ast.apiLevel >= AST.JLS12_INTERNAL) { + return expressions().isEmpty(); + } return getExpression() == null; } diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SwitchExpression.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SwitchExpression.java new file mode 100644 index 0000000000..2eea888249 --- /dev/null +++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SwitchExpression.java @@ -0,0 +1,241 @@ +/******************************************************************************* + * Copyright (c) 2019 IBM Corporation and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ + +package org.eclipse.jdt.core.dom; + +import java.util.ArrayList; +import java.util.List; + +/** + * Switch expression AST node type (added in JEP 325). + * <p> + * <pre> + * SwitchExpression: + * <b>switch</b> <b>(</b> Expression <b>)</b> + * <b>{</b> { SwitchCase | Statement } <b>}</b> + * SwitchCase: + * <b>case</b> [ Expression { <b>,</b> Expression } ] <b>{ : | ->}</b> + * <b>default</b> <b>{ : | ->}</b> + * </pre> + * <code>SwitchCase</code> nodes are treated as a kind of + * <code>Statement</code>. + * </p> + * + * @since 3.17 BETA_JAVA_12 + * @noinstantiate This class is not intended to be instantiated by clients. + */ +@SuppressWarnings({"rawtypes", "unchecked"}) +public class SwitchExpression extends Expression { + + /** + * The "expression" structural property of this node type (child type: {@link Expression}). + * @since 3.16 + */ + public static final ChildPropertyDescriptor EXPRESSION_PROPERTY = + new ChildPropertyDescriptor(SwitchExpression.class, "expression", Expression.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$ + + /** + * The "statements" structural property of this node type (element type: {@link Statement}). + * @since 3.16 + */ + public static final ChildListPropertyDescriptor STATEMENTS_PROPERTY = + new ChildListPropertyDescriptor(SwitchExpression.class, "statements", Statement.class, CYCLE_RISK); //$NON-NLS-1$ + + /** + * A list of property descriptors (element type: + * {@link StructuralPropertyDescriptor}), + * or null if uninitialized. + */ + private static final List PROPERTY_DESCRIPTORS_12_0; + + static { + List propertyList = new ArrayList(3); + createPropertyList(SwitchExpression.class, propertyList); + addProperty(EXPRESSION_PROPERTY, propertyList); + addProperty(STATEMENTS_PROPERTY, propertyList); + PROPERTY_DESCRIPTORS_12_0 = reapPropertyList(propertyList); + } + + /** + * Returns a list of structural property descriptors for this node type. + * Clients must not modify the result. + * + * @param apiLevel the API level; one of the + * <code>AST.JLS*</code> constants + * @return a list of property descriptors (element type: + * {@link StructuralPropertyDescriptor}) + * @since 3.16 + */ + public static List propertyDescriptors(int apiLevel) { + return PROPERTY_DESCRIPTORS_12_0; + } + + /** + * The expression; lazily initialized; defaults to a unspecified, but legal, + * expression. + */ + private Expression expression = null; + + /** + * The statements and SwitchCase nodes + * (element type: {@link Statement}). + * Defaults to an empty list. + */ + private ASTNode.NodeList statements = + new ASTNode.NodeList(STATEMENTS_PROPERTY); + + /** + * Creates a new unparented switch statement node owned by the given + * AST. By default, the swicth statement has an unspecified, but legal, + * expression, and an empty list of switch groups. + * <p> + * N.B. This constructor is package-private. + * </p> + * + * @param ast the AST that is to own this node + * @exception UnsupportedOperationException if this operation is used below JLS12 + */ + SwitchExpression(AST ast) { + super(ast); + unsupportedBelow12(); + } + + @Override + final List internalStructuralPropertiesForType(int apiLevel) { + return propertyDescriptors(apiLevel); + } + + @Override + final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) { + if (property == EXPRESSION_PROPERTY) { + if (get) { + return getExpression(); + } else { + setExpression((Expression) child); + return null; + } + } + // allow default implementation to flag the error + return super.internalGetSetChildProperty(property, get, child); + } + + @Override + final List internalGetChildListProperty(ChildListPropertyDescriptor property) { + if (property == STATEMENTS_PROPERTY) { + return statements(); + } + // allow default implementation to flag the error + return super.internalGetChildListProperty(property); + } + + @Override + final int getNodeType0() { + return SWITCH_EXPRESSION; + } + + @Override + ASTNode clone0(AST target) { + SwitchExpression result = new SwitchExpression(target); + result.setSourceRange(getStartPosition(), getLength()); + result.setExpression((Expression) getExpression().clone(target)); + result.statements().addAll(ASTNode.copySubtrees(target, statements())); + return result; + } + + @Override + final boolean subtreeMatch0(ASTMatcher matcher, Object other) { + // dispatch to correct overloaded match method + return matcher.match(this, other); + } + + @Override + void accept0(ASTVisitor visitor) { + boolean visitChildren = visitor.visit(this); + if (visitChildren) { + // visit children in normal left to right reading order + acceptChild(visitor, getExpression()); + acceptChildren(visitor, this.statements); + } + visitor.endVisit(this); + } + + /** + * Returns the expression of this switch statement. + * + * @return the expression node + */ + public Expression getExpression() { + if (this.expression == null) { + // lazy init must be thread-safe for readers + synchronized (this) { + if (this.expression == null) { + preLazyInit(); + this.expression = new SimpleName(this.ast); + postLazyInit(this.expression, EXPRESSION_PROPERTY); + } + } + } + return this.expression; + } + + /** + * Sets the expression of this switch statement. + * + * @param expression the new expression node + * @exception IllegalArgumentException if: + * <ul> + * <li>the node belongs to a different AST</li> + * <li>the node already has a parent</li> + * <li>a cycle in would be created</li> + * </ul> + */ + public void setExpression(Expression expression) { + if (expression == null) { + throw new IllegalArgumentException(); + } + ASTNode oldChild = this.expression; + preReplaceChild(oldChild, expression, EXPRESSION_PROPERTY); + this.expression = expression; + postReplaceChild(oldChild, expression, EXPRESSION_PROPERTY); + } + + /** + * Returns the live ordered list of statements for this switch statement. + * Within this list, <code>SwitchCase</code> nodes mark the start of + * the switch groups. + * + * @return the live list of statement nodes + * (element type: {@link Statement}) + */ + public List statements() { + return this.statements; + } + + @Override + int memSize() { + return BASE_NODE_SIZE + 3 * 4; + } + + @Override + int treeSize() { + return + memSize() + + (this.expression == null ? 0 : getExpression().treeSize()) + + this.statements.listSize(); + } +} diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/NaiveASTFlattener.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/NaiveASTFlattener.java index 7f2c004e17..001fc1fd7f 100644 --- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/NaiveASTFlattener.java +++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/NaiveASTFlattener.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2018 IBM Corporation and others. + * Copyright (c) 2000, 2019 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -7,6 +7,10 @@ * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 + * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. * * Contributors: * IBM Corporation - initial API and implementation @@ -81,6 +85,14 @@ public class NaiveASTFlattener extends ASTVisitor { * @since 3.14 */ private static final int JLS9 = AST.JLS9; + + /** + * Internal synonym for {@link AST#JLS12}. Use to alleviate + * deprecation warnings. + * @since 3.17 BETA_JAVA_12 + */ + private static final int JLS12 = AST.JLS12; + /** * The string buffer into which the serialized representation of the AST is @@ -1487,32 +1499,76 @@ public class NaiveASTFlattener extends ASTVisitor { @Override public boolean visit(SwitchCase node) { - if (node.isDefault()) { - this.buffer.append("default :\n");//$NON-NLS-1$ - } else { - this.buffer.append("case ");//$NON-NLS-1$ - node.getExpression().accept(this); - this.buffer.append(":\n");//$NON-NLS-1$ + if (node.getAST().apiLevel() >= JLS12) { + if (node.isDefault()) { + this.buffer.append("default");//$NON-NLS-1$ + this.buffer.append(node.isSwitchLabeledRule() ? "->" : ":");//$NON-NLS-1$ //$NON-NLS-2$ + } else { + this.buffer.append("case ");//$NON-NLS-1$ + for (Iterator it = node.expressions().iterator(); it.hasNext(); ) { + Expression t = (Expression) it.next(); + t.accept(this); + this.buffer.append(it.hasNext() ? ", " : //$NON-NLS-1$ + node.isSwitchLabeledRule() ? "->" : ":");//$NON-NLS-1$ //$NON-NLS-2$ + } + } + } + else { + if (node.isDefault()) { + this.buffer.append("default :\n");//$NON-NLS-1$ + } else { + this.buffer.append("case ");//$NON-NLS-1$ + getSwitchExpression(node).accept(this); + this.buffer.append(":\n");//$NON-NLS-1$ + } } this.indent++; //decremented in visit(SwitchStatement) return false; } + /** + * @deprecated + */ + private Expression getSwitchExpression(SwitchCase node) { + return node.getExpression(); + } - @Override - public boolean visit(SwitchStatement node) { + private void visitSwitchNode(ASTNode node) { this.buffer.append("switch (");//$NON-NLS-1$ - node.getExpression().accept(this); + if (node instanceof SwitchExpression) { + ((SwitchExpression)node).getExpression().accept(this); + } else if (node instanceof SwitchStatement) { + ((SwitchStatement)node).getExpression().accept(this); + } this.buffer.append(") ");//$NON-NLS-1$ this.buffer.append("{\n");//$NON-NLS-1$ this.indent++; - for (Iterator it = node.statements().iterator(); it.hasNext(); ) { - Statement s = (Statement) it.next(); - s.accept(this); - this.indent--; // incremented in visit(SwitchCase) + if (node instanceof SwitchExpression) { + for (Iterator it = ((SwitchExpression)node).statements().iterator(); it.hasNext(); ) { + Statement s = (Statement) it.next(); + s.accept(this); + this.indent--; // incremented in visit(SwitchCase) + } + } else if (node instanceof SwitchStatement) { + for (Iterator it = ((SwitchStatement)node).statements().iterator(); it.hasNext(); ) { + Statement s = (Statement) it.next(); + s.accept(this); + this.indent--; // incremented in visit(SwitchCase) + } } this.indent--; printIndent(); this.buffer.append("}\n");//$NON-NLS-1$ + + } + @Override + public boolean visit(SwitchExpression node) { + visitSwitchNode(node); + return false; + } + + @Override + public boolean visit(SwitchStatement node) { + visitSwitchNode(node); return false; } diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteAnalyzer.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteAnalyzer.java index ace31ede86..ead61a2cc7 100644 --- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteAnalyzer.java +++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteAnalyzer.java @@ -117,6 +117,9 @@ public final class ASTRewriteAnalyzer extends ASTVisitor { /** @deprecated using deprecated code */ private static final ChildListPropertyDescriptor INTERNAL_TRY_STATEMENT_RESOURCES_PROPERTY = TryStatement.RESOURCES_PROPERTY; + + /** @deprecated using deprecated code */ + private static final ChildPropertyDescriptor INTERNAL_SWITCH_EXPRESSION_PROPERTY = SwitchCase.EXPRESSION_PROPERTY; /** @deprecated using deprecated code */ private static final int JLS2_INTERNAL = AST.JLS2; @@ -132,6 +135,8 @@ public final class ASTRewriteAnalyzer extends ASTVisitor { /** @deprecated using deprecated code */ private static final int JLS9_INTERNAL = AST.JLS9; + + private static final int JLS12_INTERNAL = AST.JLS12; TextEdit currentEdit; @@ -1036,6 +1041,60 @@ public final class ASTRewriteAnalyzer extends ASTVisitor { } return pos; } + + private int rewriteExpressionOptionalQualifier(SwitchCase parent, StructuralPropertyDescriptor property, int startPos) { + RewriteEvent event= getEvent(parent, property); + if (event != null) { + switch (event.getChangeKind()) { + case RewriteEvent.INSERTED: { + ASTNode node= (ASTNode) event.getNewValue(); + TextEditGroup editGroup= getEditGroup(event); + doTextInsert(startPos, node, getIndent(startPos), true, editGroup); + doTextInsert(startPos, ".", editGroup); //$NON-NLS-1$ + return startPos; + } + case RewriteEvent.REMOVED: { + try { + ASTNode node= (ASTNode) event.getOriginalValue(); + TextEditGroup editGroup= getEditGroup(event); + int dotEnd= getScanner().getTokenEndOffset(TerminalTokens.TokenNameCOLON, node.getStartPosition() + node.getLength()); + doTextRemoveAndVisit(startPos, dotEnd - startPos, node, editGroup); + return dotEnd; + } catch (CoreException e) { + handleException(e); + } + break; + } + case RewriteEvent.REPLACED: { + ASTNode node= (ASTNode) event.getOriginalValue(); + TextEditGroup editGroup= getEditGroup(event); + SourceRange range= getExtendedRange(node); + int offset= range.getStartPosition(); + int length= range.getLength(); + + doTextRemoveAndVisit(offset, length, node, editGroup); + doTextInsert(offset, (ASTNode) event.getNewValue(), getIndent(startPos), true, editGroup); + try { + return getScanner().getTokenEndOffset(TerminalTokens.TokenNameCOLON, offset + length); + } catch (CoreException e) { + handleException(e); + } + break; + } + } + } + Object node= getOriginalValue(parent, property); + if (node == null) { + return startPos; + } + int pos= doVisit((ASTNode) node); + try { + return getScanner().getTokenEndOffset(TerminalTokens.TokenNameCOLON, pos); + } catch (CoreException e) { + handleException(e); + } + return pos; + } class ParagraphListRewriter extends ListRewriter { @@ -1543,7 +1602,48 @@ public final class ASTRewriteAnalyzer extends ASTVisitor { } } + private int rewriteExpression2(ASTNode node, ChildListPropertyDescriptor property, int pos) { + RewriteEvent event= getEvent(node, property); + if (event == null || event.getChangeKind() == RewriteEvent.UNCHANGED) { + return doVisit(node, property, pos); + } + RewriteEvent[] children= event.getChildren(); + boolean isAllInsert= isAllOfKind(children, RewriteEvent.INSERTED); + boolean isAllRemove= isAllOfKind(children, RewriteEvent.REMOVED); + String keyword= Util.EMPTY_STRING; + if (((SwitchCase)node).isSwitchLabeledRule()) { + keyword = "->"; //$NON-NLS-1$ + } else { + keyword = ":"; //$NON-NLS-1$ + } + + Prefix formatterPrefix = this.formatter.CASE_SEPARATION; + + int endPos= new ModifierRewriter(formatterPrefix).rewriteList(node, property, pos, keyword, " "); //$NON-NLS-1$ + try { + int nextPos= getScanner().getNextStartOffset(endPos, false); + RewriteEvent lastChild = children[children.length - 1]; + boolean lastUnchanged= lastChild.getChangeKind() != RewriteEvent.UNCHANGED; + + if (isAllRemove) { + doTextRemove(endPos, nextPos - endPos, getEditGroup(lastChild)); + return nextPos; + } else if (isAllInsert || (nextPos == endPos && lastUnchanged)){ + String separator; + if (lastChild.getNewValue() instanceof Annotation) { + separator= formatterPrefix.getPrefix(getIndent(pos)); + } else { + separator= String.valueOf(' '); //$NON-NLS-1$ + } + doTextInsert(endPos, separator, getEditGroup(lastChild)); + } + } catch (CoreException e) { + handleException(e); + } + return endPos; + } + private int rewriteModifiers2(ASTNode node, ChildListPropertyDescriptor property, int pos) { RewriteEvent event= getEvent(node, property); if (event == null || event.getChangeKind() == RewriteEvent.UNCHANGED) { @@ -3413,7 +3513,19 @@ public final class ASTRewriteAnalyzer extends ASTVisitor { } // dont allow switching from case to default or back. New statements should be created. - rewriteRequiredNode(node, SwitchCase.EXPRESSION_PROPERTY); + if (node.getAST().apiLevel() >= JLS12_INTERNAL) { + // rewriteExpression2(node, SwitchCase.EXPRESSIONS2_PROPERTY, node.getStartPosition()); + String keyword = Util.EMPTY_STRING; + if (node.isSwitchLabeledRule()) { + keyword = "->"; //$NON-NLS-1$ + } else { + keyword = ":"; //$NON-NLS-1$ + } + rewriteNodeList(node, SwitchCase.EXPRESSIONS2_PROPERTY, node.getStartPosition(), keyword, ", "); //$NON-NLS-1$ + } else { + rewriteExpressionOptionalQualifier(node, SwitchCase.EXPRESSION_PROPERTY, node.getStartPosition()); + } + return false; } @@ -3512,6 +3624,37 @@ public final class ASTRewriteAnalyzer extends ASTVisitor { } @Override + public boolean visit(SwitchExpression node) { + if (!hasChildrenChanges(node)) { + return doVisitUnchangedChildren(node); + } + + int pos= rewriteRequiredNode(node, SwitchExpression.EXPRESSION_PROPERTY); + + ChildListPropertyDescriptor property= SwitchExpression.STATEMENTS_PROPERTY; + if (getChangeKind(node, property) != RewriteEvent.UNCHANGED) { + try { + pos= getScanner().getTokenEndOffset(TerminalTokens.TokenNameLBRACE, pos); + int insertIndent= getIndent(node.getStartPosition()); + if (DefaultCodeFormatterConstants.TRUE.equals(this.options.get(DefaultCodeFormatterConstants.FORMATTER_INDENT_SWITCHSTATEMENTS_COMPARE_TO_SWITCH))) { + insertIndent++; + } + + ParagraphListRewriter listRewriter= new SwitchListRewriter(insertIndent); + StringBuffer leadString= new StringBuffer(); + leadString.append(getLineDelimiter()); + leadString.append(createIndentString(insertIndent)); + listRewriter.rewriteList(node, property, pos, leadString.toString()); + } catch (CoreException e) { + handleException(e); + } + } else { + voidVisit(node, SwitchExpression.STATEMENTS_PROPERTY); + } + return false; + } + + @Override public boolean visit(SwitchStatement node) { if (!hasChildrenChanges(node)) { return doVisitUnchangedChildren(node); diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteFlattener.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteFlattener.java index ee92237352..8a380d2c4c 100644 --- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteFlattener.java +++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteFlattener.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2018 IBM Corporation and others. + * Copyright (c) 2000, 2019 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -8,11 +8,16 @@ * * SPDX-License-Identifier: EPL-2.0 * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.jdt.internal.core.dom.rewrite; +import java.util.Iterator; import java.util.List; import org.eclipse.jdt.core.dom.*; @@ -76,6 +81,9 @@ public class ASTRewriteFlattener extends ASTVisitor { private static final ChildListPropertyDescriptor INTERNAL_TRY_STATEMENT_RESOURCES_PROPERTY = TryStatement.RESOURCES_PROPERTY; /** @deprecated using deprecated code */ + private static final ChildPropertyDescriptor INTERNAL_SWITCH_EXPRESSION_PROPERTY = SwitchCase.EXPRESSION_PROPERTY; + + /** @deprecated using deprecated code */ private static final int JLS2_INTERNAL = AST.JLS2; /** @deprecated using deprecated code */ @@ -89,6 +97,13 @@ public class ASTRewriteFlattener extends ASTVisitor { /** @deprecated using deprecated code */ private static final int JLS9_INTERNAL = AST.JLS9; + + /** + * Internal synonym for {@link AST#JLS12}. Use to alleviate + * deprecation warnings. + * @since 3.17 BETA_JAVA_12 + */ + private static final int JLS12 = AST.JLS12; public static String asString(ASTNode node, RewriteEventStore store) { @@ -959,25 +974,61 @@ public class ASTRewriteFlattener extends ASTVisitor { @Override public boolean visit(SwitchCase node) { - ASTNode expression= getChildNode(node, SwitchCase.EXPRESSION_PROPERTY); - if (expression == null) { - this.result.append("default"); //$NON-NLS-1$ + if (node.getAST().apiLevel() >= JLS12) { + if (node.isDefault()) { + this.result.append("default");//$NON-NLS-1$ + this.result.append(node.isSwitchLabeledRule() ? "->" : ":");//$NON-NLS-1$ //$NON-NLS-2$ + } else { + this.result.append("case ");//$NON-NLS-1$ + for (Iterator it = node.expressions().iterator(); it.hasNext(); ) { + Expression t = (Expression) it.next(); + t.accept(this); + this.result.append(it.hasNext() ? ", " : //$NON-NLS-1$ + node.isSwitchLabeledRule() ? "->" : ":");//$NON-NLS-1$ //$NON-NLS-2$ + } + } } else { - this.result.append("case "); //$NON-NLS-1$ - expression.accept(this); + ASTNode expression= getChildNode(node, SwitchCase.EXPRESSION_PROPERTY); + if (expression == null) { + this.result.append("default"); //$NON-NLS-1$ + } else { + this.result.append("case "); //$NON-NLS-1$ + expression.accept(this); + } + this.result.append(':'); } - this.result.append(':'); return false; } @Override - public boolean visit(SwitchStatement node) { + public boolean visit(SwitchExpression node) { + visitSwitchNode(node); + return false; + } + + private void visitSwitchNode(ASTNode node) { this.result.append("switch ("); //$NON-NLS-1$ - getChildNode(node, SwitchStatement.EXPRESSION_PROPERTY).accept(this); + if (node instanceof SwitchExpression) { + getChildNode(node, SwitchExpression.EXPRESSION_PROPERTY).accept(this); + } + else if (node instanceof SwitchStatement) { + getChildNode(node, SwitchStatement.EXPRESSION_PROPERTY).accept(this); + } this.result.append(')'); this.result.append('{'); - visitList(node, SwitchStatement.STATEMENTS_PROPERTY, null); + if (node instanceof SwitchExpression) { + visitList(node, SwitchExpression.STATEMENTS_PROPERTY, null); + } + else if (node instanceof SwitchStatement) { + visitList(node, SwitchStatement.STATEMENTS_PROPERTY, null); + } + this.result.append('}'); + } + + @Override + public boolean visit(SwitchStatement node) { + visitSwitchNode(node); return false; } diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteFormatter.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteFormatter.java index ad53806b93..6e936b1a0a 100644 --- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteFormatter.java +++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteFormatter.java @@ -1,10 +1,15 @@ /******************************************************************************* - * Copyright (c) 2000, 2017 IBM Corporation and others. + * Copyright (c) 2000, 2019 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 * which accompanies this distribution, and is available at * https://www.eclipse.org/legal/epl-2.0/ + * + * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. * * SPDX-License-Identifier: EPL-2.0 * @@ -574,6 +579,8 @@ public final class ASTRewriteFormatter { public final BlockContext IF_BLOCK_NO_ELSE= new BlockFormattingPrefix("if (true)", 8); //$NON-NLS-1$ public final BlockContext ELSE_AFTER_STATEMENT= new BlockFormattingPrefix("if (true) foo();else ", 15); //$NON-NLS-1$ public final BlockContext ELSE_AFTER_BLOCK= new BlockFormattingPrefix("if (true) {}else ", 11); //$NON-NLS-1$ + + public final Prefix CASE_SEPARATION= new FormattingPrefix("case A, B", "A" , CodeFormatter.K_EXPRESSION); //$NON-NLS-1$ //$NON-NLS-2$ public final BlockContext FOR_BLOCK= new BlockFormattingPrefix("for (;;) ", 7); //$NON-NLS-1$ public final BlockContext WHILE_BLOCK= new BlockFormattingPrefix("while (true)", 11); //$NON-NLS-1$ diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/core/formatter/DefaultCodeFormatterConstants.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/core/formatter/DefaultCodeFormatterConstants.java index 922b1b50a1..e2f4edd280 100644 --- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/core/formatter/DefaultCodeFormatterConstants.java +++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/core/formatter/DefaultCodeFormatterConstants.java @@ -1,3 +1,4 @@ +
/******************************************************************************* * Copyright (c) 2000, 2019 IBM Corporation and others. * diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/SpacePreparator.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/SpacePreparator.java index f194800322..ba40de8431 100644 --- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/SpacePreparator.java +++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/SpacePreparator.java @@ -386,11 +386,22 @@ public class SpacePreparator extends ASTVisitor { handleToken(node, TokenNameCOLON, this.options.insert_space_before_colon_in_default, false); } else { handleToken(node, TokenNamecase, false, true); - handleToken(node.getExpression(), TokenNameCOLON, this.options.insert_space_before_colon_in_case, false); + handleToken(getSwitchExpression(node), TokenNameCOLON, this.options.insert_space_before_colon_in_case, false); } return true; } + /** + * + * @param node + * @return expression + * @deprecated + */ + private Expression getSwitchExpression(SwitchCase node) { + return node.getExpression(); + } + + @Override public boolean visit(DoStatement node) { handleTokenBefore(node.getExpression(), TokenNameLPAREN, diff --git a/org.eclipse.jdt.core/grammar/java.g b/org.eclipse.jdt.core/grammar/java.g index 41761de113..bed20acc28 100644 --- a/org.eclipse.jdt.core/grammar/java.g +++ b/org.eclipse.jdt.core/grammar/java.g @@ -113,6 +113,7 @@ $Terminals ElidedSemicolonAndRightBrace AT308 AT308DOTDOTDOT + BeginCaseExpr -- BodyMarker @@ -1267,6 +1268,7 @@ SwitchBlockStatements ::= SwitchBlockStatements SwitchBlockStatement /.$putCase consumeSwitchBlockStatements() ; $break ./ /:$readableName SwitchBlockStatements:/ +SwitchBlockStatement -> SwitchLabeledRule SwitchBlockStatement ::= SwitchLabels BlockStatements /.$putCase consumeSwitchBlockStatement() ; $break ./ /:$readableName SwitchBlockStatement:/ @@ -1276,13 +1278,54 @@ SwitchLabels ::= SwitchLabels SwitchLabel /.$putCase consumeSwitchLabels() ; $break ./ /:$readableName SwitchLabels:/ -SwitchLabel ::= 'case' ConstantExpression ':' +SwitchLabel ::= SwitchLabelCaseLhs ':' /. $putCase consumeCaseLabel(); $break ./ SwitchLabel ::= 'default' ':' /. $putCase consumeDefaultLabel(); $break ./ /:$readableName SwitchLabel:/ +-- BEGIN SwitchExpression (JEP 325) -- + +UnaryExpressionNotPlusMinus -> SwitchExpression +UnaryExpressionNotPlusMinus_NotName -> SwitchExpression + +SwitchExpression ::= 'switch' '(' Expression ')' OpenBlock SwitchBlock +/.$putCase consumeSwitchExpression() ; $break ./ +/:$readableName SwitchExpression:/ + +SwitchLabeledRule ::= SwitchLabeledExpression +SwitchLabeledRule ::= SwitchLabeledBlock +SwitchLabeledRule ::= SwitchLabeledThrowStatement +/. $putCase consumeSwitchLabeledRule(); $break ./ +/:$readableName SwitchLabeledRule:/ + +SwitchLabeledExpression ::= SwitchLabelExpr Expression ';' +/. $putCase consumeSwitchLabeledExpression(); $break ./ +/:$readableName SwitchLabeledExpression:/ + +SwitchLabeledBlock ::= SwitchLabelExpr Block +/. $putCase consumeSwitchLabeledBlock(); $break ./ +/:$readableName SwitchLabeledBlock:/ + +SwitchLabeledThrowStatement ::= SwitchLabelExpr ThrowExpression ';' +/. $putCase consumeSwitchLabeledThrowStatement(); $break ./ +/:$readableName SwitchLabeledThrowStatement:/ + +SwitchLabelExpr ::= 'default' '->' +/. $putCase consumeDefaultLabelExpr(); $break ./ +/:$readableName SwitchLabelDefaultExpr:/ + +SwitchLabelExpr ::= SwitchLabelCaseLhs BeginCaseExpr '->' +/. $putCase consumeCaseLabelExpr(); $break ./ +/:$readableName SwitchLabelExpr:/ + +SwitchLabelCaseLhs ::= 'case' ConstantExpressions +/. $putCase consumeSwitchLabelCaseLhs(); $break ./ +/:$readableName SwitchLabelCaseLhs:/ + +-- END SwitchExpression (JEP 325) -- + WhileStatement ::= 'while' '(' Expression ')' Statement /.$putCase consumeStatementWhile() ; $break ./ /:$readableName WhileStatement:/ @@ -1330,7 +1373,7 @@ AssertStatement ::= 'assert' Expression ':' Expression ';' BreakStatement ::= 'break' ';' /.$putCase consumeStatementBreak() ; $break ./ -BreakStatement ::= 'break' Identifier ';' +BreakStatement ::= 'break' Expression ';' /.$putCase consumeStatementBreakWithLabel() ; $break ./ /:$readableName BreakStatement:/ @@ -1349,6 +1392,10 @@ ThrowStatement ::= 'throw' Expression ';' /.$putCase consumeStatementThrow(); $break ./ /:$readableName ThrowStatement:/ +ThrowExpression ::= 'throw' Expression +/.$putCase consumeThrowExpression() ; $break ./ +/:$readableName ThrowExpression:/ + SynchronizedStatement ::= OnlySynchronized '(' Expression ')' Block /.$putCase consumeStatementSynchronized(); $break ./ /:$readableName SynchronizedStatement:/ @@ -1990,6 +2037,11 @@ Expressionopt ::= $empty Expressionopt -> Expression /:$readableName Expression:/ +ConstantExpressions -> Expression +ConstantExpressions ::= ConstantExpressions ',' Expression +/.$putCase consumeConstantExpressions(); $break ./ +/:$readableName ConstantExpressions:/ + ConstantExpression -> Expression /:$readableName ConstantExpression:/ diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java index d27dacbcd7..33e9b72cef 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java @@ -1,11 +1,15 @@ /******************************************************************************* - * Copyright (c) 2000, 2018 IBM Corporation and others. + * Copyright (c) 2000, 2019 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 * which accompanies this distribution, and is available at * https://www.eclipse.org/legal/epl-2.0/ * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * SPDX-License-Identifier: EPL-2.0 * * Contributors: @@ -2571,6 +2575,31 @@ public final class JavaCore extends Plugin { public static final String CORE_MAIN_ONLY_PROJECT_HAS_TEST_ONLY_DEPENDENCY = PLUGIN_ID + ".classpath.mainOnlyProjectHasTestOnlyDependency"; //$NON-NLS-1$ /** + * Compiler option ID: Enabling support for preview language features. + * <p>When enabled, the compiler will activate the preview language features of this Java version.</p> + * + * <dl> + * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures"</code></dd> + * <dt>Possible values:</dt><dd><code>{ "enabled", "disabled" }</code></dd> + * <dt>Default:</dt><dd><code>"disabled"</code></dd> + * </dl> + * @category CompilerOptionID + * @since 3.17 BETA_JAVA_12 + */ + public static final String COMPILER_PB_ENABLE_PREVIEW_FEATURES = PLUGIN_ID + ".compiler.problem.enablePreviewFeatures"; //$NON-NLS-1$ + /** + * Compiler option ID: Reporting Preview features. + * <p>When enabled, the compiler will issue a warning when a preview feature is used.</p> + * <dl> + * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures"</code></dd> + * <dt>Possible values:</dt><dd><code>{ "warning", "info", "ignore" }</code></dd> + * <dt>Default:</dt><dd><code>"warning"</code></dd> + * </dl> + * @category CompilerOptionID + * @since 3.17 BETA_JAVA_12 + */ + public static final String COMPILER_PB_REPORT_PREVIEW_FEATURES = PLUGIN_ID + ".compiler.problem.reportPreviewFeatures"; //$NON-NLS-1$ + /** * Core option ID: Set the timeout value for retrieving the method's parameter names from javadoc. * <p>Timeout in milliseconds to retrieve the method's parameter names from javadoc.</p> * <p>If the value is <code>0</code>, the parameter names are not fetched and the raw names are returned.</p> @@ -3028,12 +3057,18 @@ public final class JavaCore extends Plugin { public static final String VERSION_11 = "11"; //$NON-NLS-1$ /** * Configurable option value: {@value}. + * @since 3.17 BETA_JAVA_12 + * @category OptionValue + */ + public static final String VERSION_12 = "12"; //$NON-NLS-1$ + /** + * Configurable option value: {@value}. * @since 3.4 * @category OptionValue */ public static final String VERSION_CLDC_1_1 = "cldc1.1"; //$NON-NLS-1$ private static List<String> allVersions = Arrays.asList(VERSION_CLDC_1_1, VERSION_1_1, VERSION_1_2, VERSION_1_3, VERSION_1_4, VERSION_1_5, - VERSION_1_6, VERSION_1_7, VERSION_1_8, VERSION_9, VERSION_10, VERSION_11); + VERSION_1_6, VERSION_1_7, VERSION_1_8, VERSION_9, VERSION_10, VERSION_11, VERSION_12); /** * Returns all {@link JavaCore}{@code #VERSION_*} levels in the order of their @@ -5986,6 +6021,8 @@ public final class JavaCore extends Plugin { * <li>{@link #COMPILER_PB_ASSERT_IDENTIFIER}</li> * <li>{@link #COMPILER_PB_ENUM_IDENTIFIER}</li> * <li>{@link #COMPILER_CODEGEN_INLINE_JSR_BYTECODE} for compliance levels 1.5 and greater</li> + * <li>{@link #COMPILER_PB_ENABLE_PREVIEW_FEATURES} for compliance levels 11 and greater</li> + * <li>{@link #COMPILER_PB_REPORT_PREVIEW_FEATURES} for compliance levels 11 and greater</li> * </ul> * * <p>If the given compliance is unknown, the given map is unmodified.</p> @@ -6072,6 +6109,8 @@ public final class JavaCore extends Plugin { options.put(JavaCore.COMPILER_PB_ENUM_IDENTIFIER, JavaCore.ERROR); options.put(JavaCore.COMPILER_CODEGEN_INLINE_JSR_BYTECODE, JavaCore.ENABLED); options.put(JavaCore.COMPILER_RELEASE, JavaCore.ENABLED); + options.put(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, JavaCore.DISABLED); + options.put(JavaCore.COMPILER_PB_REPORT_PREVIEW_FEATURES, JavaCore.WARNING); } break; } diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java index cdfd6f27d0..8de8ebe731 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java @@ -6,6 +6,10 @@ * which accompanies this distribution, and is available at * https://www.eclipse.org/legal/epl-2.0/ * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * SPDX-License-Identifier: EPL-2.0 * * Contributors: @@ -432,7 +436,7 @@ public class JavaModelManager implements ISaveParticipant, IContentTypeChangeLis public static class CompilationParticipants { - private final static int MAX_SOURCE_LEVEL = 11 ; // 1.1 to 1.8 and 9, 10 + static final int MAX_SOURCE_LEVEL = JavaCore.getAllVersions().size() - 1; // All except VERSION_CLDC_1_1 /* * The registered compilation participants (a table from int (source level) to Object[]) diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProject.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProject.java index 45cd6edb15..fdb13ad30c 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProject.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProject.java @@ -935,11 +935,7 @@ public class JavaProject } @Override - public FileVisitResult visitModule(java.nio.file.Path mod) throws IOException { - String name = mod.toString(); - if (name.endsWith("/")) { //$NON-NLS-1$ - name = name.substring(0, name.length() - 1); - } + public FileVisitResult visitModule(java.nio.file.Path path, String name) throws IOException { JrtPackageFragmentRoot root = new JrtPackageFragmentRoot(imagePath, name, JavaProject.this); roots.add(root); if (rootToResolvedEntries != null) diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JrtPackageFragmentRoot.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JrtPackageFragmentRoot.java index 93c178155b..dba3e1a374 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JrtPackageFragmentRoot.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JrtPackageFragmentRoot.java @@ -78,11 +78,7 @@ public class JrtPackageFragmentRoot extends JarPackageFragmentRoot implements IM } @Override - public FileVisitResult visitModule(Path mod) throws IOException { - String name = mod.toString(); - if (name.endsWith("/")) { //$NON-NLS-1$ - name = name.substring(0, name.length() - 1); - } + public FileVisitResult visitModule(Path path, String name) throws IOException { if (!JrtPackageFragmentRoot.this.moduleName.equals(name)) { return FileVisitResult.SKIP_SUBTREE; } diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMapper.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMapper.java index 64cf749f1f..4c99d4add2 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMapper.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMapper.java @@ -530,7 +530,7 @@ public class SourceMapper } @Override - public FileVisitResult visitModule(java.nio.file.Path mod) throws IOException { + public FileVisitResult visitModule(java.nio.file.Path path, String name) throws IOException { return FileVisitResult.CONTINUE; } } diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathJrt.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathJrt.java index 7f7a9f4398..a3aaa8f21b 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathJrt.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathJrt.java @@ -8,6 +8,10 @@ * * SPDX-License-Identifier: EPL-2.0 * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ @@ -97,8 +101,7 @@ static HashMap<String, SimpleSet> findPackagesInModules(final ClasspathJrt jrt) } @Override - public FileVisitResult visitModule(Path mod) throws IOException { - String name = mod.toString(); + public FileVisitResult visitModule(Path path, String name) throws IOException { try { jrt.acceptModule(JRTUtil.getClassfileContent(imageFile, IModule.MODULE_INFO_CLASS, name)); } catch (ClassFormatException e) { @@ -143,9 +146,9 @@ public static void loadModules(final ClasspathJrt jrt) { } @Override - public FileVisitResult visitModule(Path mod) throws IOException { + public FileVisitResult visitModule(Path path, String name) throws IOException { try { - jrt.acceptModule(JRTUtil.getClassfileContent(imageFile, IModule.MODULE_INFO_CLASS, mod.toString())); + jrt.acceptModule(JRTUtil.getClassfileContent(imageFile, IModule.MODULE_INFO_CLASS, name)); } catch (ClassFormatException e) { e.printStackTrace(); } diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathJrtWithReleaseOption.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathJrtWithReleaseOption.java index 6207656dc3..95f3523bf1 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathJrtWithReleaseOption.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathJrtWithReleaseOption.java @@ -8,6 +8,10 @@ * * SPDX-License-Identifier: EPL-2.0 * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ @@ -92,11 +96,8 @@ public class ClasspathJrtWithReleaseOption extends ClasspathJrt { private boolean isJRE12Plus(Path path) { try (DirectoryStream<java.nio.file.Path> stream = Files.newDirectoryStream(path)) { for (final java.nio.file.Path subdir : stream) { - if (Files.exists(subdir.resolve("system-modules"))) { //$NON-NLS-1$ - String rel = subdir.getFileName().toString(); - if (rel.endsWith("/")) { //$NON-NLS-1$ - rel = rel.substring(0, rel.length() - 1); - } + String rel = JRTUtil.sanitizedFileName(subdir); + if (Files.exists(this.fs.getPath(rel, "system-modules"))) { //$NON-NLS-1$ int parseInt = Integer.parseInt(rel, 16); return (parseInt > 11); } @@ -157,10 +158,7 @@ public class ClasspathJrtWithReleaseOption extends ClasspathJrt { List<String> sub = new ArrayList<>(); try (DirectoryStream<java.nio.file.Path> stream = Files.newDirectoryStream(releasePath)) { for (final java.nio.file.Path subdir : stream) { - String rel = subdir.getFileName().toString(); - if (rel.endsWith("/")) { //$NON-NLS-1$ - rel = rel.substring(0, rel.length() - 1); - } + String rel = JRTUtil.sanitizedFileName(subdir); if (rel.contains(this.releaseInHex)) { sub.add(rel); } else { @@ -207,8 +205,7 @@ public class ClasspathJrtWithReleaseOption extends ClasspathJrt { } @Override - public FileVisitResult visitModule(Path mod) throws IOException { - String name = mod.getName(1).toString(); + public FileVisitResult visitModule(Path path, String name) throws IOException { this.packageSet = new SimpleSet(41); this.packageSet.add(""); //$NON-NLS-1$ if (name.endsWith("/")) { //$NON-NLS-1$ diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/NameEnvironment.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/NameEnvironment.java index 1366b58cc0..12371d0e28 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/NameEnvironment.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/NameEnvironment.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2018 IBM Corporation and others. + * Copyright (c) 2000, 2019 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -305,7 +305,7 @@ private void computeClasspathLocations( && JavaCore.IGNORE.equals(javaProject.getOption(JavaCore.COMPILER_PB_DISCOURAGED_REFERENCE, true))) ? null : entry.getAccessRuleSet(); - String release = JavaCore.DISABLED.equals(javaProject.getOption(JavaCore.COMPILER_RELEASE, true)) ? null : compliance; + String release = JavaCore.ENABLED.equals(javaProject.getOption(JavaCore.COMPILER_RELEASE, false)) ? compliance : null; ClasspathLocation bLocation = null; String libPath = path.toOSString(); if (Util.isJrt(libPath)) { diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/State.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/State.java index a57cc107e6..db4ecde3fa 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/State.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/State.java @@ -8,6 +8,10 @@ * * SPDX-License-Identifier: EPL-2.0 * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * IBM Corporation - initial API and implementation * Stephan Herrmann - Contribution for diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/AddJrtToIndex.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/AddJrtToIndex.java index df04833ee0..baa8c67ccd 100644 --- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/AddJrtToIndex.java +++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/AddJrtToIndex.java @@ -98,7 +98,7 @@ public class AddJrtToIndex extends BinaryContainer { @Override public FileVisitResult visitFile(java.nio.file.Path path, java.nio.file.Path mod, BasicFileAttributes attrs) throws IOException { - String name = path.getFileName().toString(); + String name = JRTUtil.sanitizedFileName(path); if (Util.isClassFileName(name) && isValidPackageNameForClassOrisModule(name)) { this.indexedFileNames.put(name, FILE_INDEX_STATE.EXISTS); @@ -106,7 +106,7 @@ public class AddJrtToIndex extends BinaryContainer { return FileVisitResult.CONTINUE; } @Override - public FileVisitResult visitModule(java.nio.file.Path mod) throws IOException { + public FileVisitResult visitModule(java.nio.file.Path path, String name) throws IOException { return FileVisitResult.CONTINUE; } } @@ -132,7 +132,7 @@ public class AddJrtToIndex extends BinaryContainer { @Override public FileVisitResult visitFile(java.nio.file.Path path, java.nio.file.Path mod, BasicFileAttributes attrs) throws IOException { - String name = path.getFileName().toString(); + String name = JRTUtil.sanitizedFileName(path); if (Util.isClassFileName(name) && isValidPackageNameForClassOrisModule(name)) { try { diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/TypeReferenceLocator.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/TypeReferenceLocator.java index 3d21fab0d5..265e1cc70e 100644 --- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/TypeReferenceLocator.java +++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/TypeReferenceLocator.java @@ -1,11 +1,15 @@ /******************************************************************************* - * Copyright (c) 2000, 2013 IBM Corporation and others. + * Copyright (c) 2000, 2019 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 * which accompanies this distribution, and is available at * https://www.eclipse.org/legal/epl-2.0/ * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * SPDX-License-Identifier: EPL-2.0 * * Contributors: @@ -652,6 +656,9 @@ protected int resolveLevel(NameReference nameRef) { binding = ((ProblemReferenceBinding) binding).closestMatch(); if (binding instanceof ReferenceBinding) return resolveLevelForType((ReferenceBinding) binding); + if (((SingleNameReference) nameRef).isLabel) + return IMPOSSIBLE_MATCH; + return binding == null || binding instanceof ProblemBinding ? INACCURATE_MATCH : IMPOSSIBLE_MATCH; } |