123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915 |
- /*
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
- function FormattedContentBuilder(content, mapping, originalOffset, formattedOffset, indentString)
- {
- this._originalContent = content;
- this._originalOffset = originalOffset;
- this._lastOriginalPosition = 0;
- this._formattedContent = [];
- this._formattedContentLength = 0;
- this._formattedOffset = formattedOffset;
- this._lastFormattedPosition = 0;
- this._mapping = mapping;
- this._lineNumber = 0;
- this._nestingLevel = 0;
- this._indentString = indentString;
- this._cachedIndents = {};
- }
- FormattedContentBuilder.prototype = {
- addToken: function(token)
- {
- for (var i = 0; i < token.comments_before.length; ++i)
- this._addComment(token.comments_before[i]);
- while (this._lineNumber < token.line) {
- this._addText("\n");
- this._addIndent();
- this._needNewLine = false;
- this._lineNumber += 1;
- }
- if (this._needNewLine) {
- this._addText("\n");
- this._addIndent();
- this._needNewLine = false;
- }
- this._addMappingIfNeeded(token.pos);
- this._addText(this._originalContent.substring(token.pos, token.endPos));
- this._lineNumber = token.endLine;
- },
- addSpace: function()
- {
- this._addText(" ");
- },
- addNewLine: function()
- {
- this._needNewLine = true;
- },
- increaseNestingLevel: function()
- {
- this._nestingLevel += 1;
- },
- decreaseNestingLevel: function()
- {
- this._nestingLevel -= 1;
- },
- content: function()
- {
- return this._formattedContent.join("");
- },
- mapping: function()
- {
- return { original: this._originalPositions, formatted: this._formattedPositions };
- },
- _addIndent: function()
- {
- if (this._cachedIndents[this._nestingLevel]) {
- this._addText(this._cachedIndents[this._nestingLevel]);
- return;
- }
- var fullIndent = "";
- for (var i = 0; i < this._nestingLevel; ++i)
- fullIndent += this._indentString;
- this._addText(fullIndent);
- // Cache a maximum of 20 nesting level indents.
- if (this._nestingLevel <= 20)
- this._cachedIndents[this._nestingLevel] = fullIndent;
- },
- _addComment: function(comment)
- {
- if (this._lineNumber < comment.line) {
- for (var j = this._lineNumber; j < comment.line; ++j)
- this._addText("\n");
- this._lineNumber = comment.line;
- this._needNewLine = false;
- this._addIndent();
- } else
- this.addSpace();
- this._addMappingIfNeeded(comment.pos);
- if (comment.type === "comment1")
- this._addText("//");
- else
- this._addText("/*");
- this._addText(comment.value);
- if (comment.type !== "comment1") {
- this._addText("*/");
- var position;
- while ((position = comment.value.indexOf("\n", position + 1)) !== -1)
- this._lineNumber += 1;
- }
- },
- _addText: function(text)
- {
- this._formattedContent.push(text);
- this._formattedContentLength += text.length;
- },
- _addMappingIfNeeded: function(originalPosition)
- {
- if (originalPosition - this._lastOriginalPosition === this._formattedContentLength - this._lastFormattedPosition)
- return;
- this._mapping.original.push(this._originalOffset + originalPosition);
- this._lastOriginalPosition = originalPosition;
- this._mapping.formatted.push(this._formattedOffset + this._formattedContentLength);
- this._lastFormattedPosition = this._formattedContentLength;
- }
- }
- var tokens = [
- ["EOS"],
- ["LPAREN", "("], ["RPAREN", ")"], ["LBRACK", "["], ["RBRACK", "]"], ["LBRACE", "{"], ["RBRACE", "}"], ["COLON", ":"], ["SEMICOLON", ";"], ["PERIOD", "."], ["CONDITIONAL", "?"],
- ["INC", "++"], ["DEC", "--"],
- ["ASSIGN", "="], ["ASSIGN_BIT_OR", "|="], ["ASSIGN_BIT_XOR", "^="], ["ASSIGN_BIT_AND", "&="], ["ASSIGN_SHL", "<<="], ["ASSIGN_SAR", ">>="], ["ASSIGN_SHR", ">>>="],
- ["ASSIGN_ADD", "+="], ["ASSIGN_SUB", "-="], ["ASSIGN_MUL", "*="], ["ASSIGN_DIV", "/="], ["ASSIGN_MOD", "%="],
- ["COMMA", ","], ["OR", "||"], ["AND", "&&"], ["BIT_OR", "|"], ["BIT_XOR", "^"], ["BIT_AND", "&"], ["SHL", "<<"], ["SAR", ">>"], ["SHR", ">>>"],
- ["ADD", "+"], ["SUB", "-"], ["MUL", "*"], ["DIV", "/"], ["MOD", "%"],
- ["EQ", "=="], ["NE", "!="], ["EQ_STRICT", "==="], ["NE_STRICT", "!=="], ["LT", "<"], ["GT", ">"], ["LTE", "<="], ["GTE", ">="],
- ["INSTANCEOF", "instanceof"], ["IN", "in"], ["NOT", "!"], ["BIT_NOT", "~"], ["DELETE", "delete"], ["TYPEOF", "typeof"], ["VOID", "void"],
- ["BREAK", "break"], ["CASE", "case"], ["CATCH", "catch"], ["CONTINUE", "continue"], ["DEBUGGER", "debugger"], ["DEFAULT", "default"], ["DO", "do"], ["ELSE", "else"], ["FINALLY", "finally"],
- ["FOR", "for"], ["FUNCTION", "function"], ["IF", "if"], ["NEW", "new"], ["RETURN", "return"], ["SWITCH", "switch"], ["THIS", "this"], ["THROW", "throw"], ["TRY", "try"], ["VAR", "var"],
- ["WHILE", "while"], ["WITH", "with"], ["NULL_LITERAL", "null"], ["TRUE_LITERAL", "true"], ["FALSE_LITERAL", "false"], ["NUMBER"], ["STRING"], ["IDENTIFIER"], ["CONST", "const"]
- ];
- var Tokens = {};
- for (var i = 0; i < tokens.length; ++i)
- Tokens[tokens[i][0]] = i;
- var TokensByValue = {};
- for (var i = 0; i < tokens.length; ++i) {
- if (tokens[i][1])
- TokensByValue[tokens[i][1]] = i;
- }
- var TokensByType = {
- "eof": Tokens.EOS,
- "name": Tokens.IDENTIFIER,
- "num": Tokens.NUMBER,
- "regexp": Tokens.DIV,
- "string": Tokens.STRING
- };
- function Tokenizer(content)
- {
- this._readNextToken = parse.tokenizer(content);
- this._state = this._readNextToken.context();
- }
- Tokenizer.prototype = {
- content: function()
- {
- return this._state.text;
- },
- next: function(forceRegexp)
- {
- var uglifyToken = this._readNextToken(forceRegexp);
- uglifyToken.endPos = this._state.pos;
- uglifyToken.endLine = this._state.line;
- uglifyToken.token = this._convertUglifyToken(uglifyToken);
- return uglifyToken;
- },
- _convertUglifyToken: function(uglifyToken)
- {
- var token = TokensByType[uglifyToken.type];
- if (typeof token === "number")
- return token;
- token = TokensByValue[uglifyToken.value];
- if (typeof token === "number")
- return token;
- throw "Unknown token type " + uglifyToken.type;
- }
- }
- function JavaScriptFormatter(tokenizer, builder)
- {
- this._tokenizer = tokenizer;
- this._builder = builder;
- this._token = null;
- this._nextToken = this._tokenizer.next();
- }
- JavaScriptFormatter.prototype = {
- format: function()
- {
- this._parseSourceElements(Tokens.EOS);
- this._consume(Tokens.EOS);
- },
- _peek: function()
- {
- return this._nextToken.token;
- },
- _next: function()
- {
- if (this._token && this._token.token === Tokens.EOS)
- throw "Unexpected EOS token";
- this._builder.addToken(this._nextToken);
- this._token = this._nextToken;
- this._nextToken = this._tokenizer.next(this._forceRegexp);
- this._forceRegexp = false;
- return this._token.token;
- },
- _consume: function(token)
- {
- var next = this._next();
- if (next !== token)
- throw "Unexpected token in consume: expected " + token + ", actual " + next;
- },
- _expect: function(token)
- {
- var next = this._next();
- if (next !== token)
- throw "Unexpected token: expected " + token + ", actual " + next;
- },
- _expectSemicolon: function()
- {
- if (this._peek() === Tokens.SEMICOLON)
- this._consume(Tokens.SEMICOLON);
- },
- _hasLineTerminatorBeforeNext: function()
- {
- return this._nextToken.nlb;
- },
- _parseSourceElements: function(endToken)
- {
- while (this._peek() !== endToken) {
- this._parseStatement();
- this._builder.addNewLine();
- }
- },
- _parseStatementOrBlock: function()
- {
- if (this._peek() === Tokens.LBRACE) {
- this._builder.addSpace();
- this._parseBlock();
- return true;
- }
- this._builder.addNewLine();
- this._builder.increaseNestingLevel();
- this._parseStatement();
- this._builder.decreaseNestingLevel();
- },
- _parseStatement: function()
- {
- switch (this._peek()) {
- case Tokens.LBRACE:
- return this._parseBlock();
- case Tokens.CONST:
- case Tokens.VAR:
- return this._parseVariableStatement();
- case Tokens.SEMICOLON:
- return this._next();
- case Tokens.IF:
- return this._parseIfStatement();
- case Tokens.DO:
- return this._parseDoWhileStatement();
- case Tokens.WHILE:
- return this._parseWhileStatement();
- case Tokens.FOR:
- return this._parseForStatement();
- case Tokens.CONTINUE:
- return this._parseContinueStatement();
- case Tokens.BREAK:
- return this._parseBreakStatement();
- case Tokens.RETURN:
- return this._parseReturnStatement();
- case Tokens.WITH:
- return this._parseWithStatement();
- case Tokens.SWITCH:
- return this._parseSwitchStatement();
- case Tokens.THROW:
- return this._parseThrowStatement();
- case Tokens.TRY:
- return this._parseTryStatement();
- case Tokens.FUNCTION:
- return this._parseFunctionDeclaration();
- case Tokens.DEBUGGER:
- return this._parseDebuggerStatement();
- default:
- return this._parseExpressionOrLabelledStatement();
- }
- },
- _parseFunctionDeclaration: function()
- {
- this._expect(Tokens.FUNCTION);
- this._builder.addSpace();
- this._expect(Tokens.IDENTIFIER);
- this._parseFunctionLiteral()
- },
- _parseBlock: function()
- {
- this._expect(Tokens.LBRACE);
- this._builder.addNewLine();
- this._builder.increaseNestingLevel();
- while (this._peek() !== Tokens.RBRACE) {
- this._parseStatement();
- this._builder.addNewLine();
- }
- this._builder.decreaseNestingLevel();
- this._expect(Tokens.RBRACE);
- },
- _parseVariableStatement: function()
- {
- this._parseVariableDeclarations();
- this._expectSemicolon();
- },
- _parseVariableDeclarations: function()
- {
- if (this._peek() === Tokens.VAR)
- this._consume(Tokens.VAR);
- else
- this._consume(Tokens.CONST)
- this._builder.addSpace();
- var isFirstVariable = true;
- do {
- if (!isFirstVariable) {
- this._consume(Tokens.COMMA);
- this._builder.addSpace();
- }
- isFirstVariable = false;
- this._expect(Tokens.IDENTIFIER);
- if (this._peek() === Tokens.ASSIGN) {
- this._builder.addSpace();
- this._consume(Tokens.ASSIGN);
- this._builder.addSpace();
- this._parseAssignmentExpression();
- }
- } while (this._peek() === Tokens.COMMA);
- },
- _parseExpressionOrLabelledStatement: function()
- {
- this._parseExpression();
- if (this._peek() === Tokens.COLON) {
- this._expect(Tokens.COLON);
- this._builder.addSpace();
- this._parseStatement();
- }
- this._expectSemicolon();
- },
- _parseIfStatement: function()
- {
- this._expect(Tokens.IF);
- this._builder.addSpace();
- this._expect(Tokens.LPAREN);
- this._parseExpression();
- this._expect(Tokens.RPAREN);
- var isBlock = this._parseStatementOrBlock();
- if (this._peek() === Tokens.ELSE) {
- if (isBlock)
- this._builder.addSpace();
- else
- this._builder.addNewLine();
- this._next();
- if (this._peek() === Tokens.IF) {
- this._builder.addSpace();
- this._parseStatement();
- } else
- this._parseStatementOrBlock();
- }
- },
- _parseContinueStatement: function()
- {
- this._expect(Tokens.CONTINUE);
- var token = this._peek();
- if (!this._hasLineTerminatorBeforeNext() && token !== Tokens.SEMICOLON && token !== Tokens.RBRACE && token !== Tokens.EOS) {
- this._builder.addSpace();
- this._expect(Tokens.IDENTIFIER);
- }
- this._expectSemicolon();
- },
- _parseBreakStatement: function()
- {
- this._expect(Tokens.BREAK);
- var token = this._peek();
- if (!this._hasLineTerminatorBeforeNext() && token !== Tokens.SEMICOLON && token !== Tokens.RBRACE && token !== Tokens.EOS) {
- this._builder.addSpace();
- this._expect(Tokens.IDENTIFIER);
- }
- this._expectSemicolon();
- },
- _parseReturnStatement: function()
- {
- this._expect(Tokens.RETURN);
- var token = this._peek();
- if (!this._hasLineTerminatorBeforeNext() && token !== Tokens.SEMICOLON && token !== Tokens.RBRACE && token !== Tokens.EOS) {
- this._builder.addSpace();
- this._parseExpression();
- }
- this._expectSemicolon();
- },
- _parseWithStatement: function()
- {
- this._expect(Tokens.WITH);
- this._builder.addSpace();
- this._expect(Tokens.LPAREN);
- this._parseExpression();
- this._expect(Tokens.RPAREN);
- this._parseStatementOrBlock();
- },
- _parseCaseClause: function()
- {
- if (this._peek() === Tokens.CASE) {
- this._expect(Tokens.CASE);
- this._builder.addSpace();
- this._parseExpression();
- } else
- this._expect(Tokens.DEFAULT);
- this._expect(Tokens.COLON);
- this._builder.addNewLine();
- this._builder.increaseNestingLevel();
- while (this._peek() !== Tokens.CASE && this._peek() !== Tokens.DEFAULT && this._peek() !== Tokens.RBRACE) {
- this._parseStatement();
- this._builder.addNewLine();
- }
- this._builder.decreaseNestingLevel();
- },
- _parseSwitchStatement: function()
- {
- this._expect(Tokens.SWITCH);
- this._builder.addSpace();
- this._expect(Tokens.LPAREN);
- this._parseExpression();
- this._expect(Tokens.RPAREN);
- this._builder.addSpace();
- this._expect(Tokens.LBRACE);
- this._builder.addNewLine();
- this._builder.increaseNestingLevel();
- while (this._peek() !== Tokens.RBRACE)
- this._parseCaseClause();
- this._builder.decreaseNestingLevel();
- this._expect(Tokens.RBRACE);
- },
- _parseThrowStatement: function()
- {
- this._expect(Tokens.THROW);
- this._builder.addSpace();
- this._parseExpression();
- this._expectSemicolon();
- },
- _parseTryStatement: function()
- {
- this._expect(Tokens.TRY);
- this._builder.addSpace();
- this._parseBlock();
- var token = this._peek();
- if (token === Tokens.CATCH) {
- this._builder.addSpace();
- this._consume(Tokens.CATCH);
- this._builder.addSpace();
- this._expect(Tokens.LPAREN);
- this._expect(Tokens.IDENTIFIER);
- this._expect(Tokens.RPAREN);
- this._builder.addSpace();
- this._parseBlock();
- token = this._peek();
- }
- if (token === Tokens.FINALLY) {
- this._consume(Tokens.FINALLY);
- this._builder.addSpace();
- this._parseBlock();
- }
- },
- _parseDoWhileStatement: function()
- {
- this._expect(Tokens.DO);
- var isBlock = this._parseStatementOrBlock();
- if (isBlock)
- this._builder.addSpace();
- else
- this._builder.addNewLine();
- this._expect(Tokens.WHILE);
- this._builder.addSpace();
- this._expect(Tokens.LPAREN);
- this._parseExpression();
- this._expect(Tokens.RPAREN);
- this._expectSemicolon();
- },
- _parseWhileStatement: function()
- {
- this._expect(Tokens.WHILE);
- this._builder.addSpace();
- this._expect(Tokens.LPAREN);
- this._parseExpression();
- this._expect(Tokens.RPAREN);
- this._parseStatementOrBlock();
- },
- _parseForStatement: function()
- {
- this._expect(Tokens.FOR);
- this._builder.addSpace();
- this._expect(Tokens.LPAREN);
- if (this._peek() !== Tokens.SEMICOLON) {
- if (this._peek() === Tokens.VAR || this._peek() === Tokens.CONST) {
- this._parseVariableDeclarations();
- if (this._peek() === Tokens.IN) {
- this._builder.addSpace();
- this._consume(Tokens.IN);
- this._builder.addSpace();
- this._parseExpression();
- }
- } else
- this._parseExpression();
- }
- if (this._peek() !== Tokens.RPAREN) {
- this._expect(Tokens.SEMICOLON);
- this._builder.addSpace();
- if (this._peek() !== Tokens.SEMICOLON)
- this._parseExpression();
- this._expect(Tokens.SEMICOLON);
- this._builder.addSpace();
- if (this._peek() !== Tokens.RPAREN)
- this._parseExpression();
- }
- this._expect(Tokens.RPAREN);
- this._parseStatementOrBlock();
- },
- _parseExpression: function()
- {
- this._parseAssignmentExpression();
- while (this._peek() === Tokens.COMMA) {
- this._expect(Tokens.COMMA);
- this._builder.addSpace();
- this._parseAssignmentExpression();
- }
- },
- _parseAssignmentExpression: function()
- {
- this._parseConditionalExpression();
- var token = this._peek();
- if (Tokens.ASSIGN <= token && token <= Tokens.ASSIGN_MOD) {
- this._builder.addSpace();
- this._next();
- this._builder.addSpace();
- this._parseAssignmentExpression();
- }
- },
- _parseConditionalExpression: function()
- {
- this._parseBinaryExpression();
- if (this._peek() === Tokens.CONDITIONAL) {
- this._builder.addSpace();
- this._consume(Tokens.CONDITIONAL);
- this._builder.addSpace();
- this._parseAssignmentExpression();
- this._builder.addSpace();
- this._expect(Tokens.COLON);
- this._builder.addSpace();
- this._parseAssignmentExpression();
- }
- },
- _parseBinaryExpression: function()
- {
- this._parseUnaryExpression();
- var token = this._peek();
- while (Tokens.OR <= token && token <= Tokens.IN) {
- this._builder.addSpace();
- this._next();
- this._builder.addSpace();
- this._parseBinaryExpression();
- token = this._peek();
- }
- },
- _parseUnaryExpression: function()
- {
- var token = this._peek();
- if ((Tokens.NOT <= token && token <= Tokens.VOID) || token === Tokens.ADD || token === Tokens.SUB || token === Tokens.INC || token === Tokens.DEC) {
- this._next();
- if (token === Tokens.DELETE || token === Tokens.TYPEOF || token === Tokens.VOID)
- this._builder.addSpace();
- this._parseUnaryExpression();
- } else
- return this._parsePostfixExpression();
- },
- _parsePostfixExpression: function()
- {
- this._parseLeftHandSideExpression();
- var token = this._peek();
- if (!this._hasLineTerminatorBeforeNext() && (token === Tokens.INC || token === Tokens.DEC))
- this._next();
- },
- _parseLeftHandSideExpression: function()
- {
- if (this._peek() === Tokens.NEW)
- this._parseNewExpression();
- else
- this._parseMemberExpression();
- while (true) {
- switch (this._peek()) {
- case Tokens.LBRACK:
- this._consume(Tokens.LBRACK);
- this._parseExpression();
- this._expect(Tokens.RBRACK);
- break;
- case Tokens.LPAREN:
- this._parseArguments();
- break;
- case Tokens.PERIOD:
- this._consume(Tokens.PERIOD);
- this._expect(Tokens.IDENTIFIER);
- break;
- default:
- return;
- }
- }
- },
- _parseNewExpression: function()
- {
- this._expect(Tokens.NEW);
- this._builder.addSpace();
- if (this._peek() === Tokens.NEW)
- this._parseNewExpression();
- else
- this._parseMemberExpression();
- },
- _parseMemberExpression: function()
- {
- if (this._peek() === Tokens.FUNCTION) {
- this._expect(Tokens.FUNCTION);
- if (this._peek() === Tokens.IDENTIFIER) {
- this._builder.addSpace();
- this._expect(Tokens.IDENTIFIER);
- }
- this._parseFunctionLiteral();
- } else
- this._parsePrimaryExpression();
- while (true) {
- switch (this._peek()) {
- case Tokens.LBRACK:
- this._consume(Tokens.LBRACK);
- this._parseExpression();
- this._expect(Tokens.RBRACK);
- break;
- case Tokens.PERIOD:
- this._consume(Tokens.PERIOD);
- this._expect(Tokens.IDENTIFIER);
- break;
- case Tokens.LPAREN:
- this._parseArguments();
- break;
- default:
- return;
- }
- }
- },
- _parseDebuggerStatement: function()
- {
- this._expect(Tokens.DEBUGGER);
- this._expectSemicolon();
- },
- _parsePrimaryExpression: function()
- {
- switch (this._peek()) {
- case Tokens.THIS:
- return this._consume(Tokens.THIS);
- case Tokens.NULL_LITERAL:
- return this._consume(Tokens.NULL_LITERAL);
- case Tokens.TRUE_LITERAL:
- return this._consume(Tokens.TRUE_LITERAL);
- case Tokens.FALSE_LITERAL:
- return this._consume(Tokens.FALSE_LITERAL);
- case Tokens.IDENTIFIER:
- return this._consume(Tokens.IDENTIFIER);
- case Tokens.NUMBER:
- return this._consume(Tokens.NUMBER);
- case Tokens.STRING:
- return this._consume(Tokens.STRING);
- case Tokens.ASSIGN_DIV:
- return this._parseRegExpLiteral();
- case Tokens.DIV:
- return this._parseRegExpLiteral();
- case Tokens.LBRACK:
- return this._parseArrayLiteral();
- case Tokens.LBRACE:
- return this._parseObjectLiteral();
- case Tokens.LPAREN:
- this._consume(Tokens.LPAREN);
- this._parseExpression();
- this._expect(Tokens.RPAREN);
- return;
- default:
- return this._next();
- }
- },
- _parseArrayLiteral: function()
- {
- this._expect(Tokens.LBRACK);
- this._builder.increaseNestingLevel();
- while (this._peek() !== Tokens.RBRACK) {
- if (this._peek() !== Tokens.COMMA)
- this._parseAssignmentExpression();
- if (this._peek() !== Tokens.RBRACK) {
- this._expect(Tokens.COMMA);
- this._builder.addSpace();
- }
- }
- this._builder.decreaseNestingLevel();
- this._expect(Tokens.RBRACK);
- },
- _parseObjectLiteralGetSet: function()
- {
- var token = this._peek();
- if (token === Tokens.IDENTIFIER || token === Tokens.NUMBER || token === Tokens.STRING ||
- Tokens.DELETE <= token && token <= Tokens.FALSE_LITERAL ||
- token === Tokens.INSTANCEOF || token === Tokens.IN || token === Tokens.CONST) {
- this._next();
- this._parseFunctionLiteral();
- }
- },
- _parseObjectLiteral: function()
- {
- this._expect(Tokens.LBRACE);
- this._builder.increaseNestingLevel();
- while (this._peek() !== Tokens.RBRACE) {
- var token = this._peek();
- switch (token) {
- case Tokens.IDENTIFIER:
- this._consume(Tokens.IDENTIFIER);
- var name = this._token.value;
- if ((name === "get" || name === "set") && this._peek() !== Tokens.COLON) {
- this._builder.addSpace();
- this._parseObjectLiteralGetSet();
- if (this._peek() !== Tokens.RBRACE) {
- this._expect(Tokens.COMMA);
- }
- continue;
- }
- break;
- case Tokens.STRING:
- this._consume(Tokens.STRING);
- break;
- case Tokens.NUMBER:
- this._consume(Tokens.NUMBER);
- break;
- default:
- this._next();
- }
- this._expect(Tokens.COLON);
- this._builder.addSpace();
- this._parseAssignmentExpression();
- if (this._peek() !== Tokens.RBRACE) {
- this._expect(Tokens.COMMA);
- }
- }
- this._builder.decreaseNestingLevel();
- this._expect(Tokens.RBRACE);
- },
- _parseRegExpLiteral: function()
- {
- if (this._nextToken.type === "regexp")
- this._next();
- else {
- this._forceRegexp = true;
- this._next();
- }
- },
- _parseArguments: function()
- {
- this._expect(Tokens.LPAREN);
- var done = (this._peek() === Tokens.RPAREN);
- while (!done) {
- this._parseAssignmentExpression();
- done = (this._peek() === Tokens.RPAREN);
- if (!done) {
- this._expect(Tokens.COMMA);
- this._builder.addSpace();
- }
- }
- this._expect(Tokens.RPAREN);
- },
- _parseFunctionLiteral: function()
- {
- this._expect(Tokens.LPAREN);
- var done = (this._peek() === Tokens.RPAREN);
- while (!done) {
- this._expect(Tokens.IDENTIFIER);
- done = (this._peek() === Tokens.RPAREN);
- if (!done) {
- this._expect(Tokens.COMMA);
- this._builder.addSpace();
- }
- }
- this._expect(Tokens.RPAREN);
- this._builder.addSpace();
- this._expect(Tokens.LBRACE);
- this._builder.addNewLine();
- this._builder.increaseNestingLevel();
- this._parseSourceElements(Tokens.RBRACE);
- this._builder.decreaseNestingLevel();
- this._expect(Tokens.RBRACE);
- }
- }
|