blob: 9d9dad46ffc871e20d181fb0c896aac4fe77342c [file] [log] [blame]
package com.intellij.psi.impl.source.resolve.graphInference.constraints;
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.util.PsiUtil;
import java.util.List;
/**
* User: anna
*/
public class LambdaExpressionCompatibilityConstraint implements ConstraintFormula {
private final PsiLambdaExpression myExpression;
private final PsiType myT;
public LambdaExpressionCompatibilityConstraint(PsiLambdaExpression expression, PsiType t) {
myExpression = expression;
myT = t;
}
@Override
public boolean reduce(InferenceSession session, List<ConstraintFormula> constraints, List<ConstraintFormula> delayedConstraints) {
final InferenceVariable inferenceVariable = session.getInferenceVariable(myT);
if (inferenceVariable != null) {
delayedConstraints.add(this);
return true;
}
if (LambdaHighlightingUtil.checkInterfaceFunctional(myT) != null) {
return false;
}
if (myExpression.hasFormalParameterTypes()) {
}
final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(myT);
if (interfaceMethod == null) {
return false;
}
final PsiSubstitutor substitutor = LambdaUtil.getSubstitutor(interfaceMethod, PsiUtil.resolveGenericsClassInType(myT));
final PsiParameter[] parameters = interfaceMethod.getParameterList().getParameters();
for (PsiParameter parameter : parameters) {
if (!session.isProperType(parameter.getType())) {
delayedConstraints.add(this);
return true;
}
}
final PsiParameter[] lambdaParameters = myExpression.getParameterList().getParameters();
if (lambdaParameters.length != parameters.length) {
return false;
}
if (myExpression.hasFormalParameterTypes()) {
for (int i = 0; i < lambdaParameters.length; i++) {
constraints.add(new TypeEqualityConstraint(lambdaParameters[i].getType(), substitutor.substitute(parameters[i].getType())));
}
}
final PsiType returnType = interfaceMethod.getReturnType();
if (returnType != null) {
if (returnType.equals(PsiType.VOID)) {
if (!myExpression.isVoidCompatible() && !(myExpression.getBody() instanceof PsiExpression)) {
return false;
}
} else {
if (myExpression.isVoidCompatible()) { //not value-compatible
return false;
}
for (PsiExpression returnExpressions : LambdaUtil.getReturnExpressions(myExpression)) {
constraints.add(new ExpressionCompatibilityConstraint(returnExpressions, returnType));
}
}
}
return true;
}
}