Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Change member expression parsing.

Because of the nature of brackets like [] and (), we can't use run-time
patching to capture the position before and after some member expression
parsing routines. The solution is to create a specialized version when
we need to track the syntax node location.

Coverage regression is expected (temporarily) until variation in the
parsing options when running the test suite gets implemented.

http://code.google.com/p/esprima/issues/detail?id=324
http://code.google.com/p/esprima/issues/detail?id=343
  • Loading branch information...
commit 8f3fdb953b00fa9f60e44a9d832c77c2e63cacf2 1 parent 1f72370
@ariya authored
Showing with 225 additions and 72 deletions.
  1. +144 −71 esprima.js
  2. +81 −1 test/test.js
View
215 esprima.js
@@ -1590,36 +1590,22 @@ parseStatement: true, parseSourceElement: true */
};
}
- function parseNonComputedMember(object) {
- return {
- type: Syntax.MemberExpression,
- computed: false,
- object: object,
- property: parseNonComputedProperty()
- };
+ function parseNonComputedMember() {
+ expect('.');
+
+ return parseNonComputedProperty();
}
- function parseComputedMember(object) {
- var property, expr;
+ function parseComputedMember() {
+ var expr;
expect('[');
- property = parseExpression();
- expr = {
- type: Syntax.MemberExpression,
- computed: true,
- object: object,
- property: property
- };
+
+ expr = parseExpression();
+
expect(']');
- return expr;
- }
- function parseCallMember(object) {
- return {
- type: Syntax.CallExpression,
- callee: object,
- 'arguments': parseArguments()
- };
+ return expr;
}
function parseNewExpression() {
@@ -1641,41 +1627,58 @@ parseStatement: true, parseSourceElement: true */
}
function parseLeftHandSideExpressionAllowCall() {
- var useNew, expr;
+ var expr;
- useNew = matchKeyword('new');
- expr = useNew ? parseNewExpression() : parsePrimaryExpression();
+ expr = matchKeyword('new') ? parseNewExpression() : parsePrimaryExpression();
- while (index < length) {
- if (match('.')) {
- lex();
- expr = parseNonComputedMember(expr);
+ while (match('.') || match('[') || match('(')) {
+ if (match('(')) {
+ expr = {
+ type: Syntax.CallExpression,
+ callee: expr,
+ 'arguments': parseArguments()
+ };
} else if (match('[')) {
- expr = parseComputedMember(expr);
- } else if (match('(')) {
- expr = parseCallMember(expr);
+ expr = {
+ type: Syntax.MemberExpression,
+ computed: true,
+ object: expr,
+ property: parseComputedMember()
+ };
} else {
- break;
+ expr = {
+ type: Syntax.MemberExpression,
+ computed: false,
+ object: expr,
+ property: parseNonComputedMember()
+ };
}
}
return expr;
}
+
function parseLeftHandSideExpression() {
- var useNew, expr;
+ var expr;
- useNew = matchKeyword('new');
- expr = useNew ? parseNewExpression() : parsePrimaryExpression();
+ expr = matchKeyword('new') ? parseNewExpression() : parsePrimaryExpression();
- while (index < length) {
- if (match('.')) {
- lex();
- expr = parseNonComputedMember(expr);
- } else if (match('[')) {
- expr = parseComputedMember(expr);
+ while (match('.') || match('[')) {
+ if (match('[')) {
+ expr = {
+ type: Syntax.MemberExpression,
+ computed: true,
+ object: expr,
+ property: parseComputedMember()
+ };
} else {
- break;
+ expr = {
+ type: Syntax.MemberExpression,
+ computed: false,
+ object: expr,
+ property: parseNonComputedMember()
+ };
}
}
@@ -3378,16 +3381,99 @@ parseStatement: true, parseSourceElement: true */
marker.apply = function (node) {
if (extra.range) {
- node.range = this.range;
+ node.range = [this.range[0], this.range[1]];
}
if (extra.loc) {
- node.loc = this.loc;
+ node.loc = {
+ start: {
+ line: this.loc.start.line,
+ column: this.loc.start.column
+ },
+ end: {
+ line: this.loc.end.line,
+ column: this.loc.end.column
+ }
+ };
}
};
return marker;
}
+ function trackLeftHandSideExpression() {
+ var marker, expr;
+
+ skipComment();
+ marker = createLocationMarker();
+
+ expr = matchKeyword('new') ? parseNewExpression() : parsePrimaryExpression();
+
+ while (match('.') || match('[')) {
+ if (match('[')) {
+ expr = {
+ type: Syntax.MemberExpression,
+ computed: true,
+ object: expr,
+ property: parseComputedMember()
+ };
+ marker.end();
+ marker.apply(expr);
+ } else {
+ expr = {
+ type: Syntax.MemberExpression,
+ computed: false,
+ object: expr,
+ property: parseNonComputedMember()
+ };
+ marker.end();
+ marker.apply(expr);
+ }
+ }
+
+ return expr;
+ }
+
+ function trackLeftHandSideExpressionAllowCall() {
+ var marker, expr;
+
+ skipComment();
+ marker = createLocationMarker();
+
+ expr = matchKeyword('new') ? parseNewExpression() : parsePrimaryExpression();
+
+ while (match('.') || match('[') || match('(')) {
+ if (match('(')) {
+ expr = {
+ type: Syntax.CallExpression,
+ callee: expr,
+ 'arguments': parseArguments()
+ };
+ marker.end();
+ marker.apply(expr);
+ } else if (match('[')) {
+ expr = {
+ type: Syntax.MemberExpression,
+ computed: true,
+ object: expr,
+ property: parseComputedMember()
+ };
+ marker.end();
+ marker.apply(expr);
+ } else {
+ expr = {
+ type: Syntax.MemberExpression,
+ computed: false,
+ object: expr,
+ property: parseNonComputedMember()
+ };
+ marker.end();
+ marker.apply(expr);
+ }
+ }
+
+ return expr;
+ }
+
function wrapTrackingFunction(range, loc) {
return function (parseFunction) {
@@ -3437,24 +3523,6 @@ parseStatement: true, parseSourceElement: true */
visit(node);
}
- if (node.type === Syntax.MemberExpression) {
- if (typeof node.object.range !== 'undefined') {
- node.range[0] = node.object.range[0];
- }
- if (typeof node.object.loc !== 'undefined') {
- node.loc.start = node.object.loc.start;
- }
- }
-
- if (node.type === Syntax.CallExpression) {
- if (typeof node.callee.range !== 'undefined') {
- node.range[0] = node.callee.range[0];
- }
- if (typeof node.callee.loc !== 'undefined') {
- node.loc.start = node.callee.loc.start;
- }
- }
-
return node;
};
};
@@ -3476,6 +3544,11 @@ parseStatement: true, parseSourceElement: true */
if (extra.range || extra.loc) {
+ extra.parseLeftHandSideExpression = parseLeftHandSideExpression;
+ extra.parseLeftHandSideExpressionAllowCall = parseLeftHandSideExpressionAllowCall;
+ parseLeftHandSideExpression = trackLeftHandSideExpression;
+ parseLeftHandSideExpressionAllowCall = trackLeftHandSideExpressionAllowCall;
+
wrapTracking = wrapTrackingFunction(extra.range, extra.loc);
extra.parseAdditiveExpression = parseAdditiveExpression;
@@ -3485,7 +3558,6 @@ parseStatement: true, parseSourceElement: true */
extra.parseBitwiseXORExpression = parseBitwiseXORExpression;
extra.parseBlock = parseBlock;
extra.parseFunctionSourceElements = parseFunctionSourceElements;
- extra.parseCallMember = parseCallMember;
extra.parseCatchClause = parseCatchClause;
extra.parseComputedMember = parseComputedMember;
extra.parseConditionalExpression = parseConditionalExpression;
@@ -3495,11 +3567,12 @@ parseStatement: true, parseSourceElement: true */
extra.parseForVariableDeclaration = parseForVariableDeclaration;
extra.parseFunctionDeclaration = parseFunctionDeclaration;
extra.parseFunctionExpression = parseFunctionExpression;
+ extra.parseLeftHandSideExpression = parseLeftHandSideExpression;
+ extra.parseLeftHandSideExpressionAllowCall = parseLeftHandSideExpressionAllowCall;
extra.parseLogicalANDExpression = parseLogicalANDExpression;
extra.parseLogicalORExpression = parseLogicalORExpression;
extra.parseMultiplicativeExpression = parseMultiplicativeExpression;
extra.parseNewExpression = parseNewExpression;
- extra.parseNonComputedMember = parseNonComputedMember;
extra.parseNonComputedProperty = parseNonComputedProperty;
extra.parseObjectProperty = parseObjectProperty;
extra.parseObjectPropertyKey = parseObjectPropertyKey;
@@ -3522,7 +3595,6 @@ parseStatement: true, parseSourceElement: true */
parseBitwiseXORExpression = wrapTracking(extra.parseBitwiseXORExpression);
parseBlock = wrapTracking(extra.parseBlock);
parseFunctionSourceElements = wrapTracking(extra.parseFunctionSourceElements);
- parseCallMember = wrapTracking(extra.parseCallMember);
parseCatchClause = wrapTracking(extra.parseCatchClause);
parseComputedMember = wrapTracking(extra.parseComputedMember);
parseConditionalExpression = wrapTracking(extra.parseConditionalExpression);
@@ -3532,11 +3604,12 @@ parseStatement: true, parseSourceElement: true */
parseForVariableDeclaration = wrapTracking(extra.parseForVariableDeclaration);
parseFunctionDeclaration = wrapTracking(extra.parseFunctionDeclaration);
parseFunctionExpression = wrapTracking(extra.parseFunctionExpression);
+ parseLeftHandSideExpression = wrapTracking(parseLeftHandSideExpression);
+ parseLeftHandSideExpressionAllowCall = wrapTracking(parseLeftHandSideExpressionAllowCall);
parseLogicalANDExpression = wrapTracking(extra.parseLogicalANDExpression);
parseLogicalORExpression = wrapTracking(extra.parseLogicalORExpression);
parseMultiplicativeExpression = wrapTracking(extra.parseMultiplicativeExpression);
parseNewExpression = wrapTracking(extra.parseNewExpression);
- parseNonComputedMember = wrapTracking(extra.parseNonComputedMember);
parseNonComputedProperty = wrapTracking(extra.parseNonComputedProperty);
parseObjectProperty = wrapTracking(extra.parseObjectProperty);
parseObjectPropertyKey = wrapTracking(extra.parseObjectPropertyKey);
@@ -3579,7 +3652,6 @@ parseStatement: true, parseSourceElement: true */
parseBitwiseXORExpression = extra.parseBitwiseXORExpression;
parseBlock = extra.parseBlock;
parseFunctionSourceElements = extra.parseFunctionSourceElements;
- parseCallMember = extra.parseCallMember;
parseCatchClause = extra.parseCatchClause;
parseComputedMember = extra.parseComputedMember;
parseConditionalExpression = extra.parseConditionalExpression;
@@ -3589,11 +3661,12 @@ parseStatement: true, parseSourceElement: true */
parseForVariableDeclaration = extra.parseForVariableDeclaration;
parseFunctionDeclaration = extra.parseFunctionDeclaration;
parseFunctionExpression = extra.parseFunctionExpression;
+ parseLeftHandSideExpression = extra.parseLeftHandSideExpression;
+ parseLeftHandSideExpressionAllowCall = extra.parseLeftHandSideExpressionAllowCall;
parseLogicalANDExpression = extra.parseLogicalANDExpression;
parseLogicalORExpression = extra.parseLogicalORExpression;
parseMultiplicativeExpression = extra.parseMultiplicativeExpression;
parseNewExpression = extra.parseNewExpression;
- parseNonComputedMember = extra.parseNonComputedMember;
parseNonComputedProperty = extra.parseNonComputedProperty;
parseObjectProperty = extra.parseObjectProperty;
parseObjectPropertyKey = extra.parseObjectPropertyKey;
View
82 test/test.js
@@ -5147,7 +5147,6 @@ var testFixture = {
}
},
-
'new foo.bar()': {
type: 'ExpressionStatement',
expression: {
@@ -5193,6 +5192,60 @@ var testFixture = {
}
},
+ '( new foo).bar()': {
+ type: 'ExpressionStatement',
+ expression: {
+ type: 'CallExpression',
+ callee: {
+ type: 'MemberExpression',
+ computed: false,
+ object: {
+ type: 'NewExpression',
+ callee: {
+ type: 'Identifier',
+ name: 'foo',
+ range: [6, 9],
+ loc: {
+ start: { line: 1, column: 6 },
+ end: { line: 1, column: 9 }
+ }
+ },
+ 'arguments': [],
+ range: [2, 9],
+ loc: {
+ start: { line: 1, column: 2 },
+ end: { line: 1, column: 9 }
+ }
+ },
+ property: {
+ type: 'Identifier',
+ name: 'bar',
+ range: [11, 14],
+ loc: {
+ start: { line: 1, column: 11 },
+ end: { line: 1, column: 14 }
+ }
+ },
+ range: [0, 14],
+ loc: {
+ start: { line: 1, column: 0 },
+ end: { line: 1, column: 14 }
+ }
+ },
+ 'arguments': [],
+ range: [0, 16],
+ loc: {
+ start: { line: 1, column: 0 },
+ end: { line: 1, column: 16 }
+ }
+ },
+ range: [0, 16],
+ loc: {
+ start: { line: 1, column: 0 },
+ end: { line: 1, column: 16 }
+ }
+ },
+
'foo(bar, baz)': {
type: 'ExpressionStatement',
expression: {
@@ -5236,6 +5289,33 @@ var testFixture = {
}
},
+ '( foo )()': {
+ type: 'ExpressionStatement',
+ expression: {
+ type: 'CallExpression',
+ callee: {
+ type: 'Identifier',
+ name: 'foo',
+ range: [5, 8],
+ loc: {
+ start: { line: 1, column: 5 },
+ end: { line: 1, column: 8 }
+ }
+ },
+ 'arguments': [],
+ range: [0, 13],
+ loc: {
+ start: { line: 1, column: 0 },
+ end: { line: 1, column: 13 }
+ }
+ },
+ range: [0, 13],
+ loc: {
+ start: { line: 1, column: 0 },
+ end: { line: 1, column: 13 }
+ }
+ },
+
'universe.milkyway': {
type: 'ExpressionStatement',
expression: {
Please sign in to comment.
Something went wrong with that request. Please try again.