Retain data flow info after in (contains)

#KT-2825 In Progress
This commit is contained in:
Alexander Udalov
2012-11-12 18:22:37 +04:00
parent 3358108c3f
commit 2e6500d848
4 changed files with 34 additions and 6 deletions
@@ -19,6 +19,7 @@ package org.jetbrains.jet.lang.types.expressions;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.common.collect.Multimap; import com.google.common.collect.Multimap;
import com.intellij.lang.ASTNode; import com.intellij.lang.ASTNode;
import com.intellij.openapi.util.Pair;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import com.intellij.psi.tree.IElementType; import com.intellij.psi.tree.IElementType;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@@ -1143,7 +1144,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
result = ErrorUtils.createErrorType("No right argument"); // TODO result = ErrorUtils.createErrorType("No right argument"); // TODO
return JetTypeInfo.create(null, dataFlowInfo); return JetTypeInfo.create(null, dataFlowInfo);
} }
checkInExpression(expression, expression.getOperationReference(), expression.getLeft(), expression.getRight(), context); dataFlowInfo = checkInExpression(expression, expression.getOperationReference(), left, right, context).getSecond();
result = booleanType; result = booleanType;
} }
else if (OperatorConventions.BOOLEAN_OPERATIONS.containsKey(operationType)) { else if (OperatorConventions.BOOLEAN_OPERATIONS.containsKey(operationType)) {
@@ -1188,16 +1189,33 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
return DataFlowUtils.checkType(result, expression, contextWithExpectedType, dataFlowInfo); return DataFlowUtils.checkType(result, expression, contextWithExpectedType, dataFlowInfo);
} }
public boolean checkInExpression(JetElement callElement, @NotNull JetSimpleNameExpression operationSign, @Nullable JetExpression left, @NotNull JetExpression right, ExpressionTypingContext context) { @NotNull
public Pair<Boolean, DataFlowInfo> checkInExpression(
JetElement callElement,
@NotNull JetSimpleNameExpression operationSign,
@Nullable JetExpression left,
@NotNull JetExpression right,
ExpressionTypingContext context
) {
ExpressionTypingContext contextWithNoExpectedType = context.replaceExpectedType(NO_EXPECTED_TYPE);
DataFlowInfo dataFlowInfo = facade.getTypeInfo(right, contextWithNoExpectedType).getDataFlowInfo();
Name name = Name.identifier("contains"); Name name = Name.identifier("contains");
ExpressionReceiver receiver = safeGetExpressionReceiver(facade, right, context.replaceExpectedType(NO_EXPECTED_TYPE)); ExpressionReceiver receiver = safeGetExpressionReceiver(facade, right, contextWithNoExpectedType);
OverloadResolutionResults<FunctionDescriptor> resolutionResult = context.resolveCallWithGivenName( ExpressionTypingContext contextWithDataFlow = context.replaceDataFlowInfo(dataFlowInfo);
OverloadResolutionResults<FunctionDescriptor> resolutionResult = contextWithDataFlow.resolveCallWithGivenName(
CallMaker.makeCallWithExpressions(callElement, receiver, null, operationSign, Collections.singletonList(left)), CallMaker.makeCallWithExpressions(callElement, receiver, null, operationSign, Collections.singletonList(left)),
operationSign, operationSign,
name); name);
JetType containsType = OverloadResolutionResultsUtil.getResultType(resolutionResult); JetType containsType = OverloadResolutionResultsUtil.getResultType(resolutionResult);
ensureBooleanResult(operationSign, name, containsType, context); ensureBooleanResult(operationSign, name, containsType, context);
return resolutionResult.isSuccess();
if (left != null) {
dataFlowInfo = facade.getTypeInfo(left, contextWithDataFlow).getDataFlowInfo();
}
return Pair.create(resolutionResult.isSuccess(), dataFlowInfo);
} }
private void ensureNonemptyIntersectionOfOperandTypes(JetBinaryExpression expression, ExpressionTypingContext context) { private void ensureNonemptyIntersectionOfOperandTypes(JetBinaryExpression expression, ExpressionTypingContext context) {
@@ -74,7 +74,7 @@ public class ExpressionTypingVisitorDispatcher extends JetVisitor<JetTypeInfo, E
@Override @Override
public boolean checkInExpression(JetElement callElement, @NotNull JetSimpleNameExpression operationSign, @Nullable JetExpression left, @NotNull JetExpression right, ExpressionTypingContext context) { public boolean checkInExpression(JetElement callElement, @NotNull JetSimpleNameExpression operationSign, @Nullable JetExpression left, @NotNull JetExpression right, ExpressionTypingContext context) {
return basic.checkInExpression(callElement, operationSign, left, right, context); return basic.checkInExpression(callElement, operationSign, left, right, context).getFirst();
} }
@Override @Override
@@ -0,0 +1,5 @@
fun foo(x: Number): Boolean {
val result = (x as Int) in 1..5
x : Int
return result
}
@@ -1151,6 +1151,11 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage
doTest("compiler/testData/diagnostics/tests/dataFlowInfoTraversal/BinaryExpressionCompareToConvention.kt"); doTest("compiler/testData/diagnostics/tests/dataFlowInfoTraversal/BinaryExpressionCompareToConvention.kt");
} }
@TestMetadata("BinaryExpressionContainsConvention.kt")
public void testBinaryExpressionContainsConvention() throws Exception {
doTest("compiler/testData/diagnostics/tests/dataFlowInfoTraversal/BinaryExpressionContainsConvention.kt");
}
@TestMetadata("BinaryExpressionEqualsConvention.kt") @TestMetadata("BinaryExpressionEqualsConvention.kt")
public void testBinaryExpressionEqualsConvention() throws Exception { public void testBinaryExpressionEqualsConvention() throws Exception {
doTest("compiler/testData/diagnostics/tests/dataFlowInfoTraversal/BinaryExpressionEqualsConvention.kt"); doTest("compiler/testData/diagnostics/tests/dataFlowInfoTraversal/BinaryExpressionEqualsConvention.kt");