mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[java-highlighting] More generics stuff and switch stuff migrated
Part of IDEA-365344 Create a new Java error highlighter with minimal dependencies (PSI only) GitOrigin-RevId: 70990f955de96df8d98ee3097ca01d9b4f529d4b
This commit is contained in:
committed by
intellij-monorepo-bot
parent
1a195620e7
commit
aea97243cf
@@ -164,6 +164,16 @@ new.expression.qualified.malformed=Invalid qualified new
|
||||
new.expression.qualified.static.class=Qualified new of static class
|
||||
new.expression.qualified.anonymous.implements.interface=Anonymous class implements interface; cannot have qualifier for new
|
||||
new.expression.qualified.qualified.class.reference=Qualified class reference is not allowed in qualified new
|
||||
new.expression.diamond.not.allowed=Diamond operator is not allowed here
|
||||
|
||||
reference.type.argument.static.class=Type arguments are not allowed here because class ''{0}'' is static
|
||||
reference.type.needs.type.arguments=Improperly formed type: ''{0}'' needs type arguments because its qualifier has type arguments
|
||||
reference.local.class.other.switch.branch=Local class ''{0}'' cannot be referenced from another switch branch
|
||||
|
||||
statement.case.outside.switch=Case statement outside switch
|
||||
|
||||
guard.misplaced=Guard is allowed after patterns only
|
||||
guard.evaluated.to.false=This case label has a guard that is a constant expression with value 'false'
|
||||
|
||||
comment.shebang.java.file=Shebang mechanism in .java files is not permitted
|
||||
comment.unclosed=Unclosed comment
|
||||
|
||||
+21
@@ -115,4 +115,25 @@ final class ExpressionChecker {
|
||||
}
|
||||
myVisitor.report(JavaErrorKinds.TYPE_INCOMPATIBLE.create(elementToHighlight, new JavaIncompatibleTypeErrorContext(lType, rType)));
|
||||
}
|
||||
|
||||
void checkLocalClassReferencedFromAnotherSwitchBranch(@NotNull PsiJavaCodeReferenceElement ref, @NotNull PsiClass aClass) {
|
||||
if (!(aClass.getParent() instanceof PsiDeclarationStatement declarationStatement) ||
|
||||
!(declarationStatement.getParent() instanceof PsiCodeBlock codeBlock) ||
|
||||
!(codeBlock.getParent() instanceof PsiSwitchBlock)) {
|
||||
return;
|
||||
}
|
||||
boolean classSeen = false;
|
||||
for (PsiStatement statement : codeBlock.getStatements()) {
|
||||
if (classSeen) {
|
||||
if (PsiTreeUtil.isAncestor(statement, ref, true)) break;
|
||||
if (statement instanceof PsiSwitchLabelStatement) {
|
||||
myVisitor.report(JavaErrorKinds.REFERENCE_LOCAL_CLASS_OTHER_SWITCH_BRANCH.create(ref, aClass));
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (statement == declarationStatement) {
|
||||
classSeen = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+37
-1
@@ -81,6 +81,42 @@ final class GenericsChecker {
|
||||
if (IncompleteModelUtil.isIncompleteModel(statement) && IncompleteModelUtil.isPotentiallyConvertible(parameterType, itemType, expression)) {
|
||||
return;
|
||||
}
|
||||
myVisitor.report(JavaErrorKinds.TYPE_INCOMPATIBLE.create(parameter, new JavaIncompatibleTypeErrorContext(parameterType, itemType)));
|
||||
myVisitor.report(JavaErrorKinds.TYPE_INCOMPATIBLE.create(parameter, new JavaIncompatibleTypeErrorContext(itemType, parameterType)));
|
||||
}
|
||||
|
||||
void checkDiamondTypeNotAllowed(@NotNull PsiNewExpression expression) {
|
||||
PsiReferenceParameterList typeArgumentList = expression.getTypeArgumentList();
|
||||
PsiTypeElement[] typeParameterElements = typeArgumentList.getTypeParameterElements();
|
||||
if (typeParameterElements.length == 1 && typeParameterElements[0].getType() instanceof PsiDiamondType) {
|
||||
myVisitor.report(JavaErrorKinds.NEW_EXPRESSION_DIAMOND_NOT_ALLOWED.create(typeArgumentList));
|
||||
}
|
||||
}
|
||||
|
||||
void checkSelectStaticClassFromParameterizedType(@Nullable PsiElement resolved, @NotNull PsiJavaCodeReferenceElement ref) {
|
||||
if (resolved instanceof PsiClass psiClass && psiClass.hasModifierProperty(PsiModifier.STATIC)) {
|
||||
PsiElement qualifier = ref.getQualifier();
|
||||
if (qualifier instanceof PsiJavaCodeReferenceElement referenceElement) {
|
||||
PsiReferenceParameterList parameterList = referenceElement.getParameterList();
|
||||
if (parameterList != null && parameterList.getTypeArguments().length > 0) {
|
||||
myVisitor.report(JavaErrorKinds.REFERENCE_TYPE_ARGUMENT_STATIC_CLASS.create(parameterList, psiClass));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* see <a href="http://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.8">JLS 4.8 on raw types</a>
|
||||
*/
|
||||
void checkRawOnParameterizedType(@NotNull PsiJavaCodeReferenceElement parent, @Nullable PsiElement resolved) {
|
||||
PsiReferenceParameterList list = parent.getParameterList();
|
||||
if (list == null || list.getTypeArguments().length > 0) return;
|
||||
if (parent.getQualifier() instanceof PsiJavaCodeReferenceElement ref &&
|
||||
ref.getTypeParameters().length > 0 &&
|
||||
resolved instanceof PsiTypeParameterListOwner typeParameterListOwner &&
|
||||
typeParameterListOwner.hasTypeParameters() &&
|
||||
!typeParameterListOwner.hasModifierProperty(PsiModifier.STATIC) &&
|
||||
parent.getReferenceNameElement() != null) {
|
||||
myVisitor.report(JavaErrorKinds.REFERENCE_TYPE_NEEDS_TYPE_ARGUMENTS.create(parent));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+21
@@ -41,6 +41,7 @@ final class JavaErrorVisitor extends JavaElementVisitor {
|
||||
final @NotNull MethodChecker myMethodChecker = new MethodChecker(this);
|
||||
private final @NotNull ReceiverChecker myReceiverChecker = new ReceiverChecker(this);
|
||||
final @NotNull ExpressionChecker myExpressionChecker = new ExpressionChecker(this);
|
||||
private final @NotNull StatementChecker myStatementChecker = new StatementChecker(this);
|
||||
private final @NotNull LiteralChecker myLiteralChecker = new LiteralChecker(this);
|
||||
private boolean myHasError; // true if myHolder.add() was called with HighlightInfo of >=ERROR severity. On each .visit(PsiElement) call this flag is reset. Useful to determine whether the error was already reported while visiting this PsiElement.
|
||||
|
||||
@@ -361,9 +362,27 @@ final class JavaErrorVisitor extends JavaElementVisitor {
|
||||
JavaResolveResult result = ref instanceof PsiExpression ? resolveOptimised(ref, myFile) : doVisitReferenceElement(ref);
|
||||
if (result != null) {
|
||||
PsiElement resolved = result.getElement();
|
||||
if (!hasErrorResults() && resolved instanceof PsiClass aClass) {
|
||||
myExpressionChecker.checkLocalClassReferencedFromAnotherSwitchBranch(ref, aClass);
|
||||
}
|
||||
if (!hasErrorResults()) myGenericsChecker.checkRawOnParameterizedType(ref, resolved);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitSwitchLabelStatement(@NotNull PsiSwitchLabelStatement statement) {
|
||||
super.visitSwitchLabelStatement(statement);
|
||||
if (!hasErrorResults()) myStatementChecker.checkCaseStatement(statement);
|
||||
if (!hasErrorResults()) myStatementChecker.checkGuard(statement);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitSwitchLabeledRuleStatement(@NotNull PsiSwitchLabeledRuleStatement statement) {
|
||||
super.visitSwitchLabeledRuleStatement(statement);
|
||||
if (!hasErrorResults()) myStatementChecker.checkCaseStatement(statement);
|
||||
if (!hasErrorResults()) myStatementChecker.checkGuard(statement);
|
||||
}
|
||||
|
||||
private JavaResolveResult doVisitReferenceElement(@NotNull PsiJavaCodeReferenceElement ref) {
|
||||
JavaResolveResult result = resolveOptimised(ref, myFile);
|
||||
if (result == null) return null;
|
||||
@@ -377,6 +396,8 @@ final class JavaErrorVisitor extends JavaElementVisitor {
|
||||
if (!hasErrorResults()) myClassChecker.checkAbstractInstantiation(ref);
|
||||
if (!hasErrorResults()) myClassChecker.checkExtendsDuplicate(ref, resolved);
|
||||
if (!hasErrorResults()) myClassChecker.checkClassExtendsForeignInnerClass(ref, resolved);
|
||||
if (!hasErrorResults() && parent instanceof PsiNewExpression newExpression) myGenericsChecker.checkDiamondTypeNotAllowed(newExpression);
|
||||
if (!hasErrorResults()) myGenericsChecker.checkSelectStaticClassFromParameterizedType(resolved, ref);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.java.codeserver.highlighting;
|
||||
|
||||
import com.intellij.java.codeserver.highlighting.errors.JavaErrorKinds;
|
||||
import com.intellij.java.codeserver.highlighting.errors.JavaIncompatibleTypeErrorContext;
|
||||
import com.intellij.pom.java.JavaFeature;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
final class StatementChecker {
|
||||
private final @NotNull JavaErrorVisitor myVisitor;
|
||||
|
||||
StatementChecker(@NotNull JavaErrorVisitor visitor) { myVisitor = visitor; }
|
||||
|
||||
void checkCaseStatement(@NotNull PsiSwitchLabelStatementBase statement) {
|
||||
PsiSwitchBlock switchBlock = statement.getEnclosingSwitchBlock();
|
||||
if (switchBlock == null) {
|
||||
myVisitor.report(JavaErrorKinds.STATEMENT_CASE_OUTSIDE_SWITCH.create(statement));
|
||||
}
|
||||
}
|
||||
|
||||
void checkGuard(@NotNull PsiSwitchLabelStatementBase statement) {
|
||||
PsiExpression guardingExpr = statement.getGuardExpression();
|
||||
if (guardingExpr == null) return;
|
||||
myVisitor.checkFeature(guardingExpr, JavaFeature.PATTERN_GUARDS_AND_RECORD_PATTERNS);
|
||||
if (myVisitor.hasErrorResults()) return;
|
||||
PsiCaseLabelElementList list = statement.getCaseLabelElementList();
|
||||
if (list != null) {
|
||||
if (!ContainerUtil.exists(list.getElements(), e -> e instanceof PsiPattern)) {
|
||||
myVisitor.report(JavaErrorKinds.GUARD_MISPLACED.create(guardingExpr));
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!TypeConversionUtil.isBooleanType(guardingExpr.getType())) {
|
||||
myVisitor.report(JavaErrorKinds.TYPE_INCOMPATIBLE.create(
|
||||
guardingExpr, new JavaIncompatibleTypeErrorContext(PsiTypes.booleanType(), guardingExpr.getType())));
|
||||
return;
|
||||
}
|
||||
Object constVal = JavaPsiFacade.getInstance(myVisitor.project()).getConstantEvaluationHelper().computeConstantExpression(guardingExpr);
|
||||
if (Boolean.FALSE.equals(constVal)) {
|
||||
myVisitor.report(JavaErrorKinds.GUARD_EVALUATED_TO_FALSE.create(guardingExpr));
|
||||
}
|
||||
}
|
||||
}
|
||||
+10
@@ -354,6 +354,16 @@ public sealed interface JavaErrorKind<Psi extends PsiElement, Context> {
|
||||
return new Parameterized<>(myKey, myDescription, myTooltip, myAnchor, myRange, myHighlightType, validator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance of Parameterized with the specified highlight type function.
|
||||
*
|
||||
* @param type a function that determines the {@link JavaErrorHighlightType} for a given Psi object.
|
||||
* @return a new Parameterized instance with the updated highlight type function.
|
||||
*/
|
||||
Parameterized<Psi, Context> withHighlightType(@NotNull BiFunction<? super Psi, ? super Context, JavaErrorHighlightType> type) {
|
||||
return new Parameterized<>(myKey, myDescription, myTooltip, myAnchor, myRange, type, myValidator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance of Parameterized with a specified description function.
|
||||
*
|
||||
|
||||
+18
@@ -497,6 +497,24 @@ public final class JavaErrorKinds {
|
||||
parameterized("new.expression.qualified.anonymous.implements.interface");
|
||||
public static final Simple<PsiElement> NEW_EXPRESSION_QUALIFIED_QUALIFIED_CLASS_REFERENCE =
|
||||
error("new.expression.qualified.qualified.class.reference");
|
||||
public static final Simple<PsiReferenceParameterList> NEW_EXPRESSION_DIAMOND_NOT_ALLOWED =
|
||||
error("new.expression.diamond.not.allowed");
|
||||
|
||||
public static final Parameterized<PsiReferenceParameterList, PsiClass> REFERENCE_TYPE_ARGUMENT_STATIC_CLASS =
|
||||
parameterized(PsiReferenceParameterList.class, PsiClass.class, "reference.type.argument.static.class")
|
||||
.withRawDescription((list, cls) -> message("reference.type.argument.static.class", formatClass(cls)));
|
||||
public static final Simple<PsiJavaCodeReferenceElement> REFERENCE_TYPE_NEEDS_TYPE_ARGUMENTS =
|
||||
error(PsiJavaCodeReferenceElement.class, "reference.type.needs.type.arguments")
|
||||
.withRawDescription(ref -> message("reference.type.needs.type.arguments", requireNonNull(ref.getReferenceNameElement()).getText()));
|
||||
public static final Parameterized<PsiJavaCodeReferenceElement, PsiClass> REFERENCE_LOCAL_CLASS_OTHER_SWITCH_BRANCH =
|
||||
parameterized(PsiJavaCodeReferenceElement.class, PsiClass.class, "reference.local.class.other.switch.branch")
|
||||
.withHighlightType((ref, cls) -> JavaErrorHighlightType.WRONG_REF)
|
||||
.withRawDescription((ref, cls) -> message("reference.local.class.other.switch.branch", formatClass(cls)));
|
||||
|
||||
public static final Simple<PsiSwitchLabelStatementBase> STATEMENT_CASE_OUTSIDE_SWITCH = error("statement.case.outside.switch");
|
||||
|
||||
public static final Simple<PsiExpression> GUARD_MISPLACED = error("guard.misplaced");
|
||||
public static final Simple<PsiExpression> GUARD_EVALUATED_TO_FALSE = error("guard.evaluated.to.false");
|
||||
|
||||
public static final Simple<PsiComment> COMMENT_SHEBANG_JAVA_FILE = error(PsiComment.class, "comment.shebang.java.file")
|
||||
.withRange(psi -> TextRange.create(0, 2));
|
||||
|
||||
-51
@@ -720,19 +720,6 @@ public final class GenericsHighlightUtil {
|
||||
return info;
|
||||
}
|
||||
|
||||
static HighlightInfo.Builder checkDiamondTypeNotAllowed(@NotNull PsiNewExpression expression) {
|
||||
PsiReferenceParameterList typeArgumentList = expression.getTypeArgumentList();
|
||||
PsiTypeElement[] typeParameterElements = typeArgumentList.getTypeParameterElements();
|
||||
if (typeParameterElements.length == 1 && typeParameterElements[0].getType() instanceof PsiDiamondType) {
|
||||
String description = JavaErrorBundle.message("diamond.operator.not.allowed.here");
|
||||
HighlightInfo.Builder info =
|
||||
HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(typeArgumentList).descriptionAndTooltip(description);
|
||||
info.registerFix(QuickFixFactory.getInstance().createDeleteFix(typeArgumentList), null, null, null, null);
|
||||
return info;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static HighlightInfo.Builder checkTypeParameterInstantiation(@NotNull PsiNewExpression expression) {
|
||||
PsiJavaCodeReferenceElement classReference = expression.getClassOrAnonymousClassReference();
|
||||
if (classReference == null) return null;
|
||||
@@ -1149,44 +1136,6 @@ public final class GenericsHighlightUtil {
|
||||
return containingClass != null && PsiUtil.typeParametersIterator(containingClass).hasNext();
|
||||
}
|
||||
|
||||
static HighlightInfo.Builder checkSelectStaticClassFromParameterizedType(@Nullable PsiElement resolved, @NotNull PsiJavaCodeReferenceElement ref) {
|
||||
if (resolved instanceof PsiClass psiClass && psiClass.hasModifierProperty(PsiModifier.STATIC)) {
|
||||
PsiElement qualifier = ref.getQualifier();
|
||||
if (qualifier instanceof PsiJavaCodeReferenceElement referenceElement) {
|
||||
PsiReferenceParameterList parameterList = referenceElement.getParameterList();
|
||||
if (parameterList != null && parameterList.getTypeArguments().length > 0) {
|
||||
String message = JavaErrorBundle.message("generics.select.static.class.from.parameterized.type",
|
||||
HighlightUtil.formatClass(psiClass));
|
||||
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR)
|
||||
.range(parameterList)
|
||||
.descriptionAndTooltip(message)
|
||||
.registerFix(QuickFixFactory.getInstance().createDeleteFix(parameterList), null, null, null, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* see <a href="http://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.8">JLS 4.8 on raw types</a>
|
||||
*/
|
||||
static HighlightInfo.Builder checkRawOnParameterizedType(@NotNull PsiJavaCodeReferenceElement parent, @Nullable PsiElement resolved) {
|
||||
PsiReferenceParameterList list = parent.getParameterList();
|
||||
if (list == null || list.getTypeArguments().length > 0) return null;
|
||||
if (parent.getQualifier() instanceof PsiJavaCodeReferenceElement ref &&
|
||||
ref.getTypeParameters().length > 0 &&
|
||||
resolved instanceof PsiTypeParameterListOwner typeParameterListOwner &&
|
||||
typeParameterListOwner.hasTypeParameters() &&
|
||||
!typeParameterListOwner.hasModifierProperty(PsiModifier.STATIC)) {
|
||||
PsiElement referenceNameElement = parent.getReferenceNameElement();
|
||||
if (referenceNameElement != null) {
|
||||
String message = JavaErrorBundle.message("text.improper.formed.type", referenceNameElement.getText());
|
||||
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(parent).descriptionAndTooltip(message);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static void registerVariableParameterizedTypeFixes(@Nullable HighlightInfo.Builder builder,
|
||||
@NotNull PsiVariable variable,
|
||||
@NotNull PsiReferenceParameterList parameterList,
|
||||
|
||||
-33
@@ -2075,39 +2075,6 @@ public final class HighlightUtil {
|
||||
}
|
||||
|
||||
|
||||
static HighlightInfo.Builder checkCaseStatement(@NotNull PsiSwitchLabelStatementBase statement) {
|
||||
PsiSwitchBlock switchBlock = statement.getEnclosingSwitchBlock();
|
||||
if (switchBlock == null) {
|
||||
String description = JavaErrorBundle.message("case.statement.outside.switch");
|
||||
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(statement).descriptionAndTooltip(description);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
static HighlightInfo.Builder checkLocalClassReferencedFromAnotherSwitchBranch(@NotNull PsiJavaCodeReferenceElement ref,
|
||||
@NotNull PsiClass aClass) {
|
||||
if (!(aClass.getParent() instanceof PsiDeclarationStatement declarationStatement) ||
|
||||
!(declarationStatement.getParent() instanceof PsiCodeBlock codeBlock) ||
|
||||
!(codeBlock.getParent() instanceof PsiSwitchBlock)) {
|
||||
return null;
|
||||
}
|
||||
boolean classSeen = false;
|
||||
for (PsiStatement statement : codeBlock.getStatements()) {
|
||||
if (classSeen) {
|
||||
if (PsiTreeUtil.isAncestor(statement, ref, true)) break;
|
||||
if (statement instanceof PsiSwitchLabelStatement) {
|
||||
String description = JavaErrorBundle.message("local.class.referenced.from.other.switch.branch", formatClass(aClass));
|
||||
return HighlightInfo.newHighlightInfo(HighlightInfoType.WRONG_REF).range(ref).descriptionAndTooltip(description);
|
||||
}
|
||||
}
|
||||
else if (statement == declarationStatement) {
|
||||
classSeen = true;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static void checkSwitchExpressionHasResult(@NotNull PsiSwitchExpression switchExpression,
|
||||
@NotNull Consumer<? super HighlightInfo.Builder> errorSink) {
|
||||
PsiCodeBlock switchBody = switchExpression.getBody();
|
||||
|
||||
-22
@@ -948,10 +948,6 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
JavaResolveResult result = ref instanceof PsiExpression ? resolveOptimised(ref, myFile) : doVisitReferenceElement(ref);
|
||||
if (result != null) {
|
||||
PsiElement resolved = result.getElement();
|
||||
if (!hasErrorResults()) add(GenericsHighlightUtil.checkRawOnParameterizedType(ref, resolved));
|
||||
if (!hasErrorResults() && resolved instanceof PsiClass aClass) {
|
||||
add(HighlightUtil.checkLocalClassReferencedFromAnotherSwitchBranch(ref, aClass));
|
||||
}
|
||||
if (!hasErrorResults() && resolved instanceof PsiModifierListOwner) {
|
||||
PreviewFeatureUtil.checkPreviewFeature(ref, myPreviewFeatureVisitor);
|
||||
}
|
||||
@@ -989,10 +985,6 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasErrorResults()) add(GenericsHighlightUtil.checkSelectStaticClassFromParameterizedType(resolved, ref));
|
||||
if (!hasErrorResults() && parent instanceof PsiNewExpression newExpression) {
|
||||
add(GenericsHighlightUtil.checkDiamondTypeNotAllowed(newExpression));
|
||||
}
|
||||
if (!hasErrorResults() && (!(parent instanceof PsiNewExpression newExpression) || !newExpression.isArrayCreation())) {
|
||||
add(GenericsHighlightUtil.checkParameterizedReferenceTypeArguments(resolved, ref, result.getSubstitutor(), myJavaSdkVersion));
|
||||
}
|
||||
@@ -1476,20 +1468,6 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
if (!hasErrorResults()) visitExpression(expr);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitSwitchLabelStatement(@NotNull PsiSwitchLabelStatement statement) {
|
||||
super.visitSwitchLabelStatement(statement);
|
||||
if (!hasErrorResults()) add(HighlightUtil.checkCaseStatement(statement));
|
||||
if (!hasErrorResults()) add(SwitchBlockHighlightingModel.checkGuard(statement, myLanguageLevel, myFile));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitSwitchLabeledRuleStatement(@NotNull PsiSwitchLabeledRuleStatement statement) {
|
||||
super.visitSwitchLabeledRuleStatement(statement);
|
||||
if (!hasErrorResults()) add(HighlightUtil.checkCaseStatement(statement));
|
||||
if (!hasErrorResults()) add(SwitchBlockHighlightingModel.checkGuard(statement, myLanguageLevel, myFile));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitSwitchStatement(@NotNull PsiSwitchStatement statement) {
|
||||
super.visitSwitchStatement(statement);
|
||||
|
||||
+3
-1
@@ -72,7 +72,9 @@ final class JavaErrorFixProvider {
|
||||
ANNOTATION_NOT_ALLOWED_EXTENDS, RECEIVER_STATIC_CONTEXT, RECEIVER_WRONG_POSITION,
|
||||
RECORD_HEADER_REGULAR_CLASS, INTERFACE_CLASS_INITIALIZER, INTERFACE_CONSTRUCTOR,
|
||||
CLASS_IMPLICIT_INITIALIZER, CLASS_IMPLICIT_PACKAGE,
|
||||
RECORD_EXTENDS, ENUM_EXTENDS, RECORD_PERMITS, ENUM_PERMITS, ANNOTATION_PERMITS)) {
|
||||
RECORD_EXTENDS, ENUM_EXTENDS, RECORD_PERMITS, ENUM_PERMITS, ANNOTATION_PERMITS,
|
||||
NEW_EXPRESSION_DIAMOND_NOT_ALLOWED, REFERENCE_TYPE_ARGUMENT_STATIC_CLASS,
|
||||
STATEMENT_CASE_OUTSIDE_SWITCH)) {
|
||||
fix(kind, genericRemover);
|
||||
}
|
||||
|
||||
|
||||
-38
@@ -20,7 +20,6 @@ import com.intellij.util.SmartList;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
import com.intellij.util.containers.SmartHashSet;
|
||||
import com.siyeh.ig.psiutils.ExpressionUtils;
|
||||
import com.siyeh.ig.psiutils.SwitchUtils;
|
||||
import one.util.streamex.StreamEx;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -434,43 +433,6 @@ public class SwitchBlockHighlightingModel {
|
||||
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(range).descriptionAndTooltip(message);
|
||||
}
|
||||
|
||||
static HighlightInfo.Builder checkGuard(@NotNull PsiSwitchLabelStatementBase statement, @NotNull LanguageLevel languageLevel,
|
||||
@NotNull PsiFile psiFile) {
|
||||
PsiExpression guardingExpr = statement.getGuardExpression();
|
||||
if (guardingExpr == null) return null;
|
||||
HighlightInfo.Builder info =
|
||||
HighlightUtil.checkFeature(guardingExpr, JavaFeature.PATTERN_GUARDS_AND_RECORD_PATTERNS, languageLevel, psiFile);
|
||||
if (info != null) {
|
||||
return info;
|
||||
}
|
||||
PsiCaseLabelElementList list = statement.getCaseLabelElementList();
|
||||
if (list != null) {
|
||||
if (!ContainerUtil.exists(list.getElements(), e -> e instanceof PsiPattern)) {
|
||||
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(guardingExpr)
|
||||
.descriptionAndTooltip(JavaErrorBundle.message("error.guard.allowed.after.patterns.only"));
|
||||
}
|
||||
}
|
||||
HighlightInfo.Builder info2 = checkGuardingExpressionHasBooleanType(guardingExpr);
|
||||
if (info2 != null) {
|
||||
return info2;
|
||||
}
|
||||
Object constVal = ExpressionUtils.computeConstantExpression(guardingExpr);
|
||||
if (Boolean.FALSE.equals(constVal)) {
|
||||
String message = JavaErrorBundle.message("when.expression.is.false");
|
||||
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(guardingExpr).descriptionAndTooltip(message);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static @Nullable HighlightInfo.Builder checkGuardingExpressionHasBooleanType(@Nullable PsiExpression guardingExpression) {
|
||||
if (guardingExpression != null && !TypeConversionUtil.isBooleanType(guardingExpression.getType())) {
|
||||
String message = JavaErrorBundle.message("incompatible.types", JavaHighlightUtil.formatType(PsiTypes.booleanType()),
|
||||
JavaHighlightUtil.formatType(guardingExpression.getType()));
|
||||
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(guardingExpression).descriptionAndTooltip(message);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
enum SelectorKind {
|
||||
INT, ENUM, STRING, CLASS_OR_ARRAY,
|
||||
BOOLEAN, LONG, FLOAT, DOUBLE // primitives from Java 22 Preview
|
||||
|
||||
@@ -488,7 +488,6 @@ annotation.cannot.be.local=Local annotations are not allowed
|
||||
create.class.action.this.not.valid.java.qualified.name=This is not a valid Java qualified name
|
||||
text.class.inherits.abstract.and.default={0} inherits abstract and default for {1} from types {2} and {3}
|
||||
text.class.inherits.unrelated.defaults={0} inherits unrelated defaults for {1} from types {2}
|
||||
text.improper.formed.type=Improperly formed type: ''{0}'' needs type arguments because its qualifier has type arguments
|
||||
text.class.is.not.accessible={0} is not accessible in current context
|
||||
text.class.cannot.access=Cannot access {0}
|
||||
auto.closeable.resource=auto-closeable resource
|
||||
|
||||
Reference in New Issue
Block a user