📄 parser.java
字号:
mustMatchToken(Token.COLON, "msg.no.colon.case"); decompiler.addEOL(Token.COLON); break; default: reportError("msg.bad.switch"); break switchLoop; } Node block = nf.createLeaf(Token.BLOCK); while ((tt = peekToken()) != Token.RC && tt != Token.CASE && tt != Token.DEFAULT && tt != Token.EOF) { nf.addChildToBack(block, statement()); } // caseExpression == null => add default label nf.addSwitchCase(pn, caseExpression, block); } decompiler.addEOL(Token.RC); nf.closeSwitch(pn); } finally { exitSwitch(); } return pn; } case Token.WHILE: { consumeToken(); decompiler.addToken(Token.WHILE); Node loop = enterLoop(statementLabel, true); try { Node cond = condition(); decompiler.addEOL(Token.LC); Node body = statement(); decompiler.addEOL(Token.RC); pn = nf.createWhile(loop, cond, body); } finally { exitLoop(true); } return pn; } case Token.DO: { consumeToken(); decompiler.addToken(Token.DO); decompiler.addEOL(Token.LC); Node loop = enterLoop(statementLabel, true); try { Node body = statement(); decompiler.addToken(Token.RC); mustMatchToken(Token.WHILE, "msg.no.while.do"); decompiler.addToken(Token.WHILE); Node cond = condition(); pn = nf.createDoWhile(loop, body, cond); } finally { exitLoop(true); } // Always auto-insert semicolon to follow SpiderMonkey: // It is required by ECMAScript but is ignored by the rest of // world, see bug 238945 matchToken(Token.SEMI); decompiler.addEOL(Token.SEMI); return pn; } case Token.FOR: { consumeToken(); boolean isForEach = false; decompiler.addToken(Token.FOR); Node loop = enterLoop(statementLabel, true); try { Node init; // Node init is also foo in 'foo in object' Node cond; // Node cond is also object in 'foo in object' Node incr = null; Node body; int declType = -1; // See if this is a for each () instead of just a for () if (matchToken(Token.NAME)) { decompiler.addName(ts.getString()); if (ts.getString().equals("each")) { isForEach = true; } else { reportError("msg.no.paren.for"); } } mustMatchToken(Token.LP, "msg.no.paren.for"); decompiler.addToken(Token.LP); tt = peekToken(); if (tt == Token.SEMI) { init = nf.createLeaf(Token.EMPTY); } else { if (tt == Token.VAR || tt == Token.LET) { // set init to a var list or initial consumeToken(); // consume the token decompiler.addToken(tt); init = variables(true, tt); declType = tt; } else { init = expr(true); } } if (matchToken(Token.IN)) { decompiler.addToken(Token.IN); // 'cond' is the object over which we're iterating cond = expr(false); } else { // ordinary for loop mustMatchToken(Token.SEMI, "msg.no.semi.for"); decompiler.addToken(Token.SEMI); if (peekToken() == Token.SEMI) { // no loop condition cond = nf.createLeaf(Token.EMPTY); } else { cond = expr(false); } mustMatchToken(Token.SEMI, "msg.no.semi.for.cond"); decompiler.addToken(Token.SEMI); if (peekToken() == Token.RP) { incr = nf.createLeaf(Token.EMPTY); } else { incr = expr(false); } } mustMatchToken(Token.RP, "msg.no.paren.for.ctrl"); decompiler.addToken(Token.RP); decompiler.addEOL(Token.LC); body = statement(); decompiler.addEOL(Token.RC); if (incr == null) { // cond could be null if 'in obj' got eaten // by the init node. pn = nf.createForIn(declType, loop, init, cond, body, isForEach); } else { pn = nf.createFor(loop, init, cond, incr, body); } } finally { exitLoop(true); } return pn; } case Token.TRY: { consumeToken(); int lineno = ts.getLineno(); Node tryblock; Node catchblocks = null; Node finallyblock = null; decompiler.addToken(Token.TRY); if (peekToken() != Token.LC) { reportError("msg.no.brace.try"); } decompiler.addEOL(Token.LC); tryblock = statement(); decompiler.addEOL(Token.RC); catchblocks = nf.createLeaf(Token.BLOCK); boolean sawDefaultCatch = false; int peek = peekToken(); if (peek == Token.CATCH) { while (matchToken(Token.CATCH)) { if (sawDefaultCatch) { reportError("msg.catch.unreachable"); } decompiler.addToken(Token.CATCH); mustMatchToken(Token.LP, "msg.no.paren.catch"); decompiler.addToken(Token.LP); mustMatchToken(Token.NAME, "msg.bad.catchcond"); String varName = ts.getString(); decompiler.addName(varName); Node catchCond = null; if (matchToken(Token.IF)) { decompiler.addToken(Token.IF); catchCond = expr(false); } else { sawDefaultCatch = true; } mustMatchToken(Token.RP, "msg.bad.catchcond"); decompiler.addToken(Token.RP); mustMatchToken(Token.LC, "msg.no.brace.catchblock"); decompiler.addEOL(Token.LC); nf.addChildToBack(catchblocks, nf.createCatch(varName, catchCond, statements(null), ts.getLineno())); mustMatchToken(Token.RC, "msg.no.brace.after.body"); decompiler.addEOL(Token.RC); } } else if (peek != Token.FINALLY) { mustMatchToken(Token.FINALLY, "msg.try.no.catchfinally"); } if (matchToken(Token.FINALLY)) { decompiler.addToken(Token.FINALLY); decompiler.addEOL(Token.LC); finallyblock = statement(); decompiler.addEOL(Token.RC); } pn = nf.createTryCatchFinally(tryblock, catchblocks, finallyblock, lineno); return pn; } case Token.THROW: { consumeToken(); if (peekTokenOrEOL() == Token.EOL) { // ECMAScript does not allow new lines before throw expression, // see bug 256617 reportError("msg.bad.throw.eol"); } int lineno = ts.getLineno(); decompiler.addToken(Token.THROW); pn = nf.createThrow(expr(false), lineno); break; } case Token.BREAK: { consumeToken(); int lineno = ts.getLineno(); decompiler.addToken(Token.BREAK); // matchJumpLabelName only matches if there is one Node breakStatement = matchJumpLabelName(); if (breakStatement == null) { if (loopAndSwitchSet == null || loopAndSwitchSet.size() == 0) { reportError("msg.bad.break"); return null; } breakStatement = (Node)loopAndSwitchSet.peek(); } pn = nf.createBreak(breakStatement, lineno); break; } case Token.CONTINUE: { consumeToken(); int lineno = ts.getLineno(); decompiler.addToken(Token.CONTINUE); Node loop; // matchJumpLabelName only matches if there is one Node label = matchJumpLabelName(); if (label == null) { if (loopSet == null || loopSet.size() == 0) { reportError("msg.continue.outside"); return null; } loop = (Node)loopSet.peek(); } else { loop = nf.getLabelLoop(label); if (loop == null) { reportError("msg.continue.nonloop"); return null; } } pn = nf.createContinue(loop, lineno); break; } case Token.WITH: { consumeToken(); decompiler.addToken(Token.WITH); int lineno = ts.getLineno(); mustMatchToken(Token.LP, "msg.no.paren.with"); decompiler.addToken(Token.LP); Node obj = expr(false); mustMatchToken(Token.RP, "msg.no.paren.after.with"); decompiler.addToken(Token.RP); decompiler.addEOL(Token.LC); ++nestingOfWith; Node body; try { body = statement(); } finally { --nestingOfWith; } decompiler.addEOL(Token.RC); pn = nf.createWith(obj, body, lineno); return pn; } case Token.CONST: case Token.VAR: { consumeToken(); decompiler.addToken(tt); pn = variables(false, tt); break; } case Token.LET: { consumeToken(); decompiler.addToken(Token.LET); if (peekToken() == Token.LP) { pn = let(true); } else { pn = variables(false, tt); } return pn; } case Token.RETURN: case Token.YIELD: { pn = returnOrYield(tt, false); break; } case Token.DEBUGGER: consumeToken(); decompiler.addToken(Token.DEBUGGER); pn = nf.createDebugger(ts.getLineno()); break; case Token.LC: consumeToken(); if (statementLabel != null) { decompiler.addToken(Token.LC); } Node scope = nf.createScopeNode(Token.BLOCK, ts.getLineno()); pushScope(scope); try { statements(scope); mustMatchToken(Token.RC, "msg.no.brace.block"); if (statementLabel != null) { decompiler.addEOL(Token.RC); } return scope; } finally { popScope(); } case Token.ERROR: // Fall thru, to have a node for error recovery to work on case Token.SEMI: consumeToken(); pn = nf.createLeaf(Token.EMPTY); return pn; case Token.FUNCTION: { consumeToken(); pn = function(FunctionNode.FUNCTION_EXPRESSION_STATEMENT); return pn; } case Token.DEFAULT : consumeToken(); mustHaveXML(); decompiler.addToken(Token.DEFAULT); int nsLine = ts.getLineno(); if (!(matchToken(Token.NAME) && ts.getString().equals("xml"))) { reportError("msg.bad.namespace"); } decompiler.addName(" xml"); if (!(matchToken(Token.NAME) && ts.getString().equals("namespace"))) { reportError("msg.bad.namespace"); } decompiler.addName(" namespace"); if (!matchToken(Token.ASSIGN)) { reportError("msg.bad.namespace"); } decompiler.addToken(Token.ASSIGN);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -