diff options
author | Jay Arthanareeswaran | 2019-02-07 14:04:16 +0000 |
---|---|---|
committer | Jay Arthanareeswaran | 2019-02-08 07:02:18 +0000 |
commit | 818d36828a5ccc4ac75608bef6bd668c71a80f29 (patch) | |
tree | b7717e59ebdd313fc56cc221a2e4a21fa8a25eaa | |
parent | 5caa7124524696e2178c69f4a02c9e034d1bdbda (diff) | |
download | eclipse.jdt.core-818d36828a5ccc4ac75608bef6bd668c71a80f29.tar.gz eclipse.jdt.core-818d36828a5ccc4ac75608bef6bd668c71a80f29.tar.xz eclipse.jdt.core-818d36828a5ccc4ac75608bef6bd668c71a80f29.zip |
Bug 542561 - [12][select] Selection Support for Switch Expressions
Change-Id: Ia84d843fc2f8a9a311c886d4edad9a94dbab85a8
Signed-off-by: Jay Arthanareeswaran <jarthana@in.ibm.com>
9 files changed, 1797 insertions, 5 deletions
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 067fbe8b6b..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 @@ -193,6 +195,8 @@ public static TestSuite getTestSuite(boolean addComplianceDiagnoseTest) { 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 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 c975dca270..9124a849a4 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 @@ -1214,6 +1214,96 @@ public class SwitchExpressionTest extends AbstractRegressionTest { 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[] { diff --git a/org.eclipse.jdt.core.tests.model/JCL/jclMin12.jar b/org.eclipse.jdt.core.tests.model/JCL/jclMin12.jar Binary files differindex 6f2af93c90..0f621d1524 100644 --- a/org.eclipse.jdt.core.tests.model/JCL/jclMin12.jar +++ 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 differindex 37447f944f..bf05b46301 100644 --- a/org.eclipse.jdt.core.tests.model/JCL/jclMin12src.zip +++ b/org.eclipse.jdt.core.tests.model/JCL/jclMin12src.zip 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/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/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionParser.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionParser.java index 6f0892a5cd..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 @@ -1256,6 +1256,17 @@ protected void consumeToken(int token) { case TokenNamecase : 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; 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 5c41e1144b..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, 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 @@ -148,7 +148,7 @@ public Constant[] resolveCase(BlockScope scope, TypeBinding switchExpressionType List<Constant> cases = new ArrayList<>(); for (Expression e : this.constantExpressions) { if (e != this.constantExpression) { - if (switchExpressionType.isEnum() && (this.constantExpression instanceof SingleNameReference)) { + if (switchExpressionType.isEnum() && (e instanceof SingleNameReference)) { ((SingleNameReference) e).setActualReceiverType((ReferenceBinding)switchExpressionType); } e.resolveType(scope); |