[java][switch] IDEA-273874 "Can't resolve symbol" false-negative in switch with fall-through semantics

Remove the SwitchBlockHighlightingModel#checkFallthroughReferences because it might produce too much noise for and bring no value.

GitOrigin-RevId: 10d848aaa38ad5a4c15f77726ac835ab517068d5
This commit is contained in:
Nikita Eshkeev
2021-07-28 19:15:33 +00:00
committed by intellij-monorepo-bot
parent 52663c3431
commit 97eaa6abb6
2 changed files with 3 additions and 94 deletions
@@ -28,7 +28,6 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
import java.util.stream.Collectors;
import static com.intellij.codeInsight.daemon.impl.analysis.SwitchBlockHighlightingModel.PatternsInSwitchBlockHighlightingModel.CompletenessResult.*;
import static com.intellij.psi.PsiModifier.ABSTRACT;
@@ -573,7 +572,6 @@ public class SwitchBlockHighlightingModel {
}
}
checkFallThroughInSwitchLabels(switchBlockGroup, results, alreadyFallThroughElements);
checkFallthroughReferences(switchBlockGroup, results);
}
private static void checkFallThroughInSwitchLabels(@NotNull List<List<PsiSwitchLabelStatementBase>> switchBlockGroup,
@@ -753,70 +751,6 @@ public class SwitchBlockHighlightingModel {
results.add(info);
}
private static void checkFallthroughReferences(@NotNull List<List<PsiSwitchLabelStatementBase>> switchBlockGroup,
@NotNull List<HighlightInfo> results) {
final List<PsiSwitchLabelStatementBase> switches = switchBlockGroup.stream()
.flatMap(List::stream)
.limit(2)
.collect(Collectors.toList());
if (switches.size() < 2) return;
final Set<PsiPatternVariable> patternVariables = new HashSet<>();
int caseLabelsProcessed = 0;
for (PsiElement element = switches.get(0); element != null; element = element.getNextSibling()) {
if (element instanceof PsiSwitchLabelStatementBase) {
final PsiSwitchLabelStatementBase caseLabel = (PsiSwitchLabelStatementBase)element;
final PsiStatement prevStmt = PsiTreeUtil.getPrevSiblingOfType(caseLabel, PsiStatement.class);
final boolean currentLabelIsFallthrough = ControlFlowUtils.statementMayCompleteNormally(prevStmt);
if (!currentLabelIsFallthrough) {
caseLabelsProcessed = 0;
patternVariables.clear();
}
if (!isCaseNull(element)) caseLabelsProcessed++;
patternVariables.addAll(getPatternVariables(caseLabel));
continue;
}
if (caseLabelsProcessed < 2) continue;
final PatternVariableReferencesResolveVisitor visitor = new PatternVariableReferencesResolveVisitor(caseLabelsProcessed, patternVariables);
element.accept(visitor);
results.addAll(visitor.myResults);
}
}
@NotNull
private static Set<PsiPatternVariable> getPatternVariables(@Nullable PsiSwitchLabelStatementBase label) {
if (label == null) return Collections.emptySet();
final PsiCaseLabelElementList list = ((PsiSwitchLabelStatementBase)label).getCaseLabelElementList();
if (list == null) return Collections.emptySet();
return Arrays.stream(list.getElements())
.filter(PsiTypeTestPattern.class::isInstance)
.map(PsiTypeTestPattern.class::cast)
.map(PsiTypeTestPattern::getPatternVariable)
.collect(Collectors.toSet());
}
private static boolean isCaseNull(@Nullable PsiElement item) {
if (item == null) return false;
if (!(item instanceof PsiSwitchLabelStatementBase)) return false;
final PsiSwitchLabelStatementBase switchLabel = (PsiSwitchLabelStatementBase)item;
final PsiCaseLabelElementList caseElementsList = switchLabel.getCaseLabelElementList();
if (caseElementsList == null) return false;
final PsiCaseLabelElement[] elements = caseElementsList.getElements();
if (elements.length != 1) return false;
return elements[0].getNode().getFirstChildNode().getElementType() == JavaTokenType.NULL_KEYWORD;
}
@Nullable
private PsiElement findDefaultElement() {
PsiCodeBlock body = myBlock.getBody();
@@ -918,31 +852,6 @@ public class SwitchBlockHighlightingModel {
COMPLETE_WITHOUT_TOTAL
}
private static class PatternVariableReferencesResolveVisitor extends JavaRecursiveElementWalkingVisitor {
private final int myLabelsProcessed;
private final Set<PsiPatternVariable> myPatternVariables;
private final List<HighlightInfo> myResults;
public PatternVariableReferencesResolveVisitor(int totalCaseLabelsProcessed, Set<PsiPatternVariable> patternVariables) {
myLabelsProcessed = totalCaseLabelsProcessed;
myPatternVariables = patternVariables;
myResults = new SmartList<>();
}
@Override
public void visitReferenceElement(PsiJavaCodeReferenceElement reference) {
if (myLabelsProcessed < 2) return;
super.visitReferenceElement(reference);
final PsiElement anchor = reference.resolve();
if (!(anchor instanceof PsiPatternVariable) || !myPatternVariables.contains(anchor)) return;
final String referenceName = reference.getElement().getText();
final HighlightInfo error = createError(reference, JavaErrorBundle.message("cannot.resolve.symbol", referenceName));
myResults.add(error);
}
}
}
}
@@ -5,12 +5,12 @@ class Main {
case String s:
case null:
case <error descr="Illegal fall-through to a pattern">Integer i</error>:
System.out.println(<error descr="Cannot resolve symbol 'i'">i</error> + 1);
System.out.println(i + 1);
break;
case Long l:
System.out.println(l);
case <error descr="Illegal fall-through to a pattern">Character c</error>:
System.out.println(<error descr="Cannot resolve symbol 'c'">c</error>);
System.out.println(c);
default:
throw new IllegalStateException("Unexpected value: " + o);
}
@@ -90,7 +90,7 @@ class Main {
switch (o) {
case String s:
case <error descr="Illegal fall-through to a pattern">Integer i</error>:
System.out.println(<error descr="Cannot resolve symbol 'i'">i</error> + 1);
System.out.println(i + 1);
default:
throw new IllegalStateException("Unexpected value: " + o);
}