mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
getExpectedTypeByParent utility
This commit is contained in:
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
+40
-77
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user