JS parser: fixed labelled break/continue
This commit is contained in:
@@ -52,4 +52,12 @@ public final class AstUtil {
|
|||||||
|
|
||||||
return nodesCopy;
|
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.backend.js.ast.JsLiteral.JsBooleanLiteral;
|
||||||
import com.google.dart.compiler.common.SourceInfo;
|
import com.google.dart.compiler.common.SourceInfo;
|
||||||
import com.google.gwt.dev.js.rhino.*;
|
import com.google.gwt.dev.js.rhino.*;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
@@ -26,6 +28,8 @@ import java.util.ArrayList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Stack;
|
import java.util.Stack;
|
||||||
|
|
||||||
|
import static com.google.dart.compiler.util.AstUtil.toFunctionScope;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses JavaScript source.
|
* Parses JavaScript source.
|
||||||
*/
|
*/
|
||||||
@@ -375,7 +379,28 @@ public class JsParser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private JsBreak mapBreak(Node breakNode) {
|
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 {
|
private JsInvocation mapCall(Node callNode) throws JsParserException {
|
||||||
@@ -416,7 +441,7 @@ public class JsParser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private JsContinue mapContinue(Node contNode) {
|
private JsContinue mapContinue(Node contNode) {
|
||||||
return new JsContinue();
|
return new JsContinue(getTargetLabel(contNode));
|
||||||
}
|
}
|
||||||
|
|
||||||
private JsStatement mapDebuggerStatement(Node node) {
|
private JsStatement mapDebuggerStatement(Node node) {
|
||||||
@@ -721,10 +746,12 @@ public class JsParser {
|
|||||||
|
|
||||||
private JsLabel mapLabel(Node labelNode) throws JsParserException {
|
private JsLabel mapLabel(Node labelNode) throws JsParserException {
|
||||||
String fromName = labelNode.getFirstChild().getString();
|
String fromName = labelNode.getFirstChild().getString();
|
||||||
JsName toName = getScope().declareName(fromName);
|
JsFunctionScope scope = toFunctionScope(getScope());
|
||||||
|
JsName toName = scope.enterLabel(fromName);
|
||||||
Node fromStmt = labelNode.getFirstChild().getNext();
|
Node fromStmt = labelNode.getFirstChild().getNext();
|
||||||
JsLabel toLabel = new JsLabel(toName);
|
JsLabel toLabel = new JsLabel(toName);
|
||||||
toLabel.setStatement(mapStatement(fromStmt));
|
toLabel.setStatement(mapStatement(fromStmt));
|
||||||
|
scope.exitLabel();
|
||||||
return toLabel;
|
return toLabel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user