Retain data flow info after conditions in if-statements

This commit is contained in:
Alexander Udalov
2012-11-13 16:52:26 +04:00
parent 2872a0799a
commit ae77bf0a4e
3 changed files with 44 additions and 5 deletions
@@ -63,14 +63,19 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
super(facade); super(facade);
} }
private void checkCondition(@NotNull JetScope scope, @Nullable JetExpression condition, ExpressionTypingContext context) { @NotNull
private DataFlowInfo checkCondition(@NotNull JetScope scope, @Nullable JetExpression condition, ExpressionTypingContext context) {
if (condition != null) { if (condition != null) {
JetType conditionType = facade.getTypeInfo(condition, context.replaceScope(scope)).getType(); JetTypeInfo typeInfo = facade.getTypeInfo(condition, context.replaceScope(scope));
JetType conditionType = typeInfo.getType();
if (conditionType != null && !isBoolean(conditionType)) { if (conditionType != null && !isBoolean(conditionType)) {
context.trace.report(TYPE_MISMATCH_IN_CONDITION.on(condition, conditionType)); context.trace.report(TYPE_MISMATCH_IN_CONDITION.on(condition, conditionType));
} }
return typeInfo.getDataFlowInfo();
} }
return context.dataFlowInfo;
} }
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -84,15 +89,15 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
public JetTypeInfo visitIfExpression(JetIfExpression expression, ExpressionTypingContext contextWithExpectedType, boolean isStatement) { public JetTypeInfo visitIfExpression(JetIfExpression expression, ExpressionTypingContext contextWithExpectedType, boolean isStatement) {
ExpressionTypingContext context = contextWithExpectedType.replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE); ExpressionTypingContext context = contextWithExpectedType.replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE);
JetExpression condition = expression.getCondition(); JetExpression condition = expression.getCondition();
checkCondition(context.scope, condition, context); DataFlowInfo conditionDataFlowInfo = checkCondition(context.scope, condition, context);
JetExpression elseBranch = expression.getElse(); JetExpression elseBranch = expression.getElse();
JetExpression thenBranch = expression.getThen(); JetExpression thenBranch = expression.getThen();
WritableScopeImpl thenScope = newWritableScopeImpl(context, "Then scope"); WritableScopeImpl thenScope = newWritableScopeImpl(context, "Then scope");
WritableScopeImpl elseScope = newWritableScopeImpl(context, "Else scope"); WritableScopeImpl elseScope = newWritableScopeImpl(context, "Else scope");
DataFlowInfo thenInfo = DataFlowUtils.extractDataFlowInfoFromCondition(condition, true, context); DataFlowInfo thenInfo = DataFlowUtils.extractDataFlowInfoFromCondition(condition, true, context).and(conditionDataFlowInfo);
DataFlowInfo elseInfo = DataFlowUtils.extractDataFlowInfoFromCondition(condition, false, context); DataFlowInfo elseInfo = DataFlowUtils.extractDataFlowInfoFromCondition(condition, false, context).and(conditionDataFlowInfo);
if (elseBranch == null) { if (elseBranch == null) {
if (thenBranch != null) { if (thenBranch != null) {
@@ -0,0 +1,29 @@
fun ifThen(x: Int?) {
if (x!! == 0) {
x : Int
}
x : Int
}
fun ifElse(x: Int?) {
if (x!! == 0) else {
x : Int
}
x : Int
}
fun ifThenElse(x: Int?) {
if (x!! == 0) {
x : Int
} else {
x : Int
}
x : Int
}
fun ifIs(x: Int?, cond: Boolean) {
if ((x is Int) == cond) {
<!TYPE_MISMATCH!>x<!> : Int
}
<!TYPE_MISMATCH!>x<!> : Int
}
@@ -1231,6 +1231,11 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage
doTest("compiler/testData/diagnostics/tests/dataFlowInfoTraversal/FunctionLiteral.kt"); doTest("compiler/testData/diagnostics/tests/dataFlowInfoTraversal/FunctionLiteral.kt");
} }
@TestMetadata("IfStatement.kt")
public void testIfStatement() throws Exception {
doTest("compiler/testData/diagnostics/tests/dataFlowInfoTraversal/IfStatement.kt");
}
@TestMetadata("IfThenElse.kt") @TestMetadata("IfThenElse.kt")
public void testIfThenElse() throws Exception { public void testIfThenElse() throws Exception {
doTest("compiler/testData/diagnostics/tests/dataFlowInfoTraversal/IfThenElse.kt"); doTest("compiler/testData/diagnostics/tests/dataFlowInfoTraversal/IfThenElse.kt");