type migration: migration propagates via equals method (IDEA-147948)

This commit is contained in:
Dmitry Batkovich
2015-11-25 15:39:07 +03:00
parent f35a923139
commit de53c14328
5 changed files with 76 additions and 0 deletions
@@ -427,6 +427,9 @@ class TypeMigrationStatementProcessor extends JavaRecursiveElementVisitor {
final JavaResolveResult resolveResult = methodCallExpression.resolveMethodGenerics();
final PsiElement method = resolveResult.getElement();
if (method instanceof PsiMethod) {
if (migrateEqualsMethod(methodCallExpression, (PsiMethod)method)) {
return;
}
final PsiExpression[] psiExpressions = methodCallExpression.getArgumentList().getExpressions();
final PsiParameter[] originalParams = ((PsiMethod)method).getParameterList().getParameters();
final PsiSubstitutor evalSubstitutor = myTypeEvaluator.createMethodSubstitution(originalParams, psiExpressions, (PsiMethod)method, methodCallExpression);
@@ -457,6 +460,38 @@ class TypeMigrationStatementProcessor extends JavaRecursiveElementVisitor {
}
}
private boolean migrateEqualsMethod(PsiMethodCallExpression methodCallExpression, PsiMethod method) {
final PsiExpression qualifier = methodCallExpression.getMethodExpression().getQualifierExpression();
if (qualifier == null) {
return false;
}
final TypeView qualifierTypeView = new TypeView(qualifier);
if (!qualifierTypeView.isChanged()) {
return false;
}
if (method.getName().equals("equals") && method.getParameterList().getParametersCount() == 1) {
final PsiParameter parameter = method.getParameterList().getParameters()[0];
if (parameter.getType().equals(PsiType.getJavaLangObject(methodCallExpression.getManager(), methodCallExpression.getResolveScope()))) {
final PsiExpression[] expressions = methodCallExpression.getArgumentList().getExpressions();
if (expressions.length != 1) {
return false;
}
final TypeView argumentTypeView = new TypeView(expressions[0]);
final PsiType argumentType = argumentTypeView.getType();
if (!argumentTypeView.isChanged() && qualifierTypeView.getTypePair().getFirst().equals(argumentType)) {
final PsiType migrationType = qualifierTypeView.getType();
myLabeler.migrateExpressionType(expressions[0],
migrationType,
methodCallExpression,
TypeConversionUtil.isAssignable(migrationType, argumentType),
true);
return true;
}
}
}
return false;
}
private void processVariable(final PsiVariable variable,
final PsiExpression value,
final PsiType migrationType,
@@ -896,6 +896,10 @@ public class TypeMigrationTest extends TypeMigrationTestBase {
myFactory.createTypeFromText("Test.AnInterface2<java.lang.String, java.lang.Void>", null));
}
public void testPropagateViaEquals() {
doTestFirstParamType("meth", myFactory.createTypeFromText("java.lang.String", null), myFactory.createTypeFromText("java.lang.Long", null));
}
private void doTestForeachParameter(final PsiType rootType, final PsiType migrationType) {
start(new RulesProvider() {
@Override
@@ -0,0 +1,19 @@
Types:
PsiMethodCallExpression:p1.equals(p2) : boolean
PsiMethodCallExpression:p2.hashCode() : int
PsiMethodCallExpression:p2.toString() : java.lang.String
PsiParameter:p1 : java.lang.Long
PsiParameter:p2 : java.lang.Long
PsiReferenceExpression:p1 : java.lang.Long
PsiReferenceExpression:p2 : java.lang.Long
PsiReferenceExpression:p2 : java.lang.Long
PsiReferenceExpression:p2 : java.lang.Long
PsiReferenceExpression:p2 : java.lang.Long
Conversions:
p1.equals(p2) -> $
p2.hashCode() -> $
p2.toString() -> $
New expression type changes:
Fails:
@@ -0,0 +1,9 @@
public class Test {
public void meth(Long p1, Long p2) {
p2.hashCode();
System.out.println(p2.toString());
if (p1.equals(p2)) {
System.out.print("dummy action" + p2);
}
}
}
@@ -0,0 +1,9 @@
public class Test {
public void meth(String p1, String p2) {
p2.hashCode();
System.out.println(p2.toString());
if (p1.equals(p2)) {
System.out.print("dummy action" + p2);
}
}
}