extract diamond check for new expression

This commit is contained in:
Anna Kozlova
2015-11-30 19:45:19 +01:00
parent 878ac5560e
commit 3c0149acad
5 changed files with 58 additions and 70 deletions
@@ -22,6 +22,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Ref;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.impl.PsiDiamondTypeUtil;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.psi.util.PsiUtil;
@@ -96,12 +97,8 @@ public class ChangeClassSignatureProcessor extends BaseRefactoringProcessor {
PsiJavaCodeReferenceElement referenceElement = (PsiJavaCodeReferenceElement)reference.getElement();
PsiElement parent = referenceElement.getParent();
if (parent instanceof PsiTypeElement && parent.getParent() instanceof PsiInstanceOfExpression) continue;
if (parent instanceof PsiNewExpression && PsiUtil.isLanguageLevel7OrHigher(parent)) {
final PsiReferenceParameterList parameterList = referenceElement.getParameterList();
if (parameterList != null) {
final PsiTypeElement[] parameterElements = parameterList.getTypeParameterElements();
if (parameterElements.length == 1 && parameterElements[0].getType() instanceof PsiDiamondType) continue;
}
if (parent instanceof PsiNewExpression && PsiDiamondTypeUtil.hasDiamond((PsiNewExpression)parent)) {
continue;
}
if (parent instanceof PsiTypeElement || parent instanceof PsiNewExpression || parent instanceof PsiAnonymousClass ||
parent instanceof PsiReferenceList) {
@@ -23,6 +23,7 @@ import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.impl.PsiDiamondTypeUtil;
import com.intellij.psi.search.LocalSearchScope;
import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.psi.tree.IElementType;
@@ -384,36 +385,29 @@ 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 = PsiDiamondTypeImpl.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);
}
}
}
final PsiDiamondType diamondType = PsiDiamondTypeUtil.getDiamondType((PsiNewExpression)initializer);
if (diamondType != null) {
final PsiDiamondType.DiamondInferenceResult inferenceResult = diamondType.resolveInferredTypes();
if (inferenceResult.getErrorMessage() == null) {
final PsiElement copy = ref.copy();
final PsiElement parent = ref.replace(initializer);
final PsiDiamondType.DiamondInferenceResult result = PsiDiamondTypeImpl.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 PsiJavaCodeReferenceElement classReference = ((PsiNewExpression)initializer).getClassOrAnonymousClassReference();
LOG.assertTrue(classReference != null);
final PsiExpression expression = JavaPsiFacade.getElementFactory(initializer.getProject())
.createExpressionFromText("new " + classReference.getReferenceName() + "<" + inferredTypeText + ">" + argumentList.getText(), initializer);
return ref.replace(expression);
}
}
}
@@ -162,4 +162,25 @@ public class PsiDiamondTypeUtil {
}
return typeText;
}
public static boolean hasDiamond(PsiNewExpression expression) {
return getDiamondType(expression) != null;
}
public static PsiDiamondType getDiamondType(PsiNewExpression expression) {
if (PsiUtil.isLanguageLevel7OrHigher(expression)) {
final PsiJavaCodeReferenceElement classReference = expression.getClassOrAnonymousClassReference();
if (classReference != null) {
final PsiReferenceParameterList parameterList = classReference.getParameterList();
if (parameterList != null) {
final PsiTypeElement[] parameterElements = parameterList.getTypeParameterElements();
if (parameterElements.length == 1) {
final PsiType type = parameterElements[0].getType();
return type instanceof PsiDiamondType ? (PsiDiamondType)type : null;
}
}
}
}
return null;
}
}
@@ -22,6 +22,7 @@ import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.impl.PsiDiamondTypeUtil;
import com.intellij.psi.impl.PsiImplUtil;
import com.intellij.psi.impl.source.resolve.graphInference.constraints.*;
import com.intellij.psi.infos.MethodCandidateInfo;
@@ -257,17 +258,8 @@ public class InferenceSession {
}
else if (method.isConstructor() && gParent instanceof PsiNewExpression) {
final PsiClass containingClass = method.getContainingClass();
if (containingClass != null && containingClass.hasTypeParameters()) {
final PsiJavaCodeReferenceElement classReference = ((PsiNewExpression)gParent).getClassOrAnonymousClassReference();
if (classReference != null) {
final PsiReferenceParameterList parameterList = classReference.getParameterList();
if (parameterList != null) {
final PsiTypeElement[] typeElements = parameterList.getTypeParameterElements();
if (typeElements.length == 1 && typeElements[0].getType() instanceof PsiDiamondType) {
owner = containingClass;
}
}
}
if (containingClass != null && containingClass.hasTypeParameters() && PsiDiamondTypeUtil.hasDiamond((PsiNewExpression)gParent)) {
owner = containingClass;
}
}
return owner;
@@ -16,6 +16,7 @@
package com.intellij.psi.impl.source.resolve.graphInference;
import com.intellij.psi.*;
import com.intellij.psi.impl.PsiDiamondTypeUtil;
import com.intellij.psi.infos.MethodCandidateInfo;
import com.intellij.psi.util.PsiUtil;
import com.intellij.psi.util.TypeConversionUtil;
@@ -46,18 +47,10 @@ public class PsiPolyExpressionUtil {
else if (expression instanceof PsiParenthesizedExpression) {
return isPolyExpression(((PsiParenthesizedExpression)expression).getExpression());
}
else if (expression instanceof PsiNewExpression) {
final PsiJavaCodeReferenceElement classReference = ((PsiNewExpression)expression).getClassOrAnonymousClassReference();
if (classReference != null) {
final PsiReferenceParameterList parameterList = classReference.getParameterList();
if (parameterList != null) {
final PsiTypeElement[] typeElements = parameterList.getTypeParameterElements();
if (typeElements.length == 1 && typeElements[0].getType() instanceof PsiDiamondType) {
return isInAssignmentOrInvocationContext(expression);
}
}
}
} else if (expression instanceof PsiMethodCallExpression) {
else if (expression instanceof PsiNewExpression && PsiDiamondTypeUtil.hasDiamond((PsiNewExpression)expression)) {
return isInAssignmentOrInvocationContext(expression);
}
else if (expression instanceof PsiMethodCallExpression) {
final MethodCandidateInfo.CurrentCandidateProperties candidateProperties = MethodCandidateInfo.getCurrentMethod(((PsiMethodCallExpression)expression).getArgumentList());
return isMethodCallPolyExpression(expression, candidateProperties != null ? candidateProperties.getMethod() : ((PsiMethodCallExpression)expression).resolveMethod());
}
@@ -80,17 +73,8 @@ public class PsiPolyExpressionUtil {
return mentionsTypeParameters(returnType, typeParameters);
}
}
else if (method.isConstructor() && expression instanceof PsiNewExpression) {
final PsiJavaCodeReferenceElement classReference = ((PsiNewExpression)expression).getClassOrAnonymousClassReference();
if (classReference != null) {
final PsiReferenceParameterList parameterList = classReference.getParameterList();
if (parameterList != null) {
final PsiTypeElement[] parameterElements = parameterList.getTypeParameterElements();
if (parameterElements.length == 1 && parameterElements[0].getType() instanceof PsiDiamondType) {
return true;
}
}
}
else if (method.isConstructor() && expression instanceof PsiNewExpression && PsiDiamondTypeUtil.hasDiamond((PsiNewExpression)expression)) {
return true;
}
} else {
return true;