[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
This commit is contained in:
Nikita Eshkeev
2021-07-28 19:15:34 +00:00
committed by intellij-monorepo-bot
parent 97eaa6abb6
commit 5657d92469
4 changed files with 30 additions and 3 deletions
@@ -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;
}
@@ -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;
}
@@ -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();
}
}
}
@@ -80,6 +80,10 @@ public class LightPatternsForSwitchHighlightingTest extends LightJavaCodeInsight
doTest();
}
public void testMultipleReferencesToPatternVariable() {
doTest();
}
private void doTest() {
myFixture.configureByFile(getTestName(false) + ".java");
myFixture.checkHighlighting();