Make locations in loose parser consistent with those in regular parser

Issue #136
This commit is contained in:
Marijn Haverbeke 2014-10-08 12:35:57 +02:00
parent 3603f7d0b1
commit bdee9e8195
2 changed files with 44 additions and 26 deletions

View File

@ -1252,6 +1252,8 @@
start = pos[0];
}
node.start = start;
if (options.directSourceFile)
node.sourceFile = options.directSourceFile;
if (options.ranges)
node.range = [start, 0];

View File

@ -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);