diff --git a/acorn.js b/acorn.js index ab23dcd278..97ccf2c993 100644 --- a/acorn.js +++ b/acorn.js @@ -43,8 +43,9 @@ input = String(inpt); inputLen = input.length; setOptions(opts); initTokenState(); + var startPos = options.locations ? [tokStart, new Position] : tokStart; initParserState(); - return parseTopLevel(options.program); + return parseTopLevel(options.program || startNodeAt(startPos)); }; // A second optional argument can be given to further configure @@ -214,6 +215,7 @@ input = String(inpt); inputLen = input.length; setOptions(opts); initTokenState(); + skipSpace(); function getToken(forceRegexp) { lastEnd = tokEnd; @@ -234,6 +236,9 @@ tokRegexpAllowed = reAllowed; skipSpace(); }; + getToken.noRegexp = function() { + tokRegexpAllowed = false; + }; getToken.options = options; return getToken; }; @@ -308,6 +313,7 @@ if (options.locations) lastEndLoc = new Position; inFunction = inGenerator = strict = false; labels = []; + skipSpace(); readToken(); } @@ -446,7 +452,8 @@ parenL: _parenL, parenR: _parenR, comma: _comma, semi: _semi, colon: _colon, dot: _dot, ellipsis: _ellipsis, question: _question, slash: _slash, eq: _eq, name: _name, eof: _eof, num: _num, regexp: _regexp, string: _string, - arrow: _arrow, bquote: _bquote, dollarBraceL: _dollarBraceL, star: _star}; + arrow: _arrow, bquote: _bquote, dollarBraceL: _dollarBraceL, star: _star, + assign: _assign}; for (var kw in keywordTypes) exports.tokTypes["_" + kw] = keywordTypes[kw]; // This is a trick taken from Esprima. It turns out that, on @@ -592,7 +599,6 @@ tokRegexpAllowed = true; metParenL = 0; inTemplate = false; - skipSpace(); } // Called at the end of every token. Sets `tokEnd`, `tokVal`, and @@ -1505,15 +1511,19 @@ // `program` argument. If present, the statements will be appended // to its body instead of creating a new node. - function parseTopLevel(program) { - var node = program || startNode(), first = true; - if (!program) node.body = []; + function parseTopLevel(node) { + var first = true; + if (!node.body) node.body = []; while (tokType !== _eof) { var stmt = parseStatement(); node.body.push(stmt); if (first && isUseStrict(stmt)) setStrict(true); first = false; } + + lastStart = tokStart; + lastEnd = tokEnd; + lastEndLoc = tokEndLoc; return finishNode(node, "Program"); } @@ -2062,7 +2072,7 @@ case _parenL: var start = storeCurrentPos(); - var tokStartLoc1 = tokStartLoc, tokStart1 = tokStart, val, exprList; + var val, exprList; next(); // check whether this is generator comprehension or regular expression if (options.ecmaVersion >= 7 && tokType === _for) { diff --git a/acorn_loose.js b/acorn_loose.js index 9b739da101..649aec6241 100644 --- a/acorn_loose.js +++ b/acorn_loose.js @@ -301,9 +301,11 @@ } function parseTopLevel() { - var node = startNode(); + var node = startNodeAt(options.locations ? [0, acorn.getLineInfo(input, 0)] : 0); node.body = []; while (token.type !== tt.eof) node.body.push(parseStatement()); + lastEnd = token.end; + lastEndLoc = token.endLoc; return finishNode(node, "Program"); } @@ -881,6 +883,7 @@ function parseIdent() { var node = startNode(); node.name = token.type === tt.name ? token.value : token.type.keyword; + fetchToken.noRegexp(); next(); return finishNode(node, "Identifier"); } diff --git a/test/run.js b/test/run.js index 04f752dc3b..e896397100 100644 --- a/test/run.js +++ b/test/run.js @@ -55,6 +55,7 @@ parse: (typeof require === "undefined" ? window.acorn : require("../acorn_loose")).parse_dammit, loose: true, filter: function (test) { + if (/`/.test(test.code)) return false; // FIXME remove this when the loose parse supports template strings var opts = test.options || {}; if (opts.loose === false) return false; return (opts.ecmaVersion || 5) <= 6; diff --git a/test/tests.js b/test/tests.js index f1d9467745..e50952826c 100644 --- a/test/tests.js +++ b/test/tests.js @@ -43,8 +43,8 @@ test("this\n", { column: 0 }, end: { - line: 1, - column: 4 + line: 2, + column: 0 } } }); @@ -86,8 +86,8 @@ test("null\n", { column: 0 }, end: { - line: 1, - column: 4 + line: 2, + column: 0 } } }); @@ -125,12 +125,12 @@ test("\n 42\n\n", { ], loc: { start: { - line: 2, - column: 4 + line: 1, + column: 0 }, end: { - line: 2, - column: 6 + line: 4, + column: 0 } } }); @@ -4916,7 +4916,7 @@ test("/* block comment */ 42", { loc: { start: { line: 1, - column: 20 + column: 0 }, end: { line: 1, @@ -4963,7 +4963,7 @@ test("42 /*The*/ /*Answer*/", { }, end: { line: 1, - column: 2 + column: 21 } } }); @@ -5006,7 +5006,7 @@ test("42 /*the*/ /*answer*/", { }, end: { line: 1, - column: 2 + column: 21 } } }); @@ -5044,8 +5044,8 @@ test("/* multiline\ncomment\nshould\nbe\nignored */ 42", { ], loc: { start: { - line: 5, - column: 11 + line: 1, + column: 0 }, end: { line: 5, @@ -5087,8 +5087,8 @@ test("/*a\r\nb*/ 42", { ], loc: { start: { - line: 2, - column: 4 + line: 1, + column: 0 }, end: { line: 2, @@ -5130,8 +5130,8 @@ test("/*a\rb*/ 42", { ], loc: { start: { - line: 2, - column: 4 + line: 1, + column: 0 }, end: { line: 2, @@ -5173,8 +5173,8 @@ test("/*a\nb*/ 42", { ], loc: { start: { - line: 2, - column: 4 + line: 1, + column: 0 }, end: { line: 2, @@ -5216,8 +5216,8 @@ test("/*a\nc*/ 42", { ], loc: { start: { - line: 2, - column: 4 + line: 1, + column: 0 }, end: { line: 2, @@ -5259,7 +5259,7 @@ test("// line comment\n42", { ], loc: { start: { - line: 2, + line: 1, column: 0 }, end: { @@ -5307,7 +5307,7 @@ test("42 // line comment", { }, end: { line: 1, - column: 2 + column: 18 } } }); @@ -5345,7 +5345,7 @@ test("// Hello, world!\n42", { ], loc: { start: { - line: 2, + line: 1, column: 0 }, end: { @@ -5360,7 +5360,7 @@ test("// Hello, world!\n", { body: [], loc: { start: { - line: 2, + line: 1, column: 0 }, end: { @@ -5375,7 +5375,7 @@ test("// Hallo, world!\n", { body: [], loc: { start: { - line: 2, + line: 1, column: 0 }, end: { @@ -5418,7 +5418,7 @@ test("//\n42", { ], loc: { start: { - line: 2, + line: 1, column: 0 }, end: { @@ -5434,7 +5434,7 @@ test("//", { loc: { start: { line: 1, - column: 2 + column: 0 }, end: { line: 1, @@ -5449,7 +5449,7 @@ test("// ", { loc: { start: { line: 1, - column: 3 + column: 0 }, end: { line: 1, @@ -5492,7 +5492,7 @@ test("/**/42", { loc: { start: { line: 1, - column: 4 + column: 0 }, end: { line: 1, @@ -5534,7 +5534,7 @@ test("// Hello, world!\n\n// Another hello\n42", { ], loc: { start: { - line: 4, + line: 1, column: 0 }, end: {