mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
type migration: allow to migrate elements with type parameters if root contains these type parameters (IDEA-147944)
This commit is contained in:
+17
-7
@@ -25,6 +25,7 @@ import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.PsiImplUtil;
|
||||
import com.intellij.psi.impl.source.PsiClassReferenceType;
|
||||
import com.intellij.psi.impl.source.PsiImmediateClassType;
|
||||
import com.intellij.psi.javadoc.PsiDocTagValue;
|
||||
import com.intellij.psi.search.PsiSearchScopeUtil;
|
||||
@@ -37,11 +38,9 @@ import com.intellij.psi.util.TypeConversionUtil;
|
||||
import com.intellij.refactoring.typeMigration.usageInfo.OverridenUsageInfo;
|
||||
import com.intellij.refactoring.typeMigration.usageInfo.OverriderUsageInfo;
|
||||
import com.intellij.refactoring.typeMigration.usageInfo.TypeMigrationUsageInfo;
|
||||
import com.intellij.refactoring.util.RefactoringUtil;
|
||||
import com.intellij.usageView.UsageInfo;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.Query;
|
||||
import com.intellij.util.*;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.graph.DFSTBuilder;
|
||||
import com.intellij.util.graph.GraphGenerator;
|
||||
@@ -468,7 +467,15 @@ public class TypeMigrationLabeler {
|
||||
type = userDefinedType ? type : TypeEvaluator.substituteType(type, originalType, isContraVariantPosition);
|
||||
|
||||
if (!userDefinedType) {
|
||||
if (typeContainsTypeParameters(originalType)) return false;
|
||||
final Set<PsiTypeParameter> collector;
|
||||
if (originalType instanceof PsiClassReferenceType) {
|
||||
collector = new HashSet<PsiTypeParameter>();
|
||||
final PsiJavaCodeReferenceElement reference = ((PsiClassReferenceType)originalType).getReference();
|
||||
RefactoringUtil.collectTypeParameters(collector, reference);
|
||||
} else {
|
||||
collector = Collections.emptySet();
|
||||
}
|
||||
if (typeContainsTypeParameters(originalType, collector)) return false;
|
||||
}
|
||||
|
||||
if (type instanceof PsiCapturedWildcardType) {
|
||||
@@ -571,14 +578,17 @@ public class TypeMigrationLabeler {
|
||||
}
|
||||
}
|
||||
|
||||
static boolean typeContainsTypeParameters(PsiType originalType) {
|
||||
static boolean typeContainsTypeParameters(@Nullable PsiType originalType, @NotNull Set<PsiTypeParameter> excluded) {
|
||||
if (originalType instanceof PsiClassType) {
|
||||
final PsiClassType psiClassType = (PsiClassType)originalType;
|
||||
if (psiClassType.resolve() instanceof PsiTypeParameter) {
|
||||
return true;
|
||||
}
|
||||
for (PsiType paramType : psiClassType.getParameters()) {
|
||||
if (paramType instanceof PsiClassType && ((PsiClassType)paramType).resolve() instanceof PsiTypeParameter) return true;
|
||||
if (paramType instanceof PsiClassType) {
|
||||
final PsiClass resolved = ((PsiClassType)paramType).resolve();
|
||||
if (resolved instanceof PsiTypeParameter && !excluded.contains(resolved)) return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
+1
-1
@@ -191,7 +191,7 @@ class TypeMigrationStatementProcessor extends JavaRecursiveElementVisitor {
|
||||
final PsiType valueType = myTypeEvaluator.evaluateType(value);
|
||||
if (returnType != null && valueType != null) {
|
||||
if (!myLabeler.addMigrationRoot(method, valueType, myStatement, TypeConversionUtil.isAssignable(returnType, valueType) && !isGetter(value, method), true, true)
|
||||
&& TypeMigrationLabeler.typeContainsTypeParameters(returnType)) {
|
||||
&& TypeMigrationLabeler.typeContainsTypeParameters(returnType, Collections.<PsiTypeParameter>emptySet())) {
|
||||
value.accept(this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -862,8 +862,8 @@ public class TypeMigrationTest extends TypeMigrationTestBase {
|
||||
}
|
||||
|
||||
public void testT139() {
|
||||
doTestForeachParameter(myFactory.createTypeFromText("java.lang.String", null),
|
||||
myFactory.createTypeFromText("java.lang.Integer", null));
|
||||
doTestForeachParameter(
|
||||
myFactory.createTypeFromText("java.lang.Integer", null));
|
||||
}
|
||||
|
||||
public void testT140() {
|
||||
@@ -914,7 +914,32 @@ public class TypeMigrationTest extends TypeMigrationTestBase {
|
||||
doTestFieldType("foo", "Test", PsiType.INT, PsiType.LONG);
|
||||
}
|
||||
|
||||
private void doTestForeachParameter(final PsiType rootType, final PsiType migrationType) {
|
||||
public void testMethodReturnTypeWithTypeParameter() {
|
||||
doTestReturnType("meth", myFactory.createTypeFromText("java.util.List<T>", null));
|
||||
}
|
||||
|
||||
private void doTestReturnType(final String methodName, final PsiType migrationType) {
|
||||
start(new RulesProvider() {
|
||||
@Override
|
||||
public TypeMigrationRules provide() throws Exception {
|
||||
final TypeMigrationRules rules = new TypeMigrationRules();
|
||||
rules.setMigrationRootType(migrationType);
|
||||
return rules;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement victims(PsiClass aClass) {
|
||||
for (PsiMethod method : PsiTreeUtil.findChildrenOfType(aClass, PsiMethod.class)) {
|
||||
if (methodName.equals(method.getName())) {
|
||||
return method;
|
||||
}
|
||||
}
|
||||
throw new AssertionError();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void doTestForeachParameter(final PsiType migrationType) {
|
||||
start(new RulesProvider() {
|
||||
@Override
|
||||
public TypeMigrationRules provide() {
|
||||
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
Types:
|
||||
PsiMethod:meth : java.util.List<T>
|
||||
PsiParameter:p : java.util.List<T>
|
||||
PsiReferenceExpression:p : java.util.List<T>
|
||||
|
||||
Conversions:
|
||||
|
||||
New expression type changes:
|
||||
Fails:
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class Test {
|
||||
public <T> List<T> meth(List<T> p) { return p; }
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
import java.util.Set;
|
||||
|
||||
public class Test {
|
||||
public <T> Set<T> meth(Set<T> p) { return p; }
|
||||
}
|
||||
Reference in New Issue
Block a user