You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@netbeans.apache.org by ak...@apache.org on 2021/09/15 09:03:02 UTC
[netbeans] branch master updated: [NETBEANS-5799] : Add support for
Pattern Matching for switch (Preview) (#3007)
This is an automated email from the ASF dual-hosted git repository.
akhileshsingh pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/netbeans.git
The following commit(s) were added to refs/heads/master by this push:
new c5cc187 [NETBEANS-5799] : Add support for Pattern Matching for switch (Preview) (#3007)
c5cc187 is described below
commit c5cc187caab00cb1f8a4fb265b329ccd8c31d0c9
Author: Akhilesh Singh <ak...@oracle.com>
AuthorDate: Wed Sep 15 14:32:42 2021 +0530
[NETBEANS-5799] : Add support for Pattern Matching for switch (Preview) (#3007)
* [NETBEANS-5799] : Added support for code completion, formatting, hints(partial), variable name suggestion and semantic highlighting.
---
.../netbeans/modules/java/completion/BaseTask.java | 1 +
.../java/completion/JavaCompletionTask.java | 10 +-
...MembersSelect_GuardedPatternMatchingSwitch.pass | 15 +
...mbersSelect_GuardedPatternMatchingSwitch_1.pass | 9 +
...mbersSelect_GuardedPatternMatchingSwitch_2.pass | 51 +
...sSelect_ParenthesizedPatternMatchingSwitch.pass | 40 +
...elect_ParenthesizedPatternMatchingSwitch_1.pass | 62 ++
...on_VarNameSuggestion_PatternMatchingSwitch.pass | 2 +
.../completion/data/SwitchPatternMatching.java} | 31 +-
.../JavaCompletionTask117FeaturesTest.java | 116 +++
.../base/semantic/SemanticHighlighterBase.java | 2 +-
.../java/editor/base/semantic/DetectorTest.java | 40 +
.../jdk/ConvertToSwitchPatternInstanceOf.java | 187 ++++
.../jdk/ConvertToSwitchPatternInstanceOfTest.java | 78 ++
.../org/netbeans/api/java/source/TreeMaker.java | 24 +
.../source/support/ErrorAwareTreePathScanner.java | 7 +
.../java/source/support/ErrorAwareTreeScanner.java | 7 +
.../netbeans/modules/java/source/TreeShims.java | 62 ++
.../modules/java/source/builder/TreeFactory.java | 29 +
.../modules/java/source/pretty/VeryPretty.java | 30 +-
.../modules/java/source/save/CasualDiff.java | 8 +
.../modules/java/source/save/Reformatter.java | 102 +-
.../modules/java/source/save/FormatingTest.java | 1013 ++++++++++++++++++++
23 files changed, 1895 insertions(+), 31 deletions(-)
diff --git a/java/java.completion/src/org/netbeans/modules/java/completion/BaseTask.java b/java/java.completion/src/org/netbeans/modules/java/completion/BaseTask.java
index 74994da..a08521d 100644
--- a/java/java.completion/src/org/netbeans/modules/java/completion/BaseTask.java
+++ b/java/java.completion/src/org/netbeans/modules/java/completion/BaseTask.java
@@ -631,6 +631,7 @@ abstract class BaseTask extends UserTask {
return null;
}
+
}
private static boolean isCamelCasePrefix(String prefix) {
diff --git a/java/java.completion/src/org/netbeans/modules/java/completion/JavaCompletionTask.java b/java/java.completion/src/org/netbeans/modules/java/completion/JavaCompletionTask.java
index 43acc01..2e8db5f 100644
--- a/java/java.completion/src/org/netbeans/modules/java/completion/JavaCompletionTask.java
+++ b/java/java.completion/src/org/netbeans/modules/java/completion/JavaCompletionTask.java
@@ -2493,7 +2493,15 @@ public final class JavaCompletionTask<T> extends BaseTask {
}
} else {
TokenSequence<JavaTokenId> ts = findLastNonWhitespaceToken(env, cst, offset);
- if (ts != null && ts.token().id() != JavaTokenId.DEFAULT) {
+ if (ts != null && ts.token().id() == JavaTokenId.IDENTIFIER) {
+ for (ExpressionTree caseExpression : caseTreeList) {
+ if (caseExpression != null && caseExpression.getKind() == Tree.Kind.IDENTIFIER) {
+ TreePath tPath = new TreePath(path, caseExpression);
+ insideExpression(env, tPath);
+ return;
+ }
+ }
+ } else if (ts != null && ts.token().id() != JavaTokenId.DEFAULT) {
localResult(env);
addKeywordsForBlock(env);
}
diff --git a/java/java.completion/test/unit/data/goldenfiles/org/netbeans/modules/java/completion/JavaCompletionTaskTest/17/AutoCompletion_MembersSelect_GuardedPatternMatchingSwitch.pass b/java/java.completion/test/unit/data/goldenfiles/org/netbeans/modules/java/completion/JavaCompletionTaskTest/17/AutoCompletion_MembersSelect_GuardedPatternMatchingSwitch.pass
new file mode 100644
index 0000000..bb9bd18
--- /dev/null
+++ b/java/java.completion/test/unit/data/goldenfiles/org/netbeans/modules/java/completion/JavaCompletionTaskTest/17/AutoCompletion_MembersSelect_GuardedPatternMatchingSwitch.pass
@@ -0,0 +1,15 @@
+public abstract char charAt(int arg0)
+public default IntStream chars()
+public default IntStream codePoints()
+public boolean equals(Object arg0)
+public final native Class<?> getClass()
+public native int hashCode()
+public default boolean isEmpty()
+public abstract int length()
+public final native void notify()
+public final native void notifyAll()
+public abstract CharSequence subSequence(int arg0, int arg1)
+public abstract String toString()
+public final void wait()
+public final native void wait(long arg0)
+public final void wait(long arg0, int arg1)
diff --git a/java/java.completion/test/unit/data/goldenfiles/org/netbeans/modules/java/completion/JavaCompletionTaskTest/17/AutoCompletion_MembersSelect_GuardedPatternMatchingSwitch_1.pass b/java/java.completion/test/unit/data/goldenfiles/org/netbeans/modules/java/completion/JavaCompletionTaskTest/17/AutoCompletion_MembersSelect_GuardedPatternMatchingSwitch_1.pass
new file mode 100644
index 0000000..9200f72
--- /dev/null
+++ b/java/java.completion/test/unit/data/goldenfiles/org/netbeans/modules/java/completion/JavaCompletionTaskTest/17/AutoCompletion_MembersSelect_GuardedPatternMatchingSwitch_1.pass
@@ -0,0 +1,9 @@
+public boolean equals(Object arg0)
+public final native Class<?> getClass()
+public native int hashCode()
+public final native void notify()
+public final native void notifyAll()
+public String toString()
+public final void wait()
+public final native void wait(long arg0)
+public final void wait(long arg0, int arg1)
\ No newline at end of file
diff --git a/java/java.completion/test/unit/data/goldenfiles/org/netbeans/modules/java/completion/JavaCompletionTaskTest/17/AutoCompletion_MembersSelect_GuardedPatternMatchingSwitch_2.pass b/java/java.completion/test/unit/data/goldenfiles/org/netbeans/modules/java/completion/JavaCompletionTaskTest/17/AutoCompletion_MembersSelect_GuardedPatternMatchingSwitch_2.pass
new file mode 100644
index 0000000..f29c24e
--- /dev/null
+++ b/java/java.completion/test/unit/data/goldenfiles/org/netbeans/modules/java/completion/JavaCompletionTaskTest/17/AutoCompletion_MembersSelect_GuardedPatternMatchingSwitch_2.pass
@@ -0,0 +1,51 @@
+public abstract boolean allMatch(IntPredicate arg0)
+public abstract boolean anyMatch(IntPredicate arg0)
+public abstract R collect(Supplier<R> arg0, ObjIntConsumer<R> arg1, BiConsumer<R, R> arg2)
+public boolean equals(Object arg0)
+public abstract boolean isParallel()
+public abstract boolean noneMatch(IntPredicate arg0)
+public abstract DoubleStream asDoubleStream()
+public abstract LongStream asLongStream()
+public abstract OptionalDouble average()
+public abstract Stream<Integer> boxed()
+public abstract void close()
+public abstract long count()
+public abstract IntStream distinct()
+public default IntStream dropWhile(IntPredicate arg0)
+public abstract IntStream filter(IntPredicate arg0)
+public abstract OptionalInt findAny()
+public abstract OptionalInt findFirst()
+public abstract IntStream flatMap(IntFunction<? extends IntStream> arg0)
+public abstract void forEach(IntConsumer arg0)
+public abstract void forEachOrdered(IntConsumer arg0)
+public final native Class<?> getClass()
+public native int hashCode()
+public abstract OfInt iterator()
+public abstract IntStream limit(long arg0)
+public abstract IntStream map(IntUnaryOperator arg0)
+public default IntStream mapMulti(IntMapMultiConsumer arg0)
+public abstract DoubleStream mapToDouble(IntToDoubleFunction arg0)
+public abstract LongStream mapToLong(IntToLongFunction arg0)
+public abstract Stream<U> mapToObj(IntFunction<? extends U> arg0)
+public abstract OptionalInt max()
+public abstract OptionalInt min()
+public final native void notify()
+public final native void notifyAll()
+public abstract IntStream onClose(Runnable arg0)
+public abstract IntStream parallel()
+public abstract IntStream peek(IntConsumer arg0)
+public abstract OptionalInt reduce(IntBinaryOperator arg0)
+public abstract int reduce(int arg0, IntBinaryOperator arg1)
+public abstract IntStream sequential()
+public abstract IntStream skip(long arg0)
+public abstract IntStream sorted()
+public abstract OfInt spliterator()
+public abstract int sum()
+public abstract IntSummaryStatistics summaryStatistics()
+public default IntStream takeWhile(IntPredicate arg0)
+public abstract int[] toArray()
+public String toString()
+public abstract IntStream unordered()
+public final void wait()
+public final native void wait(long arg0)
+public final void wait(long arg0, int arg1)
diff --git a/java/java.completion/test/unit/data/goldenfiles/org/netbeans/modules/java/completion/JavaCompletionTaskTest/17/AutoCompletion_MembersSelect_ParenthesizedPatternMatchingSwitch.pass b/java/java.completion/test/unit/data/goldenfiles/org/netbeans/modules/java/completion/JavaCompletionTaskTest/17/AutoCompletion_MembersSelect_ParenthesizedPatternMatchingSwitch.pass
new file mode 100644
index 0000000..10c56d9
--- /dev/null
+++ b/java/java.completion/test/unit/data/goldenfiles/org/netbeans/modules/java/completion/JavaCompletionTaskTest/17/AutoCompletion_MembersSelect_ParenthesizedPatternMatchingSwitch.pass
@@ -0,0 +1,40 @@
+public abstract boolean add(Object arg0)
+public abstract void add(int arg0, Object arg1)
+public abstract boolean addAll(Collection arg0)
+public abstract boolean addAll(int arg0, Collection arg1)
+public abstract void clear()
+public abstract boolean contains(Object arg0)
+public abstract boolean containsAll(Collection arg0)
+public abstract boolean equals(Object arg0)
+public default void forEach(Consumer arg0)
+public abstract Object get(int arg0)
+public final native Class<?> getClass()
+public abstract int hashCode()
+public abstract int indexOf(Object arg0)
+public abstract boolean isEmpty()
+public abstract Iterator iterator()
+public abstract int lastIndexOf(Object arg0)
+public abstract ListIterator listIterator()
+public abstract ListIterator listIterator(int arg0)
+public final native void notify()
+public final native void notifyAll()
+public default Stream parallelStream()
+public abstract boolean remove(Object arg0)
+public abstract Object remove(int arg0)
+public abstract boolean removeAll(Collection arg0)
+public default boolean removeIf(Predicate arg0)
+public default void replaceAll(UnaryOperator arg0)
+public abstract boolean retainAll(Collection arg0)
+public abstract Object set(int arg0, Object arg1)
+public abstract int size()
+public default void sort(Comparator arg0)
+public default Spliterator spliterator()
+public default Stream stream()
+public abstract List subList(int arg0, int arg1)
+public abstract Object[] toArray()
+public default Object[] toArray(IntFunction arg0)
+public abstract Object[] toArray(Object[] arg0)
+public String toString()
+public final void wait()
+public final native void wait(long arg0)
+public final void wait(long arg0, int arg1)
\ No newline at end of file
diff --git a/java/java.completion/test/unit/data/goldenfiles/org/netbeans/modules/java/completion/JavaCompletionTaskTest/17/AutoCompletion_MembersSelect_ParenthesizedPatternMatchingSwitch_1.pass b/java/java.completion/test/unit/data/goldenfiles/org/netbeans/modules/java/completion/JavaCompletionTaskTest/17/AutoCompletion_MembersSelect_ParenthesizedPatternMatchingSwitch_1.pass
new file mode 100644
index 0000000..80d9da2
--- /dev/null
+++ b/java/java.completion/test/unit/data/goldenfiles/org/netbeans/modules/java/completion/JavaCompletionTaskTest/17/AutoCompletion_MembersSelect_ParenthesizedPatternMatchingSwitch_1.pass
@@ -0,0 +1,62 @@
+public boolean equals(Object arg0)
+public default boolean isEmpty()
+public StringBuilder append(CharSequence arg0)
+public StringBuilder append(Object arg0)
+public StringBuilder append(String arg0)
+public StringBuilder append(StringBuffer arg0)
+public StringBuilder append(boolean arg0)
+public StringBuilder append(char arg0)
+public StringBuilder append(char[] arg0)
+public StringBuilder append(double arg0)
+public StringBuilder append(float arg0)
+public StringBuilder append(int arg0)
+public StringBuilder append(long arg0)
+public StringBuilder append(CharSequence arg0, int arg1, int arg2)
+public StringBuilder append(char[] arg0, int arg1, int arg2)
+public StringBuilder appendCodePoint(int arg0)
+public int capacity()
+public char charAt(int arg0)
+public IntStream chars()
+public int codePointAt(int arg0)
+public int codePointBefore(int arg0)
+public int codePointCount(int arg0, int arg1)
+public IntStream codePoints()
+public int compareTo(StringBuilder arg0)
+public StringBuilder delete(int arg0, int arg1)
+public StringBuilder deleteCharAt(int arg0)
+public void ensureCapacity(int arg0)
+public void getChars(int arg0, int arg1, char[] arg2, int arg3)
+public final native Class<?> getClass()
+public native int hashCode()
+public int indexOf(String arg0)
+public int indexOf(String arg0, int arg1)
+public StringBuilder insert(int arg0, CharSequence arg1)
+public StringBuilder insert(int arg0, Object arg1)
+public StringBuilder insert(int arg0, String arg1)
+public StringBuilder insert(int arg0, boolean arg1)
+public StringBuilder insert(int arg0, char arg1)
+public StringBuilder insert(int arg0, char[] arg1)
+public StringBuilder insert(int arg0, double arg1)
+public StringBuilder insert(int arg0, float arg1)
+public StringBuilder insert(int arg0, int arg1)
+public StringBuilder insert(int arg0, long arg1)
+public StringBuilder insert(int arg0, CharSequence arg1, int arg2, int arg3)
+public StringBuilder insert(int arg0, char[] arg1, int arg2, int arg3)
+public int lastIndexOf(String arg0)
+public int lastIndexOf(String arg0, int arg1)
+public int length()
+public final native void notify()
+public final native void notifyAll()
+public int offsetByCodePoints(int arg0, int arg1)
+public StringBuilder replace(int arg0, int arg1, String arg2)
+public StringBuilder reverse()
+public void setCharAt(int arg0, char arg1)
+public void setLength(int arg0)
+public CharSequence subSequence(int arg0, int arg1)
+public String substring(int arg0)
+public String substring(int arg0, int arg1)
+public String toString()
+public void trimToSize()
+public final void wait()
+public final native void wait(long arg0)
+public final void wait(long arg0, int arg1)
diff --git a/java/java.completion/test/unit/data/goldenfiles/org/netbeans/modules/java/completion/JavaCompletionTaskTest/17/AutoCompletion_VarNameSuggestion_PatternMatchingSwitch.pass b/java/java.completion/test/unit/data/goldenfiles/org/netbeans/modules/java/completion/JavaCompletionTaskTest/17/AutoCompletion_VarNameSuggestion_PatternMatchingSwitch.pass
new file mode 100644
index 0000000..d5fbcfc
--- /dev/null
+++ b/java/java.completion/test/unit/data/goldenfiles/org/netbeans/modules/java/completion/JavaCompletionTaskTest/17/AutoCompletion_VarNameSuggestion_PatternMatchingSwitch.pass
@@ -0,0 +1,2 @@
+s
+string
\ No newline at end of file
diff --git a/java/java.source.base/src/org/netbeans/api/java/source/support/ErrorAwareTreePathScanner.java b/java/java.completion/test/unit/data/org/netbeans/modules/java/completion/data/SwitchPatternMatching.java
similarity index 60%
copy from java/java.source.base/src/org/netbeans/api/java/source/support/ErrorAwareTreePathScanner.java
copy to java/java.completion/test/unit/data/org/netbeans/modules/java/completion/data/SwitchPatternMatching.java
index a04e544..82cc419 100644
--- a/java/java.source.base/src/org/netbeans/api/java/source/support/ErrorAwareTreePathScanner.java
+++ b/java/java.completion/test/unit/data/org/netbeans/modules/java/completion/data/SwitchPatternMatching.java
@@ -1,4 +1,4 @@
-/**
+/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
@@ -16,20 +16,23 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.netbeans.api.java.source.support;
-import com.sun.source.tree.ErroneousTree;
-import com.sun.source.util.TreePathScanner;
+package test;
-/**
- *
- * @author Jan Lahoda
- */
-public class ErrorAwareTreePathScanner<R,P> extends TreePathScanner<R,P> {
+import java.util.stream.IntStream;
- @Override
- public R visitErroneous(ErroneousTree et, P p) {
- return scan(et.getErrorTrees(), p);
+public class Test{
+
+ public void op(int a) {
+ Object obj = "test";
+ String result = switch (obj) {
+ case null, String ->
+ "null & String";
+ case CharSequence s && s. && obj. && IntStream.of(1).max().->
+ "CharSequence";
+ case (java.util.List list && list. && new StringBuilder().ERROR. && java.util.ArrayList<String>.)->"list";
+ default ->
+ "default";
+ };
}
-
-}
+}
diff --git a/java/java.completion/test/unit/src/org/netbeans/modules/java/completion/JavaCompletionTask117FeaturesTest.java b/java/java.completion/test/unit/src/org/netbeans/modules/java/completion/JavaCompletionTask117FeaturesTest.java
new file mode 100644
index 0000000..436110d
--- /dev/null
+++ b/java/java.completion/test/unit/src/org/netbeans/modules/java/completion/JavaCompletionTask117FeaturesTest.java
@@ -0,0 +1,116 @@
+package org.netbeans.modules.java.completion;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.lang.model.SourceVersion;
+import javax.swing.event.ChangeListener;
+import org.netbeans.junit.NbTestSuite;
+import org.netbeans.modules.java.source.parsing.JavacParser;
+import org.netbeans.spi.java.queries.CompilerOptionsQueryImplementation;
+import org.openide.filesystems.FileObject;
+import org.openide.util.lookup.ServiceProvider;
+/**
+ *
+ * @author aksinsin
+ */
+public class JavaCompletionTask117FeaturesTest extends CompletionTestBase {
+
+ private static String SOURCE_LEVEL = "17"; //NOI18N
+
+ public JavaCompletionTask117FeaturesTest(String testName) {
+ super(testName);
+ }
+
+ public static NbTestSuite suite() {
+ NbTestSuite suite = new NbTestSuite();
+ try {
+ SourceVersion.valueOf("RELEASE_17"); //NOI18N
+ suite.addTestSuite(JavaCompletionTask117FeaturesTest.class);
+ } catch (IllegalArgumentException ex) {
+ //OK, no RELEASE_13, skip tests
+ suite.addTest(new JavaCompletionTask117FeaturesTest("noop")); //NOI18N
+ }
+ return suite;
+ }
+
+
+ public void testVariableNameSuggestion() throws Exception {
+ TestCompilerOptionsQueryImplementation.EXTRA_OPTIONS.add("--enable-preview");
+ performTest("SwitchPatternMatching", 1011, null, "AutoCompletion_VarNameSuggestion_PatternMatchingSwitch.pass", getLatestSource());
+ }
+
+ public void testClassMembersAutoCompletion_GuardedPattern() throws Exception {
+ TestCompilerOptionsQueryImplementation.EXTRA_OPTIONS.add("--enable-preview");
+ performTest("SwitchPatternMatching", 1085, null, "AutoCompletion_MembersSelect_GuardedPatternMatchingSwitch.pass", getLatestSource());
+ }
+
+ public void testClassMembersAutoCompletion_GuardedPattern_1() throws Exception {
+ TestCompilerOptionsQueryImplementation.EXTRA_OPTIONS.add("--enable-preview");
+ performTest("SwitchPatternMatching", 1093, null, "AutoCompletion_MembersSelect_GuardedPatternMatchingSwitch_1.pass", getLatestSource());
+ }
+ public void testClassMembersAutoCompletion_GuardedPattern_2() throws Exception {
+ TestCompilerOptionsQueryImplementation.EXTRA_OPTIONS.add("--enable-preview");
+ performTest("SwitchPatternMatching", 1113, null, "AutoCompletion_MembersSelect_GuardedPatternMatchingSwitch_2.pass", getLatestSource());
+ }
+ public void testClassMembersAutoCompletion_ParanthesizedPattern() throws Exception {
+ TestCompilerOptionsQueryImplementation.EXTRA_OPTIONS.add("--enable-preview");
+ performTest("SwitchPatternMatching", 1200, null, "AutoCompletion_MembersSelect_ParenthesizedPatternMatchingSwitch.pass", getLatestSource());
+ }
+ public void testClassMembersAutoCompletion_ParanthesizedPattern_1() throws Exception {
+ TestCompilerOptionsQueryImplementation.EXTRA_OPTIONS.add("--enable-preview");
+ performTest("SwitchPatternMatching", 1224, null, "AutoCompletion_MembersSelect_ParenthesizedPatternMatchingSwitch_1.pass", getLatestSource());
+ }
+ public void noop() {
+ }
+
+ static {
+ JavacParser.DISABLE_SOURCE_LEVEL_DOWNGRADE = true;
+ }
+
+ private String getLatestSource(){
+ return SourceVersion.latest().name().substring(SourceVersion.latest().name().indexOf("_")+1);
+ }
+
+ @ServiceProvider(service = CompilerOptionsQueryImplementation.class, position = 100)
+ public static class TestCompilerOptionsQueryImplementation implements CompilerOptionsQueryImplementation {
+ private static final List<String> EXTRA_OPTIONS = new ArrayList<>();
+
+ @Override
+ public CompilerOptionsQueryImplementation.Result getOptions(FileObject file) {
+ return new CompilerOptionsQueryImplementation.Result() {
+ @Override
+ public List<? extends String> getArguments() {
+ return EXTRA_OPTIONS;
+ }
+
+ @Override
+ public void addChangeListener(ChangeListener listener) {
+ }
+
+ @Override
+ public void removeChangeListener(ChangeListener listener) {
+ }
+ };
+ }
+
+ }
+}
diff --git a/java/java.editor.base/src/org/netbeans/modules/java/editor/base/semantic/SemanticHighlighterBase.java b/java/java.editor.base/src/org/netbeans/modules/java/editor/base/semantic/SemanticHighlighterBase.java
index f235ffc..bc7c078 100644
--- a/java/java.editor.base/src/org/netbeans/modules/java/editor/base/semantic/SemanticHighlighterBase.java
+++ b/java/java.editor.base/src/org/netbeans/modules/java/editor/base/semantic/SemanticHighlighterBase.java
@@ -1015,7 +1015,7 @@ public abstract class SemanticHighlighterBase extends JavaParserResultTask {
}
return super.scan(tree, p);
}
-
+
private void visitModifier(Tree tree) {
tl.moveToOffset(sourcePositions.getStartPosition(info.getCompilationUnit(), tree));
Token t = null;
diff --git a/java/java.editor.base/test/unit/src/org/netbeans/modules/java/editor/base/semantic/DetectorTest.java b/java/java.editor.base/test/unit/src/org/netbeans/modules/java/editor/base/semantic/DetectorTest.java
index 33f4553..4a00265 100644
--- a/java/java.editor.base/test/unit/src/org/netbeans/modules/java/editor/base/semantic/DetectorTest.java
+++ b/java/java.editor.base/test/unit/src/org/netbeans/modules/java/editor/base/semantic/DetectorTest.java
@@ -615,6 +615,46 @@ public class DetectorTest extends TestBase {
"[PACKAGE_PRIVATE, CLASS, DECLARATION], 1:17-1:22",
"[PACKAGE_PRIVATE, CLASS], 1:31-1:35");
}
+
+ public void testSwitchPattern() throws Exception {
+ try {
+ SourceVersion.valueOf("RELEASE_17"); //NOI18N
+ } catch (IllegalArgumentException ex) {
+ //OK, no RELEASE_17, skip tests
+ return;
+ }
+ enablePreview();
+ performTest("TestSwitchPattern.java",
+ "public class TestSwitchPattern {\n"
+ + " String strColor = \"color\";\n"
+ + " void m1() {\n"
+ + " Object obj = \"test\";\n"
+ + " switch (obj) {\n"
+ + " case String s && s.equals(strColor) -> System.out.println(\"same\");\n"
+ + " case default -> System.out.println(\"default\");\n"
+ + " }\n"
+ + " }\n"
+ + "}",
+ "[PUBLIC, CLASS, DECLARATION], 0:13-0:30\n"
+ + "[PUBLIC, CLASS], 1:4-1:10\n"
+ + "[PACKAGE_PRIVATE, FIELD, DECLARATION], 1:11-1:19\n"
+ + "[PACKAGE_PRIVATE, METHOD, DECLARATION], 2:9-2:11\n"
+ + "[PUBLIC, CLASS], 3:8-3:14\n"
+ + "[LOCAL_VARIABLE, DECLARATION], 3:15-3:18\n"
+ + "[LOCAL_VARIABLE], 4:16-4:19\n"
+ + "[PUBLIC, CLASS], 5:17-5:23\n"
+ + "[LOCAL_VARIABLE, DECLARATION], 5:24-5:25\n"
+ + "[LOCAL_VARIABLE], 5:29-5:30\n"
+ + "[PUBLIC, METHOD], 5:31-5:37\n"
+ + "[PACKAGE_PRIVATE, FIELD], 5:38-5:46\n"
+ + "[PUBLIC, CLASS], 5:51-5:57\n"
+ + "[STATIC, PUBLIC, FIELD], 5:58-5:61\n"
+ + "[PUBLIC, METHOD], 5:62-5:69\n"
+ + "[PUBLIC, CLASS], 6:28-6:34\n"
+ + "[STATIC, PUBLIC, FIELD], 6:35-6:38\n"
+ + "[PUBLIC, METHOD], 6:39-6:46\n");
+ }
+
public void testYield() throws Exception {
enablePreview();
performTest("YieldTest.java",
diff --git a/java/java.hints/src/org/netbeans/modules/java/hints/jdk/ConvertToSwitchPatternInstanceOf.java b/java/java.hints/src/org/netbeans/modules/java/hints/jdk/ConvertToSwitchPatternInstanceOf.java
new file mode 100644
index 0000000..85e22bd
--- /dev/null
+++ b/java/java.hints/src/org/netbeans/modules/java/hints/jdk/ConvertToSwitchPatternInstanceOf.java
@@ -0,0 +1,187 @@
+package org.netbeans.modules.java.hints.jdk;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import com.sun.source.tree.BlockTree;
+import com.sun.source.tree.CaseTree;
+import com.sun.source.tree.ExpressionStatementTree;
+import com.sun.source.tree.IdentifierTree;
+import com.sun.source.tree.IfTree;
+import com.sun.source.tree.InstanceOfTree;
+import com.sun.source.tree.ParenthesizedTree;
+import com.sun.source.tree.StatementTree;
+import com.sun.source.tree.SwitchTree;
+import com.sun.source.tree.ThrowTree;
+import com.sun.source.tree.Tree;
+import com.sun.source.tree.VariableTree;
+import com.sun.source.util.TreePath;
+import com.sun.tools.javac.tree.JCTree;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.Name;
+import javax.lang.model.type.TypeMirror;
+import org.netbeans.api.java.source.CompilationInfo;
+import org.netbeans.api.java.source.TreeMaker;
+import org.netbeans.api.java.source.WorkingCopy;
+import org.netbeans.spi.editor.hints.ErrorDescription;
+import org.netbeans.spi.editor.hints.Fix;
+import org.netbeans.spi.java.hints.ErrorDescriptionFactory;
+import org.netbeans.spi.java.hints.Hint;
+import org.netbeans.spi.java.hints.HintContext;
+import org.netbeans.spi.java.hints.JavaFix;
+import org.netbeans.spi.java.hints.MatcherUtilities;
+import org.netbeans.spi.java.hints.TriggerPattern;
+import org.netbeans.spi.java.hints.TriggerPatterns;
+import org.netbeans.spi.java.hints.TriggerTreeKind;
+import org.openide.util.Exceptions;
+import org.openide.util.NbBundle;
+
+/**
+ *
+ * @author aksinsin
+ */
+@NbBundle.Messages({
+ "DN_ConvertToSwitchPatternInstanceOf=Convert to switch pattern matching <pattern>",
+ "DESC_ConvertToSwitchPatternInstanceOf=Convert to switch pattern matching <pattern>",
+ "ERR_ConvertToSwitchPatternInstanceOf=switch pattern matching <pattern> can be used here",
+ "FIX_ConvertToSwitchPatternInstanceOf=Use switch pattern matching <pattern>"
+})
+@Hint(displayName="#DN_ConvertToSwitchPatternInstanceOf", description="#DESC_ConvertToSwitchPatternInstanceOf", category="rules15",
+ minSourceVersion = "17")
+public class ConvertToSwitchPatternInstanceOf {
+
+ @TriggerPatterns({
+ @TriggerPattern(value = "if ($expr0 instanceof $typeI0) { $statements0$;} else if ($expr1 instanceof $typeI1) { $statements1$;} else $else$;")
+ })
+ public static ErrorDescription trivial(HintContext ctx) {
+ TreePath parent = ctx.getPath().getParentPath();
+ if (parent.getLeaf().getKind() == Tree.Kind.IF) {
+ return null;
+ }
+ Tree ifPath = ctx.getPath().getLeaf();
+ Name expr0 = ((IdentifierTree) ctx.getVariables().get("$expr0").getLeaf()).getName();
+ int matchVarIndex = 1;
+ while (ifPath != null && ifPath.getKind() == Tree.Kind.IF) {
+ matchVarIndex++;
+ IfTree it = (IfTree) ifPath;
+ if (MatcherUtilities.matches(ctx, new TreePath(ctx.getPath(), it.getCondition()), "($expr" + matchVarIndex + " instanceof $typeI" + matchVarIndex + ")", true)
+ && MatcherUtilities.matches(ctx, new TreePath(ctx.getPath(), it.getThenStatement()), "{ $typeV" + matchVarIndex + " $var" + matchVarIndex + " = ($typeC" + matchVarIndex + ") $expr" + matchVarIndex + "; $other" + matchVarIndex + "$;}", true)) {
+ if (!((IdentifierTree) ctx.getVariables().get("$expr" + matchVarIndex).getLeaf()).getName().equals(expr0)) {
+ return null;
+ }
+ for (TreePath tp : ctx.getMultiVariables().get("$other" + matchVarIndex + "$")) {
+ if (tp.getLeaf().getKind() == Tree.Kind.BREAK || tp.getLeaf().getKind() == Tree.Kind.CONTINUE) {
+ return null;
+ }
+ }
+ TypeMirror typeI = ctx.getInfo().getTrees().getTypeMirror(ctx.getVariables().get("$typeI" + matchVarIndex + ""));
+ TypeMirror typeC = ctx.getInfo().getTrees().getTypeMirror(ctx.getVariables().get("$typeC" + matchVarIndex + ""));
+ if (!ctx.getInfo().getTypes().isSameType(typeI, typeC)) {
+ System.err.println("different types (" + typeI + ", " + typeC + ") in " + ctx.getInfo().getFileObject());
+ return null;
+ }
+ } else {
+ return null;
+ }
+ ifPath = it.getElseStatement();
+ }
+ if (ifPath != null && ifPath.getKind() == Tree.Kind.BLOCK) {
+ Fix fix = new FixImpl(ctx.getInfo(), ctx.getPath(), true, Collections.emptySet()).toEditorFix();
+ return ErrorDescriptionFactory.forName(ctx, ctx.getPath(), Bundle.ERR_ConvertToSwitchPatternInstanceOf(), fix);
+ } else {
+ return null;
+ }
+
+ }
+
+ private static final class FixImpl extends JavaFix {
+
+ private final boolean removeFirst;
+
+ public FixImpl(CompilationInfo info, TreePath main, boolean removeFirst, Set<TreePath> replaceOccurrences) {
+ super(info, main);
+ this.removeFirst = removeFirst;
+ }
+
+ @Override
+ protected String getText() {
+ return Bundle.FIX_ConvertToSwitchPatternInstanceOf();
+ }
+
+ @Override
+ protected void performRewrite(JavaFix.TransformationContext ctx) {
+ WorkingCopy wc = ctx.getWorkingCopy();
+ TreePath main = ctx.getPath();
+ List<CaseTree> ctl = new LinkedList<>();
+
+ Tree ifPath = ctx.getPath().getLeaf();
+ int matchVarIndex = 1;
+ List<IfTree> ifTrees = new ArrayList<>();
+ while (ifPath != null && ifPath.getKind() == Tree.Kind.IF) {
+ matchVarIndex++;
+ IfTree it = (IfTree) ifPath;
+ ifTrees.add(it);
+ ifPath = it.getElseStatement();
+ }
+
+ InstanceOfTree iot = null;
+ for (IfTree ifTree : ifTrees) {
+ List<Tree> caseBindPattern = new LinkedList<>();
+ iot = (InstanceOfTree) ((ParenthesizedTree) ifTree.getCondition()).getExpression();
+ StatementTree bt = ifTree.getThenStatement();
+ VariableTree var = (VariableTree) ((BlockTree) bt).getStatements().get(0);
+ StatementTree thenBlock = removeFirst ? wc.getTreeMaker().removeBlockStatement((BlockTree) bt, 0) : bt;
+ caseBindPattern.add(wc.getTreeMaker().BindingPattern(wc.getTreeMaker().Variable(wc.getTreeMaker().Modifiers(EnumSet.noneOf(Modifier.class)), var.getName().toString(), iot.getType(), null)));
+ BlockTree blockTree = (BlockTree) thenBlock;
+
+ Tree defaultTree = null;
+ defaultTree = blockTree.getStatements().size() == 1 && isValidCaseTree(blockTree.getStatements().get(0))? blockTree.getStatements().get(0) : thenBlock;
+
+ CaseTree casePatterns = wc.getTreeMaker().CasePatterns(caseBindPattern, defaultTree);
+ ctl.add(casePatterns);
+ }
+ List<Tree> caseDefaultLabel = new LinkedList<>();
+ caseDefaultLabel.add(wc.getTreeMaker().Identifier("default"));
+ BlockTree elseTree = (BlockTree) ifPath;
+ if (elseTree == null) {
+ elseTree = wc.getTreeMaker().Block(new ArrayList<>(), false);
+ }
+
+ Tree defaultTree = elseTree.getStatements().size() == 1 && isValidCaseTree(elseTree.getStatements().get(0))? elseTree.getStatements().get(0) : elseTree;
+ CaseTree casePatterns = wc.getTreeMaker().CasePatterns(caseDefaultLabel, defaultTree);
+ ctl.add(casePatterns);
+ wc.rewrite((IfTree) main.getLeaf(), wc.getTreeMaker().Switch(iot.getExpression(), ctl));
+ }
+
+ }
+
+ private static boolean isValidCaseTree(Tree tree){
+ return ((tree instanceof BlockTree)
+ || (tree instanceof ExpressionStatementTree)
+ || (tree instanceof ThrowTree)
+ || (tree instanceof CaseTree));
+ }
+}
+
diff --git a/java/java.hints/test/unit/src/org/netbeans/modules/java/hints/jdk/ConvertToSwitchPatternInstanceOfTest.java b/java/java.hints/test/unit/src/org/netbeans/modules/java/hints/jdk/ConvertToSwitchPatternInstanceOfTest.java
new file mode 100644
index 0000000..30b6eab
--- /dev/null
+++ b/java/java.hints/test/unit/src/org/netbeans/modules/java/hints/jdk/ConvertToSwitchPatternInstanceOfTest.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.netbeans.modules.java.hints.jdk;
+
+import org.netbeans.junit.NbTestCase;
+import org.netbeans.modules.java.hints.test.api.HintTest;
+import javax.lang.model.SourceVersion;
+
+/**
+ *
+ * @author aksinsin
+ */
+public class ConvertToSwitchPatternInstanceOfTest extends NbTestCase {
+
+ public ConvertToSwitchPatternInstanceOfTest(String name) {
+ super(name);
+ }
+
+ public void testSimple() throws Exception {
+ try {
+ SourceVersion.valueOf("RELEASE_17"); //NOI18N
+ } catch (IllegalArgumentException ex) {
+ //OK, no RELEASE_17, skip tests
+ return;
+ }
+ HintTest.create()
+ .input("package test;\n"
+ + "public class Test {\n"
+ + " private void test(Object o) {\n"
+ + " if (o instanceof String) {\n"
+ + " String s = (String) o;\n"
+ + " System.out.println(s + \" String\");\n"
+ + " } else if (o instanceof StringBuilder) {\n"
+ + " StringBuilder sb = (StringBuilder) o;\n"
+ + " System.out.println(sb + \" StringBuilder\");\n"
+ + " } else if (o instanceof CharSequence) {\n"
+ + " CharSequence cs = (CharSequence) o;\n"
+ + " System.out.println(cs + \" CharSequence\");\n"
+ + " } else {\n"
+ + " System.out.println(\"else\");\n"
+ + " }\n"
+ + " }\n"
+ + "}")
+ .sourceLevel(SourceVersion.latest().name())
+ .options("--enable-preview")
+ .run(ConvertToSwitchPatternInstanceOf.class)
+ .findWarning("3:8-3:10:verifier:" + Bundle.ERR_ConvertToSwitchPatternInstanceOf())
+ .applyFix()
+ .assertCompilable()
+ .assertOutput("package test;\n"
+ + "public class Test {\n"
+ + " private void test(Object o) {\n"
+ + " switch (o) {\n"
+ + " case String s -> System.out.println(s + \" String\");\n"
+ + " case StringBuilder sb -> System.out.println(sb + \" StringBuilder\");\n"
+ + " case CharSequence cs -> System.out.println(cs + \" CharSequence\");\n"
+ + " case default -> System.out.println(\"else\");\n"
+ + " }\n"
+ + " }\n"
+ + "}\n");
+ }
+}
diff --git a/java/java.source.base/src/org/netbeans/api/java/source/TreeMaker.java b/java/java.source.base/src/org/netbeans/api/java/source/TreeMaker.java
index f513299..97e455a 100644
--- a/java/java.source.base/src/org/netbeans/api/java/source/TreeMaker.java
+++ b/java/java.source.base/src/org/netbeans/api/java/source/TreeMaker.java
@@ -268,6 +268,30 @@ public final class TreeMaker {
}
/**
+ * Creates a new CaseTree for a rule case (case <constants> -> <body>).
+ *
+ * @param patterns the labels for this case statement.
+ * @param body the case's body
+ * @see com.sun.source.tree.CaseTree
+ * @since 2.39
+ */
+ public CaseTree CasePatterns(List<? extends Tree> patterns, Tree body) {
+ return delegate.CaseMultiplePatterns(patterns, body);
+ }
+
+ /**
+ * Creates a new CaseTree.
+ *
+ * @param patterns the labels for this case statement.
+ * @param statements the list of statements.
+ * @see com.sun.source.tree.CaseTree
+ * @since 2.39
+ */
+ public CaseTree CasePatterns(List<? extends Tree> patterns, List<? extends StatementTree> statements) {
+ return delegate.CaseMultiplePatterns(patterns, statements);
+ }
+
+ /**
* Creates a new CatchTree.
*
* @param parameter the exception variable declaration.
diff --git a/java/java.source.base/src/org/netbeans/api/java/source/support/ErrorAwareTreePathScanner.java b/java/java.source.base/src/org/netbeans/api/java/source/support/ErrorAwareTreePathScanner.java
index a04e544..c1d97e6 100644
--- a/java/java.source.base/src/org/netbeans/api/java/source/support/ErrorAwareTreePathScanner.java
+++ b/java/java.source.base/src/org/netbeans/api/java/source/support/ErrorAwareTreePathScanner.java
@@ -19,7 +19,9 @@
package org.netbeans.api.java.source.support;
import com.sun.source.tree.ErroneousTree;
+import com.sun.source.tree.CaseTree;
import com.sun.source.util.TreePathScanner;
+import org.netbeans.modules.java.source.TreeShims;
/**
*
@@ -32,4 +34,9 @@ public class ErrorAwareTreePathScanner<R,P> extends TreePathScanner<R,P> {
return scan(et.getErrorTrees(), p);
}
+ @Override
+ public R visitCase(CaseTree node, P p) {
+ scan(TreeShims.getLabels(node), p);
+ return super.visitCase(node, p);
+ }
}
diff --git a/java/java.source.base/src/org/netbeans/api/java/source/support/ErrorAwareTreeScanner.java b/java/java.source.base/src/org/netbeans/api/java/source/support/ErrorAwareTreeScanner.java
index eebbcb5..16e0669 100644
--- a/java/java.source.base/src/org/netbeans/api/java/source/support/ErrorAwareTreeScanner.java
+++ b/java/java.source.base/src/org/netbeans/api/java/source/support/ErrorAwareTreeScanner.java
@@ -19,7 +19,9 @@
package org.netbeans.api.java.source.support;
import com.sun.source.tree.ErroneousTree;
+import com.sun.source.tree.CaseTree;
import com.sun.source.util.TreeScanner;
+import org.netbeans.modules.java.source.TreeShims;
/**
*
@@ -32,4 +34,9 @@ public class ErrorAwareTreeScanner<R,P> extends TreeScanner<R,P> {
return scan(et.getErrorTrees(), p);
}
+ @Override
+ public R visitCase(CaseTree node, P p) {
+ scan(TreeShims.getLabels(node), p);
+ return super.visitCase(node, p);
+ }
}
diff --git a/java/java.source.base/src/org/netbeans/modules/java/source/TreeShims.java b/java/java.source.base/src/org/netbeans/modules/java/source/TreeShims.java
index 4cb0807..fb9b24c 100644
--- a/java/java.source.base/src/org/netbeans/modules/java/source/TreeShims.java
+++ b/java/java.source.base/src/org/netbeans/modules/java/source/TreeShims.java
@@ -55,6 +55,10 @@ public class TreeShims {
public static final String BINDING_VARIABLE = "BINDING_VARIABLE"; //NOI18N
public static final String RECORD = "RECORD"; //NOI18N
public static final int PATTERN_MATCHING_INSTANCEOF_PREVIEW_JDK_VERSION = 15; //NOI18N
+ public static final String DEFAULT_CASE_LABEL = "DEFAULT_CASE_LABEL"; //NOI18N
+ public static final String NULL_LITERAL = "NULL_LITERAL"; //NOI18N
+ public static final String PARENTHESIZED_PATTERN = "PARENTHESIZED_PATTERN"; //NOI18N
+ public static final String GUARDED_PATTERN = "GUARDED_PATTERN"; //NOI18N
public static List<? extends ExpressionTree> getExpressions(CaseTree node) {
try {
@@ -67,6 +71,17 @@ public class TreeShims {
}
}
+ public static List<? extends Tree> getLabels(CaseTree node) {
+ try {
+ Method getLabels = CaseTree.class.getDeclaredMethod("getLabels");
+ return (List<? extends Tree>) getLabels.invoke(node);
+ } catch (NoSuchMethodException ex) {
+ return null;
+ } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
+ throw TreeShims.<RuntimeException>throwAny(ex);
+ }
+ }
+
public static Tree getBody(CaseTree node) {
try {
Method getBody = CaseTree.class.getDeclaredMethod("getBody");
@@ -170,6 +185,49 @@ public class TreeShims {
throw TreeShims.<RuntimeException>throwAny(ex);
}
}
+
+ public static Tree getGuardedPattern(Tree node) {
+ try {
+ Class gpt = Class.forName("com.sun.source.tree.GuardedPatternTree"); //NOI18N
+ return isJDKVersionRelease17_Or_Above()
+ ? (Tree)gpt.getDeclaredMethod("getPattern").invoke(node) //NOI18N
+ : null;
+
+ } catch (NoSuchMethodException | ClassNotFoundException ex) {
+ return null;
+ } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
+ throw TreeShims.<RuntimeException>throwAny(ex);
+ }
+ }
+
+ public static Tree getParenthesizedPattern(Tree node) {
+ try {
+ Class ppt = Class.forName("com.sun.source.tree.ParenthesizedPatternTree"); //NOI18N
+ return isJDKVersionRelease17_Or_Above()
+ ? (Tree)ppt.getDeclaredMethod("getPattern").invoke(node) //NOI18N
+ : null;
+
+ } catch (NoSuchMethodException | ClassNotFoundException ex) {
+ return null;
+ } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
+ throw TreeShims.<RuntimeException>throwAny(ex);
+ }
+ }
+
+ public static ExpressionTree getGuardedExpression(Tree node) {
+ try {
+ Class gpt = Class.forName("com.sun.source.tree.GuardedPatternTree"); //NOI18N
+ return isJDKVersionRelease17_Or_Above()
+ ? (ExpressionTree)gpt.getDeclaredMethod("getExpression").invoke(node) //NOI18N
+ : null;
+
+ } catch (NoSuchMethodException | ClassNotFoundException ex) {
+ return null;
+ } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
+ throw TreeShims.<RuntimeException>throwAny(ex);
+ }
+ }
+
public static List<? extends Tree> getPermits(ClassTree node) {
List<? extends Tree> perms = null;
try {
@@ -322,6 +380,10 @@ public class TreeShims {
return Integer.valueOf(SourceVersion.latest().name().split("_")[1]).compareTo(16) >= 0;
}
+ public static boolean isJDKVersionRelease17_Or_Above(){
+ return Integer.valueOf(SourceVersion.latest().name().split("_")[1]).compareTo(17) >= 0;
+ }
+
public static ModuleTree getModule(CompilationUnitTree cut) {
try {
return (ModuleTree) CompilationUnitTree.class.getDeclaredMethod("getModule").invoke(cut);
diff --git a/java/java.source.base/src/org/netbeans/modules/java/source/builder/TreeFactory.java b/java/java.source.base/src/org/netbeans/modules/java/source/builder/TreeFactory.java
index 32758b5..94cd00c 100644
--- a/java/java.source.base/src/org/netbeans/modules/java/source/builder/TreeFactory.java
+++ b/java/java.source.base/src/org/netbeans/modules/java/source/builder/TreeFactory.java
@@ -266,6 +266,35 @@ public class TreeFactory {
}
}
+ public CaseTree CaseMultiplePatterns(List<? extends Tree> expressions, Tree body) {
+ ListBuffer<JCStatement> lb = new ListBuffer<>();
+ lb.append(body instanceof ExpressionTree ? (JCStatement) Break((ExpressionTree) body) : (JCStatement) body);
+ ListBuffer<JCTree> exprs = new ListBuffer<>();
+ for (Tree t : expressions)
+ exprs.append((JCTree)t);
+ try {
+ Class<Enum> caseKind = (Class<Enum>) Class.forName("com.sun.source.tree.CaseTree$CaseKind", false, JCTree.class.getClassLoader());
+ return (CaseTree) make.getClass().getMethod("Case", caseKind, com.sun.tools.javac.util.List.class, com.sun.tools.javac.util.List.class, JCTree.class).invoke(make.at(NOPOS), Enum.valueOf(caseKind, "RULE"), exprs.toList(), lb.toList(), body);
+ } catch (Throwable t) {
+ throw throwAny(t);
+ }
+ }
+
+ public CaseTree CaseMultiplePatterns(List<? extends Tree> expressions, List<? extends StatementTree> statements) {
+ ListBuffer<JCStatement> lb = new ListBuffer<JCStatement>();
+ for (StatementTree t : statements)
+ lb.append((JCStatement)t);
+ ListBuffer<JCTree> exprs = new ListBuffer<>();
+ for (Tree t : expressions)
+ exprs.append((JCTree)t);
+ try {
+ Class<Enum> caseKind = (Class<Enum>) Class.forName("com.sun.source.tree.CaseTree$CaseKind", false, JCTree.class.getClassLoader());
+ return (CaseTree) make.getClass().getMethod("Case", caseKind, com.sun.tools.javac.util.List.class, com.sun.tools.javac.util.List.class, JCTree.class).invoke(make.at(NOPOS), Enum.valueOf(caseKind, "STATEMENT"), exprs.toList(), lb.toList(), null);
+ } catch (Throwable t) {
+ throw throwAny(t);
+ }
+ }
+
public CatchTree Catch(VariableTree parameter, BlockTree block) {
return make.at(NOPOS).Catch((JCVariableDecl)parameter, (JCBlock)block);
}
diff --git a/java/java.source.base/src/org/netbeans/modules/java/source/pretty/VeryPretty.java b/java/java.source.base/src/org/netbeans/modules/java/source/pretty/VeryPretty.java
index 1470510..3a8e660 100644
--- a/java/java.source.base/src/org/netbeans/modules/java/source/pretty/VeryPretty.java
+++ b/java/java.source.base/src/org/netbeans/modules/java/source/pretty/VeryPretty.java
@@ -1337,18 +1337,29 @@ public final class VeryPretty extends JCTree.Visitor implements DocTreeVisitor<V
public void visitCase(JCCase tree) {
int old = cs.indentCasesFromSwitch() ? indent() : out.leftMargin;
toLeftMargin();
- java.util.List<JCExpression> patterns = CasualDiff.getCasePatterns(tree);
- if (patterns.isEmpty()) {
- print("default");
- } else {
- print("case ");
+ java.util.List<JCTree> labels = CasualDiff.getCaseLabelPatterns(tree);
+ if (labels.size() > 0) {
+ print("case ");
String sep = "";
- for (JCExpression pat : patterns) {
+ for (JCTree lab : labels) {
print(sep);
- printNoParenExpr(pat);
+ printNoParenExpr(lab);
sep = ", "; //TODO: space or not should be a configuration setting
}
- }
+ } else {
+ java.util.List<JCExpression> patterns = CasualDiff.getCasePatterns(tree);
+ if (patterns.isEmpty()) {
+ print("default");
+ } else {
+ print("case ");
+ String sep = "";
+ for (JCExpression pat : patterns) {
+ print(sep);
+ printNoParenExpr(pat);
+ sep = ", "; //TODO: space or not should be a configuration setting
+ }
+ }
+ }
Object caseKind = CasualDiff.getCaseKind(tree);
if (caseKind == null || !String.valueOf(caseKind).equals("RULE")) {
print(':');
@@ -2084,6 +2095,9 @@ public final class VeryPretty extends JCTree.Visitor implements DocTreeVisitor<V
} catch (RuntimeException ex) {
Exceptions.printStackTrace(ex);
}
+ }else if ("DEFAULT_CASE_LABEL".equals(tree.getKind().name())) {
+ print("default");
+ return;
}
print("(UNKNOWN: " + tree + ")");
newline();
diff --git a/java/java.source.base/src/org/netbeans/modules/java/source/save/CasualDiff.java b/java/java.source.base/src/org/netbeans/modules/java/source/save/CasualDiff.java
index 5b879c2..011af47 100644
--- a/java/java.source.base/src/org/netbeans/modules/java/source/save/CasualDiff.java
+++ b/java/java.source.base/src/org/netbeans/modules/java/source/save/CasualDiff.java
@@ -2078,6 +2078,14 @@ public class CasualDiff {
}
}
+ public static List<JCTree> getCaseLabelPatterns(JCCase cs) {
+ try {
+ return (List<JCTree>) CaseTree.class.getDeclaredMethod("getLabels").invoke(cs);
+ } catch (Throwable t) {
+ return Collections.emptyList();
+ }
+ }
+
public static Object getCaseKind(JCCase cs) {
try {
return CaseTree.class.getDeclaredMethod("getCaseKind").invoke(cs);
diff --git a/java/java.source.base/src/org/netbeans/modules/java/source/save/Reformatter.java b/java/java.source.base/src/org/netbeans/modules/java/source/save/Reformatter.java
index 585485d..18eea7f 100644
--- a/java/java.source.base/src/org/netbeans/modules/java/source/save/Reformatter.java
+++ b/java/java.source.base/src/org/netbeans/modules/java/source/save/Reformatter.java
@@ -594,6 +594,12 @@ public class Reformatter implements ReformatTask {
case TreeShims.BINDING_PATTERN:
ret = scanBindingPattern(tree, p);
break;
+ case TreeShims.GUARDED_PATTERN:
+ ret = scanGuardedPattern(tree, p);
+ break;
+ case TreeShims.PARENTHESIZED_PATTERN:
+ ret = scanParenthesizedPattern(tree, p);
+ break;
case TreeShims.RECORD:
ret = scanRecord((ClassTree) tree, p);
break;
@@ -2809,6 +2815,47 @@ public class Reformatter implements ReformatTask {
return true;
}
+ private Boolean scanGuardedPattern(Tree node, Void p) {
+ try {
+ Tree gpt = TreeShims.getGuardedPattern(node);
+ if (gpt != null) {
+ if (scanParenthesizedPattern(gpt, p) == false) {
+ Name name = TreeShims.getBinding(gpt);
+ Tree type = TreeShims.getBindingPatternType(gpt);
+ scan(type, p);
+ if (name != null) {
+ removeWhiteSpace(IDENTIFIER);
+ }
+ }
+ }
+ } catch (RuntimeException ex) {
+ return false;
+ }
+
+ ExpressionTree exprTree = TreeShims.getGuardedExpression(node);
+ if (exprTree != null) {
+ accept(IDENTIFIER);
+ removeWhiteSpace(IDENTIFIER);
+ scan(exprTree, p);
+ }
+ return true;
+ }
+
+ private Boolean scanParenthesizedPattern(Tree node, Void p) {
+ try {
+ Tree ppt = TreeShims.getParenthesizedPattern(node);
+ if (ppt != null) {
+ if (scanGuardedPattern(ppt, p) == false) {
+ scanBindingPattern(ppt, p);
+ }
+ removeWhiteSpace(IDENTIFIER);
+ }
+ } catch (RuntimeException ex) {
+ return false;
+ }
+ return true;
+ }
+
private Boolean handleYield(Tree node, Void p) {
ExpressionTree exprTree = TreeShims.getYieldValue(node);
if (exprTree != null) {
@@ -2930,20 +2977,44 @@ public class Reformatter implements ReformatTask {
@Override
public Boolean visitCase(CaseTree node, Void p) {
- List<? extends ExpressionTree> exprs = TreeShims.getExpressions(node);
- if (exprs.size() > 0) {
+ List<? extends Tree> labels = TreeShims.getLabels(node);
+ if (labels != null && labels.size() > 0) {
+ if (tokens.token().id() == JavaTokenId.DEFAULT && labels.get(0).getKind().toString().equals(TreeShims.DEFAULT_CASE_LABEL)) {
+ accept(DEFAULT);
+ } else {
+ accept(CASE);
+ space();
+ for (Tree label : labels) {
+ if (label.getKind().toString().equals(TreeShims.DEFAULT_CASE_LABEL)) {
+ removeWhiteSpace(JavaTokenId.DEFAULT);
+ accept(DEFAULT);
+ } else if (label.getKind().toString().equals(TreeShims.BINDING_PATTERN)
+ || label.getKind().toString().equals(TreeShims.PARENTHESIZED_PATTERN)
+ || label.getKind().toString().equals(TreeShims.GUARDED_PATTERN)) {
+ removeWhiteSpace(JavaTokenId.IDENTIFIER);
+ scan(label, p);
+ } else if (label.getKind().toString().equals(TreeShims.NULL_LITERAL)) {
+ removeWhiteSpace(JavaTokenId.NULL);
+ scan(label, p);
+ } else {
+ scan(label, p);
+ }
+ }
+ }
+ } else if (TreeShims.getExpressions(node).size() > 0) {
+ List<? extends ExpressionTree> exprs = TreeShims.getExpressions(node);
accept(CASE);
space();
- for (ExpressionTree exp : exprs) {
+ exprs.forEach(exp -> {
scan(exp, p);
- }
+ });
} else {
accept(DEFAULT);
}
List<? extends StatementTree> statements = node.getStatements();
Tree caseBody = null;
if(statements != null)
- accept(COLON);
+ accept(COLON);
else {
space();
accept(ARROW);
@@ -2979,6 +3050,24 @@ public class Reformatter implements ReformatTask {
return true;
}
+ private void removeWhiteSpace(JavaTokenId forToken) {
+ do {
+ if (tokens.offset() >= endPos) {
+ break;
+ }
+ if (tokens.token().id() == forToken) {
+ break;
+ }
+ if (tokens.token().id() == WHITESPACE) {
+ String text = tokens.token().text().toString();
+ String ind = getIndent();
+ if (!ind.equals(text)) {
+ addDiff(new Diff(tokens.offset(), tokens.offset() + tokens.token().length(), " "));
+ }
+ }
+ } while (tokens.moveNext());
+ }
+
@Override
public Boolean visitBreak(BreakTree node, Void p) {
JavaTokenId token = accept(BREAK);
@@ -5637,5 +5726,4 @@ public class Reformatter implements ReformatTask {
return "Diff<" + start + "," + end + ">:" + text; //NOI18N
}
}
-}
-
+}
\ No newline at end of file
diff --git a/java/java.source.base/test/unit/src/org/netbeans/modules/java/source/save/FormatingTest.java b/java/java.source.base/test/unit/src/org/netbeans/modules/java/source/save/FormatingTest.java
index 40846b2..2ce8bf9 100644
--- a/java/java.source.base/test/unit/src/org/netbeans/modules/java/source/save/FormatingTest.java
+++ b/java/java.source.base/test/unit/src/org/netbeans/modules/java/source/save/FormatingTest.java
@@ -1734,6 +1734,12 @@ public class FormatingTest extends NbTestCase {
}
public void testSwitch() throws Exception {
+ try {
+ SourceVersion.valueOf("RELEASE_17"); //NOI18N
+ return;
+ } catch (IllegalArgumentException ex) {
+ //OK,RELEASE_17, skip test
+ }
testFile = new File(getWorkDir(), "Test.java");
TestUtilities.copyStringToFile(testFile,
"package hierbas.del.litoral;\n\n"
@@ -1962,6 +1968,243 @@ public class FormatingTest extends NbTestCase {
reformat(doc, content, golden);
preferences.putBoolean("indentCasesFromSwitch", true);
}
+
+ public void testSwitchOnJDK17() throws Exception {
+ try {
+ SourceVersion.valueOf("RELEASE_17"); //NOI18N
+ } catch (IllegalArgumentException ex) {
+ //OK, no RELEASE_17, skip test
+ return;
+ }
+ testFile = new File(getWorkDir(), "Test.java");
+ TestUtilities.copyStringToFile(testFile,
+ "package hierbas.del.litoral;\n\n"
+ + "public class Test {\n"
+ + " public void taragui(int i) {\n"
+ + " }\n"
+ + "}\n");
+ FileObject testSourceFO = FileUtil.toFileObject(testFile);
+ DataObject testSourceDO = DataObject.find(testSourceFO);
+ EditorCookie ec = (EditorCookie)testSourceDO.getCookie(EditorCookie.class);
+ final Document doc = ec.openDocument();
+ doc.putProperty(Language.class, JavaTokenId.language());
+ JavaSource testSource = JavaSource.forDocument(doc);
+ final String stmt =
+ "switch (i) {case 0: System.out.println(i); break; default: System.out.println(\"DEFAULT\");}";
+ Task<WorkingCopy> task = new Task<WorkingCopy>() {
+
+ @Override
+ public void run(WorkingCopy workingCopy) throws java.io.IOException {
+ workingCopy.toPhase(Phase.RESOLVED);
+ ClassTree clazz = (ClassTree)workingCopy.getCompilationUnit().getTypeDecls().get(0);
+ MethodTree method = (MethodTree)clazz.getMembers().get(1);
+ BlockTree block = method.getBody();
+ StatementTree statement = workingCopy.getTreeUtilities().parseStatement(stmt, new SourcePositions[1]);
+ workingCopy.rewrite(block, workingCopy.getTreeMaker().addBlockStatement(block, statement));
+ }
+ };
+ testSource.runModificationTask(task).commit();
+
+ Preferences preferences = MimeLookup.getLookup(JavaTokenId.language().mimeType()).lookup(Preferences.class);
+ preferences.putBoolean("spaceBeforeSwitchParen", false);
+ preferences.putBoolean("spaceWithinSwitchParens", true);
+ preferences.putBoolean("spaceBeforeSwitchLeftBrace", false);
+ testSource.runModificationTask(task).commit();
+ preferences.putBoolean("spaceBeforeSwitchParen", true);
+ preferences.putBoolean("spaceWithinSwitchParens", false);
+ preferences.putBoolean("spaceBeforeSwitchLeftBrace", true);
+
+ preferences.put("otherBracePlacement", CodeStyle.BracePlacement.NEW_LINE.name());
+ testSource.runModificationTask(task).commit();
+
+ preferences.put("otherBracePlacement", CodeStyle.BracePlacement.NEW_LINE_HALF_INDENTED.name());
+ testSource.runModificationTask(task).commit();
+
+ preferences.put("otherBracePlacement", CodeStyle.BracePlacement.NEW_LINE_INDENTED.name());
+ testSource.runModificationTask(task).commit();
+ preferences.put("otherBracePlacement", CodeStyle.BracePlacement.SAME_LINE.name());
+
+ preferences.putBoolean("indentCasesFromSwitch", false);
+ testSource.runModificationTask(task).commit();
+ preferences.putBoolean("indentCasesFromSwitch", true);
+
+ ec.saveDocument();
+ String res = TestUtilities.copyFileToString(testFile);
+ System.err.println(res);
+
+ String golden =
+ "package hierbas.del.litoral;\n\n"
+ + "public class Test {\n"
+ + " public void taragui(int i) {\n"
+ + " switch (i) {\n"
+ + " case 0:\n"
+ + " System.out.println(i);\n"
+ + " break;\n"
+ + " case default:\n"
+ + " System.out.println(\"DEFAULT\");\n"
+ + " }\n"
+ + " switch( i ){\n"
+ + " case 0:\n"
+ + " System.out.println(i);\n"
+ + " break;\n"
+ + " case default:\n"
+ + " System.out.println(\"DEFAULT\");\n"
+ + " }\n"
+ + " switch (i)\n"
+ + " {\n"
+ + " case 0:\n"
+ + " System.out.println(i);\n"
+ + " break;\n"
+ + " case default:\n"
+ + " System.out.println(\"DEFAULT\");\n"
+ + " }\n"
+ + " switch (i)\n"
+ + " {\n"
+ + " case 0:\n"
+ + " System.out.println(i);\n"
+ + " break;\n"
+ + " case default:\n"
+ + " System.out.println(\"DEFAULT\");\n"
+ + " }\n"
+ + " switch (i)\n"
+ + " {\n"
+ + " case 0:\n"
+ + " System.out.println(i);\n"
+ + " break;\n"
+ + " case default:\n"
+ + " System.out.println(\"DEFAULT\");\n"
+ + " }\n"
+ + " switch (i) {\n"
+ + " case 0:\n"
+ + " System.out.println(i);\n"
+ + " break;\n"
+ + " case default:\n"
+ + " System.out.println(\"DEFAULT\");\n"
+ + " }\n"
+ + " }\n"
+ + "}\n";
+ assertEquals(golden, res);
+
+ String content =
+ "package hierbas.del.litoral;"
+ + "public class Test{"
+ + "public void taragui(int i){"
+ + "switch(i){"
+ + "case 0:"
+ + "System.out.println(i);"
+ + "break;"
+ + "default:"
+ + "System.out.println(\"DEFAULT\");"
+ + "}"
+ + "}"
+ + "}\n";
+
+ golden =
+ "package hierbas.del.litoral;\n\n"
+ + "public class Test {\n\n"
+ + " public void taragui(int i) {\n"
+ + " switch (i) {\n"
+ + " case 0:\n"
+ + " System.out.println(i);\n"
+ + " break;\n"
+ + " default:\n"
+ + " System.out.println(\"DEFAULT\");\n"
+ + " }\n"
+ + " }\n"
+ + "}\n";
+ reformat(doc, content, golden);
+
+ golden =
+ "package hierbas.del.litoral;\n\n"
+ + "public class Test {\n\n"
+ + " public void taragui(int i) {\n"
+ + " switch( i ){\n"
+ + " case 0:\n"
+ + " System.out.println(i);\n"
+ + " break;\n"
+ + " default:\n"
+ + " System.out.println(\"DEFAULT\");\n"
+ + " }\n"
+ + " }\n"
+ + "}\n";
+ preferences.putBoolean("spaceBeforeSwitchParen", false);
+ preferences.putBoolean("spaceWithinSwitchParens", true);
+ preferences.putBoolean("spaceBeforeSwitchLeftBrace", false);
+ reformat(doc, content, golden);
+ preferences.putBoolean("spaceBeforeSwitchParen", true);
+ preferences.putBoolean("spaceWithinSwitchParens", false);
+ preferences.putBoolean("spaceBeforeSwitchLeftBrace", true);
+
+ golden =
+ "package hierbas.del.litoral;\n\n"
+ + "public class Test {\n\n"
+ + " public void taragui(int i) {\n"
+ + " switch (i)\n"
+ + " {\n"
+ + " case 0:\n"
+ + " System.out.println(i);\n"
+ + " break;\n"
+ + " default:\n"
+ + " System.out.println(\"DEFAULT\");\n"
+ + " }\n"
+ + " }\n"
+ + "}\n";
+ preferences.put("otherBracePlacement", CodeStyle.BracePlacement.NEW_LINE.name());
+ reformat(doc, content, golden);
+
+ golden =
+ "package hierbas.del.litoral;\n\n"
+ + "public class Test {\n\n"
+ + " public void taragui(int i) {\n"
+ + " switch (i)\n"
+ + " {\n"
+ + " case 0:\n"
+ + " System.out.println(i);\n"
+ + " break;\n"
+ + " default:\n"
+ + " System.out.println(\"DEFAULT\");\n"
+ + " }\n"
+ + " }\n"
+ + "}\n";
+ preferences.put("otherBracePlacement", CodeStyle.BracePlacement.NEW_LINE_HALF_INDENTED.name());
+ reformat(doc, content, golden);
+
+ golden =
+ "package hierbas.del.litoral;\n\n"
+ + "public class Test {\n\n"
+ + " public void taragui(int i) {\n"
+ + " switch (i)\n"
+ + " {\n"
+ + " case 0:\n"
+ + " System.out.println(i);\n"
+ + " break;\n"
+ + " default:\n"
+ + " System.out.println(\"DEFAULT\");\n"
+ + " }\n"
+ + " }\n"
+ + "}\n";
+ preferences.put("otherBracePlacement", CodeStyle.BracePlacement.NEW_LINE_INDENTED.name());
+ reformat(doc, content, golden);
+ preferences.put("otherBracePlacement", CodeStyle.BracePlacement.SAME_LINE.name());
+
+ golden =
+ "package hierbas.del.litoral;\n\n"
+ + "public class Test {\n\n"
+ + " public void taragui(int i) {\n"
+ + " switch (i) {\n"
+ + " case 0:\n"
+ + " System.out.println(i);\n"
+ + " break;\n"
+ + " default:\n"
+ + " System.out.println(\"DEFAULT\");\n"
+ + " }\n"
+ + " }\n"
+ + "}\n";
+ preferences.putBoolean("indentCasesFromSwitch", false);
+ reformat(doc, content, golden);
+ preferences.putBoolean("indentCasesFromSwitch", true);
+
+ }
public void testRuleSwitch() throws Exception {
testFile = new File(getWorkDir(), "Test.java");
TestUtilities.copyStringToFile(testFile,
@@ -2362,6 +2605,776 @@ public class FormatingTest extends NbTestCase {
reformat(doc, content, golden);
}
+ public void testSwitchCaseNull() throws Exception {
+ try {
+ SourceVersion.valueOf("RELEASE_17"); //NOI18N
+ } catch (IllegalArgumentException ex) {
+ //OK, no RELEASE_17, skip test
+ return;
+ }
+ testFile = new File(getWorkDir(), "Test.java");
+ TestUtilities.copyStringToFile(testFile, "");
+ FileObject testSourceFO = FileUtil.toFileObject(testFile);
+ DataObject testSourceDO = DataObject.find(testSourceFO);
+ EditorCookie ec = (EditorCookie) testSourceDO.getCookie(EditorCookie.class);
+ final Document doc = ec.openDocument();
+ doc.putProperty(Language.class, JavaTokenId.language());
+ String content = "package p;"
+ + "public class Test{ \n"
+ + "void testSwitchCaseNull() {\n"
+ + " Object str = \"pattern matching switch\";\n"
+ + " switch (str) {\n"
+ + " case \n"
+ + " null -> System.out.println(\"case with null formatting\");\n"
+ + " default ->\n"
+ + " System.out.println(\"default formatting\");\n"
+ + " }\n"
+ + " }\n"
+ + "}";
+
+ String golden
+ = "package p;\n"
+ + "\n"
+ + "public class Test {\n"
+ + "\n"
+ + " void testSwitchCaseNull() {\n"
+ + " Object str = \"pattern matching switch\";\n"
+ + " switch (str) {\n"
+ + " case null ->\n"
+ + " System.out.println(\"case with null formatting\");\n"
+ + " default ->\n"
+ + " System.out.println(\"default formatting\");\n"
+ + " }\n"
+ + " }\n"
+ + "}\n";
+ reformat(doc, content, golden);
+ }
+
+ public void testSwitchCaseDefault() throws Exception {
+ try {
+ SourceVersion.valueOf("RELEASE_17"); //NOI18N
+ } catch (IllegalArgumentException ex) {
+ //OK, no RELEASE_17, skip test
+ return;
+ }
+ testFile = new File(getWorkDir(), "Test.java");
+ TestUtilities.copyStringToFile(testFile, "");
+ FileObject testSourceFO = FileUtil.toFileObject(testFile);
+ DataObject testSourceDO = DataObject.find(testSourceFO);
+ EditorCookie ec = (EditorCookie) testSourceDO.getCookie(EditorCookie.class);
+ final Document doc = ec.openDocument();
+ doc.putProperty(Language.class, JavaTokenId.language());
+ String content = "package p;"
+ + "public class Test{ \n"
+ + " void testSwitchCaseDefault() {\n"
+ + " Object str = \"pattern matching switch\";\n"
+ + " switch (str) {\n"
+ + " case\n"
+ + " \n"
+ + " default\n"
+ + " ->\n"
+ + " System.out.println(\"default formatting\");\n"
+ + " }\n"
+ + " }"
+ + "}";
+
+ String golden
+ = "package p;\n"
+ + "\n"
+ + "public class Test {\n"
+ + "\n"
+ + " void testSwitchCaseDefault() {\n"
+ + " Object str = \"pattern matching switch\";\n"
+ + " switch (str) {\n"
+ + " case default ->\n"
+ + " System.out.println(\"default formatting\");\n"
+ + " }\n"
+ + " }\n"
+ + "}\n";
+ reformat(doc, content, golden);
+ }
+
+ public void testSwitchCaseNullAndDefault() throws Exception {
+ try {
+ SourceVersion.valueOf("RELEASE_17"); //NOI18N
+ } catch (IllegalArgumentException ex) {
+ //OK, no RELEASE_17, skip test
+ return;
+ }
+ testFile = new File(getWorkDir(), "Test.java");
+ TestUtilities.copyStringToFile(testFile, "");
+ FileObject testSourceFO = FileUtil.toFileObject(testFile);
+ DataObject testSourceDO = DataObject.find(testSourceFO);
+ EditorCookie ec = (EditorCookie) testSourceDO.getCookie(EditorCookie.class);
+ final Document doc = ec.openDocument();
+ doc.putProperty(Language.class, JavaTokenId.language());
+ String content = "package p;"
+ + "public class Test{ \n"
+ + "void testSwitchCaseNullAndDefault() {\n"
+ + " Object str = \"pattern matching switch\";\n"
+ + " switch (str) {\n"
+ + " case \n"
+ + "null, default ->System.out.println(\"case with null and default formatting\");\n"
+ + " \n"
+ + " }\n"
+ + " }"
+ + "}";
+
+ String golden
+ = "package p;\n"
+ + "\n"
+ + "public class Test {\n"
+ + "\n"
+ + " void testSwitchCaseNullAndDefault() {\n"
+ + " Object str = \"pattern matching switch\";\n"
+ + " switch (str) {\n"
+ + " case null, default ->\n"
+ + " System.out.println(\"case with null and default formatting\");\n"
+ + "\n"
+ + " }\n"
+ + " }\n"
+ + "}\n";
+ reformat(doc, content, golden);
+ }
+
+ public void testSwitchCaseBindingPattern() throws Exception {
+ try {
+ SourceVersion.valueOf("RELEASE_17"); //NOI18N
+ } catch (IllegalArgumentException ex) {
+ //OK, no RELEASE_17, skip test
+ return;
+ }
+ testFile = new File(getWorkDir(), "Test.java");
+ TestUtilities.copyStringToFile(testFile, "");
+ FileObject testSourceFO = FileUtil.toFileObject(testFile);
+ DataObject testSourceDO = DataObject.find(testSourceFO);
+ EditorCookie ec = (EditorCookie) testSourceDO.getCookie(EditorCookie.class);
+ final Document doc = ec.openDocument();
+ doc.putProperty(Language.class, JavaTokenId.language());
+ String content = "package p;"
+ + "public class Test{ \n"
+ + " void testSwitchCaseBindingPattern() {\n"
+ + " Object str = \"pattern matching switch\";\n"
+ + " switch (str) {\n"
+ + " case \n"
+ + " String \n"
+ + " s \n"
+ + " -> System.out.println(\"case with binding pattern formatting\");\n"
+ + " default ->\n"
+ + " System.out.println(\"default formatting\");\n"
+ + " }\n"
+ + " }"
+ + "}";
+
+ String golden
+ = "package p;\n"
+ + "\n"
+ + "public class Test {\n"
+ + "\n"
+ + " void testSwitchCaseBindingPattern() {\n"
+ + " Object str = \"pattern matching switch\";\n"
+ + " switch (str) {\n"
+ + " case String s ->\n"
+ + " System.out.println(\"case with binding pattern formatting\");\n"
+ + " default ->\n"
+ + " System.out.println(\"default formatting\");\n"
+ + " }\n"
+ + " }\n"
+ + "}\n"
+ + "";
+ reformat(doc, content, golden);
+ }
+
+ public void testSwitchCaseNullAndBindingPattern() throws Exception {
+ try {
+ SourceVersion.valueOf("RELEASE_17"); //NOI18N
+ } catch (IllegalArgumentException ex) {
+ //OK, no RELEASE_17, skip test
+ return;
+ }
+ testFile = new File(getWorkDir(), "Test.java");
+ TestUtilities.copyStringToFile(testFile, "");
+ FileObject testSourceFO = FileUtil.toFileObject(testFile);
+ DataObject testSourceDO = DataObject.find(testSourceFO);
+ EditorCookie ec = (EditorCookie) testSourceDO.getCookie(EditorCookie.class);
+ final Document doc = ec.openDocument();
+ doc.putProperty(Language.class, JavaTokenId.language());
+ String content = "package p;"
+ + "public class Test{ \n"
+ + "void testSwitchCaseNullAndBindingPattern() {\n"
+ + " Object str = \"pattern matching switch\";\n"
+ + " switch (str) {\n"
+ + " case null,\n"
+ + " String \n"
+ + " s \n"
+ + " -> System.out.println(\"case with null and binding pattern formatting\");\n"
+ + " default ->\n"
+ + " System.out.println(\"default formatting\");\n"
+ + " }\n"
+ + " }"
+ + "}";
+
+ String golden
+ = "package p;\n"
+ + "\n"
+ + "public class Test {\n"
+ + "\n"
+ + " void testSwitchCaseNullAndBindingPattern() {\n"
+ + " Object str = \"pattern matching switch\";\n"
+ + " switch (str) {\n"
+ + " case null, String s ->\n"
+ + " System.out.println(\"case with null and binding pattern formatting\");\n"
+ + " default ->\n"
+ + " System.out.println(\"default formatting\");\n"
+ + " }\n"
+ + " }\n"
+ + "}\n"
+ + "";
+ reformat(doc, content, golden);
+ }
+
+ public void testSwitchCaseGuardedPattern() throws Exception {
+ try {
+ SourceVersion.valueOf("RELEASE_17"); //NOI18N
+ } catch (IllegalArgumentException ex) {
+ //OK, no RELEASE_17, skip test
+ return;
+ }
+ testFile = new File(getWorkDir(), "Test.java");
+ TestUtilities.copyStringToFile(testFile, "");
+ FileObject testSourceFO = FileUtil.toFileObject(testFile);
+ DataObject testSourceDO = DataObject.find(testSourceFO);
+ EditorCookie ec = (EditorCookie) testSourceDO.getCookie(EditorCookie.class);
+ final Document doc = ec.openDocument();
+ doc.putProperty(Language.class, JavaTokenId.language());
+ String content = "package p;"
+ + "public class Test{ \n"
+ + "void testSwitchCaseGuardedPattern() {\n"
+ + " Object str = \"pattern matching switch\";\n"
+ + " switch (str) {\n"
+ + "case \n"
+ + " String s && s.length() == 1\n"
+ + " \n"
+ + " ->\n"
+ + " System.out.println(\"case with guarded pattern formatting\");\n"
+ + " default ->\n"
+ + " System.out.println(\"default formatting\");\n"
+ + " }\n"
+ + " }"
+ + "}";
+
+ String golden
+ = "package p;\n"
+ + "\n"
+ + "public class Test {\n"
+ + "\n"
+ + " void testSwitchCaseGuardedPattern() {\n"
+ + " Object str = \"pattern matching switch\";\n"
+ + " switch (str) {\n"
+ + " case String s && s.length() == 1 ->\n"
+ + " System.out.println(\"case with guarded pattern formatting\");\n"
+ + " default ->\n"
+ + " System.out.println(\"default formatting\");\n"
+ + " }\n"
+ + " }\n"
+ + "}\n"
+ + "";
+ reformat(doc, content, golden);
+ }
+
+ public void testSwitchCaseNullAndGuardedPattern() throws Exception {
+ try {
+ SourceVersion.valueOf("RELEASE_17"); //NOI18N
+ } catch (IllegalArgumentException ex) {
+ //OK, no RELEASE_17, skip test
+ return;
+ }
+ testFile = new File(getWorkDir(), "Test.java");
+ TestUtilities.copyStringToFile(testFile, "");
+ FileObject testSourceFO = FileUtil.toFileObject(testFile);
+ DataObject testSourceDO = DataObject.find(testSourceFO);
+ EditorCookie ec = (EditorCookie) testSourceDO.getCookie(EditorCookie.class);
+ final Document doc = ec.openDocument();
+ doc.putProperty(Language.class, JavaTokenId.language());
+ String content = "package p;"
+ + "public class Test{ \n"
+ + "void testSwitchCaseNullAndGuardedPattern() {\n"
+ + " Object str = \"pattern matching switch\";\n"
+ + " switch (str) {\n"
+ + "case \n"
+ + " null,\n"
+ + " String s && s.length() == 1\n"
+ + " \n"
+ + " ->\n"
+ + " System.out.println(\"case with null and guarded pattern formatting\");\n"
+ + " default ->\n"
+ + " System.out.println(\"default formatting\");\n"
+ + " }\n"
+ + " }"
+ + "}";
+
+ String golden
+ = "package p;\n"
+ + "\n"
+ + "public class Test {\n"
+ + "\n"
+ + " void testSwitchCaseNullAndGuardedPattern() {\n"
+ + " Object str = \"pattern matching switch\";\n"
+ + " switch (str) {\n"
+ + " case null, String s && s.length() == 1 ->\n"
+ + " System.out.println(\"case with null and guarded pattern formatting\");\n"
+ + " default ->\n"
+ + " System.out.println(\"default formatting\");\n"
+ + " }\n"
+ + " }\n"
+ + "}\n"
+ + "";
+ reformat(doc, content, golden);
+ }
+
+ public void testSwitchCaseParenthesizedBindingPattern() throws Exception {
+ try {
+ SourceVersion.valueOf("RELEASE_17"); //NOI18N
+ } catch (IllegalArgumentException ex) {
+ //OK, no RELEASE_17, skip test
+ return;
+ }
+ testFile = new File(getWorkDir(), "Test.java");
+ TestUtilities.copyStringToFile(testFile, "");
+ FileObject testSourceFO = FileUtil.toFileObject(testFile);
+ DataObject testSourceDO = DataObject.find(testSourceFO);
+ EditorCookie ec = (EditorCookie) testSourceDO.getCookie(EditorCookie.class);
+ final Document doc = ec.openDocument();
+ doc.putProperty(Language.class, JavaTokenId.language());
+ String content = "package p;"
+ + "public class Test{ \n"
+ + "void testSwitchCaseParenthesizedBindingPattern() {\n"
+ + " Object str = \"pattern matching switch\";\n"
+ + " switch (str) {\n"
+ + "case \n"
+ + " (String \n"
+ + " s )\n"
+ + " \n"
+ + " ->\n"
+ + " System.out.println(\"case with Parenthesized Binding Pattern formatting\");\n"
+ + " default ->\n"
+ + " System.out.println(\"default formatting\");\n"
+ + " }\n"
+ + " } "
+ + "}";
+
+ String golden
+ = "package p;\n"
+ + "\n"
+ + "public class Test {\n"
+ + "\n"
+ + " void testSwitchCaseParenthesizedBindingPattern() {\n"
+ + " Object str = \"pattern matching switch\";\n"
+ + " switch (str) {\n"
+ + " case (String s ) ->\n"
+ + " System.out.println(\"case with Parenthesized Binding Pattern formatting\");\n"
+ + " default ->\n"
+ + " System.out.println(\"default formatting\");\n"
+ + " }\n"
+ + " }\n"
+ + "}\n"
+ + "";
+ reformat(doc, content, golden);
+ }
+
+ public void testSwitchCaseNullAndParenthesizedBindingPattern() throws Exception {
+ try {
+ SourceVersion.valueOf("RELEASE_17"); //NOI18N
+ } catch (IllegalArgumentException ex) {
+ //OK, no RELEASE_17, skip test
+ return;
+ }
+ testFile = new File(getWorkDir(), "Test.java");
+ TestUtilities.copyStringToFile(testFile, "");
+ FileObject testSourceFO = FileUtil.toFileObject(testFile);
+ DataObject testSourceDO = DataObject.find(testSourceFO);
+ EditorCookie ec = (EditorCookie) testSourceDO.getCookie(EditorCookie.class);
+ final Document doc = ec.openDocument();
+ doc.putProperty(Language.class, JavaTokenId.language());
+ String content = "package p;"
+ + "public class Test{ \n"
+ + "void testSwitchCaseNullAndParenthesizedBindingPattern() {\n"
+ + " Object str = \"pattern matching switch\";\n"
+ + " switch (str) {\n"
+ + "case null,\n"
+ + " (String \n"
+ + " s )\n"
+ + " \n"
+ + " ->System.out.println(\"case with null and Parenthesized Binding Pattern formatting\");\n"
+ + " default ->\n"
+ + " System.out.println(\"default formatting\");\n"
+ + " }\n"
+ + " }"
+ + "}";
+
+ String golden
+ = "package p;\n"
+ + "\n"
+ + "public class Test {\n"
+ + "\n"
+ + " void testSwitchCaseNullAndParenthesizedBindingPattern() {\n"
+ + " Object str = \"pattern matching switch\";\n"
+ + " switch (str) {\n"
+ + " case null, (String s ) ->\n"
+ + " System.out.println(\"case with null and Parenthesized Binding Pattern formatting\");\n"
+ + " default ->\n"
+ + " System.out.println(\"default formatting\");\n"
+ + " }\n"
+ + " }\n"
+ + "}\n"
+ + "";
+ reformat(doc, content, golden);
+ }
+
+ public void testSwitchCaseParenthesizedGuardedPattern() throws Exception {
+ try {
+ SourceVersion.valueOf("RELEASE_17"); //NOI18N
+ } catch (IllegalArgumentException ex) {
+ //OK, no RELEASE_17, skip test
+ return;
+ }
+ testFile = new File(getWorkDir(), "Test.java");
+ TestUtilities.copyStringToFile(testFile, "");
+ FileObject testSourceFO = FileUtil.toFileObject(testFile);
+ DataObject testSourceDO = DataObject.find(testSourceFO);
+ EditorCookie ec = (EditorCookie) testSourceDO.getCookie(EditorCookie.class);
+ final Document doc = ec.openDocument();
+ doc.putProperty(Language.class, JavaTokenId.language());
+ String content = "package p;"
+ + "public class Test{ \n"
+ + "void testSwitchCaseParenthesizedGuardedPattern() {\n"
+ + " Object str = \"pattern matching switch\";\n"
+ + " switch (str) {\n"
+ + "case \n"
+ + " (String \n"
+ + " s &&\n"
+ + " s.length() == 1\n"
+ + " )\n"
+ + " \n"
+ + " ->\n"
+ + " System.out.println(\"case with Parenthesized Guarded Pattern formatting\");default ->\n"
+ + " System.out.println(\"default formatting\");\n"
+ + " }\n"
+ + " }"
+ + "}";
+
+ String golden
+ = "package p;\n"
+ + "\n"
+ + "public class Test {\n"
+ + "\n"
+ + " void testSwitchCaseParenthesizedGuardedPattern() {\n"
+ + " Object str = \"pattern matching switch\";\n"
+ + " switch (str) {\n"
+ + " case (String s && s.length() == 1 ) ->\n"
+ + " System.out.println(\"case with Parenthesized Guarded Pattern formatting\");\n"
+ + " default ->\n"
+ + " System.out.println(\"default formatting\");\n"
+ + " }\n"
+ + " }\n"
+ + "}\n"
+ + "";
+ reformat(doc, content, golden);
+ }
+
+ public void testSwitchCaseParenthesizedGuardedPatternAndNull() throws Exception {
+ try {
+ SourceVersion.valueOf("RELEASE_17"); //NOI18N
+ } catch (IllegalArgumentException ex) {
+ //OK, no RELEASE_17, skip test
+ return;
+ }
+ testFile = new File(getWorkDir(), "Test.java");
+ TestUtilities.copyStringToFile(testFile, "");
+ FileObject testSourceFO = FileUtil.toFileObject(testFile);
+ DataObject testSourceDO = DataObject.find(testSourceFO);
+ EditorCookie ec = (EditorCookie) testSourceDO.getCookie(EditorCookie.class);
+ final Document doc = ec.openDocument();
+ doc.putProperty(Language.class, JavaTokenId.language());
+ String content = "package p;"
+ + "public class Test{ \n"
+ + "void testSwitchCaseParenthesizedGuardedPatternAndNull() {\n"
+ + " Object str = \"pattern matching switch\";\n"
+ + " switch (str) {\n"
+ + "case \n"
+ + " (String \n"
+ + " s &&\n"
+ + " s.length() == 1\n"
+ + " ) , \n"
+ + " null\n"
+ + " \n"
+ + " ->\n"
+ + " System.out.println(\"case with Parenthesized Binding Pattern formatting\");default ->\n"
+ + " System.out.println(\"default formatting\");\n"
+ + " }\n"
+ + " }"
+ + "}";
+
+ String golden
+ = "package p;\n"
+ + "\n"
+ + "public class Test {\n"
+ + "\n"
+ + " void testSwitchCaseParenthesizedGuardedPatternAndNull() {\n"
+ + " Object str = \"pattern matching switch\";\n"
+ + " switch (str) {\n"
+ + " case (String s && s.length() == 1 ) , null ->\n"
+ + " System.out.println(\"case with Parenthesized Binding Pattern formatting\");\n"
+ + " default ->\n"
+ + " System.out.println(\"default formatting\");\n"
+ + " }\n"
+ + " }\n"
+ + "}\n"
+ + "";
+ reformat(doc, content, golden);
+ }
+
+ public void testSwitchCaseGuardedPatternNestedParenthesizedPatternWithNull() throws Exception {
+ try {
+ SourceVersion.valueOf("RELEASE_17"); //NOI18N
+ } catch (IllegalArgumentException ex) {
+ //OK, no RELEASE_17, skip test
+ return;
+ }
+ testFile = new File(getWorkDir(), "Test.java");
+ TestUtilities.copyStringToFile(testFile, "");
+ FileObject testSourceFO = FileUtil.toFileObject(testFile);
+ DataObject testSourceDO = DataObject.find(testSourceFO);
+ EditorCookie ec = (EditorCookie) testSourceDO.getCookie(EditorCookie.class);
+ final Document doc = ec.openDocument();
+ doc.putProperty(Language.class, JavaTokenId.language());
+ String content = "package p;"
+ + "public class Test{ \n"
+ + "void testSwitchCaseGuardedPatternNestedParenthesizedPattern() {\n"
+ + " Object str = \"pattern matching switch\";\n"
+ + " switch (str) {\n"
+ + "case \n"
+ + " (String \n"
+ + " s ) &&\n"
+ + " s.length() == 1\n"
+ + " , \n"
+ + " null\n"
+ + " \n"
+ + " ->\n"
+ + " System.out.println(\"SwitchCaseGuardedPatternNestedParenthesizedPattern\");default ->\n"
+ + " System.out.println(\"default formatting\");\n"
+ + " }\n"
+ + " }"
+ + "}";
+
+ String golden
+ = "package p;\n"
+ + "\n"
+ + "public class Test {\n"
+ + "\n"
+ + " void testSwitchCaseGuardedPatternNestedParenthesizedPattern() {\n"
+ + " Object str = \"pattern matching switch\";\n"
+ + " switch (str) {\n"
+ + " case (String s ) && s.length() == 1 , null ->\n"
+ + " System.out.println(\"SwitchCaseGuardedPatternNestedParenthesizedPattern\");\n"
+ + " default ->\n"
+ + " System.out.println(\"default formatting\");\n"
+ + " }\n"
+ + " }\n"
+ + "}\n"
+ + "";
+ reformat(doc, content, golden);
+ }
+
+ public void testSwitchCaseGuardedPatternNestedParenthesizedPattern() throws Exception {
+ try {
+ SourceVersion.valueOf("RELEASE_17"); //NOI18N
+ } catch (IllegalArgumentException ex) {
+ //OK, no RELEASE_17, skip test
+ return;
+ }
+ testFile = new File(getWorkDir(), "Test.java");
+ TestUtilities.copyStringToFile(testFile, "");
+ FileObject testSourceFO = FileUtil.toFileObject(testFile);
+ DataObject testSourceDO = DataObject.find(testSourceFO);
+ EditorCookie ec = (EditorCookie) testSourceDO.getCookie(EditorCookie.class);
+ final Document doc = ec.openDocument();
+ doc.putProperty(Language.class, JavaTokenId.language());
+ String content = "package p;"
+ + "public class Test{ \n"
+ + " void testSwitchCaseGuardedPatternNestedParenthesizedPattern() {\n"
+ + " Object str = \"pattern matching switch\";\n"
+ + " switch (str) {\n"
+ + "case ( \n"
+ + " String s) && s.length() >= 2 && \n"
+ + " \n"
+ + " (s.contains(\"@\") || s.contains(\"!\")) \n"
+ + " \n"
+ + " ->\n"
+ + " String.format(\"Valid string value is %s\", s);default ->\n"
+ + " System.out.println(\"default formatting\");\n"
+ + " }\n"
+ + " }\n"
+ + "}";
+
+ String golden
+ = "package p;\n"
+ + "\n"
+ + "public class Test {\n"
+ + "\n"
+ + " void testSwitchCaseGuardedPatternNestedParenthesizedPattern() {\n"
+ + " Object str = \"pattern matching switch\";\n"
+ + " switch (str) {\n"
+ + " case ( String s) && s.length() >= 2\n"
+ + " && (s.contains(\"@\") || s.contains(\"!\")) ->\n"
+ + " String.format(\"Valid string value is %s\", s);\n"
+ + " default ->\n"
+ + " System.out.println(\"default formatting\");\n"
+ + " }\n"
+ + " }\n"
+ + "}\n"
+ + "";
+ reformat(doc, content, golden);
+ }
+
+ public void testSwitchCaseAllPatterns() throws Exception {
+ try {
+ SourceVersion.valueOf("RELEASE_17"); //NOI18N
+ } catch (IllegalArgumentException ex) {
+ //OK, no RELEASE_17, skip test
+ return;
+ }
+ testFile = new File(getWorkDir(), "Test.java");
+ TestUtilities.copyStringToFile(testFile, "");
+ FileObject testSourceFO = FileUtil.toFileObject(testFile);
+ DataObject testSourceDO = DataObject.find(testSourceFO);
+ EditorCookie ec = (EditorCookie) testSourceDO.getCookie(EditorCookie.class);
+ final Document doc = ec.openDocument();
+ doc.putProperty(Language.class, JavaTokenId.language());
+ String content = "package p;"
+ + "public class Test{ \n"
+ + " void testSwitchCaseAllPatterns() {\n"
+ + " Object str = \"pattern matching switch\";\n"
+ + " IntStream iso = IntStream.of(1, 2);\n"
+ + " switch (str) {\n"
+ + "case null ->\n"
+ + " System.out.println(\"case with null formatting\");\n"
+ + " case String string\n"
+ + " && (string.length()== iso.filter(i -> i / 2 == 0).count() || string.length() == 0)\n"
+ + " ->\n"
+ + " System.out.println(\"case with pattern matching + condition + lambda expression formatting\");\n"
+ + " case String s && s.length() == 1 ->System.out.println(\"case with pattern matching + condition formatting\");\n"
+ + " case (String s && true )-> \n"
+ + " System.out.println(\"case with pattern matching + condition formatting\");\n"
+ + " case CharSequence\n"
+ + " s ->\n"
+ + " System.out.println(\"case with pattern matching formatting\");\n"
+ + " case\n"
+ + " default ->\n"
+ + " System.out.println(\"default formatting\");\n"
+ + "\n"
+ + " }\n"
+ + " }"
+ + "}";
+
+ String golden
+ = "package p;\n"
+ + "\n"
+ + "public class Test {\n"
+ + "\n"
+ + " void testSwitchCaseAllPatterns() {\n"
+ + " Object str = \"pattern matching switch\";\n"
+ + " IntStream iso = IntStream.of(1, 2);\n"
+ + " switch (str) {\n"
+ + " case null ->\n"
+ + " System.out.println(\"case with null formatting\");\n"
+ + " case String string && (string.length() == iso.filter(i -> i / 2 == 0).count() || string.length() == 0) ->\n"
+ + " System.out.println(\"case with pattern matching + condition + lambda expression formatting\");\n"
+ + " case String s && s.length() == 1 ->\n"
+ + " System.out.println(\"case with pattern matching + condition formatting\");\n"
+ + " case (String s && true ) ->\n"
+ + " System.out.println(\"case with pattern matching + condition formatting\");\n"
+ + " case CharSequence s ->\n"
+ + " System.out.println(\"case with pattern matching formatting\");\n"
+ + " case default ->\n"
+ + " System.out.println(\"default formatting\");\n"
+ + "\n"
+ + " }\n"
+ + " }\n"
+ + "}\n"
+ + "";
+ reformat(doc, content, golden);
+ }
+
+ public void testSwitchCaseAllPatternsWithReturnValue() throws Exception {
+ try {
+ SourceVersion.valueOf("RELEASE_17"); //NOI18N
+ } catch (IllegalArgumentException ex) {
+ //OK, no RELEASE_17, skip test
+ return;
+ }
+ testFile = new File(getWorkDir(), "Test.java");
+ TestUtilities.copyStringToFile(testFile, "");
+ FileObject testSourceFO = FileUtil.toFileObject(testFile);
+ DataObject testSourceDO = DataObject.find(testSourceFO);
+ EditorCookie ec = (EditorCookie) testSourceDO.getCookie(EditorCookie.class);
+ final Document doc = ec.openDocument();
+ doc.putProperty(Language.class, JavaTokenId.language());
+ String content = "package p;"
+ + "public class Test{ \n"
+ + "void testSwitchCaseAllPatterns() {\n"
+ + " Object str = \"pattern matching switch\";\n"
+ + " IntStream iso = IntStream.of(1, 2);\n"
+ + " String retVal = switch (str) {\n"
+ + "case null ->\n"
+ + " \"case with null formatting\";\n"
+ + " case String string\n"
+ + " && (string.length()== iso.filter(i -> i / 2 == 0).count() || string.length() == 0)\n"
+ + " ->\n"
+ + " \"case with pattern matching + condition + lambda expression formatting\";\n"
+ + " case String s && s.length() == 1 ->\"case with pattern matching + condition formatting\";\n"
+ + " case (String s && true )-> \n"
+ + " \"case with pattern matching + condition formatting\";\n"
+ + " case CharSequence\n"
+ + " s ->\n"
+ + " \"case with pattern matching formatting\";\n"
+ + " case\n"
+ + " default ->\n"
+ + " \"default formatting\";\n"
+ + "\n"
+ + " };\n"
+ + " }"
+ + "}";
+
+ String golden
+ = "package p;\n"
+ + "\n"
+ + "public class Test {\n"
+ + "\n"
+ + " void testSwitchCaseAllPatterns() {\n"
+ + " Object str = \"pattern matching switch\";\n"
+ + " IntStream iso = IntStream.of(1, 2);\n"
+ + " String retVal = switch (str) {\n"
+ + " case null ->\n"
+ + " \"case with null formatting\";\n"
+ + " case String string && (string.length() == iso.filter(i -> i / 2 == 0).count() || string.length() == 0) ->\n"
+ + " \"case with pattern matching + condition + lambda expression formatting\";\n"
+ + " case String s && s.length() == 1 ->\n"
+ + " \"case with pattern matching + condition formatting\";\n"
+ + " case (String s && true ) ->\n"
+ + " \"case with pattern matching + condition formatting\";\n"
+ + " case CharSequence s ->\n"
+ + " \"case with pattern matching formatting\";\n"
+ + " case default ->\n"
+ + " \"default formatting\";\n"
+ + "\n"
+ + " };\n"
+ + " }\n"
+ + "}\n"
+ + "";
+ reformat(doc, content, golden);
+ }
+
public void testDoWhile() throws Exception {
testFile = new File(getWorkDir(), "Test.java");
TestUtilities.copyStringToFile(testFile,
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@netbeans.apache.org
For additional commands, e-mail: commits-help@netbeans.apache.org
For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists