diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java index 19bb6b8b3d15..2158fe8c316e 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java @@ -48,6 +48,8 @@ import org.jetbrains.annotations.Nullable; import java.util.*; import java.util.function.Function; +import static com.intellij.util.ObjectUtils.tryCast; + // java highlighting: problems in java code like unresolved/incompatible symbols/methods etc. public class HighlightVisitorImpl extends JavaElementVisitor implements HighlightVisitor { private HighlightInfoHolder myHolder; @@ -1950,6 +1952,32 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh myHolder.add(checkFeature(deconstructionPattern, HighlightingFeature.PATTERN_GUARDS_AND_RECORD_PATTERNS)); } + @Override + public void visitDeconstructionList(@NotNull PsiDeconstructionList deconstructionList) { + super.visitDeconstructionList(deconstructionList); + // We are checking the case when the pattern looks similar to method call in switch and want to show user-friendly message that here + // only constant expressions are expected. + // it is required to do it in deconstruction list because unresolved reference won't let any parents show any highlighting, + // so we need element which is not parent + PsiElement parent = deconstructionList.getParent(); + PsiDeconstructionPattern pattern = tryCast(parent, PsiDeconstructionPattern.class); + if (pattern == null) return; + PsiElement grandParent = parent.getParent(); + if (!(grandParent instanceof PsiCaseLabelElementList)) return; + PsiTypeElement typeElement = pattern.getTypeElement(); + PsiJavaCodeReferenceElement ref = PsiTreeUtil.getChildOfType(typeElement, PsiJavaCodeReferenceElement.class); + if (ref == null) return; + if (ref.multiResolve(true).length == 0) { + PsiElementFactory elementFactory = PsiElementFactory.getInstance(myFile.getProject()); + PsiExpression expression = elementFactory.createExpressionFromText(pattern.getText(), grandParent); + PsiMethodCallExpression call = tryCast(expression, PsiMethodCallExpression.class); + if (call == null) return; + if (call.getMethodExpression().resolve() != null) { + myHolder.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(pattern.getTextRange()).descriptionAndTooltip(JavaErrorBundle.message("switch.constant.expression.required")).create()); + } + } + } + @Override public void visitTypeTestPattern(@NotNull PsiTypeTestPattern pattern) { super.visitTypeTestPattern(pattern); diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/SwitchByString.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/SwitchByString.java index f320c374c5b5..3badd11710cf 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/SwitchByString.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/SwitchByString.java @@ -25,7 +25,7 @@ public class Test { String key = "key"; switch (key) { case foo: - case getStringValue(): { + case getStringValue(): { System.out.println("illegal"); break; } diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/IncompleteSwitchEnum.java b/java/java-tests/testData/inspection/dataFlow/fixture/IncompleteSwitchEnum.java index 5ecc3d9dfe7e..953af9b5e85a 100644 --- a/java/java-tests/testData/inspection/dataFlow/fixture/IncompleteSwitchEnum.java +++ b/java/java-tests/testData/inspection/dataFlow/fixture/IncompleteSwitchEnum.java @@ -4,7 +4,7 @@ public enum Test { void test() { Integer code = getCode(); switch (code) { - case VALUE.value() + case VALUE.value() } if (code == VALUE.value()) { getCode();