diff --git a/packages/new/src/index.js b/packages/new/src/index.js index 1ef743a..12710ab 100644 --- a/packages/new/src/index.js +++ b/packages/new/src/index.js @@ -12,10 +12,13 @@ export default { } env.node = node.argument; - // Change CALL_EXP to NewExpression (could be a nested member) + // Change CALL_EXP to NewExpression (could be a nested member, even within a call expr) let callNode = env.node; - while (callNode.type === 'MemberExpression') { - callNode = callNode.object; + while (callNode.type === jsep.MEMBER_EXP || ( + callNode.type === jsep.CALL_EXP && callNode.callee.type === jsep.MEMBER_EXP)) { + callNode = callNode.type === jsep.MEMBER_EXP + ? callNode.object + : callNode.callee.object; } callNode.type = 'NewExpression'; } diff --git a/packages/new/test/index.test.js b/packages/new/test/index.test.js index b883ea3..ec374e5 100644 --- a/packages/new/test/index.test.js +++ b/packages/new/test/index.test.js @@ -49,6 +49,68 @@ const { test } = QUnit; }, assert); }); + test('should parse multiple nested new expressions', (assert) => { + testParser('new Date(new Date().setDate(new Date().getDate() - 5))', { + type: 'NewExpression', + arguments: [ + { + type: 'CallExpression', + arguments: [ + { + type: 'BinaryExpression', + operator: '-', + left: { + type: 'CallExpression', + arguments: [], + callee: { + type: 'MemberExpression', + computed: false, + object: { + type: 'NewExpression', + arguments: [], + callee: { + type: 'Identifier', + name: 'Date' + } + }, + property: { + type: 'Identifier', + name: 'getDate' + } + } + }, + right: { + type: 'Literal', + value: 5, + raw: '5' + } + } + ], + callee: { + type: 'MemberExpression', + computed: false, + object: { + type: 'NewExpression', + arguments: [], + callee: { + type: 'Identifier', + name: 'Date' + } + }, + property: { + type: 'Identifier', + name: 'setDate' + } + } + } + ], + callee: { + type: 'Identifier', + name: 'Date' + } + }, assert); + }); + [ 'new A().b', 'new A()["b"].c + 2',