suggest to fix return type based on args of method call in return stmt (IDEA-140894)

This commit is contained in:
Anna Kozlova
2015-08-19 12:34:41 +02:00
parent 6b08a2da04
commit 3b3bf18b69
3 changed files with 55 additions and 0 deletions
@@ -41,6 +41,8 @@ import com.intellij.psi.infos.MethodCandidateInfo;
import com.intellij.psi.util.*;
import com.intellij.refactoring.util.RefactoringChangeUtil;
import com.intellij.ui.ColorUtil;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.MostlySingularMultiMap;
import com.intellij.util.ui.UIUtil;
import com.intellij.xml.util.XmlStringUtil;
@@ -400,6 +402,7 @@ public class HighlightMethodUtil {
.description(description).escapedToolTip(toolTip).navigationShift(navigationShift).create();
if (highlightInfo != null) {
registerMethodCallIntentions(highlightInfo, methodCall, list, resolveHelper);
registerMethodReturnFixAction(highlightInfo, candidateInfo, methodCall, resolveHelper);
}
}
else {
@@ -435,6 +438,36 @@ public class HighlightMethodUtil {
return highlightInfo;
}
private static void registerMethodReturnFixAction(HighlightInfo highlightInfo,
MethodCandidateInfo candidate,
PsiMethodCallExpression methodCall,
PsiResolveHelper resolveHelper) {
if (methodCall.getParent() instanceof PsiReturnStatement) {
final PsiMethod containerMethod = PsiTreeUtil.getParentOfType(methodCall, PsiMethod.class, true, PsiLambdaExpression.class);
if (containerMethod != null) {
final PsiMethod method = candidate.getElement();
final List<PsiType> list = ContainerUtil.map(method.getParameterList().getParameters(),
new Function<PsiParameter, PsiType>() {
@Override
public PsiType fun(PsiParameter parameter) {
return parameter.getType();
}
});
PsiType[] leftTypes = list.toArray(new PsiType[list.size()]);
final PsiSubstitutor substitutor = resolveHelper
.inferTypeArguments(method.getTypeParameters(), leftTypes, methodCall.getArgumentList().getExpressionTypes(),
PsiUtil.getLanguageLevel(methodCall));
PsiType methodCallTypeByArgs = substitutor.substitute(methodCall.getType());
//ensure type params are not included
methodCallTypeByArgs = JavaPsiFacade.getElementFactory(method.getProject())
.createRawSubstitutor(method).substitute(methodCallTypeByArgs);
QuickFixAction.registerQuickFixAction(highlightInfo,
getFixRange(methodCall),
QUICK_FIX_FACTORY.createMethodReturnFix(containerMethod, methodCallTypeByArgs, true));
}
}
}
private static String buildOneLineMismatchDescription(@NotNull PsiExpressionList list,
@NotNull MethodCandidateInfo candidateInfo,
@NotNull Ref<PsiElement> elementToHighlight) {
@@ -0,0 +1,12 @@
import java.util.List;
// "Make 'bar' return 'java.util.List<java.lang.String>'" "true"
public class Foo {
<T> java.util.List<T> foo(T t) {
return null;
}
List<String> bar() {
return foo("");
}
}
@@ -0,0 +1,10 @@
// "Make 'bar' return 'java.util.List<java.lang.String>'" "true"
public class Foo {
<T> java.util.List<T> foo(T t) {
return null;
}
String bar() {
return fo<caret>o("");
}
}