From aea97243cfa1bc70c640d539b3662279d8879d62 Mon Sep 17 00:00:00 2001 From: Tagir Valeev Date: Thu, 16 Jan 2025 17:08:59 +0100 Subject: [PATCH] [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 --- .../JavaCompilationErrorBundle.properties | 10 ++++ .../highlighting/ExpressionChecker.java | 21 ++++++++ .../highlighting/GenericsChecker.java | 38 +++++++++++++- .../highlighting/JavaErrorVisitor.java | 21 ++++++++ .../highlighting/StatementChecker.java | 46 +++++++++++++++++ .../highlighting/errors/JavaErrorKind.java | 10 ++++ .../highlighting/errors/JavaErrorKinds.java | 18 +++++++ .../impl/analysis/GenericsHighlightUtil.java | 51 ------------------- .../daemon/impl/analysis/HighlightUtil.java | 33 ------------ .../impl/analysis/HighlightVisitorImpl.java | 22 -------- .../impl/analysis/JavaErrorFixProvider.java | 4 +- .../SwitchBlockHighlightingModel.java | 38 -------------- .../messages/JavaErrorBundle.properties | 1 - 13 files changed, 166 insertions(+), 147 deletions(-) create mode 100644 java/codeserver/highlighting/src/com/intellij/java/codeserver/highlighting/StatementChecker.java diff --git a/java/codeserver/highlighting/resources/messages/JavaCompilationErrorBundle.properties b/java/codeserver/highlighting/resources/messages/JavaCompilationErrorBundle.properties index 213c26e90217..0e25762001b0 100644 --- a/java/codeserver/highlighting/resources/messages/JavaCompilationErrorBundle.properties +++ b/java/codeserver/highlighting/resources/messages/JavaCompilationErrorBundle.properties @@ -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 diff --git a/java/codeserver/highlighting/src/com/intellij/java/codeserver/highlighting/ExpressionChecker.java b/java/codeserver/highlighting/src/com/intellij/java/codeserver/highlighting/ExpressionChecker.java index 1db39e3dab03..c08d3ca29f04 100644 --- a/java/codeserver/highlighting/src/com/intellij/java/codeserver/highlighting/ExpressionChecker.java +++ b/java/codeserver/highlighting/src/com/intellij/java/codeserver/highlighting/ExpressionChecker.java @@ -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; + } + } + } } diff --git a/java/codeserver/highlighting/src/com/intellij/java/codeserver/highlighting/GenericsChecker.java b/java/codeserver/highlighting/src/com/intellij/java/codeserver/highlighting/GenericsChecker.java index eaba823745f2..e093bf4662d1 100644 --- a/java/codeserver/highlighting/src/com/intellij/java/codeserver/highlighting/GenericsChecker.java +++ b/java/codeserver/highlighting/src/com/intellij/java/codeserver/highlighting/GenericsChecker.java @@ -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 JLS 4.8 on raw types + */ + 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)); + } } } diff --git a/java/codeserver/highlighting/src/com/intellij/java/codeserver/highlighting/JavaErrorVisitor.java b/java/codeserver/highlighting/src/com/intellij/java/codeserver/highlighting/JavaErrorVisitor.java index 5810db20a7b6..268800e088f9 100644 --- a/java/codeserver/highlighting/src/com/intellij/java/codeserver/highlighting/JavaErrorVisitor.java +++ b/java/codeserver/highlighting/src/com/intellij/java/codeserver/highlighting/JavaErrorVisitor.java @@ -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; } diff --git a/java/codeserver/highlighting/src/com/intellij/java/codeserver/highlighting/StatementChecker.java b/java/codeserver/highlighting/src/com/intellij/java/codeserver/highlighting/StatementChecker.java new file mode 100644 index 000000000000..e39950508387 --- /dev/null +++ b/java/codeserver/highlighting/src/com/intellij/java/codeserver/highlighting/StatementChecker.java @@ -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)); + } + } +} diff --git a/java/codeserver/highlighting/src/com/intellij/java/codeserver/highlighting/errors/JavaErrorKind.java b/java/codeserver/highlighting/src/com/intellij/java/codeserver/highlighting/errors/JavaErrorKind.java index 1cd6fc3bbc33..7bc0b8393f7d 100644 --- a/java/codeserver/highlighting/src/com/intellij/java/codeserver/highlighting/errors/JavaErrorKind.java +++ b/java/codeserver/highlighting/src/com/intellij/java/codeserver/highlighting/errors/JavaErrorKind.java @@ -354,6 +354,16 @@ public sealed interface JavaErrorKind { 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 withHighlightType(@NotNull BiFunction type) { + return new Parameterized<>(myKey, myDescription, myTooltip, myAnchor, myRange, type, myValidator); + } + /** * Creates a new instance of Parameterized with a specified description function. * diff --git a/java/codeserver/highlighting/src/com/intellij/java/codeserver/highlighting/errors/JavaErrorKinds.java b/java/codeserver/highlighting/src/com/intellij/java/codeserver/highlighting/errors/JavaErrorKinds.java index fe11570fa2db..3dee9fb1d019 100644 --- a/java/codeserver/highlighting/src/com/intellij/java/codeserver/highlighting/errors/JavaErrorKinds.java +++ b/java/codeserver/highlighting/src/com/intellij/java/codeserver/highlighting/errors/JavaErrorKinds.java @@ -497,6 +497,24 @@ public final class JavaErrorKinds { parameterized("new.expression.qualified.anonymous.implements.interface"); public static final Simple NEW_EXPRESSION_QUALIFIED_QUALIFIED_CLASS_REFERENCE = error("new.expression.qualified.qualified.class.reference"); + public static final Simple NEW_EXPRESSION_DIAMOND_NOT_ALLOWED = + error("new.expression.diamond.not.allowed"); + + public static final Parameterized 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 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 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 STATEMENT_CASE_OUTSIDE_SWITCH = error("statement.case.outside.switch"); + + public static final Simple GUARD_MISPLACED = error("guard.misplaced"); + public static final Simple GUARD_EVALUATED_TO_FALSE = error("guard.evaluated.to.false"); public static final Simple COMMENT_SHEBANG_JAVA_FILE = error(PsiComment.class, "comment.shebang.java.file") .withRange(psi -> TextRange.create(0, 2)); diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java index 562ad99928cc..f3982ff6a5fc 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java @@ -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 JLS 4.8 on raw types - */ - 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, diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java index 92ee00f50f98..e6cf39e29722 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java @@ -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 errorSink) { PsiCodeBlock switchBody = switchExpression.getBody(); 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 49a8904d82e2..a0eca95c0861 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 @@ -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); diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/JavaErrorFixProvider.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/JavaErrorFixProvider.java index b718089c053d..dd5940f17070 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/JavaErrorFixProvider.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/JavaErrorFixProvider.java @@ -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); } diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/SwitchBlockHighlightingModel.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/SwitchBlockHighlightingModel.java index 9f9a07a60dfc..7e14f0d7504b 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/SwitchBlockHighlightingModel.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/SwitchBlockHighlightingModel.java @@ -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 diff --git a/java/java-psi-impl/resources/messages/JavaErrorBundle.properties b/java/java-psi-impl/resources/messages/JavaErrorBundle.properties index 802d72a9225d..6e01881c72de 100644 --- a/java/java-psi-impl/resources/messages/JavaErrorBundle.properties +++ b/java/java-psi-impl/resources/messages/JavaErrorBundle.properties @@ -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