new inference: infer from condition

This commit is contained in:
Anna Kozlova
2013-09-18 16:39:26 +04:00
parent 052290e90e
commit 5c1c1b0bb6
3 changed files with 43 additions and 33 deletions
@@ -189,35 +189,15 @@ public class PsiTypesUtil {
public static PsiType getExpectedTypeByParent(PsiExpression methodCall) {
final PsiElement parent = PsiUtil.skipParenthesizedExprUp(methodCall.getParent());
if (parent instanceof PsiVariable) {
if (checkSameExpression(methodCall, ((PsiVariable)parent).getInitializer())) {
if (PsiUtil.checkSameExpression(methodCall, ((PsiVariable)parent).getInitializer())) {
return ((PsiVariable)parent).getType();
}
}
else if (parent instanceof PsiAssignmentExpression) {
if (checkSameExpression(methodCall, ((PsiAssignmentExpression)parent).getRExpression())) {
if (PsiUtil.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 PsiReturnStatement) {
final PsiLambdaExpression lambdaExpression = PsiTreeUtil.getParentOfType(parent, PsiLambdaExpression.class);
if (lambdaExpression != null) {
@@ -230,10 +210,9 @@ public class PsiTypesUtil {
}
}
}
else if (PsiUtil.isCondition(methodCall, parent)) {
return PsiType.BOOLEAN.getBoxedType(parent);
}
return null;
}
private static boolean checkSameExpression(PsiExpression templateExpr, final PsiExpression expression) {
return templateExpr.equals(PsiUtil.skipParenthesizedExprDown(expression));
}
}
@@ -1061,4 +1061,32 @@ public final class PsiUtil extends PsiUtilCore {
if (className == null) return null;
return className + "." + member.getName();
}
static boolean checkSameExpression(PsiExpression templateExpr, final PsiExpression expression) {
return templateExpr.equals(skipParenthesizedExprDown(expression));
}
public static boolean isCondition(PsiExpression expr, PsiElement parent) {
if (parent instanceof PsiIfStatement) {
if (checkSameExpression(expr, ((PsiIfStatement)parent).getCondition())) {
return true;
}
}
else if (parent instanceof PsiWhileStatement) {
if (checkSameExpression(expr, ((PsiWhileStatement)parent).getCondition())) {
return true;
}
}
else if (parent instanceof PsiForStatement) {
if (checkSameExpression(expr, ((PsiForStatement)parent).getCondition())) {
return true;
}
}
else if (parent instanceof PsiDoWhileStatement) {
if (checkSameExpression(expr, ((PsiDoWhileStatement)parent).getCondition())) {
return true;
}
}
return false;
}
}
@@ -17,6 +17,7 @@ package com.intellij.psi.impl.source.resolve.graphInference;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTypesUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.psi.util.TypeConversionUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -54,12 +55,12 @@ public class PsiPolyExpressionUtil {
if (parameterList != null) {
final PsiTypeElement[] typeElements = parameterList.getTypeParameterElements();
if (typeElements.length == 1 && typeElements[0].getType() instanceof PsiDiamondType) {
return isAssignmentOrInvocationContext(expression.getParent());
return isInAssignmentOrInvocationContext(expression);
}
}
}
} else if (expression instanceof PsiMethodCallExpression) {
if (isAssignmentOrInvocationContext(expression.getParent()) && ((PsiMethodCallExpression)expression).getTypeArguments().length == 0) {
if (isInAssignmentOrInvocationContext(expression) && ((PsiMethodCallExpression)expression).getTypeArguments().length == 0) {
final PsiMethod method = ((PsiMethodCallExpression)expression).resolveMethod();
if (method != null) {
final Set<PsiTypeParameter> typeParameters = new HashSet<PsiTypeParameter>(Arrays.asList(method.getTypeParameters()));
@@ -75,7 +76,7 @@ public class PsiPolyExpressionUtil {
else if (expression instanceof PsiConditionalExpression) {
final ConditionalKind conditionalKind = isBooleanOrNumeric(expression);
if (conditionalKind == null) {
return isAssignmentOrInvocationContext(expression.getParent());
return isInAssignmentOrInvocationContext(expression);
}
}
return false;
@@ -121,12 +122,14 @@ public class PsiPolyExpressionUtil {
});
}
private static boolean isAssignmentOrInvocationContext(PsiElement context) {
return context instanceof PsiExpressionList || isAssignmentContext(context);
private static boolean isInAssignmentOrInvocationContext(PsiExpression expr) {
final PsiElement context = expr.getParent();
return context instanceof PsiExpressionList || isAssignmentContext(expr, context);
}
private static boolean isAssignmentContext(PsiElement context) {
return context instanceof PsiReturnStatement ||
private static boolean isAssignmentContext(PsiExpression expr, PsiElement context) {
return PsiUtil.isCondition(expr, context) ||
context instanceof PsiReturnStatement ||
context instanceof PsiAssignmentExpression ||
context instanceof PsiVariable;
}