mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
wrap return value: teach inference (IDEA-135027)
This commit is contained in:
+10
-3
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.intellij.refactoring.wrapreturnvalue;
|
||||
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.ui.ListCellRendererWrapper;
|
||||
import com.intellij.ide.util.TreeClassChooser;
|
||||
import com.intellij.ide.util.TreeClassChooserFactory;
|
||||
@@ -215,12 +216,18 @@ class WrapReturnValueDialog extends RefactoringDialog {
|
||||
final PsiClass currentClass = facade.findClass(existingClassField.getText(), GlobalSearchScope.allScope(myProject));
|
||||
if (currentClass != null) {
|
||||
model.removeAllElements();
|
||||
final PsiType returnType = sourceMethod.getReturnType();
|
||||
assert returnType != null;
|
||||
for (PsiField field : currentClass.getFields()) {
|
||||
final PsiType returnType = sourceMethod.getReturnType();
|
||||
assert returnType != null;
|
||||
if (TypeConversionUtil.isAssignable(field.getType(), returnType)) {
|
||||
final PsiType fieldType = field.getType();
|
||||
if (TypeConversionUtil.isAssignable(fieldType, returnType)) {
|
||||
model.addElement(field);
|
||||
}
|
||||
else {
|
||||
if (WrapReturnValueProcessor.getInferredType(fieldType, returnType, currentClass, sourceMethod) != null) {
|
||||
model.addElement(field);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+25
-1
@@ -31,6 +31,7 @@ import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.search.searches.OverridingMethodsSearch;
|
||||
import com.intellij.psi.search.searches.ReferencesSearch;
|
||||
import com.intellij.psi.util.PropertyUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import com.intellij.refactoring.MoveDestination;
|
||||
import com.intellij.refactoring.RefactorJBundle;
|
||||
@@ -157,9 +158,32 @@ public class WrapReturnValueProcessor extends FixableUsagesRefactoringProcessor
|
||||
}, ","));
|
||||
returnTypeBuffer.append('>');
|
||||
}
|
||||
else if (myDelegateField != null) {
|
||||
final PsiType type = myDelegateField.getType();
|
||||
final PsiType returnType = myMethod.getReturnType();
|
||||
final PsiClass containingClass = myDelegateField.getContainingClass();
|
||||
final PsiType inferredType = getInferredType(type, returnType, containingClass, myMethod);
|
||||
if (inferredType != null) {
|
||||
returnTypeBuffer.append("<").append(inferredType.getCanonicalText()).append(">");
|
||||
}
|
||||
}
|
||||
return returnTypeBuffer.toString();
|
||||
}
|
||||
|
||||
protected static PsiType getInferredType(PsiType type, PsiType returnType, PsiClass containingClass, PsiMethod method) {
|
||||
if (containingClass != null && containingClass.getTypeParameters().length == 1) {
|
||||
final PsiSubstitutor substitutor = PsiResolveHelper.SERVICE.getInstance(method.getProject())
|
||||
.inferTypeArguments(containingClass.getTypeParameters(), new PsiType[]{type}, new PsiType[]{returnType}, PsiUtil.getLanguageLevel(
|
||||
method));
|
||||
final PsiTypeParameter typeParameter = containingClass.getTypeParameters()[0];
|
||||
final PsiType substituted = substitutor.substitute(typeParameter);
|
||||
if (substituted != null && !typeParameter.equals(PsiUtil.resolveClassInClassTypeOnly(substituted))) {
|
||||
return substituted;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean preprocessUsages(final Ref<UsageInfo[]> refUsages) {
|
||||
MultiMap<PsiElement, String> conflicts = new MultiMap<PsiElement, String>();
|
||||
@@ -198,7 +222,7 @@ public class WrapReturnValueProcessor extends FixableUsagesRefactoringProcessor
|
||||
final PsiParameter parameter = parameters[0];
|
||||
final PsiType parameterType = parameter.getType();
|
||||
for (PsiType returnType : returnTypes) {
|
||||
if (!TypeConversionUtil.isAssignable(parameterType, returnType)) {
|
||||
if (getInferredType(parameterType, returnType, existingClass, myMethod) == null && !TypeConversionUtil.isAssignable(parameterType, returnType)) {
|
||||
continue constr;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
class Test {
|
||||
Wrapper<String> foo() {
|
||||
return new Wrapper<String>("");
|
||||
}
|
||||
|
||||
void bar() {
|
||||
String s = foo().getMyField();
|
||||
}
|
||||
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
class Wrapper<T> {
|
||||
T myField;
|
||||
Wrapper(T s) {
|
||||
myField = s;
|
||||
}
|
||||
|
||||
String getMyField() {
|
||||
return myField;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
class Test {
|
||||
String foo() {
|
||||
return "";
|
||||
}
|
||||
|
||||
void bar() {
|
||||
String s = foo();
|
||||
}
|
||||
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
class Wrapper<T> {
|
||||
T myField;
|
||||
Wrapper(T s) {
|
||||
myField = s;
|
||||
}
|
||||
|
||||
String getMyField() {
|
||||
return myField;
|
||||
}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
import java.util.List;
|
||||
|
||||
class Test {
|
||||
Wrapper<String> foo() {
|
||||
return new Wrapper<String>(null);
|
||||
}
|
||||
|
||||
void bar() {
|
||||
List<String> s = foo().getMyField();
|
||||
}
|
||||
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
import java.util.List;
|
||||
class Wrapper<T> {
|
||||
List<T> myField;
|
||||
Wrapper(List<T> s) {
|
||||
myField = s;
|
||||
}
|
||||
|
||||
List<T> getMyField() {
|
||||
return myField;
|
||||
}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
import java.util.List;
|
||||
|
||||
class Test {
|
||||
List<String> foo() {
|
||||
return null;
|
||||
}
|
||||
|
||||
void bar() {
|
||||
List<String> s = foo();
|
||||
}
|
||||
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
import java.util.List;
|
||||
class Wrapper<T> {
|
||||
List<T> myField;
|
||||
Wrapper(List<T> s) {
|
||||
myField = s;
|
||||
}
|
||||
|
||||
List<T> getMyField() {
|
||||
return myField;
|
||||
}
|
||||
}
|
||||
@@ -51,6 +51,8 @@ public class WrapReturnValueTest extends MultiFileTestCase {
|
||||
public void testHierarchy() { doTest(false, null, true); }
|
||||
public void testAnonymous() { doTest(true, null, false); }
|
||||
public void testWrongFieldAssignment() { doTest(true, "Existing class does not have appropriate constructor", false); }
|
||||
public void testInferFieldType() { doTest(true, null, false); }
|
||||
public void testInferFieldTypeArg() { doTest(true, null, false); }
|
||||
public void testWrongFieldType() { doTest(true, "Existing class does not have appropriate constructor", false); }
|
||||
public void testStaticMethodInnerClass() { doTest(false, null, true); }
|
||||
public void testRawReturnType() { doTest(true, "Existing class does not have appropriate constructor"); }
|
||||
|
||||
Reference in New Issue
Block a user