diff --git a/acorn.js b/acorn.js index 8b5cb15aed..f1872f4419 100644 --- a/acorn.js +++ b/acorn.js @@ -1252,6 +1252,8 @@ start = pos[0]; } node.start = start; + if (options.directSourceFile) + node.sourceFile = options.directSourceFile; if (options.ranges) node.range = [start, 0]; diff --git a/acorn_loose.js b/acorn_loose.js index c6b7f46bce..634479280c 100644 --- a/acorn_loose.js +++ b/acorn_loose.js @@ -212,10 +212,20 @@ return node; } - function startNodeFrom(other) { - var node = new Node(other.start); - if (options.locations) - node.loc = new SourceLocation(other.loc.start); + function storeCurrentPos() { + return options.locations ? [token.start, token.startLoc] : token.start; + } + + function startNodeAt(pos) { + var node; + if (options.locations) { + node = new Node(pos[0]); + node.loc = new SourceLocation(pos[1]); + } else { + node = new Node(pos); + } + if (options.directSourceFile) + node.sourceFile = options.directSourceFile; return node; } @@ -399,7 +409,6 @@ case tt._var: next(); node = parseVar(node); - semicolon(); return node; case tt._while: @@ -487,13 +496,15 @@ decl.id = dummyIdent(); node.declarations.push(finishNode(decl, "VariableDeclarator")); } + if (!noIn) semicolon(); return finishNode(node, "VariableDeclaration"); } function parseExpression(noComma, noIn) { + var start = storeCurrentPos(); var expr = parseMaybeAssign(noIn); if (!noComma && token.type === tt.comma) { - var node = startNodeFrom(expr); + var node = startNodeAt(start); node.expressions = [expr]; while (eat(tt.comma)) node.expressions.push(parseMaybeAssign(noIn)); return finishNode(node, "SequenceExpression"); @@ -511,9 +522,10 @@ } function parseMaybeAssign(noIn) { + var start = storeCurrentPos(); var left = parseMaybeConditional(noIn); if (token.type.isAssign) { - var node = startNodeFrom(left); + var node = startNodeAt(start); node.operator = token.value; node.left = checkLVal(left); next(); @@ -524,9 +536,10 @@ } function parseMaybeConditional(noIn) { + var start = storeCurrentPos(); var expr = parseExprOps(noIn); if (eat(tt.question)) { - var node = startNodeFrom(expr); + var node = startNodeAt(start); node.test = expr; node.consequent = parseExpression(true); node.alternate = expect(tt.colon) ? parseExpression(true, noIn) : dummyIdent(); @@ -536,25 +549,28 @@ } function parseExprOps(noIn) { + var start = storeCurrentPos(); var indent = curIndent, line = curLineStart; - return parseExprOp(parseMaybeUnary(noIn), -1, noIn, indent, line); + return parseExprOp(parseMaybeUnary(noIn), start, -1, noIn, indent, line); } - function parseExprOp(left, minPrec, noIn, indent, line) { + function parseExprOp(left, start, minPrec, noIn, indent, line) { if (curLineStart != line && curIndent < indent && tokenStartsLine()) return left; var prec = token.type.binop; if (prec != null && (!noIn || token.type !== tt._in)) { if (prec > minPrec) { - var node = startNodeFrom(left); + var node = startNodeAt(start); node.left = left; node.operator = token.value; next(); - if (curLineStart != line && curIndent < indent && tokenStartsLine()) + if (curLineStart != line && curIndent < indent && tokenStartsLine()) { node.right = dummyIdent(); - else - node.right = parseExprOp(parseMaybeUnary(noIn), prec, noIn, indent, line); - var node = finishNode(node, /&&|\|\|/.test(node.operator) ? "LogicalExpression" : "BinaryExpression"); - return parseExprOp(node, minPrec, noIn, indent, line); + } else { + var rightStart = storeCurrentPos(); + node.right = parseExprOp(parseMaybeUnary(noIn), rightStart, prec, noIn, indent, line); + } + finishNode(node, /&&|\|\|/.test(node.operator) ? "LogicalExpression" : "BinaryExpression"); + return parseExprOp(node, start, minPrec, noIn, indent, line); } } return left; @@ -570,9 +586,10 @@ if (update) node.argument = checkLVal(node.argument); return finishNode(node, update ? "UpdateExpression" : "UnaryExpression"); } + var start = storeCurrentPos(); var expr = parseExprSubscripts(); while (token.type.postfix && !canInsertSemicolon()) { - var node = startNodeFrom(expr); + var node = startNodeAt(start); node.operator = token.value; node.prefix = false; node.argument = checkLVal(expr); @@ -583,10 +600,11 @@ } function parseExprSubscripts() { - return parseSubscripts(parseExprAtom(), false, curIndent, curLineStart); + var start = storeCurrentPos(); + return parseSubscripts(parseExprAtom(), start, false, curIndent, curLineStart); } - function parseSubscripts(base, noCalls, startIndent, line) { + function parseSubscripts(base, start, noCalls, startIndent, line) { for (;;) { if (curLineStart != line && curIndent <= startIndent && tokenStartsLine()) { if (token.type == tt.dot && curIndent == startIndent) @@ -596,7 +614,7 @@ } if (eat(tt.dot)) { - var node = startNodeFrom(base); + var node = startNodeAt(start); node.object = base; if (curLineStart != line && curIndent <= startIndent && tokenStartsLine()) node.property = dummyIdent(); @@ -607,7 +625,7 @@ } else if (token.type == tt.bracketL) { pushCx(); next(); - var node = startNodeFrom(base); + var node = startNodeAt(start); node.object = base; node.property = parseExpression(); node.computed = true; @@ -616,7 +634,7 @@ base = finishNode(node, "MemberExpression"); } else if (!noCalls && token.type == tt.parenL) { pushCx(); - var node = startNodeFrom(base); + var node = startNodeAt(start); node.callee = base; node.arguments = parseExprList(tt.parenR); base = finishNode(node, "CallExpression"); @@ -649,11 +667,8 @@ return finishNode(node, "Literal"); case tt.parenL: - var tokStart1 = token.start; next(); var val = parseExpression(); - val.start = tokStart1; - val.end = token.end; expect(tt.parenR); return val; @@ -682,7 +697,8 @@ function parseNew() { var node = startNode(), startIndent = curIndent, line = curLineStart; next(); - node.callee = parseSubscripts(parseExprAtom(), true, startIndent, line); + var start = storeCurrentPos(); + node.callee = parseSubscripts(parseExprAtom(), start, true, startIndent, line); if (token.type == tt.parenL) { pushCx(); node.arguments = parseExprList(tt.parenR);