checked for 'isBinaryExpressionDependentOnExpectedType'

both in analyzing expressions & completion phase
This commit is contained in:
Svetlana Isakova
2013-09-01 17:16:14 +04:00
parent cf22bc7c35
commit da07d60ad6
3 changed files with 17 additions and 21 deletions
@@ -22,7 +22,6 @@ import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.intellij.openapi.progress.ProgressIndicatorProvider;
import com.intellij.psi.PsiElement;
import com.intellij.psi.tree.IElementType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*;
@@ -51,7 +50,6 @@ import org.jetbrains.jet.lang.types.*;
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
import org.jetbrains.jet.lang.types.expressions.DataFlowUtils;
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingUtils;
import org.jetbrains.jet.lang.types.expressions.OperatorConventions;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import javax.inject.Inject;
@@ -417,21 +415,9 @@ public class CandidateResolver {
return expression;
}
@SuppressWarnings("SuspiciousMethodCalls")
@Override
public JetExpression visitBinaryExpression(JetBinaryExpression expression, Void data) {
IElementType operationType = expression.getOperationReference().getReferencedNameElementType();
if (OperatorConventions.COMPARISON_OPERATIONS.contains(operationType)) {
//Result type of comparison doesn't depend on expected type:
//it's 'Boolean', but 'compareTo' should return 'Int'.
//So we shouldn't check result type of such a call('Int') at completion phase.
return null;
}
if (OperatorConventions.ASSIGNMENT_OPERATIONS.containsKey(operationType)) {
//the same, result type is always 'Unit'
return null;
}
return super.visitBinaryExpression(expression, data);
return ExpressionTypingUtils.isBinaryExpressionDependentOnExpectedType(expression) ? expression : null;
}
};
return expression.accept(selectorExpressionFinder, null);
@@ -881,9 +881,11 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
@Override
public JetTypeInfo visitBinaryExpression(JetBinaryExpression expression, ExpressionTypingContext contextWithExpectedType) {
ExpressionTypingContext context = contextWithExpectedType.replaceContextDependency(INDEPENDENT).replaceExpectedType(NO_EXPECTED_TYPE);
JetSimpleNameExpression operationSign = expression.getOperationReference();
ExpressionTypingContext context = isBinaryExpressionDependentOnExpectedType(expression)
? contextWithExpectedType
: contextWithExpectedType.replaceContextDependency(INDEPENDENT).replaceExpectedType(NO_EXPECTED_TYPE);
JetSimpleNameExpression operationSign = expression.getOperationReference();
JetExpression left = expression.getLeft();
JetExpression right = expression.getRight();
IElementType operationType = operationSign.getReferencedNameElementType();
@@ -893,15 +895,15 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
//Expressions that can depend on expected type
if (operationType == JetTokens.IDENTIFIER) {
Name referencedName = operationSign.getReferencedNameAsName();
result = getTypeInfoForBinaryCall(referencedName, contextWithExpectedType, expression);
result = getTypeInfoForBinaryCall(referencedName, context, expression);
}
else if (OperatorConventions.BINARY_OPERATION_NAMES.containsKey(operationType)) {
Name referencedName = OperatorConventions.BINARY_OPERATION_NAMES.get(operationType);
result = getTypeInfoForBinaryCall(referencedName, contextWithExpectedType, expression);
result = getTypeInfoForBinaryCall(referencedName, context, expression);
}
else if (operationType == JetTokens.ELVIS) {
//base expression of elvis operator (not the whole expression) is checked for 'type mismatch'
return visitElvisExpression(expression, contextWithExpectedType);
//base expression of elvis operator is checked for 'type mismatch', so the whole expression shouldn't be checked
return visitElvisExpression(expression, context);
}
//Expressions that don't depend on expected type
@@ -51,6 +51,7 @@ import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue;
import org.jetbrains.jet.lang.types.*;
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import org.jetbrains.jet.lexer.JetTokens;
import org.jetbrains.jet.util.slicedmap.WritableSlice;
import java.util.*;
@@ -484,4 +485,11 @@ public class ExpressionTypingUtils {
? facade.getTypeInfo(expression, context)
: JetTypeInfo.create(null, context.dataFlowInfo);
}
@SuppressWarnings("SuspiciousMethodCalls")
public static boolean isBinaryExpressionDependentOnExpectedType(@NotNull JetBinaryExpression expression) {
IElementType operationType = expression.getOperationReference().getReferencedNameElementType();
return (operationType == JetTokens.IDENTIFIER || OperatorConventions.BINARY_OPERATION_NAMES.containsKey(operationType)
|| operationType == JetTokens.ELVIS);
}
}