From 248f36eac88432d5cd1e053f7255bb3a59a6e7a5 Mon Sep 17 00:00:00 2001 From: Bartek Pacia Date: Tue, 4 Mar 2025 22:19:59 +0000 Subject: [PATCH] [java-typing] fix typing `{` inside a Java string in switch-case expression adding `}` outside the string literal fix IDEA-368266 Merge-request: IJ-MR-156690 Merged-by: Bartek Pacia GitOrigin-RevId: 68b837ddad0bc7e614ee51fa1934e86b13df69b4 --- .../AbstractBasicJavaTypedHandler.java | 9 ++++++- ...essionAssignmentInStringLiteral_after.java | 10 ++++++++ ...ssionAssignmentInStringLiteral_before.java | 10 ++++++++ ...itchRuleExpressionInCharLiteral_after.java | 7 ++++++ ...tchRuleExpressionInCharLiteral_before.java | 7 ++++++ ...chRuleExpressionInStringLiteral_after.java | 7 ++++++ ...hRuleExpressionInStringLiteral_before.java | 7 ++++++ ...uleExpressionInTextBlockLiteral_after.java | 9 +++++++ ...leExpressionInTextBlockLiteral_before.java | 9 +++++++ ...tchRuleStatementInStringLiteral_after.java | 10 ++++++++ ...chRuleStatementInStringLiteral_before.java | 10 ++++++++ .../java/codeInsight/JavaTypingTest.java | 25 +++++++++++++++++++ 12 files changed, 119 insertions(+), 1 deletion(-) create mode 100644 java/java-tests/testData/codeInsight/typing/openBracesAfterSwitchRuleExpressionAssignmentInStringLiteral_after.java create mode 100644 java/java-tests/testData/codeInsight/typing/openBracesAfterSwitchRuleExpressionAssignmentInStringLiteral_before.java create mode 100644 java/java-tests/testData/codeInsight/typing/openBracesAfterSwitchRuleExpressionInCharLiteral_after.java create mode 100644 java/java-tests/testData/codeInsight/typing/openBracesAfterSwitchRuleExpressionInCharLiteral_before.java create mode 100644 java/java-tests/testData/codeInsight/typing/openBracesAfterSwitchRuleExpressionInStringLiteral_after.java create mode 100644 java/java-tests/testData/codeInsight/typing/openBracesAfterSwitchRuleExpressionInStringLiteral_before.java create mode 100644 java/java-tests/testData/codeInsight/typing/openBracesAfterSwitchRuleExpressionInTextBlockLiteral_after.java create mode 100644 java/java-tests/testData/codeInsight/typing/openBracesAfterSwitchRuleExpressionInTextBlockLiteral_before.java create mode 100644 java/java-tests/testData/codeInsight/typing/openBracesAfterSwitchRuleStatementInStringLiteral_after.java create mode 100644 java/java-tests/testData/codeInsight/typing/openBracesAfterSwitchRuleStatementInStringLiteral_before.java diff --git a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/AbstractBasicJavaTypedHandler.java b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/AbstractBasicJavaTypedHandler.java index 5a6ecd95cccf..a62660c123e5 100644 --- a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/AbstractBasicJavaTypedHandler.java +++ b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/AbstractBasicJavaTypedHandler.java @@ -17,6 +17,7 @@ import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; import com.intellij.psi.codeStyle.CodeStyleManager; import com.intellij.psi.impl.source.BasicJavaAstTreeUtil; +import com.intellij.psi.tree.IElementType; import com.intellij.psi.tree.ParentAwareTokenSet; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.text.CharArrayUtil; @@ -129,7 +130,7 @@ public abstract class AbstractBasicJavaTypedHandler extends TypedHandlerDelegate } } if (fileType instanceof JavaFileType && c == '{') { - int offset = editor.getCaretModel().getOffset(); + final int offset = editor.getCaretModel().getOffset(); if (offset == 0) { return Result.CONTINUE; } @@ -234,6 +235,12 @@ public abstract class AbstractBasicJavaTypedHandler extends TypedHandlerDelegate private static boolean afterArrowInCase(@Nullable PsiElement leaf) { if (leaf == null) return false; + IElementType leafElementType = leaf.getNode().getElementType(); + if (leafElementType == JavaTokenType.STRING_LITERAL || + leafElementType == JavaTokenType.TEXT_BLOCK_LITERAL || + leafElementType == JavaTokenType.CHARACTER_LITERAL) { + return false; + } PsiElement prevLeaf = PsiTreeUtil.prevVisibleLeaf(leaf); if (prevLeaf == null) return false; if (prevLeaf.getNode().getElementType() != JavaTokenType.ARROW) return false; diff --git a/java/java-tests/testData/codeInsight/typing/openBracesAfterSwitchRuleExpressionAssignmentInStringLiteral_after.java b/java/java-tests/testData/codeInsight/typing/openBracesAfterSwitchRuleExpressionAssignmentInStringLiteral_after.java new file mode 100644 index 000000000000..d9370dfa5391 --- /dev/null +++ b/java/java-tests/testData/codeInsight/typing/openBracesAfterSwitchRuleExpressionAssignmentInStringLiteral_after.java @@ -0,0 +1,10 @@ +class X { + public static String foo(int bar) { + String path1 = null; + switch (foo) { + case 1 -> path1 = "bar{"; + case 2 -> path1 = "Hello"; + } + return path1; + } +} diff --git a/java/java-tests/testData/codeInsight/typing/openBracesAfterSwitchRuleExpressionAssignmentInStringLiteral_before.java b/java/java-tests/testData/codeInsight/typing/openBracesAfterSwitchRuleExpressionAssignmentInStringLiteral_before.java new file mode 100644 index 000000000000..e27acfe4584c --- /dev/null +++ b/java/java-tests/testData/codeInsight/typing/openBracesAfterSwitchRuleExpressionAssignmentInStringLiteral_before.java @@ -0,0 +1,10 @@ +class X { + public static String foo(int bar) { + String path1 = null; + switch (foo) { + case 1 -> path1 = "bar"; + case 2 -> path1 = "Hello"; + } + return path1; + } +} diff --git a/java/java-tests/testData/codeInsight/typing/openBracesAfterSwitchRuleExpressionInCharLiteral_after.java b/java/java-tests/testData/codeInsight/typing/openBracesAfterSwitchRuleExpressionInCharLiteral_after.java new file mode 100644 index 000000000000..2487b1cd6f50 --- /dev/null +++ b/java/java-tests/testData/codeInsight/typing/openBracesAfterSwitchRuleExpressionInCharLiteral_after.java @@ -0,0 +1,7 @@ +class X { + public static void main(String[] args) { + var a = switch (new Object()){ + case Object object -> '{'; + }; + } +} diff --git a/java/java-tests/testData/codeInsight/typing/openBracesAfterSwitchRuleExpressionInCharLiteral_before.java b/java/java-tests/testData/codeInsight/typing/openBracesAfterSwitchRuleExpressionInCharLiteral_before.java new file mode 100644 index 000000000000..c734df48db6c --- /dev/null +++ b/java/java-tests/testData/codeInsight/typing/openBracesAfterSwitchRuleExpressionInCharLiteral_before.java @@ -0,0 +1,7 @@ +class X { + public static void main(String[] args) { + var a = switch (new Object()){ + case Object object -> ''; + }; + } +} diff --git a/java/java-tests/testData/codeInsight/typing/openBracesAfterSwitchRuleExpressionInStringLiteral_after.java b/java/java-tests/testData/codeInsight/typing/openBracesAfterSwitchRuleExpressionInStringLiteral_after.java new file mode 100644 index 000000000000..8c9d2a34e48f --- /dev/null +++ b/java/java-tests/testData/codeInsight/typing/openBracesAfterSwitchRuleExpressionInStringLiteral_after.java @@ -0,0 +1,7 @@ +class X { + public static void main(String[] args) { + var a = switch (new Object()){ + case Object object -> "here{"; + }; + } +} diff --git a/java/java-tests/testData/codeInsight/typing/openBracesAfterSwitchRuleExpressionInStringLiteral_before.java b/java/java-tests/testData/codeInsight/typing/openBracesAfterSwitchRuleExpressionInStringLiteral_before.java new file mode 100644 index 000000000000..f5b284b75034 --- /dev/null +++ b/java/java-tests/testData/codeInsight/typing/openBracesAfterSwitchRuleExpressionInStringLiteral_before.java @@ -0,0 +1,7 @@ +class X { + public static void main(String[] args) { + var a = switch (new Object()){ + case Object object -> "here"; + }; + } +} diff --git a/java/java-tests/testData/codeInsight/typing/openBracesAfterSwitchRuleExpressionInTextBlockLiteral_after.java b/java/java-tests/testData/codeInsight/typing/openBracesAfterSwitchRuleExpressionInTextBlockLiteral_after.java new file mode 100644 index 000000000000..88c8a6bdfff2 --- /dev/null +++ b/java/java-tests/testData/codeInsight/typing/openBracesAfterSwitchRuleExpressionInTextBlockLiteral_after.java @@ -0,0 +1,9 @@ +class X { + public static void main(String[] args) { + var a = switch (new Object()){ + case Object object -> """ + hello{ + """; + }; + } +} diff --git a/java/java-tests/testData/codeInsight/typing/openBracesAfterSwitchRuleExpressionInTextBlockLiteral_before.java b/java/java-tests/testData/codeInsight/typing/openBracesAfterSwitchRuleExpressionInTextBlockLiteral_before.java new file mode 100644 index 000000000000..b0c932f0a58f --- /dev/null +++ b/java/java-tests/testData/codeInsight/typing/openBracesAfterSwitchRuleExpressionInTextBlockLiteral_before.java @@ -0,0 +1,9 @@ +class X { + public static void main(String[] args) { + var a = switch (new Object()){ + case Object object -> """ + hello + """; + }; + } +} diff --git a/java/java-tests/testData/codeInsight/typing/openBracesAfterSwitchRuleStatementInStringLiteral_after.java b/java/java-tests/testData/codeInsight/typing/openBracesAfterSwitchRuleStatementInStringLiteral_after.java new file mode 100644 index 000000000000..42b5fc7bbb16 --- /dev/null +++ b/java/java-tests/testData/codeInsight/typing/openBracesAfterSwitchRuleStatementInStringLiteral_after.java @@ -0,0 +1,10 @@ +class X { + public static String foo(int bar) { + switch (bar) { + case 10: + return "matched{"; + default: + return "default"; + } + } +} diff --git a/java/java-tests/testData/codeInsight/typing/openBracesAfterSwitchRuleStatementInStringLiteral_before.java b/java/java-tests/testData/codeInsight/typing/openBracesAfterSwitchRuleStatementInStringLiteral_before.java new file mode 100644 index 000000000000..fd3c97cfba27 --- /dev/null +++ b/java/java-tests/testData/codeInsight/typing/openBracesAfterSwitchRuleStatementInStringLiteral_before.java @@ -0,0 +1,10 @@ +class X { + public static String foo(int bar) { + switch (bar) { + case 10: + return "matched"; + default: + return "default"; + } + } +} diff --git a/java/java-tests/testSrc/com/intellij/java/codeInsight/JavaTypingTest.java b/java/java-tests/testSrc/com/intellij/java/codeInsight/JavaTypingTest.java index 5c6a08eba533..3256cc3651c1 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInsight/JavaTypingTest.java +++ b/java/java-tests/testSrc/com/intellij/java/codeInsight/JavaTypingTest.java @@ -105,4 +105,29 @@ public class JavaTypingTest extends AbstractBasicJavaTypingTest { setLanguageLevel(LanguageLevel.JDK_21); doTest('{'); } + + public void testOpenBracesAfterSwitchRuleStatementInStringLiteral() { + setLanguageLevel(LanguageLevel.JDK_21); + doTest('{'); + } + + public void testOpenBracesAfterSwitchRuleExpressionAssignmentInStringLiteral() { + setLanguageLevel(LanguageLevel.JDK_21); + doTest('{'); + } + + public void testOpenBracesAfterSwitchRuleExpressionInStringLiteral() { + setLanguageLevel(LanguageLevel.JDK_21); + doTest('{'); + } + + public void testOpenBracesAfterSwitchRuleExpressionInTextBlockLiteral() { + setLanguageLevel(LanguageLevel.JDK_21); + doTest('{'); + } + + public void testOpenBracesAfterSwitchRuleExpressionInCharLiteral() { + setLanguageLevel(LanguageLevel.JDK_21); + doTest('{'); + } }