mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
new inference: simplify target type calculation
This commit is contained in:
@@ -227,13 +227,19 @@ public class JavaResolveUtil {
|
||||
|
||||
public static void substituteResults(@NotNull PsiJavaCodeReferenceElement ref, @NotNull JavaResolveResult[] result) {
|
||||
if (result.length > 0 && result[0].getElement() instanceof PsiClass) {
|
||||
PsiType[] parameters = ref.getTypeParameters();
|
||||
for (int i = 0; i < result.length; i++) {
|
||||
CandidateInfo resolveResult = (CandidateInfo)result[i];
|
||||
PsiElement resultElement = resolveResult.getElement();
|
||||
if (resultElement instanceof PsiClass && ((PsiClass)resultElement).hasTypeParameters()) {
|
||||
PsiSubstitutor substitutor = resolveResult.getSubstitutor().putAll((PsiClass)resultElement, parameters);
|
||||
result[i] = new CandidateInfo(resolveResult, substitutor);
|
||||
PsiSubstitutor substitutor = resolveResult.getSubstitutor();
|
||||
result[i] = new CandidateInfo(resolveResult, substitutor) {
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiSubstitutor getSubstitutor() {
|
||||
final PsiType[] parameters = ref.getTypeParameters();
|
||||
return super.getSubstitutor().putAll((PsiClass)resultElement, parameters);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+16
-79
@@ -23,12 +23,6 @@ import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.PsiImplUtil;
|
||||
import com.intellij.psi.impl.source.resolve.graphInference.constraints.*;
|
||||
import com.intellij.psi.infos.MethodCandidateInfo;
|
||||
import com.intellij.psi.scope.MethodProcessorSetupFailedException;
|
||||
import com.intellij.psi.scope.PsiConflictResolver;
|
||||
import com.intellij.psi.scope.conflictResolvers.JavaMethodsConflictResolver;
|
||||
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.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiTypesUtil;
|
||||
@@ -174,7 +168,8 @@ public class InferenceSession {
|
||||
return true;
|
||||
}
|
||||
|
||||
private static PsiType getParameterType(PsiParameter[] parameters, PsiExpression[] args, int i, PsiSubstitutor substitutor) {
|
||||
private static PsiType getParameterType(PsiParameter[] parameters, PsiExpression[] args, int i, @Nullable PsiSubstitutor substitutor) {
|
||||
if (substitutor == null) return null;
|
||||
PsiType parameterType = substitutor.substitute(parameters[i < parameters.length ? i : parameters.length - 1].getType());
|
||||
if (parameterType instanceof PsiEllipsisType) {
|
||||
final PsiExpression arg = args[i];
|
||||
@@ -366,19 +361,13 @@ public class InferenceSession {
|
||||
}
|
||||
|
||||
private void initReturnTypeConstraint(PsiMethod method, final PsiCallExpression context) {
|
||||
if (PsiPolyExpressionUtil.isMethodCallPolyExpression(context, method) ||
|
||||
context instanceof PsiNewExpression && PsiDiamondType.ourDiamondGuard.currentStack().contains(context)) {
|
||||
if (PsiPolyExpressionUtil.isMethodCallPolyExpression(context, method)) {
|
||||
PsiType returnType = method.getReturnType();
|
||||
if (!PsiType.VOID.equals(returnType) && returnType != null) {
|
||||
returnType = PsiImplUtil.normalizeWildcardTypeByPosition(returnType, context);
|
||||
PsiType targetType = PsiTypesUtil.getExpectedTypeByParent(context);
|
||||
if (targetType == null) {
|
||||
targetType = PsiResolveHelper.ourGraphGuard.doPreventingRecursion(context, false, new Computable<PsiType>() {
|
||||
@Override
|
||||
public PsiType compute() {
|
||||
return getTargetType(context);
|
||||
}
|
||||
});
|
||||
targetType = getTargetType(context);
|
||||
}
|
||||
if (targetType != null) {
|
||||
registerConstraints(returnType, targetType);
|
||||
@@ -495,7 +484,7 @@ public class InferenceSession {
|
||||
return false;
|
||||
}
|
||||
|
||||
private PsiType getTargetType(final PsiExpression context) {
|
||||
private static PsiType getTargetType(final PsiExpression context) {
|
||||
final PsiElement parent = PsiUtil.skipParenthesizedExprUp(context.getParent());
|
||||
if (parent instanceof PsiExpressionList) {
|
||||
PsiElement gParent = parent.getParent();
|
||||
@@ -505,28 +494,8 @@ public class InferenceSession {
|
||||
if (gParent instanceof PsiCallExpression) {
|
||||
final PsiExpressionList argumentList = ((PsiCallExpression)gParent).getArgumentList();
|
||||
if (argumentList != null) {
|
||||
final Pair<PsiMethod, PsiSubstitutor> pair = MethodCandidateInfo.getCurrentMethod(argumentList);
|
||||
final PsiFile placeFile = context.getContainingFile();
|
||||
final JavaMethodsConflictResolver conflictResolver = new JavaMethodsConflictResolver(argumentList, PsiUtil.getLanguageLevel(placeFile)){
|
||||
@Override
|
||||
protected PsiType[] getArgumentTypes() {
|
||||
return InferenceSession.getArgumentTypes(argumentList, context);
|
||||
}
|
||||
};
|
||||
final MethodCandidatesProcessor processor = new MethodResolverProcessor((PsiCallExpression)gParent, placeFile, new PsiConflictResolver[]{conflictResolver}) {
|
||||
@Override
|
||||
protected PsiType[] getExpressionTypes(PsiExpressionList argumentList) {
|
||||
return getArgumentTypes(argumentList, context);
|
||||
}
|
||||
};
|
||||
try {
|
||||
PsiScopesUtil.setupAndRunProcessor(processor, (PsiCallExpression)gParent, false);
|
||||
}
|
||||
catch (MethodProcessorSetupFailedException e) {
|
||||
return null;
|
||||
}
|
||||
final JavaResolveResult[] results = processor.getResult();
|
||||
return results.length == 1 ? getTypeByMethod(context, argumentList, pair, results[0], results[0].getElement()) : null;
|
||||
final JavaResolveResult result = ((PsiCallExpression)gParent).resolveMethodGenerics();
|
||||
return getTypeByMethod(context, argumentList, result, result.getElement());
|
||||
}
|
||||
}
|
||||
} else if (parent instanceof PsiConditionalExpression) {
|
||||
@@ -546,30 +515,9 @@ public class InferenceSession {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static PsiType[] getArgumentTypes(PsiExpressionList argumentList, PsiExpression context) {
|
||||
if (argumentList != null) {
|
||||
final PsiExpression[] expressions = argumentList.getExpressions();
|
||||
final int idx = LambdaUtil.getLambdaIdx(argumentList, context);
|
||||
final PsiType[] types = PsiType.createArray(expressions.length);
|
||||
for (int i = 0; i < expressions.length; i++) {
|
||||
if (i != idx) {
|
||||
types[i] = expressions[i].getType();
|
||||
}
|
||||
else {
|
||||
types[i] = PsiType.NULL;
|
||||
}
|
||||
}
|
||||
return types;
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private PsiType getTypeByMethod(PsiExpression context,
|
||||
PsiExpressionList argumentList,
|
||||
Pair<PsiMethod, PsiSubstitutor> pair,
|
||||
JavaResolveResult result, PsiElement parentMethod) {
|
||||
private static PsiType getTypeByMethod(PsiExpression context,
|
||||
PsiExpressionList argumentList,
|
||||
final JavaResolveResult result, PsiElement parentMethod) {
|
||||
if (parentMethod instanceof PsiMethod) {
|
||||
final PsiParameter[] parameters = ((PsiMethod)parentMethod).getParameterList().getParameters();
|
||||
if (parameters.length == 0) return null;
|
||||
@@ -581,23 +529,12 @@ public class InferenceSession {
|
||||
}
|
||||
final int i = ArrayUtilRt.find(args, arg);
|
||||
if (i < 0) return null;
|
||||
final PsiCallExpression callExpression = PsiTreeUtil.getParentOfType(argumentList, PsiCallExpression.class);
|
||||
if (callExpression != null && callExpression.getTypeArguments().length > 0) {
|
||||
return getParameterType(parameters, args, i, ((MethodCandidateInfo)result).typeArgumentsSubstitutor());
|
||||
}
|
||||
final PsiType parameterType = getParameterType(parameters, args, i, pair != null ? pair.second : PsiSubstitutor.EMPTY);
|
||||
args[i] = null;
|
||||
final PsiTypeParameter[] typeParameters = ((PsiMethod)parentMethod).getTypeParameters();
|
||||
final InferenceSession session = new InferenceSession(typeParameters, ((MethodCandidateInfo)result).getSiteSubstitutor(), myManager, argumentList);
|
||||
session.initExpressionConstraints(parameters, args, argumentList, (PsiMethod)parentMethod);
|
||||
if (session.tryToInfer(parameters, args, callExpression, (PsiMethod)parentMethod) != null) {
|
||||
return null;
|
||||
}
|
||||
final Collection<PsiTypeParameter> params = session.getTypeParams();
|
||||
initBounds(params.toArray(new PsiTypeParameter[params.size()]));
|
||||
liftBounds(session.getInferenceVariables());
|
||||
final PsiSubstitutor substitutor = ((MethodCandidateInfo)result).getSiteSubstitutor();
|
||||
return substitutor.substitute(parameterType);
|
||||
return getParameterType(parameters, args, i, PsiResolveHelper.ourGraphGuard.doPreventingRecursion(argumentList.getParent(), false, new Computable<PsiSubstitutor>() {
|
||||
@Override
|
||||
public PsiSubstitutor compute() {
|
||||
return result.getSubstitutor();
|
||||
}
|
||||
}));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
-11
@@ -48,17 +48,6 @@ public class CheckedExceptionCompatibilityConstraint extends InputOutputConstrai
|
||||
if (!PsiPolyExpressionUtil.isPolyExpression(myExpression)) {
|
||||
return true;
|
||||
}
|
||||
if (myExpression instanceof PsiCallExpression) {
|
||||
final PsiExpressionList argumentList = ((PsiCallExpression)myExpression).getArgumentList();
|
||||
if (argumentList != null) {
|
||||
for (PsiExpression expression : argumentList.getExpressions()) {
|
||||
if (PsiPolyExpressionUtil.isPolyExpression(expression)) {
|
||||
//todo additional constraints [JDK-8033488]
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (myExpression instanceof PsiParenthesizedExpression) {
|
||||
constraints.add(new CheckedExceptionCompatibilityConstraint(((PsiParenthesizedExpression)myExpression).getExpression(), myT));
|
||||
return true;
|
||||
|
||||
+8
-8
@@ -103,18 +103,18 @@ public class ExpressionCompatibilityConstraint extends InputOutputConstraintForm
|
||||
session.addCapturedVariable(typeParam);
|
||||
}
|
||||
PsiSubstitutor substitutor = PsiSubstitutor.EMPTY;
|
||||
//typeParams are already included
|
||||
final Collection<PsiTypeParameter> params = session.getTypeParams();
|
||||
InferenceSession callSession = new InferenceSession(params.toArray(new PsiTypeParameter[params.size()]), resolveResult instanceof MethodCandidateInfo ? ((MethodCandidateInfo)resolveResult).getSiteSubstitutor()
|
||||
: PsiSubstitutor.EMPTY, myExpression.getManager(), myExpression);
|
||||
if (method != null) {
|
||||
//typeParams are already included
|
||||
final Collection<PsiTypeParameter> params = session.getTypeParams();
|
||||
InferenceSession callSession = new InferenceSession(params.toArray(new PsiTypeParameter[params.size()]), resolveResult instanceof MethodCandidateInfo ? ((MethodCandidateInfo)resolveResult).getSiteSubstitutor()
|
||||
: PsiSubstitutor.EMPTY, myExpression.getManager(), myExpression);
|
||||
final PsiExpression[] args = argumentList.getExpressions();
|
||||
final PsiParameter[] parameters = method.getParameterList().getParameters();
|
||||
callSession.initExpressionConstraints(parameters, args, myExpression, method);
|
||||
callSession.registerConstraints(returnType, myT);
|
||||
if (callSession.repeatInferencePhases(true)) {
|
||||
session.liftBounds(callSession.getInferenceVariables());
|
||||
}
|
||||
}
|
||||
callSession.registerConstraints(returnType, myT);
|
||||
if (callSession.repeatInferencePhases(true)) {
|
||||
session.liftBounds(callSession.getInferenceVariables());
|
||||
}
|
||||
final PsiType capturedReturnType = myExpression instanceof PsiMethodCallExpression
|
||||
? PsiMethodCallExpressionImpl.captureReturnType((PsiMethodCallExpression)myExpression, method, returnType, substitutor)
|
||||
|
||||
Reference in New Issue
Block a user