Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(465)

Unified Diff: compiler/java/com/google/dart/compiler/parser/DartParser.java

Issue 10534065: In analyzer, catch use of continue and break in inappropriate places (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: # Created 8 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: compiler/java/com/google/dart/compiler/parser/DartParser.java
diff --git a/compiler/java/com/google/dart/compiler/parser/DartParser.java b/compiler/java/com/google/dart/compiler/parser/DartParser.java
index f9cd10098f342f64d33ff83e7b40b21dba40514a..3469d04b9f0f668141da8367e2aa6b0242510b84 100644
--- a/compiler/java/com/google/dart/compiler/parser/DartParser.java
+++ b/compiler/java/com/google/dart/compiler/parser/DartParser.java
@@ -221,6 +221,12 @@ public class DartParser extends CompletionHooksParserBase {
* {@link #setAllowFunctionExpression(boolean)}.
*/
private boolean allowFunctionExpression = true;
+
+ /**
+ * breaks and continues are not valid just anywhere, you need to be inside a loop
+ * or a case stmt.
+ */
+ private boolean inBreakableStatement = false;
Brian Wilkerson 2012/06/08 18:49:05 Looking at the spec, it seems that there is a diff
zundel 2012/06/08 20:15:08 I realized this halfway through the patch. I had
/**
* Set the {@link #allowFunctionExpression} flag indicating whether function expressions are
@@ -3181,6 +3187,9 @@ public class DartParser extends CompletionHooksParserBase {
DartIdentifier label = null;
if (match(Token.IDENTIFIER)) {
label = parseIdentifier();
+ } else if (!inBreakableStatement) {
+ // The validation of matching of labels to break statements is done later.
+ reportErrorWithoutAdvancing(ParserErrorCode.BREAK_OUTSIDE_OF_LOOP);
}
expectStatmentTerminator();
return done(new DartBreakStatement(label));
@@ -3190,6 +3199,9 @@ public class DartParser extends CompletionHooksParserBase {
beginContinueStatement();
expect(Token.CONTINUE);
DartIdentifier label = null;
+ if (!inBreakableStatement) {
+ reportErrorWithoutAdvancing(ParserErrorCode.CONTINUE_OUTSIDE_OF_LOOP);
+ }
if (peek(0) == Token.IDENTIFIER) {
label = parseIdentifier();
}
@@ -3653,7 +3665,7 @@ public class DartParser extends CompletionHooksParserBase {
expect(Token.LPAREN);
DartExpression condition = parseExpression();
expectCloseParen();
- DartStatement body = parseStatement();
+ DartStatement body = parseBreakableStatement();
return done(new DartWhileStatement(condition, body));
}
@@ -3669,7 +3681,7 @@ public class DartParser extends CompletionHooksParserBase {
private DartDoWhileStatement parseDoWhileStatement() {
beginDoStatement();
expect(Token.DO);
- DartStatement body = parseStatement();
+ DartStatement body = parseBreakableStatement();
expect(Token.WHILE);
expect(Token.LPAREN);
DartExpression condition = parseExpression();
@@ -3679,6 +3691,20 @@ public class DartParser extends CompletionHooksParserBase {
}
/**
+ * Use this wrapper to parse the body of a loop or case statement.
+ *
+ * Sets up flag variables to make sure continue and break are properly
+ * marked as errors when in wrong context.
+ */
+ private DartStatement parseBreakableStatement() {
Brian Wilkerson 2012/06/08 18:49:05 This is fine for both "breakable" and "continuable
zundel 2012/06/08 20:15:08 Renamed, this just records the fact that your in a
+ boolean oldInBreakable = inBreakableStatement;
+ inBreakableStatement = true;
+ DartStatement stmt = parseStatement();
+ inBreakableStatement = oldInBreakable;
+ return stmt;
+ }
+
+ /**
* <pre>
* iterationStatement
* : WHILE '(' expression ')' statement
@@ -3745,7 +3771,7 @@ public class DartParser extends CompletionHooksParserBase {
DartExpression iterable = parseExpression();
expectCloseParen();
- DartStatement body = parseStatement();
+ DartStatement body = parseBreakableStatement();
return done(new DartForInStatement(setup, iterable, body));
} else if (optional(Token.SEMICOLON)) {
@@ -3764,7 +3790,7 @@ public class DartParser extends CompletionHooksParserBase {
}
expectCloseParen();
- DartStatement body = parseStatement();
+ DartStatement body = parseBreakableStatement();
return done(new DartForStatement(setup, condition, next, body));
} else {
reportUnexpectedToken(position(), null, peek(0));
@@ -3812,7 +3838,7 @@ public class DartParser extends CompletionHooksParserBase {
case EOS:
return statements;
default:
- if ((statement = parseStatement()) == null) {
+ if ((statement = parseBreakableStatement()) == null) {
return statements;
}
statements.add(statement);

Powered by Google App Engine
This is Rietveld 408576698