From c4981145755c93a3f3d795ddf78d88eedbd2eb34 Mon Sep 17 00:00:00 2001 From: Tagir Valeev Date: Mon, 23 Jun 2025 17:28:04 +0200 Subject: [PATCH] [java-intentions] Add fix to replace an unresolved type with initializer type Fixes IDEA-225526 Replace var with inferred type in Java 9 or below GitOrigin-RevId: 465b0163a2a8b3e8f0346b350a5e373d9b958817 --- .../impl/analysis/DefaultJavaErrorFixProvider.java | 1 + .../daemon/impl/analysis/HighlightFixUtil.java | 14 ++++++++++++++ .../setVariableType/afterUnresolvedType.java | 6 ++++++ .../setVariableType/beforeUnresolvedType.java | 6 ++++++ .../beforeUnresolvedTypeBothSide.java | 6 ++++++ .../beforeUnresolvedTypeNoInitializer.java | 7 +++++++ 6 files changed, 40 insertions(+) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/setVariableType/afterUnresolvedType.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/setVariableType/beforeUnresolvedType.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/setVariableType/beforeUnresolvedTypeBothSide.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/setVariableType/beforeUnresolvedTypeNoInitializer.java diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/DefaultJavaErrorFixProvider.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/DefaultJavaErrorFixProvider.java index c3abc32d9ad0..455f8d52551c 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/DefaultJavaErrorFixProvider.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/DefaultJavaErrorFixProvider.java @@ -656,6 +656,7 @@ public final class DefaultJavaErrorFixProvider extends AbstractJavaErrorFixProvi fixes(EXPRESSION_SUPER_UNQUALIFIED_DEFAULT_METHOD, (error, sink) -> QualifySuperArgumentFix.registerQuickFixAction(error.context(), sink)); fix(REFERENCE_UNRESOLVED, error -> HighlightFixUtil.createUnresolvedReferenceFix(error.psi())); + fix(REFERENCE_UNRESOLVED, error -> HighlightFixUtil.createVariableTypeFix(error.psi())); fix(REFERENCE_QUALIFIER_PRIMITIVE, error -> error.psi() instanceof PsiReferenceExpression ref ? myFactory.createRenameWrongRefFix(ref) : null); fix(CAST_INTERSECTION_NOT_INTERFACE, error -> { diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightFixUtil.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightFixUtil.java index 6d293bd3fda1..e5d15bb6c4fa 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightFixUtil.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightFixUtil.java @@ -25,6 +25,7 @@ import com.intellij.pom.java.JavaFeature; import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.*; import com.intellij.psi.controlFlow.*; +import com.intellij.psi.impl.IncompleteModelUtil; import com.intellij.psi.infos.CandidateInfo; import com.intellij.psi.infos.MethodCandidateInfo; import com.intellij.psi.search.GlobalSearchScope; @@ -1116,6 +1117,19 @@ public final class HighlightFixUtil { .toList(); } + static @Nullable CommonIntentionAction createVariableTypeFix(PsiJavaCodeReferenceElement ref) { + if (!(ref.getParent() instanceof PsiTypeElement typeElement)) return null; + if (!(typeElement.getParent() instanceof PsiLocalVariable localVariable)) return null; + PsiExpression initializer = localVariable.getInitializer(); + if (initializer == null) return null; + PsiType type = initializer.getType(); + if (type == null || !PsiTypesUtil.isDenotableType(type, localVariable)) return null; + if (PsiTypes.voidType().equals(type) || PsiTypes.nullType().equals(type)) return null; + if (IncompleteModelUtil.hasUnresolvedComponent(type)) return null; + return PriorityIntentionActionWrapper.highPriority( + QuickFixFactory.getInstance().createSetVariableTypeFix(localVariable, type)); + } + private static final class ReturnModel { final PsiReturnStatement myStatement; final PsiType myType; diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/setVariableType/afterUnresolvedType.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/setVariableType/afterUnresolvedType.java new file mode 100644 index 000000000000..f9407776c0a1 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/setVariableType/afterUnresolvedType.java @@ -0,0 +1,6 @@ +// "Set variable type to 'int'" "true-preview" +public class Demo { + void test() { + int s = 123; + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/setVariableType/beforeUnresolvedType.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/setVariableType/beforeUnresolvedType.java new file mode 100644 index 000000000000..7f9b351a6721 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/setVariableType/beforeUnresolvedType.java @@ -0,0 +1,6 @@ +// "Set variable type to 'int'" "true-preview" +public class Demo { + void test() { + intt s = 123; + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/setVariableType/beforeUnresolvedTypeBothSide.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/setVariableType/beforeUnresolvedTypeBothSide.java new file mode 100644 index 000000000000..01c8c45329f8 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/setVariableType/beforeUnresolvedTypeBothSide.java @@ -0,0 +1,6 @@ +// "Set variable type to 'intt'" "false" +public class Demo { + void test(intt s1) { + intt s = s1; + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/setVariableType/beforeUnresolvedTypeNoInitializer.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/setVariableType/beforeUnresolvedTypeNoInitializer.java new file mode 100644 index 000000000000..458b1d679aeb --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/setVariableType/beforeUnresolvedTypeNoInitializer.java @@ -0,0 +1,7 @@ +// "Set variable type to 'int'" "false" +public class Demo { + void test() { + intt s; + s = 123; + } +}