[java] show user-friendly error message for patterns similar to calls in switch labels

GitOrigin-RevId: 09f4de4b1929950320511e853a00c2a3dc1e4fb0
This commit is contained in:
Roman Ivanov
2022-07-19 18:03:40 +00:00
committed by intellij-monorepo-bot
parent 914b662e53
commit f5621d553f
3 changed files with 30 additions and 2 deletions
@@ -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);
@@ -25,7 +25,7 @@ public class Test {
String key = "key";
switch (key) {
case foo:
case <error descr="Cannot resolve symbol 'getStringValue'">getStringValue</error>(): {
case <error descr="Constant expression, pattern or null is required"><error descr="Cannot resolve symbol 'getStringValue'">getStringValue</error>()</error>: {
System.out.println("illegal");
break;
}
@@ -4,7 +4,7 @@ public enum Test {
void test() {
Integer code = getCode();
switch (code) {
case <warning descr="Switch label 'VALUE.value()' is the only reachable in the whole switch">VALUE.<error descr="Cannot resolve symbol 'value'">value</error>()</warning><EOLError descr="':' expected"></EOLError>
case <error descr="Constant expression, pattern or null is required"><warning descr="Switch label 'VALUE.value()' is the only reachable in the whole switch">VALUE.<error descr="Cannot resolve symbol 'value'">value</error>()</warning></error><EOLError descr="':' expected"></EOLError>
}
if (code == VALUE.value()) {
getCode();