[java-highlighting] Provide fixes for unexpected primitive type pattern: fixes after review (IJ-CR-15006)

GitOrigin-RevId: 7d13a79dbf52273c15f6d24b4957a68d8e1e9715
This commit is contained in:
Andrey.Cherkasov
2021-10-18 17:39:43 +03:00
committed by intellij-monorepo-bot
parent 48d2830934
commit 23fbe72cac
16 changed files with 81 additions and 48 deletions

View File

@@ -369,6 +369,10 @@ public abstract class QuickFixFactory {
@NotNull String typeName,
@NotNull String boxedTypeName);
@Nullable
public abstract IntentionAction createReplacePrimitiveWithBoxedTypeAction(@NotNull PsiType operandType,
@NotNull PsiTypeElement checkTypeElement);
@NotNull
public abstract IntentionAction createMakeVarargParameterLastFix(@NotNull PsiParameter parameter);

View File

@@ -221,7 +221,12 @@ public final class HighlightUtil {
|| !TypeConversionUtil.areTypesConvertible(operandType, checkType)) {
String message = JavaErrorBundle.message("inconvertible.type.cast", JavaHighlightUtil.formatType(operandType), JavaHighlightUtil
.formatType(checkType));
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip(message).create();
HighlightInfo info =
HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip(message).create();
if (TypeConversionUtil.isPrimitiveAndNotNull(checkType)) {
QuickFixAction.registerQuickFixAction(info, getFixFactory().createReplacePrimitiveWithBoxedTypeAction(operandType, typeElement));
}
return info;
}
return null;
}
@@ -3248,7 +3253,7 @@ public final class HighlightUtil {
static HighlightInfo checkAnnotationMethodParameters(@NotNull PsiParameterList list) {
final PsiElement parent = list.getParent();
if (PsiUtil.isAnnotationMethod(parent) &&
if (PsiUtil.isAnnotationMethod(parent) &&
(!list.isEmpty() || PsiTreeUtil.getChildOfType(list, PsiReceiverParameter.class) != null)) {
final String message = JavaErrorBundle.message("annotation.interface.members.may.not.have.parameters");
final HighlightInfo highlightInfo =

View File

@@ -444,13 +444,19 @@ public class SwitchBlockHighlightingModel {
}
else if (label instanceof PsiPattern) {
PsiPattern pattern = (PsiPattern)label;
PsiType patternType = JavaPsiPatternUtil.getPatternType(pattern);
PsiPatternVariable patternVariable = JavaPsiPatternUtil.getPatternVariable(pattern);
if (patternVariable == null) return null;
PsiTypeElement typeElement = patternVariable.getTypeElement();
PsiType patternType = typeElement.getType();
if (!(patternType instanceof PsiClassType) && !(patternType instanceof PsiArrayType)) {
String expectedTypes = JavaErrorBundle.message("switch.class.or.array.type.expected");
String message = JavaErrorBundle.message("unexpected.type", expectedTypes, JavaHighlightUtil.formatType(patternType));
HighlightInfo info = createError(label, message);
if (patternType instanceof PsiPrimitiveType) {
registerVariableTypeFixes(info, pattern, (PsiPrimitiveType)patternType);
PsiPrimitiveType primitiveType = ObjectUtils.tryCast(patternType, PsiPrimitiveType.class);
if (primitiveType != null) {
IntentionAction fix = getFixFactory().createReplacePrimitiveWithBoxedTypeAction(mySelectorType, typeElement);
QuickFixAction.registerQuickFixAction(info, fix);
}
return info;
}
@@ -746,20 +752,6 @@ public class SwitchBlockHighlightingModel {
QuickFixAction.registerQuickFixAction(info, getFixFactory().createDeleteDefaultFix(myFile, info));
}
private static void registerVariableTypeFixes(@Nullable HighlightInfo info,
@NotNull PsiPattern pattern,
@NotNull PsiPrimitiveType primitiveType) {
PsiType arrayType = PsiTypesUtil.createArrayType(primitiveType, 1);
PsiPatternVariable patternVariable = JavaPsiPatternUtil.getPatternVariable(pattern);
if (patternVariable == null) return;
PsiClassType boxedType = primitiveType.getBoxedType(patternVariable);
IntentionAction changeToArrayTypeFix = getFixFactory().createVariableTypeFix(patternVariable, arrayType);
QuickFixAction.registerQuickFixAction(info, changeToArrayTypeFix);
if (boxedType == null) return;
IntentionAction changeToBoxTypeFix = getFixFactory().createVariableTypeFix(patternVariable, boxedType);
QuickFixAction.registerQuickFixAction(info, changeToBoxTypeFix);
}
private void checkSealedClassCompleteness(@NotNull PsiClass selectorClass,
@NotNull List<PsiCaseLabelElement> elements,
@NotNull List<HighlightInfo> results) {

View File

@@ -41,6 +41,7 @@ import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.ClassKind;
import com.intellij.psi.util.InheritanceUtil;
import com.intellij.psi.util.PropertyMemberType;
import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.refactoring.memberPushDown.JavaPushDownHandler;
import com.intellij.util.DocumentUtil;
import com.intellij.util.IncorrectOperationException;
@@ -620,6 +621,18 @@ public final class QuickFixFactoryImpl extends QuickFixFactory {
return new ReplacePrimitiveWithBoxedTypeAction(element, typeName, boxedTypeName);
}
@Nullable
@Override
public IntentionAction createReplacePrimitiveWithBoxedTypeAction(@NotNull PsiType operandType, @NotNull PsiTypeElement checkTypeElement) {
PsiPrimitiveType primitiveType = ObjectUtils.tryCast(checkTypeElement.getType(), PsiPrimitiveType.class);
if (primitiveType == null) return null;
PsiClassType boxedType = primitiveType.getBoxedType(checkTypeElement);
if (boxedType == null || !TypeConversionUtil.areTypesConvertible(operandType, boxedType)) return null;
if (primitiveType.getBoxedTypeName() == null) return null;
return createReplacePrimitiveWithBoxedTypeAction(checkTypeElement, primitiveType.getPresentableText(),
primitiveType.getBoxedTypeName());
}
@NotNull
@Override
public IntentionAction createMakeVarargParameterLastFix(@NotNull PsiParameter parameter) {

View File

@@ -0,0 +1,6 @@
// "Replace 'int' with 'java.lang.Integer'" "true"
class Test {
void foo(Object o) {
boolean b = o instanceof Integer;
}
}

View File

@@ -0,0 +1,6 @@
// "Replace 'int' with 'java.lang.Integer'" "true"
class Test {
void foo(Object o) {
boolean b = o instanceof Integer i;
}
}

View File

@@ -1,8 +1,9 @@
// "Change variable 'i' type to 'Integer'" "true"
// "Replace 'int' with 'java.lang.Integer'" "true"
class Test {
void foo(Object o) {
switch (o) {
case Integer i -> System.out.println("int");
default -> System.out.println("default");
}
}
}

View File

@@ -0,0 +1,6 @@
// "Replace 'int' with 'java.lang.Integer'" "true"
class Test {
void foo(Object o) {
boolean b = o instanceof int<caret>;
}
}

View File

@@ -0,0 +1,6 @@
// "Replace 'int' with 'java.lang.Integer'" "false"
class Test {
void foo(String o) {
boolean b = o instanceof int<caret>;
}
}

View File

@@ -0,0 +1,6 @@
// "Replace 'int' with 'java.lang.Integer'" "true"
class Test {
void foo(Object o) {
boolean b = o instanceof int<caret> i;
}
}

View File

@@ -1,8 +1,9 @@
// "Change variable 'i' type to 'Integer'" "true"
// "Replace 'int' with 'java.lang.Integer'" "true"
class Test {
void foo(Object o) {
switch (o) {
case int i<caret> -> System.out.println("int");
default -> System.out.println("default");
}
}
}

View File

@@ -0,0 +1,9 @@
// "Replace 'int' with 'java.lang.Integer'" "false"
class Test {
void foo(String o) {
switch (o) {
case int i<caret> -> System.out.println("int");
default -> System.out.println("default");
}
}
}

View File

@@ -1,8 +0,0 @@
// "Change variable 'i' type to 'int[]'" "true"
class Test {
void foo(Object o) {
switch (o) {
case int[] i -> System.out.println("int");
}
}
}

View File

@@ -1,8 +0,0 @@
// "Change variable 'i' type to 'int[]'" "true"
class Test {
void foo(Object o) {
switch (o) {
case int i<caret> -> System.out.println("int");
}
}
}

View File

@@ -16,7 +16,9 @@
package com.intellij.java.codeInsight.daemon.quickFix;
import com.intellij.codeInsight.daemon.quickFix.LightQuickFixParameterizedTestCase;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.testFramework.LightProjectDescriptor;
import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase;
import org.jetbrains.annotations.NotNull;
public class ReplacePrimitiveWithBoxedTypeTest extends LightQuickFixParameterizedTestCase {
@Override
@@ -25,8 +27,8 @@ public class ReplacePrimitiveWithBoxedTypeTest extends LightQuickFixParameterize
}
@Override
protected LanguageLevel getLanguageLevel() {
return LanguageLevel.JDK_1_5;
protected @NotNull LightProjectDescriptor getProjectDescriptor() {
return LightJavaCodeInsightFixtureTestCase.JAVA_17;
}
}

View File

@@ -2,19 +2,11 @@
package com.intellij.java.codeInsight.daemon.quickFix;
import com.intellij.codeInsight.daemon.quickFix.LightQuickFixParameterizedTestCase;
import com.intellij.testFramework.LightProjectDescriptor;
import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase;
import org.jetbrains.annotations.NotNull;
public class VariableTypeTest extends LightQuickFixParameterizedTestCase {
@Override
protected String getBasePath() {
return "/codeInsight/daemonCodeAnalyzer/quickFix/variableType";
}
@Override
protected @NotNull LightProjectDescriptor getProjectDescriptor() {
return LightJavaCodeInsightFixtureTestCase.JAVA_17;
}
}