From 9bcd85acf3013cdadadc7d6e6a60795926723c56 Mon Sep 17 00:00:00 2001 From: Sven SAULEAU Date: Tue, 30 May 2017 20:12:43 +0200 Subject: [PATCH] feat: CallExpression support --- ast/spec.md | 1 + src/parser/expression.js | 10 ++ .../optional-chaining/function-call/actual.js | 2 + .../function-call/expected.json | 133 ++++++++++++++++++ 4 files changed, 146 insertions(+) create mode 100644 test/fixtures/experimental/optional-chaining/function-call/expected.json diff --git a/ast/spec.md b/ast/spec.md index 1dd5be0282..ce24b1e5df 100644 --- a/ast/spec.md +++ b/ast/spec.md @@ -897,6 +897,7 @@ interface CallExpression <: Expression { type: "CallExpression"; callee: Expression | Super | Import; arguments: [ Expression | SpreadElement ]; + optional: boolean | null; } ``` diff --git a/src/parser/expression.js b/src/parser/expression.js index 0ab2c501cd..30e459c3a0 100644 --- a/src/parser/expression.js +++ b/src/parser/expression.js @@ -316,6 +316,16 @@ export default class ExpressionParser extends LValParser { node.computed = true; this.expect(tt.bracketR); base = this.finishNode(node, "MemberExpression"); + } if (this.eat(tt.parenL)) { + const possibleAsync = this.state.potentialArrowAt === base.start && + base.type === "Identifier" && + base.name === "async" && + !this.canInsertSemicolon(); + + node.arguments = this.parseCallExpressionArguments(tt.parenR, possibleAsync); + node.optional = true; + + base = this.finishNode(node, "CallExpression"); } else { node.object = base; node.property = this.parseIdentifier(true); diff --git a/test/fixtures/experimental/optional-chaining/function-call/actual.js b/test/fixtures/experimental/optional-chaining/function-call/actual.js index 4488735365..7a5a8c001b 100644 --- a/test/fixtures/experimental/optional-chaining/function-call/actual.js +++ b/test/fixtures/experimental/optional-chaining/function-call/actual.js @@ -1 +1,3 @@ func?.() + +func?.(a, b) diff --git a/test/fixtures/experimental/optional-chaining/function-call/expected.json b/test/fixtures/experimental/optional-chaining/function-call/expected.json new file mode 100644 index 0000000000..60248b0e79 --- /dev/null +++ b/test/fixtures/experimental/optional-chaining/function-call/expected.json @@ -0,0 +1,133 @@ +{ + "type": "File", + "start": 0, + "end": 22, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 3, + "column": 12 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 22, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 3, + "column": 12 + } + }, + "sourceType": "script", + "body": [ + { + "type": "ExpressionStatement", + "start": 0, + "end": 8, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 8 + } + }, + "expression": { + "type": "CallExpression", + "start": 0, + "end": 8, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 8 + } + }, + "arguments": [], + "optional": true + } + }, + { + "type": "ExpressionStatement", + "start": 10, + "end": 22, + "loc": { + "start": { + "line": 3, + "column": 0 + }, + "end": { + "line": 3, + "column": 12 + } + }, + "expression": { + "type": "CallExpression", + "start": 10, + "end": 22, + "loc": { + "start": { + "line": 3, + "column": 0 + }, + "end": { + "line": 3, + "column": 12 + } + }, + "arguments": [ + { + "type": "Identifier", + "start": 17, + "end": 18, + "loc": { + "start": { + "line": 3, + "column": 7 + }, + "end": { + "line": 3, + "column": 8 + }, + "identifierName": "a" + }, + "name": "a" + }, + { + "type": "Identifier", + "start": 20, + "end": 21, + "loc": { + "start": { + "line": 3, + "column": 10 + }, + "end": { + "line": 3, + "column": 11 + }, + "identifierName": "b" + }, + "name": "b" + } + ], + "optional": true + } + } + ], + "directives": [] + } +} \ No newline at end of file