diff --git a/compiler/frontend/src/org/jetbrains/kotlin/psi/JetPsiUtil.java b/compiler/frontend/src/org/jetbrains/kotlin/psi/JetPsiUtil.java index 9e81e10f036..4ec12174eb6 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/psi/JetPsiUtil.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/psi/JetPsiUtil.java @@ -398,6 +398,11 @@ public class JetPsiUtil { return deparenthesized instanceof JetConstantExpression && deparenthesized.getNode().getElementType() == JetNodeTypes.NULL; } + public static boolean isTrueConstant(@Nullable JetExpression condition) { + return (condition != null && condition.getNode().getElementType() == JetNodeTypes.BOOLEAN_CONSTANT && + condition.getNode().findChildByType(JetTokens.TRUE_KEYWORD) != null); + } + public static boolean isAbstract(@NotNull JetDeclarationWithBody declaration) { return declaration.getBodyExpression() == null; } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/BindingContext.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/BindingContext.java index 66b56a1b3f2..303d2022b7d 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/BindingContext.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/BindingContext.java @@ -83,13 +83,17 @@ public interface BindingContext { WritableSlice TYPE = Slices.createSimpleSlice(); WritableSlice EXPRESSION_TYPE = new BasicWritableSlice(DO_NOTHING); - WritableSlice EXPRESSION_JUMP_OUT_POSSIBLE = new BasicWritableSlice(DO_NOTHING); WritableSlice EXPECTED_EXPRESSION_TYPE = new BasicWritableSlice(DO_NOTHING); WritableSlice EXPECTED_RETURN_TYPE = new BasicWritableSlice(DO_NOTHING); WritableSlice EXPRESSION_DATA_FLOW_INFO = new BasicWritableSlice(DO_NOTHING); WritableSlice EXPRESSION_RESULT_APPROXIMATION = new BasicWritableSlice(DO_NOTHING); WritableSlice DATAFLOW_INFO_AFTER_CONDITION = Slices.createSimpleSlice(); + /** + * Expression has jump out of the loop (break/continue) inside + */ + WritableSlice EXPRESSION_JUMP_OUT_POSSIBLE = new BasicWritableSlice(DO_NOTHING); + /** * A qualifier corresponds to a receiver expression (if any). For 'A.B' qualifier is recorded for 'A'. */ diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/BindingContextUtils.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/BindingContextUtils.java index ccc714d3f11..b14553bec79 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/BindingContextUtils.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/BindingContextUtils.java @@ -30,8 +30,8 @@ import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall; import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCall; import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo; import org.jetbrains.kotlin.types.JetType; -import org.jetbrains.kotlin.types.JetTypeInfo; import org.jetbrains.kotlin.types.TypeUtils; +import org.jetbrains.kotlin.types.expressions.TypeInfoWithJumpInfo; import org.jetbrains.kotlin.util.slicedMap.ReadOnlySlice; import java.util.Collection; @@ -144,11 +144,12 @@ public class BindingContextUtils { } @Nullable - public static JetTypeInfo getRecordedTypeInfo(@NotNull JetExpression expression, @NotNull BindingContext context) { + public static TypeInfoWithJumpInfo getRecordedTypeInfo(@NotNull JetExpression expression, @NotNull BindingContext context) { if (!context.get(BindingContext.PROCESSED, expression)) return null; DataFlowInfo dataFlowInfo = BindingContextUtilPackage.getDataFlowInfo(context, expression); JetType type = context.get(BindingContext.EXPRESSION_TYPE, expression); - return JetTypeInfo.create(type, dataFlowInfo); + Boolean jumpOutPossible = context.get(BindingContext.EXPRESSION_JUMP_OUT_POSSIBLE, expression); + return new TypeInfoWithJumpInfo(type, dataFlowInfo, Boolean.TRUE.equals(jumpOutPossible), dataFlowInfo); } public static boolean isExpressionWithValidReference( diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java index b42a76cd817..53e9de1cc1f 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java @@ -1236,14 +1236,15 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { Call call = createCallForSpecialConstruction(expression, expression.getOperationReference(), Lists.newArrayList(left, right)); ResolvedCall resolvedCall = components.controlStructureTypingUtils.resolveSpecialConstructionAsCall( call, "Elvis", Lists.newArrayList("left", "right"), Lists.newArrayList(true, false), contextWithExpectedType, null); - JetTypeInfo leftTypeInfo = BindingContextUtils.getRecordedTypeInfo(left, context.trace.getBindingContext()); + TypeInfoWithJumpInfo leftTypeInfo = BindingContextUtils.getRecordedTypeInfo(left, context.trace.getBindingContext()); assert leftTypeInfo != null : "Left expression was not processed: " + expression; JetType leftType = leftTypeInfo.getType(); if (leftType != null && isKnownToBeNotNull(left, leftType, context)) { context.trace.report(USELESS_ELVIS.on(left, leftType)); } - JetTypeInfo rightTypeInfo = BindingContextUtils.getRecordedTypeInfo(right, context.trace.getBindingContext()); + TypeInfoWithJumpInfo rightTypeInfo = BindingContextUtils.getRecordedTypeInfo(right, context.trace.getBindingContext()); assert rightTypeInfo != null : "Right expression was not processed: " + expression; + boolean loopBreakContinuePossible = leftTypeInfo.getJumpOutPossible() || rightTypeInfo.getJumpOutPossible(); JetType rightType = rightTypeInfo.getType(); DataFlowInfo dataFlowInfo = resolvedCall.getDataFlowInfoForArguments().getResultInfo(); @@ -1262,7 +1263,9 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { if (context.contextDependency == DEPENDENT) { return JetTypeInfo.create(type, dataFlowInfo); } - return DataFlowUtils.checkType(type, expression, context, dataFlowInfo); + JetTypeInfo result = DataFlowUtils.checkType(type, expression, context, dataFlowInfo); + // If break or continue was possible, take condition check info as the jump info + return new TypeInfoWithJumpInfo(result.getType(), result.getDataFlowInfo(), loopBreakContinuePossible, context.dataFlowInfo); } @NotNull diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ControlStructureTypingVisitor.java b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ControlStructureTypingVisitor.java index d1f2c96e9ef..9cc61e9bf13 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ControlStructureTypingVisitor.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ControlStructureTypingVisitor.java @@ -104,11 +104,12 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor { if (elseBranch == null) { if (thenBranch != null) { - LoopTypeInfo result = getTypeInfoWhenOnlyOneBranchIsPresent( + TypeInfoWithJumpInfo result = getTypeInfoWhenOnlyOneBranchIsPresent( thenBranch, thenScope, thenInfo, elseInfo, contextWithExpectedType, ifExpression, isStatement); // If jump was possible, take condition check info as the jump info - return result.isJumpOutPossible() ? - new LoopTypeInfo(result.getType(), result.getDataFlowInfo(), true, conditionDataFlowInfo) : result; + return result.getJumpOutPossible() + ? result.replaceJumpOutPossible(true).replaceJumpFlowInfo(conditionDataFlowInfo) + : result; } return DataFlowUtils.checkImplicitCast(components.builtIns.getUnitType(), ifExpression, contextWithExpectedType, isStatement, thenInfo.or(elseInfo)); @@ -129,13 +130,11 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor { contextWithExpectedType, dataFlowInfoForArguments); BindingContext bindingContext = context.trace.getBindingContext(); - JetTypeInfo thenTypeInfo = BindingContextUtils.getRecordedTypeInfo(thenBranch, bindingContext); - JetTypeInfo elseTypeInfo = BindingContextUtils.getRecordedTypeInfo(elseBranch, bindingContext); - Boolean thenLoopBreakContinuePossible = bindingContext.get(BindingContext.EXPRESSION_JUMP_OUT_POSSIBLE, thenBranch); - Boolean elseLoopBreakContinuePossible = bindingContext.get(BindingContext.EXPRESSION_JUMP_OUT_POSSIBLE, elseBranch); - boolean loopBreakContinuePossible = (thenLoopBreakContinuePossible == Boolean.TRUE || elseLoopBreakContinuePossible == Boolean.TRUE); + TypeInfoWithJumpInfo thenTypeInfo = BindingContextUtils.getRecordedTypeInfo(thenBranch, bindingContext); + TypeInfoWithJumpInfo elseTypeInfo = BindingContextUtils.getRecordedTypeInfo(elseBranch, bindingContext); assert thenTypeInfo != null : "'Then' branch of if expression was not processed: " + ifExpression; assert elseTypeInfo != null : "'Else' branch of if expression was not processed: " + ifExpression; + boolean loopBreakContinuePossible = thenTypeInfo.getJumpOutPossible() || elseTypeInfo.getJumpOutPossible(); JetType thenType = thenTypeInfo.getType(); JetType elseType = elseTypeInfo.getType(); @@ -162,11 +161,11 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor { JetType resultType = resolvedCall.getResultingDescriptor().getReturnType(); JetTypeInfo result = DataFlowUtils.checkImplicitCast(resultType, ifExpression, contextWithExpectedType, isStatement, resultDataFlowInfo); // If break or continue was possible, take condition check info as the jump info - return new LoopTypeInfo(result.getType(), result.getDataFlowInfo(), loopBreakContinuePossible, conditionDataFlowInfo); + return new TypeInfoWithJumpInfo(result.getType(), result.getDataFlowInfo(), loopBreakContinuePossible, conditionDataFlowInfo); } @NotNull - private LoopTypeInfo getTypeInfoWhenOnlyOneBranchIsPresent( + private TypeInfoWithJumpInfo getTypeInfoWhenOnlyOneBranchIsPresent( @NotNull JetExpression presentBranch, @NotNull WritableScopeImpl presentScope, @NotNull DataFlowInfo presentInfo, @@ -177,7 +176,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor { ) { ExpressionTypingContext newContext = context.replaceDataFlowInfo(presentInfo).replaceExpectedType(NO_EXPECTED_TYPE) .replaceContextDependency(INDEPENDENT); - LoopTypeInfo typeInfo = components.expressionTypingServices.getBlockReturnedTypeWithWritableScope( + TypeInfoWithJumpInfo typeInfo = components.expressionTypingServices.getBlockReturnedTypeWithWritableScope( presentScope, Collections.singletonList(presentBranch), CoercionStrategy.NO_COERCION, newContext); JetType type = typeInfo.getType(); DataFlowInfo dataFlowInfo; @@ -188,7 +187,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor { } JetType typeForIfExpression = DataFlowUtils.checkType(components.builtIns.getUnitType(), ifExpression, context); JetTypeInfo result = DataFlowUtils.checkImplicitCast(typeForIfExpression, ifExpression, context, isStatement, dataFlowInfo); - return new LoopTypeInfo(result.getType(), result.getDataFlowInfo(), typeInfo.isJumpOutPossible(), typeInfo.getJumpFlowInfo()); + return new TypeInfoWithJumpInfo(result.getType(), result.getDataFlowInfo(), typeInfo.getJumpOutPossible(), typeInfo.getJumpFlowInfo()); } @Override @@ -196,11 +195,6 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor { return visitWhileExpression(expression, context, false); } - private static boolean isTrueConstant(JetExpression condition) { - return (condition != null && condition.getNode().getElementType() == JetNodeTypes.BOOLEAN_CONSTANT && - condition.getNode().findChildByType(JetTokens.TRUE_KEYWORD) != null); - } - public JetTypeInfo visitWhileExpression(JetWhileExpression expression, ExpressionTypingContext contextWithExpectedType, boolean isStatement) { if (!isStatement) return DataFlowUtils.illegalStatementType(expression, contextWithExpectedType, facade); @@ -216,7 +210,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor { DataFlowInfo dataFlowInfo = checkCondition(context.scope, condition, context); JetExpression body = expression.getBody(); - LoopTypeInfo bodyTypeInfo = null; + TypeInfoWithJumpInfo bodyTypeInfo = null; if (body != null) { WritableScopeImpl scopeToExtend = newWritableScopeImpl(context, "Scope extended in while's condition"); DataFlowInfo conditionInfo = DataFlowUtils.extractDataFlowInfoFromCondition(condition, true, context).and(dataFlowInfo); @@ -234,7 +228,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor { // In this case we must record data flow information at the nearest break / continue and // .and it with entrance data flow information, because while body until break is executed at least once in this case // See KT-6284 - if (bodyTypeInfo != null && isTrueConstant(condition)) { + if (bodyTypeInfo != null && JetPsiUtil.isTrueConstant(condition)) { // We should take data flow info from the first jump point, // but without affecting changing variables dataFlowInfo = dataFlowInfo.and(loopVisitor.clearDataFlowInfoForAssignedLocalVariables(bodyTypeInfo.getJumpFlowInfo())); @@ -300,7 +294,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor { // Here we must record data flow information at the end of the body (or at the first jump, to be precise) and // .and it with entrance data flow information, because do-while body is executed at least once // See KT-6283 - LoopTypeInfo bodyTypeInfo = null; + TypeInfoWithJumpInfo bodyTypeInfo = null; if (body instanceof JetFunctionLiteralExpression) { JetFunctionLiteralExpression function = (JetFunctionLiteralExpression) body; JetFunctionLiteral functionLiteral = function.getFunctionLiteral(); @@ -570,17 +564,17 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor { } @Override - public LoopTypeInfo visitBreakExpression(@NotNull JetBreakExpression expression, ExpressionTypingContext context) { + public TypeInfoWithJumpInfo visitBreakExpression(@NotNull JetBreakExpression expression, ExpressionTypingContext context) { LabelResolver.INSTANCE.resolveControlLabel(expression, context); JetTypeInfo result = DataFlowUtils.checkType(components.builtIns.getNothingType(), expression, context, context.dataFlowInfo); - return new LoopTypeInfo(result.getType(), result.getDataFlowInfo(), true, result.getDataFlowInfo()); + return new TypeInfoWithJumpInfo(result.getType(), result.getDataFlowInfo(), true, result.getDataFlowInfo()); } @Override - public LoopTypeInfo visitContinueExpression(@NotNull JetContinueExpression expression, ExpressionTypingContext context) { + public TypeInfoWithJumpInfo visitContinueExpression(@NotNull JetContinueExpression expression, ExpressionTypingContext context) { LabelResolver.INSTANCE.resolveControlLabel(expression, context); JetTypeInfo result = DataFlowUtils.checkType(components.builtIns.getNothingType(), expression, context, context.dataFlowInfo); - return new LoopTypeInfo(result.getType(), result.getDataFlowInfo(), true, result.getDataFlowInfo()); + return new TypeInfoWithJumpInfo(result.getType(), result.getDataFlowInfo(), true, result.getDataFlowInfo()); } @NotNull diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ExpressionTypingServices.java b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ExpressionTypingServices.java index d777cb479e2..a8f278c451d 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ExpressionTypingServices.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ExpressionTypingServices.java @@ -308,14 +308,14 @@ public class ExpressionTypingServices { * Determines block returned type and data flow information at the end of the block AND * at the nearest jump point from the block beginning. */ - /*package*/ LoopTypeInfo getBlockReturnedTypeWithWritableScope( + /*package*/ TypeInfoWithJumpInfo getBlockReturnedTypeWithWritableScope( @NotNull WritableScope scope, @NotNull List block, @NotNull CoercionStrategy coercionStrategyForLastExpression, @NotNull ExpressionTypingContext context ) { if (block.isEmpty()) { - return new LoopTypeInfo(builtIns.getUnitType(), context.dataFlowInfo); + return new TypeInfoWithJumpInfo(builtIns.getUnitType(), context.dataFlowInfo, false, context.dataFlowInfo); } ExpressionTypingInternals blockLevelVisitor = ExpressionTypingVisitorDispatcher.createForBlock(expressionTypingComponents, scope); @@ -344,10 +344,10 @@ public class ExpressionTypingServices { DataFlowInfo newDataFlowInfo = result.getDataFlowInfo(); // If jump is not possible, we take new data flow info before jump if (!jumpOutPossible) { - if (result instanceof LoopTypeInfo) { - LoopTypeInfo loopTypeInfo = (LoopTypeInfo) result; - beforeJumpInfo = loopTypeInfo.getJumpFlowInfo(); - jumpOutPossible = loopTypeInfo.isJumpOutPossible(); + if (result instanceof TypeInfoWithJumpInfo) { + TypeInfoWithJumpInfo jumpTypeInfo = (TypeInfoWithJumpInfo) result; + beforeJumpInfo = jumpTypeInfo.getJumpFlowInfo(); + jumpOutPossible = jumpTypeInfo.getJumpOutPossible(); } else { beforeJumpInfo = newDataFlowInfo; @@ -359,7 +359,7 @@ public class ExpressionTypingServices { } blockLevelVisitor = ExpressionTypingVisitorDispatcher.createForBlock(expressionTypingComponents, scope); } - return new LoopTypeInfo(result.getType(), result.getDataFlowInfo(), jumpOutPossible, beforeJumpInfo); + return new TypeInfoWithJumpInfo(result.getType(), result.getDataFlowInfo(), jumpOutPossible, beforeJumpInfo); } private JetTypeInfo getTypeOfLastExpressionInBlock( diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ExpressionTypingVisitorDispatcher.java b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ExpressionTypingVisitorDispatcher.java index 05420730df0..8501ab1904e 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ExpressionTypingVisitorDispatcher.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ExpressionTypingVisitorDispatcher.java @@ -142,13 +142,11 @@ public class ExpressionTypingVisitorDispatcher extends JetVisitorx.length() + } while (true) + // x is null because of the break + return x.length() +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/smartCasts/loops/elvisBreakInsideDoWhile.txt b/compiler/testData/diagnostics/tests/smartCasts/loops/elvisBreakInsideDoWhile.txt new file mode 100644 index 00000000000..cd85b07bb38 --- /dev/null +++ b/compiler/testData/diagnostics/tests/smartCasts/loops/elvisBreakInsideDoWhile.txt @@ -0,0 +1,3 @@ +package + +public fun foo(/*0*/ x: kotlin.String?): kotlin.Int diff --git a/compiler/testData/diagnostics/tests/smartCasts/loops/elvisIfBreakInsideWhileTrue.kt b/compiler/testData/diagnostics/tests/smartCasts/loops/elvisIfBreakInsideWhileTrue.kt new file mode 100644 index 00000000000..312fff11a94 --- /dev/null +++ b/compiler/testData/diagnostics/tests/smartCasts/loops/elvisIfBreakInsideWhileTrue.kt @@ -0,0 +1,9 @@ +public fun foo(x: String?, y: String?): Int { + while (true) { + x ?: if (y == null) break + // y is not null in both branches + y.length() + } + // y is null because of the break + return y.length() +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/smartCasts/loops/elvisIfBreakInsideWhileTrue.txt b/compiler/testData/diagnostics/tests/smartCasts/loops/elvisIfBreakInsideWhileTrue.txt new file mode 100644 index 00000000000..74faaa4f9c5 --- /dev/null +++ b/compiler/testData/diagnostics/tests/smartCasts/loops/elvisIfBreakInsideWhileTrue.txt @@ -0,0 +1,3 @@ +package + +public fun foo(/*0*/ x: kotlin.String?, /*1*/ y: kotlin.String?): kotlin.Int diff --git a/compiler/testData/diagnostics/tests/smartCasts/loops/elvisInsideDoWhile.kt b/compiler/testData/diagnostics/tests/smartCasts/loops/elvisInsideDoWhile.kt new file mode 100644 index 00000000000..e2af3839253 --- /dev/null +++ b/compiler/testData/diagnostics/tests/smartCasts/loops/elvisInsideDoWhile.kt @@ -0,0 +1,9 @@ +public fun foo(x: String?): Int { + do { + // After the check, smart cast should work + x ?: x!!.length() + // x is not null in both branches + if (x.length() == 0) break + } while (true) + return x.length() +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/smartCasts/loops/elvisInsideDoWhile.txt b/compiler/testData/diagnostics/tests/smartCasts/loops/elvisInsideDoWhile.txt new file mode 100644 index 00000000000..cd85b07bb38 --- /dev/null +++ b/compiler/testData/diagnostics/tests/smartCasts/loops/elvisInsideDoWhile.txt @@ -0,0 +1,3 @@ +package + +public fun foo(/*0*/ x: kotlin.String?): kotlin.Int diff --git a/compiler/testData/diagnostics/tests/smartCasts/loops/elvisLeftBreakInsideWhileTrue.kt b/compiler/testData/diagnostics/tests/smartCasts/loops/elvisLeftBreakInsideWhileTrue.kt new file mode 100644 index 00000000000..bf043a200dd --- /dev/null +++ b/compiler/testData/diagnostics/tests/smartCasts/loops/elvisLeftBreakInsideWhileTrue.kt @@ -0,0 +1,9 @@ +public fun foo(x: String?, y: String?): Int { + while (true) { + (if (x != null) break else y) ?: y!! + // x is not null in both branches + y.length() + } + // y can be null because of the break + return y.length() +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/smartCasts/loops/elvisLeftBreakInsideWhileTrue.txt b/compiler/testData/diagnostics/tests/smartCasts/loops/elvisLeftBreakInsideWhileTrue.txt new file mode 100644 index 00000000000..74faaa4f9c5 --- /dev/null +++ b/compiler/testData/diagnostics/tests/smartCasts/loops/elvisLeftBreakInsideWhileTrue.txt @@ -0,0 +1,3 @@ +package + +public fun foo(/*0*/ x: kotlin.String?, /*1*/ y: kotlin.String?): kotlin.Int diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java index 12b9431f402..62634acfb42 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java @@ -11132,6 +11132,30 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest { doTest(fileName); } + @TestMetadata("elvisBreakInsideDoWhile.kt") + public void testElvisBreakInsideDoWhile() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/smartCasts/loops/elvisBreakInsideDoWhile.kt"); + doTest(fileName); + } + + @TestMetadata("elvisIfBreakInsideWhileTrue.kt") + public void testElvisIfBreakInsideWhileTrue() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/smartCasts/loops/elvisIfBreakInsideWhileTrue.kt"); + doTest(fileName); + } + + @TestMetadata("elvisInsideDoWhile.kt") + public void testElvisInsideDoWhile() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/smartCasts/loops/elvisInsideDoWhile.kt"); + doTest(fileName); + } + + @TestMetadata("elvisLeftBreakInsideWhileTrue.kt") + public void testElvisLeftBreakInsideWhileTrue() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/smartCasts/loops/elvisLeftBreakInsideWhileTrue.kt"); + doTest(fileName); + } + @TestMetadata("ifBlockInsideDoWhile.kt") public void testIfBlockInsideDoWhile() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/smartCasts/loops/ifBlockInsideDoWhile.kt");