Retain data flow info after conditions in if-statements
This commit is contained in:
+10
-5
@@ -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");
|
||||||
|
|||||||
Reference in New Issue
Block a user