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);
}
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) {
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)) {
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) {
ExpressionTypingContext context = contextWithExpectedType.replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE);
JetExpression condition = expression.getCondition();
checkCondition(context.scope, condition, context);
DataFlowInfo conditionDataFlowInfo = checkCondition(context.scope, condition, context);
JetExpression elseBranch = expression.getElse();
JetExpression thenBranch = expression.getThen();
WritableScopeImpl thenScope = newWritableScopeImpl(context, "Then scope");
WritableScopeImpl elseScope = newWritableScopeImpl(context, "Else scope");
DataFlowInfo thenInfo = DataFlowUtils.extractDataFlowInfoFromCondition(condition, true, context);
DataFlowInfo elseInfo = DataFlowUtils.extractDataFlowInfoFromCondition(condition, false, context);
DataFlowInfo thenInfo = DataFlowUtils.extractDataFlowInfoFromCondition(condition, true, context).and(conditionDataFlowInfo);
DataFlowInfo elseInfo = DataFlowUtils.extractDataFlowInfoFromCondition(condition, false, context).and(conditionDataFlowInfo);
if (elseBranch == 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");
}
@TestMetadata("IfStatement.kt")
public void testIfStatement() throws Exception {
doTest("compiler/testData/diagnostics/tests/dataFlowInfoTraversal/IfStatement.kt");
}
@TestMetadata("IfThenElse.kt")
public void testIfThenElse() throws Exception {
doTest("compiler/testData/diagnostics/tests/dataFlowInfoTraversal/IfThenElse.kt");