summaryrefslogtreecommitdiff
path: root/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints
diff options
context:
space:
mode:
Diffstat (limited to 'java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints')
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/ExpressionCompatibilityConstraint.java65
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/LambdaExpressionCompatibilityConstraint.java4
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/PsiMethodReferenceCompatibilityConstraint.java22
3 files changed, 25 insertions, 66 deletions
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/ExpressionCompatibilityConstraint.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/ExpressionCompatibilityConstraint.java
index 82b320ae99f3..b59cf70bdb69 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/ExpressionCompatibilityConstraint.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/ExpressionCompatibilityConstraint.java
@@ -19,16 +19,12 @@ import com.intellij.psi.*;
import com.intellij.psi.impl.source.resolve.graphInference.InferenceSession;
import com.intellij.psi.impl.source.resolve.graphInference.InferenceVariable;
import com.intellij.psi.impl.source.resolve.graphInference.PsiPolyExpressionUtil;
-import com.intellij.psi.impl.source.tree.java.PsiMethodCallExpressionImpl;
import com.intellij.psi.infos.MethodCandidateInfo;
import com.intellij.psi.util.PsiUtil;
import com.intellij.psi.util.TypeConversionUtil;
-import com.intellij.util.containers.ContainerUtil;
-import com.intellij.util.containers.HashSet;
import org.jetbrains.annotations.NotNull;
-import java.util.Collection;
-import java.util.Iterator;
+import java.util.ArrayList;
import java.util.List;
import java.util.Set;
@@ -94,7 +90,11 @@ public class ExpressionCompatibilityConstraint extends InputOutputConstraintForm
if (method != null && !method.isConstructor()) {
returnType = method.getReturnType();
if (returnType != null) {
- typeParams = method.getTypeParameters();
+ List<PsiTypeParameter> params = new ArrayList<PsiTypeParameter>();
+ for (PsiTypeParameter parameter : PsiUtil.typeParametersIterable(method)) {
+ params.add(parameter);
+ }
+ typeParams = params.toArray(new PsiTypeParameter[params.size()]);
}
} else if (myExpression instanceof PsiNewExpression) { //default constructor
final PsiJavaCodeReferenceElement classReference = ((PsiNewExpression)myExpression).getClassOrAnonymousClassReference();
@@ -108,38 +108,8 @@ public class ExpressionCompatibilityConstraint extends InputOutputConstraintForm
}
if (typeParams != null) {
-
- final Set<PsiTypeParameter> oldBounds = ContainerUtil.newHashSet(session.getParamsToInfer());
- final boolean sameMethodCall = session.initBounds(myExpression, typeParams);
- PsiSubstitutor substitutor = PsiSubstitutor.EMPTY;
- final HashSet<InferenceVariable> variables = new HashSet<InferenceVariable>();
- session.collectDependencies(returnType, variables);
- final PsiTypeParameter[] params = new PsiTypeParameter[typeParams.length];
- for (int i = 0; i < typeParams.length; i++) {
- if (variables.contains(session.getInferenceVariable(typeParams[i]))) {
- params[i] = JavaPsiFacade.getElementFactory(myExpression.getProject()).createTypeParameterFromText("copyOf" + myExpression.hashCode() + typeParams[i].getName(), null);
- substitutor = substitutor.put(typeParams[i], JavaPsiFacade.getElementFactory(myExpression.getProject()).createType(params[i]));
- }
- else {
- params[i] = typeParams[i];
- }
- }
- PsiSubstitutor siteSubstitutor = PsiSubstitutor.EMPTY;
- if (method != null && !method.isConstructor()) {
- if (resolveResult instanceof MethodCandidateInfo) {
- siteSubstitutor = ((MethodCandidateInfo)resolveResult).getSiteSubstitutor();
- }
- else if (candidateProperties != null) {
- siteSubstitutor = candidateProperties.getSubstitutor();
- }
- }
- for (PsiTypeParameter typeParameter : siteSubstitutor.getSubstitutionMap().keySet()) {
- substitutor = substitutor.put(typeParameter, substitutor.substitute(siteSubstitutor.substitute(typeParameter)));
- }
-
- final Collection<PsiTypeParameter> params1 = session.getTypeParams();
- final InferenceSession callSession = new InferenceSession(params, substitutor, myExpression.getManager(), myExpression);
- callSession.initBounds(session.getContext(), params1.toArray(new PsiTypeParameter[params1.size()]));
+ final InferenceSession callSession = new InferenceSession(typeParams, PsiSubstitutor.EMPTY, myExpression.getManager(), myExpression);
+ callSession.propagateVariables(session.getInferenceVariables());
if (method != null) {
final PsiExpression[] args = argumentList.getExpressions();
final PsiParameter[] parameters = method.getParameterList().getParameters();
@@ -150,27 +120,12 @@ public class ExpressionCompatibilityConstraint extends InputOutputConstraintForm
if (!accepted) {
return false;
}
- callSession.registerReturnTypeConstraints(
- method != null && !PsiUtil.isRawSubstitutor(method, siteSubstitutor) ? siteSubstitutor.substitute(returnType) : returnType,
- substitutor.substitute(returnType));
+ callSession.registerReturnTypeConstraints(returnType, myT);
if (callSession.repeatInferencePhases(true)) {
- final Collection<InferenceVariable> inferenceVariables = callSession.getInferenceVariables();
- if (sameMethodCall) {
- for (Iterator<InferenceVariable> iterator = inferenceVariables.iterator(); iterator.hasNext(); ) {
- InferenceVariable variable = iterator.next();
- if (oldBounds.contains(variable.getParameter())) {
- iterator.remove();
- }
- }
- }
- session.liftBounds(myExpression, inferenceVariables);
+ session.registerNestedSession(callSession);
} else {
return false;
}
- final PsiType capturedReturnType = myExpression instanceof PsiMethodCallExpression
- ? PsiMethodCallExpressionImpl.captureReturnType((PsiMethodCallExpression)myExpression, method, returnType, substitutor)
- : substitutor.substitute(returnType);
- constraints.add(new TypeCompatibilityConstraint(myT, capturedReturnType));
}
}
return true;
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/LambdaExpressionCompatibilityConstraint.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/LambdaExpressionCompatibilityConstraint.java
index cbed2ea59491..c282481e79c0 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/LambdaExpressionCompatibilityConstraint.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/LambdaExpressionCompatibilityConstraint.java
@@ -45,7 +45,7 @@ public class LambdaExpressionCompatibilityConstraint implements ConstraintFormul
constraints.add(new StrictSubtypingConstraint(myT, groundTargetType));
} else {
for (PsiParameter parameter : parameters) {
- if (!session.isProperType(substitutor.substitute(parameter.getType()))) {
+ if (!session.isProperType(session.substituteWithInferenceVariables(substitutor.substitute(parameter.getType())))) {
return false;
}
}
@@ -62,7 +62,7 @@ public class LambdaExpressionCompatibilityConstraint implements ConstraintFormul
if (returnExpressions.isEmpty() && !myExpression.isValueCompatible()) { //not value-compatible
return false;
}
- returnType = substitutor.substitute(returnType);
+ returnType = session.substituteWithInferenceVariables(substitutor.substitute(returnType));
if (!session.isProperType(returnType)) {
for (PsiExpression returnExpression : returnExpressions) {
constraints.add(new ExpressionCompatibilityConstraint(returnExpression, returnType));
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/PsiMethodReferenceCompatibilityConstraint.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/PsiMethodReferenceCompatibilityConstraint.java
index eefd040b2a99..fbfd8195fc11 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/PsiMethodReferenceCompatibilityConstraint.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/PsiMethodReferenceCompatibilityConstraint.java
@@ -93,11 +93,13 @@ public class PsiMethodReferenceCompatibilityConstraint implements ConstraintForm
if (targetParameters.length == parameters.length + 1) {
specialCase(session, constraints, substitutor, targetParameters, true);
for (int i = 1; i < targetParameters.length; i++) {
- constraints.add(new TypeCompatibilityConstraint(psiSubstitutor.substitute(parameters[i - 1].getType()), substitutor.substitute(targetParameters[i].getType())));
+ constraints.add(new TypeCompatibilityConstraint(session.substituteWithInferenceVariables(psiSubstitutor.substitute(parameters[i - 1].getType())),
+ substitutor.substitute(targetParameters[i].getType())));
}
} else if (targetParameters.length == parameters.length) {
for (int i = 0; i < targetParameters.length; i++) {
- constraints.add(new TypeCompatibilityConstraint(psiSubstitutor.substitute(parameters[i].getType()), substitutor.substitute(targetParameters[i].getType())));
+ constraints.add(new TypeCompatibilityConstraint(session.substituteWithInferenceVariables(psiSubstitutor.substitute(parameters[i].getType())),
+ substitutor.substitute(targetParameters[i].getType())));
}
} else {
return false;
@@ -108,12 +110,13 @@ public class PsiMethodReferenceCompatibilityConstraint implements ConstraintForm
}
if (applicableMethodReturnType != null) {
- constraints.add(new TypeCompatibilityConstraint(returnType, psiSubstitutor.substitute(applicableMethodReturnType)));
- } else if (applicableMember instanceof PsiClass || applicableMember instanceof PsiMethod && ((PsiMethod)applicableMember).isConstructor()) {
+ constraints.add(new TypeCompatibilityConstraint(returnType,
+ session.substituteWithInferenceVariables(psiSubstitutor.substitute(applicableMethodReturnType))));
+ }
+ else if (applicableMember instanceof PsiClass || applicableMember instanceof PsiMethod && ((PsiMethod)applicableMember).isConstructor()) {
final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(applicableMember.getProject());
-
if (containingClass != null) {
- final PsiClassType classType = elementFactory.createType(containingClass, psiSubstitutor);
+ final PsiType classType = session.substituteWithInferenceVariables(elementFactory.createType(containingClass, psiSubstitutor));
constraints.add(new TypeCompatibilityConstraint(returnType, classType));
}
}
@@ -122,7 +125,7 @@ public class PsiMethodReferenceCompatibilityConstraint implements ConstraintForm
}
final Map<PsiMethodReferenceExpression, PsiType> map = PsiMethodReferenceUtil.getFunctionalTypeMap();
- final PsiType added = map.put(myExpression, groundTargetType);
+ final PsiType added = map.put(myExpression, session.startWithFreshVars(groundTargetType));
final JavaResolveResult resolve;
try {
resolve = myExpression.advancedResolve(true);
@@ -205,7 +208,7 @@ public class PsiMethodReferenceCompatibilityConstraint implements ConstraintForm
PsiPolyExpressionUtil.mentionsTypeParameters(referencedMethodReturnType, ContainerUtil.newHashSet(containingClass.getTypeParameters()))) { //todo specification bug?
specialCase(session, constraints, substitutor, targetParameters, false);
}
- constraints.add(new TypeCompatibilityConstraint(returnType, psiSubstitutor.substitute(referencedMethodReturnType)));
+ constraints.add(new TypeCompatibilityConstraint(returnType, session.substituteWithInferenceVariables(psiSubstitutor.substitute(referencedMethodReturnType))));
}
return true;
@@ -241,7 +244,8 @@ public class PsiMethodReferenceCompatibilityConstraint implements ConstraintForm
final PsiClass qualifierClass = PsiUtil.resolveClassInType(qualifierType);
if (qualifierClass != null) {
session.initBounds(qualifierClass.getTypeParameters());
- constraints.add(new StrictSubtypingConstraint(qualifierType, substitutor.substitute(targetParameters[0].getType())));
+ constraints.add(new StrictSubtypingConstraint(session.substituteWithInferenceVariables(qualifierType),
+ session.substituteWithInferenceVariables(substitutor.substitute(targetParameters[0].getType()))));
}
}