Permalink
Browse files

Fix wrong handling of relational expression in a for statement.

If operator 'in' is not allowed, it can not be just allowed within
the binary expression.

https://code.google.com/p/esprima/issues/detail?id=449
  • Loading branch information...
ariya committed Aug 29, 2013
1 parent 38b068d commit db275592e1837353a3906fd71d668dea8dd535b3
Showing with 206 additions and 10 deletions.
  1. +10 −10 esprima.js
  2. +196 −0 test/test.js
View
@@ -2193,11 +2193,14 @@ parseStatement: true, parseSourceElement: true */
}
function parseLeftHandSideExpressionAllowCall() {
- var marker, expr, args, property;
+ var marker, previousAllowIn, expr, args, property;
marker = createLocationMarker();
+ previousAllowIn = state.allowIn;
+ state.allowIn = true;
expr = matchKeyword('new') ? parseNewExpression() : parsePrimaryExpression();
+ state.allowIn = previousAllowIn;
while (match('.') || match('[') || match('(')) {
if (match('(')) {
@@ -2220,11 +2223,13 @@ parseStatement: true, parseSourceElement: true */
}
function parseLeftHandSideExpression() {
- var marker, expr, property;
+ var marker, previousAllowIn, expr, property;
marker = createLocationMarker();
+ previousAllowIn = state.allowIn;
expr = matchKeyword('new') ? parseNewExpression() : parsePrimaryExpression();
+ state.allowIn = previousAllowIn;
while (match('.') || match('[')) {
if (match('[')) {
@@ -2390,16 +2395,13 @@ parseStatement: true, parseSourceElement: true */
// 11.11 Binary Logical Operators
function parseBinaryExpression() {
- var marker, markers, expr, token, prec, previousAllowIn, stack, right, operator, left, i;
-
- previousAllowIn = state.allowIn;
- state.allowIn = true;
+ var marker, markers, expr, token, prec, stack, right, operator, left, i;
marker = createLocationMarker();
left = parseUnaryExpression();
token = lookahead;
- prec = binaryPrecedence(token, previousAllowIn);
+ prec = binaryPrecedence(token, state.allowIn);
if (prec === 0) {
return left;
}
@@ -2411,7 +2413,7 @@ parseStatement: true, parseSourceElement: true */
stack = [left, token, right];
- while ((prec = binaryPrecedence(lookahead, previousAllowIn)) > 0) {
+ while ((prec = binaryPrecedence(lookahead, state.allowIn)) > 0) {
// Reduce: make a binary expression from the three topmost entries.
while ((stack.length > 2) && (prec <= stack[stack.length - 2].prec)) {
@@ -2438,8 +2440,6 @@ parseStatement: true, parseSourceElement: true */
stack.push(expr);
}
- state.allowIn = previousAllowIn;
-
// Final reduce to clean-up the stack.
i = stack.length - 1;
expr = stack[i];
View
@@ -12758,6 +12758,202 @@ var testFixture = {
}
},
+ 'for (var x = y = z in q);': {
+ type: 'ForInStatement',
+ left: {
+ type: 'VariableDeclaration',
+ declarations: [{
+ type: 'VariableDeclarator',
+ id: {
+ type: 'Identifier',
+ name: 'x',
+ range: [9, 10],
+ loc: {
+ start: { line: 1, column: 9 },
+ end: { line: 1, column: 10 }
+ }
+ },
+ init: {
+ type: 'AssignmentExpression',
+ operator: '=',
+ left: {
+ type: 'Identifier',
+ name: 'y',
+ range: [13, 14],
+ loc: {
+ start: { line: 1, column: 13 },
+ end: { line: 1, column: 14 }
+ }
+ },
+ right: {
+ type: 'Identifier',
+ name: 'z',
+ range: [17, 18],
+ loc: {
+ start: { line: 1, column: 17 },
+ end: { line: 1, column: 18 }
+ }
+ },
+ range: [12, 18],
+ loc: {
+ start: { line: 1, column: 12 },
+ end: { line: 1, column: 18 }
+ }
+ },
+ range: [9, 18],
+ loc: {
+ start: { line: 1, column: 9 },
+ end: { line: 1, column: 18 }
+ }
+ }],
+ kind: 'var',
+ range: [5, 18],
+ loc: {
+ start: { line: 1, column: 5 },
+ end: { line: 1, column: 18 }
+ }
+ },
+ right: {
+ type: 'Identifier',
+ name: 'q',
+ range: [22, 23],
+ loc: {
+ start: { line: 1, column: 22 },
+ end: { line: 1, column: 23 }
+ }
+ },
+ body: {
+ type: 'EmptyStatement',
+ range: [24, 25],
+ loc: {
+ start: { line: 1, column: 24 },
+ end: { line: 1, column: 25 }
+ }
+ },
+ each: false,
+ range: [0, 25],
+ loc: {
+ start: { line: 1, column: 0 },
+ end: { line: 1, column: 25 }
+ }
+ },
+
+ 'for (var a = b = c = (d in e) in z);': {
+ type: 'ForInStatement',
+ left: {
+ type: 'VariableDeclaration',
+ declarations: [{
+ type: 'VariableDeclarator',
+ id: {
+ type: 'Identifier',
+ name: 'a',
+ range: [9, 10],
+ loc: {
+ start: { line: 1, column: 9 },
+ end: { line: 1, column: 10 }
+ }
+ },
+ init: {
+ type: 'AssignmentExpression',
+ operator: '=',
+ left: {
+ type: 'Identifier',
+ name: 'b',
+ range: [13, 14],
+ loc: {
+ start: { line: 1, column: 13 },
+ end: { line: 1, column: 14 }
+ }
+ },
+ right: {
+ type: 'AssignmentExpression',
+ operator: '=',
+ left: {
+ type: 'Identifier',
+ name: 'c',
+ range: [17, 18],
+ loc: {
+ start: { line: 1, column: 17 },
+ end: { line: 1, column: 18 }
+ }
+ },
+ right: {
+ type: 'BinaryExpression',
+ operator: 'in',
+ left: {
+ type: 'Identifier',
+ name: 'd',
+ range: [22, 23],
+ loc: {
+ start: { line: 1, column: 22 },
+ end: { line: 1, column: 23 }
+ }
+ },
+ right: {
+ type: 'Identifier',
+ name: 'e',
+ range: [27, 28],
+ loc: {
+ start: { line: 1, column: 27 },
+ end: { line: 1, column: 28 }
+ }
+ },
+ range: [22, 28],
+ loc: {
+ start: { line: 1, column: 22 },
+ end: { line: 1, column: 28 }
+ }
+ },
+ range: [16, 29],
+ loc: {
+ start: { line: 1, column: 16 },
+ end: { line: 1, column: 29 }
+ }
+ },
+ range: [12, 29],
+ loc: {
+ start: { line: 1, column: 12 },
+ end: { line: 1, column: 29 }
+ }
+ },
+ range: [9, 29],
+ loc: {
+ start: { line: 1, column: 9 },
+ end: { line: 1, column: 29 }
+ }
+ }],
+ kind: 'var',
+ range: [5, 29],
+ loc: {
+ start: { line: 1, column: 5 },
+ end: { line: 1, column: 29 }
+ }
+ },
+ right: {
+ type: 'Identifier',
+ name: 'z',
+ range: [33, 34],
+ loc: {
+ start: { line: 1, column: 33 },
+ end: { line: 1, column: 34 }
+ }
+ },
+ body: {
+ type: 'EmptyStatement',
+ range: [35, 36],
+ loc: {
+ start: { line: 1, column: 35 },
+ end: { line: 1, column: 36 }
+ }
+ },
+ each: false,
+ range: [0, 36],
+ loc: {
+ start: { line: 1, column: 0 },
+ end: { line: 1, column: 36 }
+ }
+ },
+
'for (var i = function() { return 10 in [] } in list) process(x);': {
type: 'ForInStatement',
left: {

0 comments on commit db27559

Please sign in to comment.