JS parser: fixed labelled break/continue
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user