[java-highlighting] IDEA-357868 Better error message for primitive types in instanceof

GitOrigin-RevId: bb638cf01ec27474d89859c27c5410add6be5931
This commit is contained in:
Mikhail Pyltsin
2024-08-21 20:14:45 +02:00
committed by intellij-monorepo-bot
parent 5b12db3e7e
commit e39d914c56
5 changed files with 49 additions and 27 deletions

View File

@@ -215,6 +215,14 @@ public final class HighlightUtil {
.formatType(checkType));
HighlightInfo.Builder info =
HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip(message);
if (((operandIsPrimitive || checkIsPrimitive) && !primitiveInPatternsEnabled) && convertible) {
HighlightInfo.Builder infoFeature =
HighlightUtil.checkFeature(expression, JavaFeature.PRIMITIVE_TYPES_IN_PATTERNS,
PsiUtil.getLanguageLevel(expression), expression.getContainingFile());
if (infoFeature != null) {
info = infoFeature;
}
}
if (checkIsPrimitive) {
IntentionAction action = getFixFactory().createReplacePrimitiveWithBoxedTypeAction(operandType, typeElement);
if (action != null) {
@@ -222,10 +230,6 @@ public final class HighlightUtil {
}
}
if (((operandIsPrimitive || checkIsPrimitive) && !primitiveInPatternsEnabled) && convertible) {
registerIncreaseLanguageLevelFixes(expression, JavaFeature.PRIMITIVE_TYPES_IN_PATTERNS, info);
}
errorSink.accept(info);
return;
}

View File

@@ -182,6 +182,14 @@ public class PatternsInSwitchBlockHighlightingModel extends SwitchBlockHighlight
String expectedTypes = JavaErrorBundle.message("switch.class.or.array.type.expected");
String message = JavaErrorBundle.message("unexpected.type", expectedTypes, JavaHighlightUtil.formatType(patternType));
HighlightInfo.Builder info = createError(elementToReport, message);
if (patternType instanceof PsiPrimitiveType) {
HighlightInfo.Builder infoFeature =
HighlightUtil.checkFeature(elementToReport, JavaFeature.PRIMITIVE_TYPES_IN_PATTERNS,
PsiUtil.getLanguageLevel(elementToReport), elementToReport.getContainingFile());
if (infoFeature != null) {
info = infoFeature;
}
}
PsiPrimitiveType primitiveType = ObjectUtils.tryCast(patternType, PsiPrimitiveType.class);
if (primitiveType != null) {
IntentionAction fix = getFixFactory().createReplacePrimitiveWithBoxedTypeAction(mySelectorType, typeElement);
@@ -189,9 +197,6 @@ public class PatternsInSwitchBlockHighlightingModel extends SwitchBlockHighlight
info.registerFix(fix, null, null, null, null);
}
}
if (patternType instanceof PsiPrimitiveType) {
HighlightUtil.registerIncreaseLanguageLevelFixes(mySelector, JavaFeature.PRIMITIVE_TYPES_IN_PATTERNS, info);
}
errorSink.accept(info);
return true;
}
@@ -210,7 +215,12 @@ public class PatternsInSwitchBlockHighlightingModel extends SwitchBlockHighlight
HighlightInfo.Builder error =
HighlightUtil.createIncompatibleTypeHighlightInfo(mySelectorType, patternType, elementToReport.getTextRange(), 0);
if (mySelectorType instanceof PsiPrimitiveType) {
HighlightUtil.registerIncreaseLanguageLevelFixes(mySelector, JavaFeature.PRIMITIVE_TYPES_IN_PATTERNS, error);
HighlightInfo.Builder infoFeature =
HighlightUtil.checkFeature(elementToReport, JavaFeature.PRIMITIVE_TYPES_IN_PATTERNS,
PsiUtil.getLanguageLevel(elementToReport), elementToReport.getContainingFile());
if (infoFeature != null) {
error = infoFeature;
}
}
errorSink.accept(error);
return true;

View File

