[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:
Tagir Valeev
2025-01-17 16:02:19 +00:00
committed by intellij-monorepo-bot
parent 1a195620e7
commit aea97243cf
13 changed files with 166 additions and 147 deletions
@@ -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
@@ -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;
}
}
}
}
@@ -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));
}
}
}
@@ -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;
}
@@ -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));
}
}
}
@@ -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.
*
@@ -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));
@@ -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,
@@ -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();
@@ -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);
@@ -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);
}
@@ -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