From 5657d924699816c79e6b8329e207c7639da3829b Mon Sep 17 00:00:00 2001 From: Nikita Eshkeev Date: Mon, 26 Jul 2021 19:29:33 +0300 Subject: [PATCH] [java][switch resolve] IDEA-273929 Good code red - cannot resolve symbol in switch statement group IDEA used to allow resolving if a statement or an expression that uses a pattern variable in a switch case label follows the switch case label immediately. This led to errors in resolving references to pattern variables when their enclosing statement or expression is not the immediate right sibling of the case label. Now IDEA looks for a switch case label among all the left siblings of the currently analyzing scope and enables resolving if a case label is found, and it's the same switch case label that is being analyzed. GitOrigin-RevId: 758c34fde30db2fe9692d8076c49af2b3efae38f --- .../java/PsiCaseLabelElementListImpl.java | 1 + .../java/PsiSwitchLabelStatementImpl.java | 9 ++++++--- .../MultipleReferencesToPatternVariable.java | 19 +++++++++++++++++++ ...ightPatternsForSwitchHighlightingTest.java | 4 ++++ 4 files changed, 30 insertions(+), 3 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlightingPatternsInSwitch/MultipleReferencesToPatternVariable.java diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiCaseLabelElementListImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiCaseLabelElementListImpl.java index 7229106d1b15..ee56f6289fd6 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiCaseLabelElementListImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiCaseLabelElementListImpl.java @@ -92,6 +92,7 @@ public class PsiCaseLabelElementListImpl extends CompositePsiElement implements // Do not resolve elements from the list of elements of the case rule if (lastParent != null) return true; for (PsiCaseLabelElement label : getElements()) { + if (place == label) return true; boolean shouldKeepGoing = label.processDeclarations(processor, state, null, place); if (!shouldKeepGoing) return false; } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiSwitchLabelStatementImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiSwitchLabelStatementImpl.java index e3f63e1792d0..3bdada3f8626 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiSwitchLabelStatementImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiSwitchLabelStatementImpl.java @@ -95,9 +95,12 @@ public class PsiSwitchLabelStatementImpl extends PsiSwitchLabelStatementBaseImpl final AtomicBoolean thisSwitchLabelIsImmediate = new AtomicBoolean(); - PsiTreeUtil.treeWalkUp(place, getParent(), (currentScope, __) -> { - final PsiElement sibling = PsiTreeUtil.skipWhitespacesBackward(currentScope.getPrevSibling()); - if (sibling == this) { + PsiTreeUtil.treeWalkUp(place, getParent(), (currentScope, prevScope) -> { + final PsiElement immediateSwitchLabel = PsiTreeUtil.findSiblingBackward(currentScope, + JavaElementType.SWITCH_LABEL_STATEMENT, + false, + null); + if (immediateSwitchLabel == this) { thisSwitchLabelIsImmediate.set(true); return false; } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlightingPatternsInSwitch/MultipleReferencesToPatternVariable.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlightingPatternsInSwitch/MultipleReferencesToPatternVariable.java new file mode 100644 index 000000000000..a7c92e9cd0a9 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlightingPatternsInSwitch/MultipleReferencesToPatternVariable.java @@ -0,0 +1,19 @@ + +class Main { + void multipleReferencesToPatternVariable(Object o) { + switch (o) { + case Character c: + if (c == 7) { + System.out.println(c > 2); + } + if (c == 9) { + System.out.println(c + 2); + } + // hello, world + if (c == 11) { } + System.out.println(c); + default: + System.out.println(); + } + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/LightPatternsForSwitchHighlightingTest.java b/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/LightPatternsForSwitchHighlightingTest.java index cf6c2f41893a..8599835cf8be 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/LightPatternsForSwitchHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/LightPatternsForSwitchHighlightingTest.java @@ -80,6 +80,10 @@ public class LightPatternsForSwitchHighlightingTest extends LightJavaCodeInsight doTest(); } + public void testMultipleReferencesToPatternVariable() { + doTest(); + } + private void doTest() { myFixture.configureByFile(getTestName(false) + ".java"); myFixture.checkHighlighting();