use of org.mozilla.javascript.ast.Block in project HL4A by HL4A.
the class IRFactory method transformSwitch.
private Node transformSwitch(SwitchStatement node) {
// The switch will be rewritten from:
//
// switch (expr) {
// case test1: statements1;
// ...
// default: statementsDefault;
// ...
// case testN: statementsN;
// }
//
// to:
//
// {
// switch (expr) {
// case test1: goto label1;
// ...
// case testN: goto labelN;
// }
// goto labelDefault;
// label1:
// statements1;
// ...
// labelDefault:
// statementsDefault;
// ...
// labelN:
// statementsN;
// breakLabel:
// }
//
// where inside switch each "break;" without label will be replaced
// by "goto breakLabel".
//
// If the original switch does not have the default label, then
// after the switch he transformed code would contain this goto:
// goto breakLabel;
// instead of:
// goto labelDefault;
decompiler.addToken(Token.SWITCH);
decompiler.addToken(Token.LP);
Node switchExpr = transform(node.getExpression());
decompiler.addToken(Token.RP);
node.addChildToBack(switchExpr);
Node block = new Node(Token.BLOCK, node, node.getLineno());
decompiler.addEOL(Token.LC);
for (SwitchCase sc : node.getCases()) {
AstNode expr = sc.getExpression();
Node caseExpr = null;
if (expr != null) {
decompiler.addToken(Token.CASE);
caseExpr = transform(expr);
} else {
decompiler.addToken(Token.DEFAULT);
}
decompiler.addEOL(Token.COLON);
List<AstNode> stmts = sc.getStatements();
Node body = new Block();
if (stmts != null) {
for (AstNode kid : stmts) {
body.addChildToBack(transform(kid));
}
}
addSwitchCase(block, caseExpr, body);
}
decompiler.addEOL(Token.RC);
closeSwitch(block);
return block;
}
use of org.mozilla.javascript.ast.Block in project HL4A by HL4A.
the class Parser method parseFunctionBody.
private AstNode parseFunctionBody(int type, FunctionNode fnNode) throws IOException {
boolean isExpressionClosure = false;
if (!matchToken(Token.LC)) {
if (compilerEnv.getLanguageVersion() < Context.VERSION_1_8 && type != FunctionNode.ARROW_FUNCTION) {
reportError("msg.no.brace.body");
} else {
isExpressionClosure = true;
}
}
boolean isArrow = type == FunctionNode.ARROW_FUNCTION;
++nestingOfFunction;
int pos = ts.tokenBeg;
// starts at LC position
Block pn = new Block(pos);
boolean inDirectivePrologue = true;
boolean savedStrictMode = inUseStrictDirective;
// Don't set 'inUseStrictDirective' to false: inherit strict mode.
pn.setLineno(ts.lineno);
try {
if (isExpressionClosure) {
AstNode returnValue = assignExpr();
ReturnStatement n = new ReturnStatement(returnValue.getPosition(), returnValue.getLength(), returnValue);
// expression closure flag is required on both nodes
n.putProp(Node.EXPRESSION_CLOSURE_PROP, Boolean.TRUE);
pn.putProp(Node.EXPRESSION_CLOSURE_PROP, Boolean.TRUE);
if (isArrow) {
n.putProp(Node.ARROW_FUNCTION_PROP, Boolean.TRUE);
}
pn.addStatement(n);
} else {
bodyLoop: for (; ; ) {
AstNode n;
int tt = peekToken();
switch(tt) {
case Token.ERROR:
case Token.EOF:
case Token.RC:
break bodyLoop;
case Token.FUNCTION:
consumeToken();
n = function(FunctionNode.FUNCTION_STATEMENT);
break;
default:
n = statement();
if (inDirectivePrologue) {
String directive = getDirective(n);
if (directive == null) {
inDirectivePrologue = false;
} else if (directive.equals("严格模式")) {
inUseStrictDirective = true;
fnNode.setInStrictMode(true);
if (!savedStrictMode) {
setRequiresActivation();
}
}
}
break;
}
pn.addStatement(n);
}
}
} catch (ParserException e) {
// Ignore it
} finally {
--nestingOfFunction;
inUseStrictDirective = savedStrictMode;
}
int end = ts.tokenEnd;
getAndResetJsDoc();
if (!isExpressionClosure && mustMatchToken(Token.RC, "msg.no.brace.after.body"))
end = ts.tokenEnd;
pn.setLength(end - pos);
return pn;
}
use of org.mozilla.javascript.ast.Block in project HL4A by HL4A.
the class Parser method statements.
// This function does not match the closing RC: the caller matches
// the RC so it can provide a suitable error message if not matched.
// This means it's up to the caller to set the length of the node to
// include the closing RC. The node start pos is set to the
// absolute buffer start position, and the caller should fix it up
// to be relative to the parent node. All children of this block
// node are given relative start positions and correct lengths.
private AstNode statements(AstNode parent) throws IOException {
if (// assertion can be invalid in bad code
currentToken != Token.LC && !compilerEnv.isIdeMode())
codeBug();
int pos = ts.tokenBeg;
AstNode block = parent != null ? parent : new Block(pos);
block.setLineno(ts.lineno);
int tt;
while ((tt = peekToken()) > Token.EOF && tt != Token.RC) {
block.addChild(statement());
}
block.setLength(ts.tokenBeg - pos);
return block;
}
Aggregations