diff options
author | Manoj Palat | 2019-01-23 02:19:53 +0000 |
---|---|---|
committer | Jay Arthanareeswaran | 2019-01-23 16:52:02 +0000 |
commit | 8cf269f8d316be8a6bf363adbcb5e456d7e7e722 (patch) | |
tree | a9c44e1d8c62f1109592e9819c91ea679cc98eed | |
parent | 93c279fe25a5c7ae85ed69dd9a39f76dc0efe5ef (diff) | |
download | eclipse.jdt.core-8cf269f8d316be8a6bf363adbcb5e456d7e7e722.tar.gz eclipse.jdt.core-8cf269f8d316be8a6bf363adbcb5e456d7e7e722.tar.xz eclipse.jdt.core-8cf269f8d316be8a6bf363adbcb5e456d7e7e722.zip |
missing
Change-Id: Ifd3ec58cae737f9a3c47393887c6727e1cbad079
Signed-off-by: Jay Arthanareeswaran <jarthana@in.ibm.com>
8 files changed, 866 insertions, 166 deletions
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 a5a0e5ecb2..ec6f7a7b42 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 @@ -1049,7 +1049,6 @@ protected static class JavacTestOptions { protected INameEnvironment javaClassLib; protected TestVerifier verifier; protected boolean shouldSwallowCaptureId; - protected boolean enablePreview; public AbstractRegressionTest(String name) { super(name); } @@ -1734,6 +1733,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 */, @@ -1748,7 +1750,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 */, @@ -2549,10 +2551,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 @@ -2573,7 +2584,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 */, @@ -3113,16 +3124,6 @@ protected void runNegativeTest(boolean skipJavac, JavacTestOptions javacTestOpti this.verifier = new TestVerifier(false); this.createdVerifier = true; } - if (this.enablePreview) { - if (vmArguments == null) { - vmArguments = new String[1]; - vmArguments[0] = "--enable-preview"; - } else { - int size = vmArguments.length; - System.arraycopy(vmArguments, 0, vmArguments = new String[size + 1], 0, size); - vmArguments[size] = "--enable-preview"; - } - } boolean passed = this.verifier.verifyClassFiles( sourceFile, 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 index 143f7c1757..4dc1e10c5d 100644 --- 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 @@ -26,7 +26,7 @@ public class SwitchExpressionTest extends AbstractRegressionTest { static { // TESTS_NUMBERS = new int [] { 40 }; -// TESTS_NAMES = new String[] { "testBug531714_010" }; +// TESTS_NAMES = new String[] { "testBug543240_1" }; } public static Class<?> testClass() { @@ -51,37 +51,30 @@ public class SwitchExpressionTest extends AbstractRegressionTest { public void testSimpleExpressions() { - boolean old = this.enablePreview; - try { - this.enablePreview = true; - runConformTest( - new String[] { + 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"); - } finally { - this.enablePreview = old; - } + " 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() { - boolean old = this.enablePreview; - try { - this.enablePreview = true; - runConformTest( - new String[] { + runConformTest( + new String[] { "X.java", "public class X {\n"+ " static int twice(int i) throws Exception {\n"+ @@ -109,11 +102,10 @@ public class SwitchExpressionTest extends AbstractRegressionTest { " }\n"+ " }\n"+ "}\n" - }, - "Got Exception"); - } finally { - this.enablePreview = old; - } + }, + "Got Exception", + null, + new String[] {"--enable-preview"}); } public void testBug531714_error_003() { this.runNegativeTest( @@ -245,36 +237,32 @@ public class SwitchExpressionTest extends AbstractRegressionTest { * dev note: ref consumeToken().case Switch */ public void testBug531714_error_007() { - boolean old = this.enablePreview; - try { - this.enablePreview = true; - runConformTest( - new String[] { + 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"); - } finally { - this.enablePreview = old; - } + " 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(); @@ -430,37 +418,32 @@ public class SwitchExpressionTest extends AbstractRegressionTest { options); } public void testBug531714_011() { - boolean old = this.enablePreview; - try { - Map<String, String> options = getCompilerOptions(); - options.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED); - options.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.WARNING); - this.enablePreview = true; - 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", - }; + 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 = - "0"; - this.runConformTest( - testFiles, - expectedProblemLog, - options); - } finally { - this.enablePreview = old; - } + String expectedProblemLog = + "0"; + this.runConformTest( + testFiles, + expectedProblemLog, + options, + new String[] {"--enable-preview"}); } public void testBug531714_012() { Map<String, String> options = getCompilerOptions(); @@ -529,4 +512,618 @@ public class SwitchExpressionTest extends AbstractRegressionTest { 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); + } }
\ No newline at end of file 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 849f870daa..5c41e1144b 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 @@ -17,6 +17,9 @@ *******************************************************************************/ 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; @@ -25,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; @@ -49,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; } @@ -108,7 +122,7 @@ public void resolve(BlockScope scope) { * 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 @@ -119,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() && (this.constantExpression 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); @@ -148,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; @@ -161,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/Statement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Statement.java index bcafc9bd08..e7605c23ce 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 @@ -447,10 +447,10 @@ 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 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 c3e40cad0b..d21237a1b8 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 @@ -59,6 +59,7 @@ public class SwitchStatement extends Expression { public int blockStart; public int caseCount; int[] constants; + int[] constMapping; String[] stringConstants; public boolean switchLabeledRules = false; // true if case ->, false if case : @@ -212,33 +213,60 @@ public class SwitchStatement extends Expression { "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); } @@ -265,7 +293,7 @@ public class SwitchStatement extends Expression { 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; @@ -352,6 +380,7 @@ public class SwitchStatement extends Expression { // 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)); @@ -384,18 +413,18 @@ public class SwitchStatement extends Expression { } // 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 @@ -409,6 +438,7 @@ public class SwitchStatement extends Expression { max, this.constants, sortedIndexes, + this.constMapping, caseLabels); } } else { @@ -424,7 +454,7 @@ public class SwitchStatement extends Expression { 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); @@ -535,32 +565,52 @@ public class SwitchStatement extends Expression { 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 constant1; + Constant[] constantsList; final Statement statement = this.statements[i]; - if ((constant1 = statement.resolveCase(this.scope, expressionType, this)) != Constant.NotAConstant) { - if (!isStringSwitch) { - int key = constant1.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 = constant1.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; } } } @@ -570,6 +620,7 @@ public class SwitchStatement extends Expression { } 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) { @@ -591,14 +642,14 @@ public class SwitchStatement extends Expression { 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; } 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 cba674ab74..a3b5793bd9 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 @@ -6895,7 +6895,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 +6926,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/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/problem/messages.properties b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties index 6201a1918a..37a77dfcf5 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 @@ -976,7 +976,7 @@ # Switch-Expressions 1600 = Incompatible switch results expressions {0} 1601 = A switch expression should have a non-empty switch block -1602 = A switch expression {0} should have at least one result expression +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. |