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

Unified Diff: compiler/java/com/google/dart/compiler/resolver/Resolver.java

Issue 10725002: Validate the target of break and continue statments from within a switch (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/resolver/Resolver.java
diff --git a/compiler/java/com/google/dart/compiler/resolver/Resolver.java b/compiler/java/com/google/dart/compiler/resolver/Resolver.java
index 697154ad9876ba88c29d0e6ce1d1de42fd0af671..204a795201e681adb45289e07875dde47532462d 100644
--- a/compiler/java/com/google/dart/compiler/resolver/Resolver.java
+++ b/compiler/java/com/google/dart/compiler/resolver/Resolver.java
@@ -18,6 +18,7 @@ import com.google.dart.compiler.ast.DartBreakStatement;
import com.google.dart.compiler.ast.DartCatchBlock;
import com.google.dart.compiler.ast.DartClass;
import com.google.dart.compiler.ast.DartClassMember;
+import com.google.dart.compiler.ast.DartContinueStatement;
import com.google.dart.compiler.ast.DartDoWhileStatement;
import com.google.dart.compiler.ast.DartDoubleLiteral;
import com.google.dart.compiler.ast.DartExpression;
@@ -69,6 +70,7 @@ import com.google.dart.compiler.ast.Modifiers;
import com.google.dart.compiler.common.HasSourceInfo;
import com.google.dart.compiler.common.SourceInfo;
import com.google.dart.compiler.parser.Token;
+import com.google.dart.compiler.resolver.LabelElement.LabeledStatementType;
import com.google.dart.compiler.type.InterfaceType;
import com.google.dart.compiler.type.InterfaceType.Member;
import com.google.dart.compiler.type.Type;
@@ -753,17 +755,22 @@ public class Resolver {
@Override
public Element visitLabel(DartLabel x) {
- LabelElement currentLabel = Elements.labelElement(x, x.getName(), innermostFunction);
- recordElement(x.getLabel(), currentLabel);
- recordElement(x, currentLabel);
- x.visitChildren(this);
- if (!labelsInScopes.contains(currentLabel)) {
- // TODO(zundel): warning, not type error.
- // topLevelContext.typeError(x, DartCompilerErrorCode.USELESS_LABEL, x.getName());
- } else if (!referencedLabels.contains(currentLabel)) {
- // TODO(zundel): warning, not type error.
- // topLevelContext.typeError(x, DartCompilerErrorCode.UNREFERENCED_LABEL, x.getName());
+ DartNode parent = x.getParent();
+ if (!(parent instanceof DartSwitchMember)) {
+ LabelElement labelElement;
+ DartStatement childStatement = x.getStatement();
+ while (childStatement instanceof DartLabel) {
+ childStatement = ((DartLabel)childStatement).getStatement();
+ }
+ if (childStatement instanceof DartSwitchStatement) {
+ labelElement = Elements.switchLabelElement(x, x.getName(), innermostFunction);
+ } else {
+ labelElement = Elements.statementLabelElement(x, x.getName(), innermostFunction);
+ }
+ recordElement(x.getLabel(), labelElement);
+ recordElement(x, labelElement);
}
+ x.visitChildren(this);
return null;
}
@@ -903,29 +910,17 @@ public class Resolver {
return null;
}
- private void addLabelToStatement(DartStatement x) {
+ private void addLabelToStatement(DartNode x) {
DartNode parent = x.getParent();
while (parent instanceof DartLabel) {
- LabelElement currentLabel = ((DartLabel) parent).getElement();
+ DartLabel label = (DartLabel) parent;
+ LabelElement currentLabel = label.getElement();
getContext().getScope().addLabel(currentLabel);
labelsInScopes.add(currentLabel);
parent = parent.getParent();
}
}
- private void addLabelToSwitchMember(DartSwitchMember x) {
- DartLabel label = x.getLabel();
- if (label != null) {
- LabelElement currentLabel = label.getElement(); // TODO(zundel): Y U NO HAVE ELEMENT?
- if (getContext().getScope().hasLocalLabel(label.getName())) {
- onError(label, ResolverErrorCode.DUPLICATE_LABEL_IN_SWITCH_STATEMENT);
- }
- getContext().getScope().addLabel(currentLabel);
- labelsInScopes.add(currentLabel);
- }
- }
-
-
@Override
public Element visitForStatement(DartForStatement x) {
getContext().pushScope("<for>");
@@ -940,6 +935,11 @@ public class Resolver {
public Element visitSwitchStatement(DartSwitchStatement x) {
getContext().pushScope("<switch>");
addLabelToStatement(x);
+ // The scope of a label on the case statement is the case statement itself. These labels
+ // need to be resolved before the continue <label>; statements can be resolved.
+ for (DartSwitchMember member : x.getMembers()) {
+ recordSwitchMamberLabel(member);
+ }
x.visitChildren(this);
getContext().popScope();
return null;
@@ -950,11 +950,24 @@ public class Resolver {
getContext().pushScope("<switch member>");
x.visitChildren(this);
getContext().popScope();
- // The scope of a label on the case statement is the case statement itself.
- addLabelToSwitchMember(x);
return null;
}
+ private void recordSwitchMamberLabel(DartSwitchMember x) {
+ DartLabel label = x.getLabel();
+ if (label != null) {
+ LabelElement labelElement = Elements.switchMemberLabelElement(label, label.getName(),
+ innermostFunction);
+ recordElement(label.getLabel(), labelElement);
+ recordElement(label, labelElement);
+ if (getContext().getScope().hasLocalLabel(label.getName())) {
+ onError(label, ResolverErrorCode.DUPLICATE_LABEL_IN_SWITCH_STATEMENT);
+ }
+ getContext().getScope().addLabel(labelElement);
+ labelsInScopes.add(labelElement);
+ }
+ }
+
@Override
public Element visitThisExpression(DartThisExpression x) {
if (ElementKind.of(currentHolder).equals(ElementKind.LIBRARY)) {
@@ -1568,6 +1581,16 @@ public class Resolver {
Element element = getContext().getScope().findLabel(x.getTargetName(), innermostFunction);
if (ElementKind.of(element).equals(ElementKind.LABEL)) {
LabelElement labelElement = (LabelElement) element;
+ if (x instanceof DartBreakStatement
+ && labelElement.getStatementType() == LabeledStatementType.SWITCH_MEMBER_STATEMENT) {
+ onError(x.getLabel(), ResolverErrorCode.BREAK_LABEL_RESOLVES_TO_CASE_OR_DEFAULT);
+ return null;
+ }
+ if (x instanceof DartContinueStatement
+ && labelElement.getStatementType() == LabeledStatementType.SWITCH_STATEMENT) {
+ onError(x.getLabel(), ResolverErrorCode.CONTINUE_LABEL_RESOLVES_TO_SWITCH);
+ return null;
+ }
MethodElement enclosingFunction = (labelElement).getEnclosingFunction();
if (enclosingFunction == innermostFunction) {
referencedLabels.add(labelElement);
@@ -1615,7 +1638,7 @@ public class Resolver {
case CONSTRUCTOR:
onError(errorNode, ResolverErrorCode.IS_A_CONSTRUCTOR, classOrLibrary.getName(),
- name);
+ name);
break;
case METHOD: {

Powered by Google App Engine
This is Rietveld 408576698