@@ -83,7 +83,7 @@ class C {
void unsupported() {
Object o = 42;
if (<error descr="Inconvertible types; cannot cast 'java.lang.Object' to 'int'">o instanceof int</error>) {
if (<error descr="Primitive types in patterns, instanceof and switch are not supported at language level '7'">o instanceof int</error>) {
int i = (Integer) o;
System.out.println(i);
}

View File

@@ -10,34 +10,34 @@ public class InstanceofPrimitivesNotAllowed {
private static void testObjectToPrimitive() {
Integer i = 1;
Object l = 1;
if (<error descr="Inconvertible types; cannot cast 'java.lang.Integer' to 'double'">i instanceof double</error>) { } //error
if (<error descr="Inconvertible types; cannot cast 'java.lang.Integer' to 'int'">i instanceof int</error>) { } //error
if (<error descr="Inconvertible types; cannot cast 'java.lang.Integer' to 'int'">i instanceof int ii</error>) { } //error
if (<error descr="Inconvertible types; cannot cast 'java.lang.Object' to 'double'">l instanceof double</error>) { } //error
if (<error descr="Inconvertible types; cannot cast 'java.lang.Object' to 'int'">l instanceof int</error>) { } //error
if (<error descr="Inconvertible types; cannot cast 'java.lang.Object' to 'int'">l instanceof int ii</error>) { } //error
if (<error descr="Primitive types in patterns, instanceof and switch are not supported at language level '22'">i instanceof double</error>) { } //error
if (<error descr="Primitive types in patterns, instanceof and switch are not supported at language level '22'">i instanceof int</error>) { } //error
if (<error descr="Primitive types in patterns, instanceof and switch are not supported at language level '22'">i instanceof int ii</error>) { } //error
if (<error descr="Primitive types in patterns, instanceof and switch are not supported at language level '22'">l instanceof double</error>) { } //error
if (<error descr="Primitive types in patterns, instanceof and switch are not supported at language level '22'">l instanceof int</error>) { } //error
if (<error descr="Primitive types in patterns, instanceof and switch are not supported at language level '22'">l instanceof int ii</error>) { } //error
}
private static void testPrimitiveToPrimitive() {
int i = 1;
long l = 1;
if (<error descr="Inconvertible types; cannot cast 'int' to 'double'">i instanceof double</error>) { } //error
if (<error descr="Inconvertible types; cannot cast 'int' to 'int'">i instanceof int</error>) { } //error
if (<error descr="Inconvertible types; cannot cast 'int' to 'int'">i instanceof int ii</error>) { } //error
if (<error descr="Inconvertible types; cannot cast 'long' to 'double'">l instanceof double</error>) { } //error
if (<error descr="Inconvertible types; cannot cast 'long' to 'int'">l instanceof int</error>) { } //error
if (<error descr="Inconvertible types; cannot cast 'long' to 'int'">l instanceof int ii</error>) { } //error
if (<error descr="Primitive types in patterns, instanceof and switch are not supported at language level '22'">i instanceof double</error>) { } //error
if (<error descr="Primitive types in patterns, instanceof and switch are not supported at language level '22'">i instanceof int</error>) { } //error
if (<error descr="Primitive types in patterns, instanceof and switch are not supported at language level '22'">i instanceof int ii</error>) { } //error
if (<error descr="Primitive types in patterns, instanceof and switch are not supported at language level '22'">l instanceof double</error>) { } //error
if (<error descr="Primitive types in patterns, instanceof and switch are not supported at language level '22'">l instanceof int</error>) { } //error
if (<error descr="Primitive types in patterns, instanceof and switch are not supported at language level '22'">l instanceof int ii</error>) { } //error
}
private static void testPrimitiveToObject() {
int i = 1;
long l = 1;
if (<error descr="Inconvertible types; cannot cast 'int' to 'java.lang.Double'">i instanceof Double</error>) { } //error
if (<error descr="Inconvertible types; cannot cast 'int' to 'java.lang.Integer'">i instanceof Integer</error>) { } //error
if (<error descr="Inconvertible types; cannot cast 'int' to 'java.lang.Object'">i instanceof Object</error>) { } //error
if (<error descr="Inconvertible types; cannot cast 'int' to 'java.lang.Integer'">i instanceof Integer ii</error>) { } //error
if (<error descr="Primitive types in patterns, instanceof and switch are not supported at language level '22'">i instanceof Integer</error>) { } //error
if (<error descr="Primitive types in patterns, instanceof and switch are not supported at language level '22'">i instanceof Object</error>) { } //error
if (<error descr="Primitive types in patterns, instanceof and switch are not supported at language level '22'">i instanceof Integer ii</error>) { } //error
if (<error descr="Inconvertible types; cannot cast 'long' to 'java.lang.Double'">l instanceof Double</error>) { } //error
if (<error descr="Inconvertible types; cannot cast 'long' to 'java.lang.Integer'">l instanceof Integer</error>) { } //error
if (<error descr="Inconvertible types; cannot cast 'long' to 'java.lang.Object'">l instanceof Object</error>) { } //error
if (<error descr="Primitive types in patterns, instanceof and switch are not supported at language level '22'">l instanceof Object</error>) { } //error
}
}

View File

@@ -13,8 +13,16 @@ class X {
int switchTest2(int i) {
return switch (i) {
case <error descr="Incompatible types. Found: 'java.lang.Integer', required: 'int'">Integer integer</error> -> "int";
case <error descr="Incompatible types. Found: 'java.lang.Object', required: 'int'">Object obj</error> -> "Object";
case <error descr="Primitive types in patterns, instanceof and switch are not supported at language level '21'">Integer integer</error> -> "int";
case <error descr="Primitive types in patterns, instanceof and switch are not supported at language level '21'">Object obj</error> -> "Object";
default -> "not ok";
};
}
int switchTest2_2(Integer i) {
return switch (i) {
case <error descr="Primitive types in patterns, instanceof and switch are not supported at language level '21'">int integer</error> -> "int";
case Object obj -> "Object";
default -> "not ok";
};
}