Retain data flow info after conditions in while-statements

This commit is contained in:
Alexander Udalov
2012-11-13 18:25:11 +04:00
parent ae77bf0a4e
commit b0e9c7aab7
3 changed files with 32 additions and 7 deletions
@@ -162,19 +162,17 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
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 dataFlowInfo = checkCondition(context.scope, condition, context);
JetExpression body = expression.getBody(); JetExpression body = expression.getBody();
if (body != null) { if (body != null) {
WritableScopeImpl scopeToExtend = newWritableScopeImpl(context, "Scope extended in while's condition"); WritableScopeImpl scopeToExtend = newWritableScopeImpl(context, "Scope extended in while's condition");
DataFlowInfo conditionInfo = condition == null ? context.dataFlowInfo : DataFlowUtils.extractDataFlowInfoFromCondition(condition, true, context); DataFlowInfo conditionInfo = DataFlowUtils.extractDataFlowInfoFromCondition(condition, true, context).and(dataFlowInfo);
context.expressionTypingServices.getBlockReturnedTypeWithWritableScope(scopeToExtend, Collections.singletonList(body), CoercionStrategy.NO_COERCION, context.replaceDataFlowInfo(conditionInfo), context.trace); context.expressionTypingServices.getBlockReturnedTypeWithWritableScope(scopeToExtend, Collections.singletonList(body), CoercionStrategy.NO_COERCION, context.replaceDataFlowInfo(conditionInfo), context.trace);
} }
DataFlowInfo dataFlowInfo;
if (!containsBreak(expression, context)) { if (!containsBreak(expression, context)) {
dataFlowInfo = DataFlowUtils.extractDataFlowInfoFromCondition(condition, false, context); dataFlowInfo = DataFlowUtils.extractDataFlowInfoFromCondition(condition, false, context).and(dataFlowInfo);
}
else {
dataFlowInfo = context.dataFlowInfo;
} }
return DataFlowUtils.checkType(KotlinBuiltIns.getInstance().getUnitType(), expression, contextWithExpectedType, dataFlowInfo); return DataFlowUtils.checkType(KotlinBuiltIns.getInstance().getUnitType(), expression, contextWithExpectedType, dataFlowInfo);
} }
@@ -0,0 +1,22 @@
fun simpleWhile(x: Int?, var y: Int) {
while (x!! == y) {
x : Int
y++
}
x : Int
}
fun whileWithBreak(x: Int?, var y: Int) {
while (x!! == y) {
x : Int
break
}
x : Int
}
fun whileWithNoCondition(x: Int?) {
while (<!SYNTAX!><!>) {
x!!
}
<!TYPE_MISMATCH!>x<!> : Int
}
@@ -1301,6 +1301,11 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage
doTest("compiler/testData/diagnostics/tests/dataFlowInfoTraversal/While.kt"); doTest("compiler/testData/diagnostics/tests/dataFlowInfoTraversal/While.kt");
} }
@TestMetadata("WhileCondition.kt")
public void testWhileCondition() throws Exception {
doTest("compiler/testData/diagnostics/tests/dataFlowInfoTraversal/WhileCondition.kt");
}
} }
@TestMetadata("compiler/testData/diagnostics/tests/declarationChecks") @TestMetadata("compiler/testData/diagnostics/tests/declarationChecks")