JS parser: fixed labelled break/continue

This commit is contained in:
Alexey Tsvetkov
2014-11-10 14:57:21 +03:00
parent 939a8cce4e
commit 21d51147bf
2 changed files with 38 additions and 3 deletions
@@ -52,4 +52,12 @@ public final class AstUtil {
return nodesCopy;
}
@NotNull
public static JsFunctionScope toFunctionScope(JsScope scope) {
assert scope instanceof JsFunctionScope: "JsFunctionScope type is expected, but "
+ scope.getClass().getSimpleName() + " is found";
return (JsFunctionScope) scope;
}
}
@@ -19,6 +19,8 @@ import com.google.dart.compiler.backend.js.ast.*;
import com.google.dart.compiler.backend.js.ast.JsLiteral.JsBooleanLiteral;
import com.google.dart.compiler.common.SourceInfo;
import com.google.gwt.dev.js.rhino.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.IOException;
import java.io.Reader;
@@ -26,6 +28,8 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
import static com.google.dart.compiler.util.AstUtil.toFunctionScope;
/**
* Parses JavaScript source.
*/
@@ -375,7 +379,28 @@ public class JsParser {
}
private JsBreak mapBreak(Node breakNode) {
return new JsBreak();
return new JsBreak(getTargetLabel(breakNode));
}
@Nullable
private JsNameRef getTargetLabel(@NotNull Node statementWithLabel) {
int type = statementWithLabel.getType();
if (type != TokenStream.BREAK && type != TokenStream.CONTINUE) {
String tokenTypeName = TokenStream.tokenToName(statementWithLabel.getType());
throw new AssertionError("Unexpected node type with label: " + tokenTypeName);
}
Node label = statementWithLabel.getFirstChild();
if (label == null) return null;
String identifier = label.getString();
assert identifier != null: "If label exists identifier should not be null";
JsFunctionScope scope = toFunctionScope(getScope());
JsName labelName = scope.findLabel(identifier);
assert labelName != null: "Unknown label name: " + identifier;
return labelName.makeRef();
}
private JsInvocation mapCall(Node callNode) throws JsParserException {
@@ -416,7 +441,7 @@ public class JsParser {
}
private JsContinue mapContinue(Node contNode) {
return new JsContinue();
return new JsContinue(getTargetLabel(contNode));
}
private JsStatement mapDebuggerStatement(Node node) {
@@ -721,10 +746,12 @@ public class JsParser {
private JsLabel mapLabel(Node labelNode) throws JsParserException {
String fromName = labelNode.getFirstChild().getString();
JsName toName = getScope().declareName(fromName);
JsFunctionScope scope = toFunctionScope(getScope());
JsName toName = scope.enterLabel(fromName);
Node fromStmt = labelNode.getFirstChild().getNext();
JsLabel toLabel = new JsLabel(toName);
toLabel.setStatement(mapStatement(fromStmt));
scope.exitLabel();
return toLabel;
}