getExpectedTypeByParent utility

This commit is contained in:
anna
2013-04-24 19:16:26 +02:00
parent c7a5dd9fa2
commit 0dc7262c45
2 changed files with 95 additions and 77 deletions
@@ -184,4 +184,59 @@ public class PsiTypesUtil {
}
return null;
}
@Nullable
public static PsiType getExpectedTypeByParent(PsiExpression methodCall) {
final PsiElement parent = PsiUtil.skipParenthesizedExprUp(methodCall.getParent());
if (parent instanceof PsiVariable) {
if (checkSameExpression(methodCall, ((PsiVariable)parent).getInitializer())) {
return ((PsiVariable)parent).getType();
}
}
else if (parent instanceof PsiAssignmentExpression) {
if (checkSameExpression(methodCall, ((PsiAssignmentExpression)parent).getRExpression())) {
return ((PsiAssignmentExpression)parent).getLExpression().getType();
}
}
else if (parent instanceof PsiIfStatement) {
if (checkSameExpression(methodCall, ((PsiIfStatement)parent).getCondition())) {
return PsiType.BOOLEAN.getBoxedType(parent);
}
}
else if (parent instanceof PsiWhileStatement) {
if (checkSameExpression(methodCall, ((PsiWhileStatement)parent).getCondition())) {
return PsiType.BOOLEAN.getBoxedType(parent);
}
}
else if (parent instanceof PsiForStatement) {
if (checkSameExpression(methodCall, ((PsiForStatement)parent).getCondition())) {
return PsiType.BOOLEAN.getBoxedType(parent);
}
}
else if (parent instanceof PsiDoWhileStatement) {
if (checkSameExpression(methodCall, ((PsiDoWhileStatement)parent).getCondition())) {
return PsiType.BOOLEAN.getBoxedType(parent);
}
}
else if (parent instanceof PsiTypeCastExpression) {
return ((PsiTypeCastExpression)parent).getType();
}
else if (parent instanceof PsiReturnStatement) {
final PsiLambdaExpression lambdaExpression = PsiTreeUtil.getParentOfType(parent, PsiLambdaExpression.class);
if (lambdaExpression != null) {
return LambdaUtil.getFunctionalInterfaceReturnType(lambdaExpression.getFunctionalInterfaceType());
}
else {
PsiMethod method = PsiTreeUtil.getParentOfType(parent, PsiMethod.class);
if (method != null) {
return method.getReturnType();
}
}
}
return null;
}
private static boolean checkSameExpression(PsiExpression templateExpr, final PsiExpression expression) {
return templateExpr.equals(PsiUtil.skipParenthesizedExprDown(expression));
}
}
@@ -34,10 +34,7 @@ import com.intellij.psi.scope.processor.MethodCandidatesProcessor;
import com.intellij.psi.scope.processor.MethodResolverProcessor;
import com.intellij.psi.scope.util.PsiScopesUtil;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.InheritanceUtil;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.psi.util.*;
import com.intellij.util.ArrayUtil;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.containers.HashMap;
@@ -1015,88 +1012,50 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
PsiSubstitutor substitutor,
ParameterTypeInferencePolicy policy) {
Pair<PsiType, ConstraintType> constraint = null;
PsiType expectedType = null;
PsiType expectedType = PsiTypesUtil.getExpectedTypeByParent(methodCall);
if (parent instanceof PsiVariable) {
if (methodCall.equals(PsiUtil.skipParenthesizedExprDown(((PsiVariable)parent).getInitializer()))) {
expectedType = ((PsiVariable)parent).getType();
}
}
else if (parent instanceof PsiAssignmentExpression) {
if (methodCall.equals(PsiUtil.skipParenthesizedExprDown(((PsiAssignmentExpression)parent).getRExpression()))) {
expectedType = ((PsiAssignmentExpression)parent).getLExpression().getType();
}
}
else if (parent instanceof PsiIfStatement) {
if (methodCall.equals(PsiUtil.skipParenthesizedExprDown(((PsiIfStatement)parent).getCondition()))) {
expectedType = PsiType.BOOLEAN.getBoxedType(parent);
}
}
else if (parent instanceof PsiWhileStatement) {
if (methodCall.equals(PsiUtil.skipParenthesizedExprDown(((PsiWhileStatement)parent).getCondition()))) {
expectedType = PsiType.BOOLEAN.getBoxedType(parent);
}
}
else if (parent instanceof PsiForStatement) {
if (methodCall.equals(PsiUtil.skipParenthesizedExprDown(((PsiForStatement)parent).getCondition()))) {
expectedType = PsiType.BOOLEAN.getBoxedType(parent);
}
}
else if (parent instanceof PsiDoWhileStatement) {
if (methodCall.equals(PsiUtil.skipParenthesizedExprDown(((PsiDoWhileStatement)parent).getCondition()))) {
expectedType = PsiType.BOOLEAN.getBoxedType(parent);
}
}
else if (parent instanceof PsiReturnStatement) {
final PsiLambdaExpression lambdaExpression = PsiTreeUtil.getParentOfType(parent, PsiLambdaExpression.class);
if (lambdaExpression != null) {
expectedType = LambdaUtil.getFunctionalInterfaceReturnType(lambdaExpression.getFunctionalInterfaceType());
if (expectedType == null) {
if (expectedType == null) {
if (parent instanceof PsiReturnStatement) {
final PsiLambdaExpression lambdaExpression = PsiTreeUtil.getParentOfType(parent, PsiLambdaExpression.class);
if (lambdaExpression != null) {
return getFailedInferenceConstraint(typeParameter);
}
} else {
PsiMethod method = PsiTreeUtil.getParentOfType(parent, PsiMethod.class);
if (method != null) {
expectedType = method.getReturnType();
}
}
}
else if (parent instanceof PsiExpressionList) {
final PsiElement pParent = parent.getParent();
if (pParent instanceof PsiCallExpression && parent.equals(((PsiCallExpression)pParent).getArgumentList())) {
constraint = policy.inferTypeConstraintFromCallContext(methodCall, (PsiExpressionList)parent, (PsiCallExpression)pParent, typeParameter);
if (constraint == null && PsiUtil.isLanguageLevel8OrHigher(methodCall)) {
constraint = graphInferenceFromCallContext(methodCall, typeParameter, (PsiCallExpression)pParent);
if (constraint != null) {
final PsiType constraintFirst = constraint.getFirst();
if (constraintFirst == null || constraintFirst.equalsToText(CommonClassNames.JAVA_LANG_OBJECT)) {
constraint = null;
else if (parent instanceof PsiExpressionList) {
final PsiElement pParent = parent.getParent();
if (pParent instanceof PsiCallExpression && parent.equals(((PsiCallExpression)pParent).getArgumentList())) {
constraint = policy.inferTypeConstraintFromCallContext(methodCall, (PsiExpressionList)parent, (PsiCallExpression)pParent, typeParameter);
if (constraint == null && PsiUtil.isLanguageLevel8OrHigher(methodCall)) {
constraint = graphInferenceFromCallContext(methodCall, typeParameter, (PsiCallExpression)pParent);
if (constraint != null) {
final PsiType constraintFirst = constraint.getFirst();
if (constraintFirst == null || constraintFirst.equalsToText(CommonClassNames.JAVA_LANG_OBJECT)) {
constraint = null;
}
}
}
}
}
} else if (parent instanceof PsiLambdaExpression) {
expectedType = ourGraphGuard.doPreventingRecursion(methodCall, true, new Computable<PsiType>() {
@Override
public PsiType compute() {
return LambdaUtil.getFunctionalInterfaceReturnType(((PsiLambdaExpression)parent).getFunctionalInterfaceType());
}
});
if (expectedType == null) {
return null;
}
} else if (parent instanceof PsiTypeCastExpression) {
expectedType = ((PsiTypeCastExpression)parent).getType();
} else if (parent instanceof PsiConditionalExpression) {
if (PsiUtil.isLanguageLevel8OrHigher(parent)) {
try {
final Pair<PsiType, ConstraintType> pair = inferFromConditionalExpression(parent, methodCall, typeParameter, substitutor, policy);
if (pair != null) {
return pair;
} else if (parent instanceof PsiLambdaExpression) {
expectedType = ourGraphGuard.doPreventingRecursion(methodCall, true, new Computable<PsiType>() {
@Override
public PsiType compute() {
return LambdaUtil.getFunctionalInterfaceReturnType(((PsiLambdaExpression)parent).getFunctionalInterfaceType());
}
});
if (expectedType == null) {
return null;
}
finally {
GraphInferencePolicy.forget(parent);
} else if (parent instanceof PsiConditionalExpression) {
if (PsiUtil.isLanguageLevel8OrHigher(parent)) {
try {
final Pair<PsiType, ConstraintType> pair = inferFromConditionalExpression(parent, methodCall, typeParameter, substitutor, policy);
if (pair != null) {
return pair;
}
}
finally {
GraphInferencePolicy.forget(parent);
}
}
}
}
@@ -1196,6 +1155,10 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
return result;
}
private static boolean checkSameExpression(PsiExpression templateExpr, final PsiExpression expression) {
return templateExpr.equals(PsiUtil.skipParenthesizedExprDown(expression));
}
private static Pair<PsiType, ConstraintType> inferExceptionConstrains(PsiTypeParameter typeParameter,
PsiExpression expression,
PsiMethod method,