report 'break' and 'continue' inside 'when' as errors (even if 'when' is nested in a loop)
This commit is contained in:
committed by
Andrey Breslav
parent
8ab12e217d
commit
252c4118eb
@@ -977,6 +977,12 @@ public class JetControlFlowProcessor {
|
|||||||
loop = builder.getCurrentLoop();
|
loop = builder.getCurrentLoop();
|
||||||
if (loop == null) {
|
if (loop == null) {
|
||||||
trace.report(BREAK_OR_CONTINUE_OUTSIDE_A_LOOP.on(expression));
|
trace.report(BREAK_OR_CONTINUE_OUTSIDE_A_LOOP.on(expression));
|
||||||
|
} else {
|
||||||
|
JetWhenExpression whenExpression = PsiTreeUtil.getParentOfType(expression, JetWhenExpression.class, true,
|
||||||
|
JetLoopExpression.class);
|
||||||
|
if (whenExpression != null) {
|
||||||
|
trace.report(BREAK_OR_CONTINUE_IN_WHEN.on(expression));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (loop != null && loop.getBody() != null
|
if (loop != null && loop.getBody() != null
|
||||||
|
|||||||
@@ -500,6 +500,7 @@ public interface Errors {
|
|||||||
DiagnosticFactory0<JetSimpleNameExpression> AMBIGUOUS_LABEL = DiagnosticFactory0.create(ERROR);
|
DiagnosticFactory0<JetSimpleNameExpression> AMBIGUOUS_LABEL = DiagnosticFactory0.create(ERROR);
|
||||||
|
|
||||||
DiagnosticFactory0<JetExpressionWithLabel> BREAK_OR_CONTINUE_OUTSIDE_A_LOOP = DiagnosticFactory0.create(ERROR);
|
DiagnosticFactory0<JetExpressionWithLabel> BREAK_OR_CONTINUE_OUTSIDE_A_LOOP = DiagnosticFactory0.create(ERROR);
|
||||||
|
DiagnosticFactory0<JetExpressionWithLabel> BREAK_OR_CONTINUE_IN_WHEN = DiagnosticFactory0.create(ERROR);
|
||||||
DiagnosticFactory0<JetExpressionWithLabel> BREAK_OR_CONTINUE_JUMPS_ACROSS_FUNCTION_BOUNDARY = DiagnosticFactory0.create(ERROR);
|
DiagnosticFactory0<JetExpressionWithLabel> BREAK_OR_CONTINUE_JUMPS_ACROSS_FUNCTION_BOUNDARY = DiagnosticFactory0.create(ERROR);
|
||||||
DiagnosticFactory1<JetExpressionWithLabel, String> NOT_A_LOOP_LABEL = DiagnosticFactory1.create(ERROR);
|
DiagnosticFactory1<JetExpressionWithLabel, String> NOT_A_LOOP_LABEL = DiagnosticFactory1.create(ERROR);
|
||||||
DiagnosticFactory1<JetReturnExpression, String> NOT_A_RETURN_LABEL = DiagnosticFactory1.create(ERROR);
|
DiagnosticFactory1<JetReturnExpression, String> NOT_A_RETURN_LABEL = DiagnosticFactory1.create(ERROR);
|
||||||
|
|||||||
+1
@@ -407,6 +407,7 @@ public class DefaultErrorMessages {
|
|||||||
MAP.put(NO_TAIL_CALLS_FOUND, "A function is marked as tail-recursive but no tail calls are found");
|
MAP.put(NO_TAIL_CALLS_FOUND, "A function is marked as tail-recursive but no tail calls are found");
|
||||||
MAP.put(VALUE_PARAMETER_WITH_NO_TYPE_ANNOTATION, "A type annotation is required on a value parameter");
|
MAP.put(VALUE_PARAMETER_WITH_NO_TYPE_ANNOTATION, "A type annotation is required on a value parameter");
|
||||||
MAP.put(BREAK_OR_CONTINUE_OUTSIDE_A_LOOP, "'break' and 'continue' are only allowed inside a loop");
|
MAP.put(BREAK_OR_CONTINUE_OUTSIDE_A_LOOP, "'break' and 'continue' are only allowed inside a loop");
|
||||||
|
MAP.put(BREAK_OR_CONTINUE_IN_WHEN, "'break' and 'continue' are not allowed in 'when' statements. Consider using labels to continue/break from the outer loop");
|
||||||
MAP.put(BREAK_OR_CONTINUE_JUMPS_ACROSS_FUNCTION_BOUNDARY, "'break' or 'continue' jumps across a function boundary");
|
MAP.put(BREAK_OR_CONTINUE_JUMPS_ACROSS_FUNCTION_BOUNDARY, "'break' or 'continue' jumps across a function boundary");
|
||||||
MAP.put(NOT_A_LOOP_LABEL, "The label ''{0}'' does not denote a loop", STRING);
|
MAP.put(NOT_A_LOOP_LABEL, "The label ''{0}'' does not denote a loop", STRING);
|
||||||
MAP.put(NOT_A_RETURN_LABEL, "The label ''{0}'' does not reference to a context from which we can return", STRING);
|
MAP.put(NOT_A_RETURN_LABEL, "The label ''{0}'' does not reference to a context from which we can return", STRING);
|
||||||
|
|||||||
@@ -82,4 +82,4 @@ class C {
|
|||||||
}
|
}
|
||||||
a<!UNSAFE_CALL!>.<!>compareTo("2")
|
a<!UNSAFE_CALL!>.<!>compareTo("2")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package
|
package
|
||||||
|
|
||||||
internal final class C {
|
internal final class C {
|
||||||
public constructor C()
|
public constructor C()
|
||||||
|
|||||||
@@ -0,0 +1,55 @@
|
|||||||
|
fun breakContinueInWhen(i: Int) {
|
||||||
|
for (y in 0..10) {
|
||||||
|
when(i) {
|
||||||
|
0 -> <!BREAK_OR_CONTINUE_IN_WHEN!>continue<!>
|
||||||
|
1 -> <!BREAK_OR_CONTINUE_IN_WHEN!>break<!>
|
||||||
|
2 -> {
|
||||||
|
for(z in 0..10) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
for(w in 0..10) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun breakContinueInWhenWithWhile(i: Int, j: Int) {
|
||||||
|
while (i > 0) {
|
||||||
|
when (i) {
|
||||||
|
0 -> <!BREAK_OR_CONTINUE_IN_WHEN!>continue<!>
|
||||||
|
1 -> <!BREAK_OR_CONTINUE_IN_WHEN!>break<!>
|
||||||
|
2 -> {
|
||||||
|
while (j > 0) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun breakContinueInWhenWithDoWhile(i: Int, j: Int) {
|
||||||
|
do {
|
||||||
|
when (i) {
|
||||||
|
0 -> <!BREAK_OR_CONTINUE_IN_WHEN!>continue<!>
|
||||||
|
1 -> <!BREAK_OR_CONTINUE_IN_WHEN!>break<!>
|
||||||
|
2 -> {
|
||||||
|
do {
|
||||||
|
if (j == 5) break
|
||||||
|
if (j == 10) continue
|
||||||
|
} while (j > 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (i > 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun labeledBreakContinue(i: Int) {
|
||||||
|
@outer for (y in 0..10) {
|
||||||
|
when (i) {
|
||||||
|
0 -> continue@outer
|
||||||
|
1 -> break@outer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
internal fun breakContinueInWhen(/*0*/ i: kotlin.Int): kotlin.Unit
|
||||||
|
internal fun breakContinueInWhenWithDoWhile(/*0*/ i: kotlin.Int, /*1*/ j: kotlin.Int): kotlin.Unit
|
||||||
|
internal fun breakContinueInWhenWithWhile(/*0*/ i: kotlin.Int, /*1*/ j: kotlin.Int): kotlin.Unit
|
||||||
|
internal fun labeledBreakContinue(/*0*/ i: kotlin.Int): kotlin.Unit
|
||||||
@@ -180,6 +180,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("BreakContinueInWhen.kt")
|
||||||
|
public void testBreakContinueInWhen() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/BreakContinueInWhen.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("Builders.kt")
|
@TestMetadata("Builders.kt")
|
||||||
public void testBuilders() throws Exception {
|
public void testBuilders() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/Builders.kt");
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/Builders.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user