From 412d071d08f317da853fd18f2e145b5a2d4cfe51 Mon Sep 17 00:00:00 2001 From: "Anna.Kozlova" Date: Thu, 6 Apr 2017 12:50:23 +0200 Subject: [PATCH] add fixes to change expected type when inference fails due to it (IDEA-162846) --- .../impl/analysis/HighlightMethodUtil.java | 32 +++++++++++++++++++ ...FailedInferenceDueToWrongExpectedType.java | 10 ++++++ ...renceDueToWrongExpectedTypeAssignment.java | 11 +++++++ ...ceDueToWrongExpectedTypeNotApplicable.java | 15 +++++++++ ...FailedInferenceDueToWrongExpectedType.java | 10 ++++++ ...renceDueToWrongExpectedTypeAssignment.java | 11 +++++++ ...ceDueToWrongExpectedTypeNotApplicable.java | 15 +++++++++ 7 files changed, 104 insertions(+) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/afterFailedInferenceDueToWrongExpectedType.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/afterFailedInferenceDueToWrongExpectedTypeAssignment.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/afterFailedInferenceDueToWrongExpectedTypeNotApplicable.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/beforeFailedInferenceDueToWrongExpectedType.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/beforeFailedInferenceDueToWrongExpectedTypeAssignment.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/beforeFailedInferenceDueToWrongExpectedTypeNotApplicable.java diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java index 7e9e22850c1e..5b4b97d96ecf 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java @@ -390,6 +390,7 @@ public class HighlightMethodUtil { if (highlightInfo != null) { registerMethodCallIntentions(highlightInfo, methodCall, list, resolveHelper); registerMethodReturnFixAction(highlightInfo, (MethodCandidateInfo)resolveResult, methodCall); + registerTargetTypeFixesBasedOnApplicabilityInference(methodCall, (MethodCandidateInfo)resolveResult, (PsiMethod)resolved, highlightInfo); } } } @@ -430,6 +431,7 @@ public class HighlightMethodUtil { if (highlightInfo != null) { registerMethodCallIntentions(highlightInfo, methodCall, list, resolveHelper); registerMethodReturnFixAction(highlightInfo, candidateInfo, methodCall); + registerTargetTypeFixesBasedOnApplicabilityInference(methodCall, candidateInfo, resolvedMethod, highlightInfo); } } else { @@ -472,6 +474,36 @@ public class HighlightMethodUtil { return highlightInfo; } + private static void registerTargetTypeFixesBasedOnApplicabilityInference(@NotNull PsiMethodCallExpression methodCall, + MethodCandidateInfo resolveResult, + PsiMethod resolved, + HighlightInfo highlightInfo) { + PsiElement parent = PsiUtil.skipParenthesizedExprUp(methodCall.getParent()); + PsiVariable variable = null; + if (parent instanceof PsiVariable) { + variable = (PsiVariable)parent; + } + else if (parent instanceof PsiAssignmentExpression) { + PsiExpression lExpression = ((PsiAssignmentExpression)parent).getLExpression(); + if (lExpression instanceof PsiReferenceExpression) { + PsiElement resolve = ((PsiReferenceExpression)lExpression).resolve(); + if (resolve instanceof PsiVariable) { + variable = (PsiVariable)resolve; + } + } + } + + if (variable != null) { + PsiType rType = methodCall.getType(); + if (rType != null && !variable.getType().isAssignableFrom(rType)) { + PsiType expectedTypeByApplicabilityConstraints = resolveResult.getSubstitutor(false).substitute(resolved.getReturnType()); + if (expectedTypeByApplicabilityConstraints != null && !expectedTypeByApplicabilityConstraints.equals(rType)) { + HighlightUtil.registerChangeVariableTypeFixes(variable, expectedTypeByApplicabilityConstraints, methodCall, highlightInfo); + } + } + } + } + /* see also PsiReferenceExpressionImpl.hasValidQualifier() */ @Nullable private static String checkStaticInterfaceMethodCallQualifier(PsiReferenceExpression ref, PsiElement scope, PsiClass containingClass) { diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/afterFailedInferenceDueToWrongExpectedType.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/afterFailedInferenceDueToWrongExpectedType.java new file mode 100644 index 000000000000..ccea5e7c4883 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/afterFailedInferenceDueToWrongExpectedType.java @@ -0,0 +1,10 @@ +// "Change variable 'foo' type to 'java.util.List'" "true" + +import java.util.Arrays; +import java.util.List; + +class MyClass { + void bar() { + List foo = Arrays.asList("a"); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/afterFailedInferenceDueToWrongExpectedTypeAssignment.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/afterFailedInferenceDueToWrongExpectedTypeAssignment.java new file mode 100644 index 000000000000..a7297a2d5e66 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/afterFailedInferenceDueToWrongExpectedTypeAssignment.java @@ -0,0 +1,11 @@ +// "Change variable 'foo' type to 'java.util.List'" "true" + +import java.util.Arrays; +import java.util.List; + +class MyClass { + void bar() { + List foo; + foo = (Arrays.asList("a")); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/afterFailedInferenceDueToWrongExpectedTypeNotApplicable.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/afterFailedInferenceDueToWrongExpectedTypeNotApplicable.java new file mode 100644 index 000000000000..5861eb786683 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/afterFailedInferenceDueToWrongExpectedTypeNotApplicable.java @@ -0,0 +1,15 @@ +// "Change variable 'foo' type to 'java.lang.String'" "true" + +import java.util.List; +import java.util.Set; + +class MyClass { + public static void sort(final List list) { + String foo = (findStart(list)); + } + + private static V findStart(List result) { + return result.get(0); + } + +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/beforeFailedInferenceDueToWrongExpectedType.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/beforeFailedInferenceDueToWrongExpectedType.java new file mode 100644 index 000000000000..802171f834a2 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/beforeFailedInferenceDueToWrongExpectedType.java @@ -0,0 +1,10 @@ +// "Change variable 'foo' type to 'java.util.List'" "true" + +import java.util.Arrays; +import java.util.List; + +class MyClass { + void bar() { + String[] foo = Arrays.asList("a"); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/beforeFailedInferenceDueToWrongExpectedTypeAssignment.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/beforeFailedInferenceDueToWrongExpectedTypeAssignment.java new file mode 100644 index 000000000000..42be9d9e4e0e --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/beforeFailedInferenceDueToWrongExpectedTypeAssignment.java @@ -0,0 +1,11 @@ +// "Change variable 'foo' type to 'java.util.List'" "true" + +import java.util.Arrays; +import java.util.List; + +class MyClass { + void bar() { + String[] foo; + foo = (Arrays.asList("a")); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/beforeFailedInferenceDueToWrongExpectedTypeNotApplicable.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/beforeFailedInferenceDueToWrongExpectedTypeNotApplicable.java new file mode 100644 index 000000000000..f9612e9aa742 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/beforeFailedInferenceDueToWrongExpectedTypeNotApplicable.java @@ -0,0 +1,15 @@ +// "Change variable 'foo' type to 'java.lang.String'" "true" + +import java.util.List; +import java.util.Set; + +class MyClass { + public static void sort(final List list) { + Set foo = (findStart(list)); + } + + private static V findStart(List result) { + return result.get(0); + } + +} \ No newline at end of file