replace diamond with type on inline when after inline diamond won't be inferred (IDEA-66142)

This commit is contained in:
anna
2011-03-08 11:25:19 +01:00
parent 7a2f03d06b
commit afd90a6695
7 changed files with 114 additions and 4 deletions

View File

@@ -53,7 +53,7 @@ public class InlineUtil {
initializer = RefactoringUtil.convertInitializerToNormalExpression(initializer, varType);
ChangeContextUtil.encodeContextInfo(initializer, false);
PsiExpression expr = (PsiExpression)ref.replace(initializer);
PsiExpression expr = (PsiExpression)replaceDiamondWithInferredTypesIfNeeded(initializer, ref);
PsiType exprType = expr.getType();
if (exprType != null && (!varType.equals(exprType) && varType instanceof PsiPrimitiveType
|| !TypeConversionUtil.isAssignable(varType, exprType))) {
@@ -315,6 +315,46 @@ public class InlineUtil {
});
}
private static PsiElement replaceDiamondWithInferredTypesIfNeeded(PsiExpression initializer, PsiElement ref) {
if (initializer instanceof PsiNewExpression) {
final PsiJavaCodeReferenceElement classReference = ((PsiNewExpression)initializer).getClassOrAnonymousClassReference();
if (classReference != null) {
final PsiReferenceParameterList parameterList = classReference.getParameterList();
if (parameterList != null) {
final PsiTypeElement[] typeParameterElements = parameterList.getTypeParameterElements();
if (typeParameterElements.length == 1) {
final PsiType type = typeParameterElements[0].getType();
if (type instanceof PsiDiamondType) {
final PsiDiamondType.DiamondInferenceResult inferenceResult = ((PsiDiamondType)type).resolveInferredTypes();
if (inferenceResult.getErrorMessage() == null) {
final PsiElement copy = ref.copy();
final PsiElement parent = ref.replace(initializer);
final PsiDiamondType.DiamondInferenceResult result = PsiDiamondType.resolveInferredTypes((PsiNewExpression)initializer, parent);
ref = parent.replace(copy);
if (!result.equals(inferenceResult)) {
final String inferredTypeText = StringUtil.join(inferenceResult.getTypes(),
new Function<PsiType, String>() {
@Override
public String fun(PsiType psiType) {
return psiType.getCanonicalText();
}
}, ", ");
final PsiExpressionList argumentList = ((PsiNewExpression)initializer).getArgumentList();
if (argumentList != null) {
final PsiExpression expression = JavaPsiFacade.getElementFactory(initializer.getProject())
.createExpressionFromText("new " + classReference.getReferenceName() + "<" + inferredTypeText + ">" + argumentList.getText(), initializer);
return ref.replace(expression);
}
}
}
}
}
}
}
}
return ref.replace(initializer);
}
public enum TailCallType {
None, Simple, Return
}

View File

@@ -0,0 +1,9 @@
import java.util.*;
class Test {
void foo(){
Map<Integer, String> m<caret>ap = new HashMap<>();
System.out.println(map);
}
}

View File

@@ -0,0 +1,8 @@
import java.util.*;
class Test {
void foo(){
System.out.println(new HashMap<Integer, String>());
}
}

View File

@@ -0,0 +1,9 @@
import java.util.*;
class Test {
void foo(){
Map<Integer, String> m<caret>ap = new HashMap<>();
Map<Integer, String> map1 = map;
}
}

View File

@@ -0,0 +1,8 @@
import java.util.*;
class Test {
void foo(){
Map<Integer, String> map1 = new HashMap<>();
}
}

View File

@@ -70,6 +70,14 @@ public class InlineLocalTest extends LightCodeInsightTestCase {
doTest(false);
}
public void testNewExpressionWithDiamond() throws Exception {
doTest(false);
}
public void testNewExpressionWithPreservedDiamond() throws Exception {
doTest(false);
}
public void testAugmentedAssignment() throws Exception {
String exception = null;
try {

View File

@@ -18,11 +18,13 @@ package com.intellij.psi;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.ArrayUtil;
import com.intellij.util.Function;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -97,6 +99,11 @@ public class PsiDiamondType extends PsiType {
}
public static DiamondInferenceResult resolveInferredTypes(PsiNewExpression newExpression) {
return resolveInferredTypes(newExpression, newExpression);
}
public static DiamondInferenceResult resolveInferredTypes(PsiNewExpression newExpression,
PsiElement context) {
final PsiClass psiClass = findClass(newExpression);
if (psiClass == null) return DiamondInferenceResult.NULL_RESULT;
final PsiExpressionList argumentList = newExpression.getArgumentList();
@@ -107,7 +114,7 @@ public class PsiDiamondType extends PsiType {
if (staticFactory == null) {
return DiamondInferenceResult.NULL_RESULT;
}
final PsiSubstitutor inferredSubstitutor = inferTypeParametersForStaticFactory(staticFactory, newExpression);
final PsiSubstitutor inferredSubstitutor = inferTypeParametersForStaticFactory(staticFactory, newExpression, context);
final PsiTypeParameter[] parameters = staticFactory.getTypeParameters();
final PsiTypeParameter[] classParameters = psiClass.getTypeParameters();
final PsiJavaCodeReferenceElement classOrAnonymousClassReference = newExpression.getClassOrAnonymousClassReference();
@@ -210,14 +217,15 @@ public class PsiDiamondType extends PsiType {
private static PsiSubstitutor inferTypeParametersForStaticFactory(@NotNull PsiMethod staticFactoryMethod,
PsiNewExpression expression) {
PsiNewExpression expression,
PsiElement parent) {
final JavaPsiFacade facade = JavaPsiFacade.getInstance(staticFactoryMethod.getProject());
final PsiResolveHelper resolveHelper = facade.getResolveHelper();
final PsiParameter[] parameters = staticFactoryMethod.getParameterList().getParameters();
final PsiExpressionList argumentList = expression.getArgumentList();
final PsiExpression[] expressions = argumentList.getExpressions();
return resolveHelper
.inferTypeArguments(staticFactoryMethod.getTypeParameters(), parameters, expressions, PsiSubstitutor.EMPTY, expression, false);
.inferTypeArguments(staticFactoryMethod.getTypeParameters(), parameters, expressions, PsiSubstitutor.EMPTY, parent, false);
}
public static class DiamondInferenceResult {
@@ -301,6 +309,26 @@ public class PsiDiamondType extends PsiType {
}
});
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
DiamondInferenceResult that = (DiamondInferenceResult)o;
if (myErrorMessage != null ? !myErrorMessage.equals(that.myErrorMessage) : that.myErrorMessage != null) return false;
if (!myInferredTypes.equals(that.myInferredTypes)) return false;
return true;
}
@Override
public int hashCode() {
int result = myInferredTypes.hashCode();
result = 31 * result + (myErrorMessage != null ? myErrorMessage.hashCode() : 0);
return result;
}
}
public static boolean hasDefaultConstructor(@NotNull final PsiClass psiClass) {