diff --git a/src/parser/expression.js b/src/parser/expression.js index 0941a6b587..e78b8955f1 100644 --- a/src/parser/expression.js +++ b/src/parser/expression.js @@ -302,18 +302,23 @@ export default class ExpressionParser extends LValParser { node.callee = this.parseNoCallExpr(); return this.parseSubscripts(this.finishNode(node, "BindExpression"), startPos, startLoc, noCalls); - } else if (this.eat(tt.questionDot)) { - const node = this.startNodeAt(startPos, startLoc); - + } else if (this.match(tt.questionDot)) { if (!this.hasPlugin("optionalChaining")) { - this.raise(node.start, "You can only use optional-chaining when the 'optionalChaining' plugin is enabled."); + this.raise(startPos, "You can only use optional-chaining when the 'optionalChaining' plugin is enabled."); + } + + if (noCalls && this.lookahead().type == tt.parenL) { + return base; } + this.next(); + + const node = this.startNodeAt(startPos, startLoc); if (this.eat(tt.bracketL)) { node.object = base; - node.optional = true; node.property = this.parseExpression(); node.computed = true; + node.optional = true; this.expect(tt.bracketR); base = this.finishNode(node, "MemberExpression"); } else if (this.eat(tt.parenL)) { @@ -322,6 +327,7 @@ export default class ExpressionParser extends LValParser { base.name === "async" && !this.canInsertSemicolon(); + node.callee = base; node.arguments = this.parseCallExpressionArguments(tt.parenR, possibleAsync); node.optional = true; @@ -329,8 +335,8 @@ export default class ExpressionParser extends LValParser { } else { node.object = base; node.property = this.parseIdentifier(true); - node.optional = true; node.computed = false; + node.optional = true; base = this.finishNode(node, "MemberExpression"); } } else if (this.eat(tt.dot)) { @@ -768,6 +774,7 @@ export default class ExpressionParser extends LValParser { } node.callee = this.parseNoCallExpr(); + const optional = this.eat(tt.questionDot); if (this.eat(tt.parenL)) { node.arguments = this.parseExprList(tt.parenR); @@ -775,6 +782,9 @@ export default class ExpressionParser extends LValParser { } else { node.arguments = []; } + if (optional) { + node.optional = true; + } return this.finishNode(node, "NewExpression"); } diff --git a/src/tokenizer/index.js b/src/tokenizer/index.js index 538597df3a..460538f838 100644 --- a/src/tokenizer/index.js +++ b/src/tokenizer/index.js @@ -428,11 +428,11 @@ export default class Tokenizer extends LocationParser { readToken_question() { // '?' const next = this.input.charCodeAt(this.state.pos + 1); - if (next === 46) { // '.' + const next2 = this.input.charCodeAt(this.state.pos + 2); + if (next === 46 && !(next2 >= 48 && next2 <= 57)) { // '.' not followed by a number this.state.pos += 2; return this.finishToken(tt.questionDot); - } - else { + } else { ++this.state.pos; return this.finishToken(tt.question); } diff --git a/test/fixtures/experimental/optional-chaining/class-contructor-call/actual.js b/test/fixtures/experimental/optional-chaining/class-contructor-call/actual.js index e08331157e..8cefe81821 100644 --- a/test/fixtures/experimental/optional-chaining/class-contructor-call/actual.js +++ b/test/fixtures/experimental/optional-chaining/class-contructor-call/actual.js @@ -1,3 +1,9 @@ new C?.() new C?.(a, b) + +new B?.C?.() + +new B?.C?.(a, b) + +new B?.C diff --git a/test/fixtures/experimental/optional-chaining/class-contructor-call/expected.json b/test/fixtures/experimental/optional-chaining/class-contructor-call/expected.json index 38e9ba308e..cd91d5b86e 100644 --- a/test/fixtures/experimental/optional-chaining/class-contructor-call/expected.json +++ b/test/fixtures/experimental/optional-chaining/class-contructor-call/expected.json @@ -1,29 +1,29 @@ { "type": "File", "start": 0, - "end": 24, + "end": 66, "loc": { "start": { "line": 1, "column": 0 }, "end": { - "line": 3, - "column": 13 + "line": 9, + "column": 8 } }, "program": { "type": "Program", "start": 0, - "end": 24, + "end": 66, "loc": { "start": { "line": 1, "column": 0 }, "end": { - "line": 3, - "column": 13 + "line": 9, + "column": 8 } }, "sourceType": "script", @@ -107,24 +107,342 @@ }, "callee": { "type": "Identifier", - "start": 4, - "end": 5, + "start": 15, + "end": 16, "loc": { "start": { - "line": 1, + "line": 3, "column": 4 }, "end": { - "line": 1, + "line": 3, "column": 5 }, "identifierName": "C" }, "name": "C" }, + "arguments": [ + { + "type": "Identifier", + "start": 19, + "end": 20, + "loc": { + "start": { + "line": 3, + "column": 8 + }, + "end": { + "line": 3, + "column": 9 + }, + "identifierName": "a" + }, + "name": "a" + }, + { + "type": "Identifier", + "start": 22, + "end": 23, + "loc": { + "start": { + "line": 3, + "column": 11 + }, + "end": { + "line": 3, + "column": 12 + }, + "identifierName": "b" + }, + "name": "b" + } + ], + "optional": true + } + }, + { + "type": "ExpressionStatement", + "start": 26, + "end": 38, + "loc": { + "start": { + "line": 5, + "column": 0 + }, + "end": { + "line": 5, + "column": 12 + } + }, + "expression": { + "type": "NewExpression", + "start": 26, + "end": 38, + "loc": { + "start": { + "line": 5, + "column": 0 + }, + "end": { + "line": 5, + "column": 12 + } + }, + "callee": { + "type": "MemberExpression", + "start": 30, + "end": 34, + "loc": { + "start": { + "line": 5, + "column": 4 + }, + "end": { + "line": 5, + "column": 8 + } + }, + "object": { + "type": "Identifier", + "start": 30, + "end": 31, + "loc": { + "start": { + "line": 5, + "column": 4 + }, + "end": { + "line": 5, + "column": 5 + }, + "identifierName": "B" + }, + "name": "B" + }, + "optional": true, + "property": { + "type": "Identifier", + "start": 33, + "end": 34, + "loc": { + "start": { + "line": 5, + "column": 7 + }, + "end": { + "line": 5, + "column": 8 + }, + "identifierName": "C" + }, + "name": "C" + }, + "computed": false + }, "arguments": [], "optional": true } + }, + { + "type": "ExpressionStatement", + "start": 40, + "end": 56, + "loc": { + "start": { + "line": 7, + "column": 0 + }, + "end": { + "line": 7, + "column": 16 + } + }, + "expression": { + "type": "NewExpression", + "start": 40, + "end": 56, + "loc": { + "start": { + "line": 7, + "column": 0 + }, + "end": { + "line": 7, + "column": 16 + } + }, + "callee": { + "type": "MemberExpression", + "start": 44, + "end": 48, + "loc": { + "start": { + "line": 7, + "column": 4 + }, + "end": { + "line": 7, + "column": 8 + } + }, + "object": { + "type": "Identifier", + "start": 44, + "end": 45, + "loc": { + "start": { + "line": 7, + "column": 4 + }, + "end": { + "line": 7, + "column": 5 + }, + "identifierName": "B" + }, + "name": "B" + }, + "optional": true, + "property": { + "type": "Identifier", + "start": 47, + "end": 48, + "loc": { + "start": { + "line": 7, + "column": 7 + }, + "end": { + "line": 7, + "column": 8 + }, + "identifierName": "C" + }, + "name": "C" + }, + "computed": false + }, + "arguments": [ + { + "type": "Identifier", + "start": 51, + "end": 52, + "loc": { + "start": { + "line": 7, + "column": 11 + }, + "end": { + "line": 7, + "column": 12 + }, + "identifierName": "a" + }, + "name": "a" + }, + { + "type": "Identifier", + "start": 54, + "end": 55, + "loc": { + "start": { + "line": 7, + "column": 14 + }, + "end": { + "line": 7, + "column": 15 + }, + "identifierName": "b" + }, + "name": "b" + } + ], + "optional": true + } + }, + { + "type": "ExpressionStatement", + "start": 58, + "end": 66, + "loc": { + "start": { + "line": 9, + "column": 0 + }, + "end": { + "line": 9, + "column": 8 + } + }, + "expression": { + "type": "NewExpression", + "start": 58, + "end": 66, + "loc": { + "start": { + "line": 9, + "column": 0 + }, + "end": { + "line": 9, + "column": 8 + } + }, + "callee": { + "type": "MemberExpression", + "start": 62, + "end": 66, + "loc": { + "start": { + "line": 9, + "column": 4 + }, + "end": { + "line": 9, + "column": 8 + } + }, + "object": { + "type": "Identifier", + "start": 62, + "end": 63, + "loc": { + "start": { + "line": 9, + "column": 4 + }, + "end": { + "line": 9, + "column": 5 + }, + "identifierName": "B" + }, + "name": "B" + }, + "optional": true, + "property": { + "type": "Identifier", + "start": 65, + "end": 66, + "loc": { + "start": { + "line": 9, + "column": 7 + }, + "end": { + "line": 9, + "column": 8 + }, + "identifierName": "C" + }, + "name": "C" + }, + "computed": false + }, + "arguments": [] + } } ], "directives": [] diff --git a/test/fixtures/experimental/optional-chaining/conditional-decimal/actual.js b/test/fixtures/experimental/optional-chaining/conditional-decimal/actual.js new file mode 100644 index 0000000000..d45b871d97 --- /dev/null +++ b/test/fixtures/experimental/optional-chaining/conditional-decimal/actual.js @@ -0,0 +1,3 @@ +true?.3:0 + +true ? .3 : 0 diff --git a/test/fixtures/experimental/optional-chaining/conditional-decimal/expected.json b/test/fixtures/experimental/optional-chaining/conditional-decimal/expected.json new file mode 100644 index 0000000000..a7c530f542 --- /dev/null +++ b/test/fixtures/experimental/optional-chaining/conditional-decimal/expected.json @@ -0,0 +1,206 @@ +{ + "type": "File", + "start": 0, + "end": 24, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 3, + "column": 13 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 24, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 3, + "column": 13 + } + }, + "sourceType": "script", + "body": [ + { + "type": "ExpressionStatement", + "start": 0, + "end": 9, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 9 + } + }, + "expression": { + "type": "ConditionalExpression", + "start": 0, + "end": 9, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 9 + } + }, + "test": { + "type": "BooleanLiteral", + "start": 0, + "end": 4, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 4 + } + }, + "value": true + }, + "consequent": { + "type": "NumericLiteral", + "start": 5, + "end": 7, + "loc": { + "start": { + "line": 1, + "column": 5 + }, + "end": { + "line": 1, + "column": 7 + } + }, + "extra": { + "rawValue": 0.3, + "raw": ".3" + }, + "value": 0.3 + }, + "alternate": { + "type": "NumericLiteral", + "start": 8, + "end": 9, + "loc": { + "start": { + "line": 1, + "column": 8 + }, + "end": { + "line": 1, + "column": 9 + } + }, + "extra": { + "rawValue": 0, + "raw": "0" + }, + "value": 0 + } + } + }, + { + "type": "ExpressionStatement", + "start": 11, + "end": 24, + "loc": { + "start": { + "line": 3, + "column": 0 + }, + "end": { + "line": 3, + "column": 13 + } + }, + "expression": { + "type": "ConditionalExpression", + "start": 11, + "end": 24, + "loc": { + "start": { + "line": 3, + "column": 0 + }, + "end": { + "line": 3, + "column": 13 + } + }, + "test": { + "type": "BooleanLiteral", + "start": 11, + "end": 15, + "loc": { + "start": { + "line": 3, + "column": 0 + }, + "end": { + "line": 3, + "column": 4 + } + }, + "value": true + }, + "consequent": { + "type": "NumericLiteral", + "start": 18, + "end": 20, + "loc": { + "start": { + "line": 3, + "column": 7 + }, + "end": { + "line": 3, + "column": 9 + } + }, + "extra": { + "rawValue": 0.3, + "raw": ".3" + }, + "value": 0.3 + }, + "alternate": { + "type": "NumericLiteral", + "start": 23, + "end": 24, + "loc": { + "start": { + "line": 3, + "column": 12 + }, + "end": { + "line": 3, + "column": 13 + } + }, + "extra": { + "rawValue": 0, + "raw": "0" + }, + "value": 0 + } + } + } + ], + "directives": [] + } +} diff --git a/test/fixtures/experimental/optional-chaining/conditional-decimal/options.json b/test/fixtures/experimental/optional-chaining/conditional-decimal/options.json new file mode 100644 index 0000000000..fd201c1bdb --- /dev/null +++ b/test/fixtures/experimental/optional-chaining/conditional-decimal/options.json @@ -0,0 +1,3 @@ +{ + "plugins": ["optionalChaining"] +} diff --git a/test/fixtures/experimental/optional-chaining/function-call/actual.js b/test/fixtures/experimental/optional-chaining/function-call/actual.js index 7a5a8c001b..ccf7cad6ee 100644 --- a/test/fixtures/experimental/optional-chaining/function-call/actual.js +++ b/test/fixtures/experimental/optional-chaining/function-call/actual.js @@ -1,3 +1,7 @@ func?.() func?.(a, b) + +a?.func?.() + +a?.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 index 60248b0e79..6b21fceb08 100644 --- a/test/fixtures/experimental/optional-chaining/function-call/expected.json +++ b/test/fixtures/experimental/optional-chaining/function-call/expected.json @@ -1,29 +1,29 @@ { "type": "File", "start": 0, - "end": 22, + "end": 52, "loc": { "start": { "line": 1, "column": 0 }, "end": { - "line": 3, - "column": 12 + "line": 7, + "column": 15 } }, "program": { "type": "Program", "start": 0, - "end": 22, + "end": 52, "loc": { "start": { "line": 1, "column": 0 }, "end": { - "line": 3, - "column": 12 + "line": 7, + "column": 15 } }, "sourceType": "script", @@ -56,6 +56,23 @@ "column": 8 } }, + "callee": { + "type": "Identifier", + "start": 0, + "end": 4, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 4 + }, + "identifierName": "func" + }, + "name": "func" + }, "arguments": [], "optional": true } @@ -88,6 +105,23 @@ "column": 12 } }, + "callee": { + "type": "Identifier", + "start": 10, + "end": 14, + "loc": { + "start": { + "line": 3, + "column": 0 + }, + "end": { + "line": 3, + "column": 4 + }, + "identifierName": "func" + }, + "name": "func" + }, "arguments": [ { "type": "Identifier", @@ -126,8 +160,209 @@ ], "optional": true } + }, + { + "type": "ExpressionStatement", + "start": 24, + "end": 35, + "loc": { + "start": { + "line": 5, + "column": 0 + }, + "end": { + "line": 5, + "column": 11 + } + }, + "expression": { + "type": "CallExpression", + "start": 24, + "end": 35, + "loc": { + "start": { + "line": 5, + "column": 0 + }, + "end": { + "line": 5, + "column": 11 + } + }, + "callee": { + "type": "MemberExpression", + "start": 24, + "end": 31, + "loc": { + "start": { + "line": 5, + "column": 0 + }, + "end": { + "line": 5, + "column": 7 + } + }, + "object": { + "type": "Identifier", + "start": 24, + "end": 25, + "loc": { + "start": { + "line": 5, + "column": 0 + }, + "end": { + "line": 5, + "column": 1 + }, + "identifierName": "a" + }, + "name": "a" + }, + "optional": true, + "property": { + "type": "Identifier", + "start": 27, + "end": 31, + "loc": { + "start": { + "line": 5, + "column": 3 + }, + "end": { + "line": 5, + "column": 7 + }, + "identifierName": "func" + }, + "name": "func" + }, + "computed": false + }, + "arguments": [], + "optional": true + } + }, + { + "type": "ExpressionStatement", + "start": 37, + "end": 52, + "loc": { + "start": { + "line": 7, + "column": 0 + }, + "end": { + "line": 7, + "column": 15 + } + }, + "expression": { + "type": "CallExpression", + "start": 37, + "end": 52, + "loc": { + "start": { + "line": 7, + "column": 0 + }, + "end": { + "line": 7, + "column": 15 + } + }, + "callee": { + "type": "MemberExpression", + "start": 37, + "end": 44, + "loc": { + "start": { + "line": 7, + "column": 0 + }, + "end": { + "line": 7, + "column": 7 + } + }, + "object": { + "type": "Identifier", + "start": 37, + "end": 38, + "loc": { + "start": { + "line": 7, + "column": 0 + }, + "end": { + "line": 7, + "column": 1 + }, + "identifierName": "a" + }, + "name": "a" + }, + "optional": true, + "property": { + "type": "Identifier", + "start": 40, + "end": 44, + "loc": { + "start": { + "line": 7, + "column": 3 + }, + "end": { + "line": 7, + "column": 7 + }, + "identifierName": "func" + }, + "name": "func" + }, + "computed": false + }, + "arguments": [ + { + "type": "Identifier", + "start": 47, + "end": 48, + "loc": { + "start": { + "line": 7, + "column": 10 + }, + "end": { + "line": 7, + "column": 11 + }, + "identifierName": "a" + }, + "name": "a" + }, + { + "type": "Identifier", + "start": 50, + "end": 51, + "loc": { + "start": { + "line": 7, + "column": 13 + }, + "end": { + "line": 7, + "column": 14 + }, + "identifierName": "b" + }, + "name": "b" + } + ], + "optional": true + } } ], "directives": [] } -} \ No newline at end of file +} diff --git a/test/fixtures/experimental/optional-chaining/member-access-bracket/actual.js b/test/fixtures/experimental/optional-chaining/member-access-bracket/actual.js index faf3fc3ac0..ee45bfdb9e 100644 --- a/test/fixtures/experimental/optional-chaining/member-access-bracket/actual.js +++ b/test/fixtures/experimental/optional-chaining/member-access-bracket/actual.js @@ -1 +1,7 @@ obj?.[expr] + +obj?.[expr]?.[other] + +obj?.[true] + +obj?.[true]?.[true] diff --git a/test/fixtures/experimental/optional-chaining/member-access-bracket/expected.json b/test/fixtures/experimental/optional-chaining/member-access-bracket/expected.json index cd6a6d9c88..aa2588dde0 100644 --- a/test/fixtures/experimental/optional-chaining/member-access-bracket/expected.json +++ b/test/fixtures/experimental/optional-chaining/member-access-bracket/expected.json @@ -1,29 +1,29 @@ { "type": "File", "start": 0, - "end": 11, + "end": 67, "loc": { "start": { "line": 1, "column": 0 }, "end": { - "line": 1, - "column": 11 + "line": 7, + "column": 19 } }, "program": { "type": "Program", "start": 0, - "end": 11, + "end": 67, "loc": { "start": { "line": 1, "column": 0 }, "end": { - "line": 1, - "column": 11 + "line": 7, + "column": 19 } }, "sourceType": "script", @@ -73,7 +73,6 @@ }, "name": "obj" }, - "optional": true, "property": { "type": "Identifier", "start": 6, @@ -91,7 +90,271 @@ }, "name": "expr" }, - "computed": true + "computed": true, + "optional": true + } + }, + { + "type": "ExpressionStatement", + "start": 13, + "end": 33, + "loc": { + "start": { + "line": 3, + "column": 0 + }, + "end": { + "line": 3, + "column": 20 + } + }, + "expression": { + "type": "MemberExpression", + "start": 13, + "end": 33, + "loc": { + "start": { + "line": 3, + "column": 0 + }, + "end": { + "line": 3, + "column": 20 + } + }, + "object": { + "type": "MemberExpression", + "start": 13, + "end": 24, + "loc": { + "start": { + "line": 3, + "column": 0 + }, + "end": { + "line": 3, + "column": 11 + } + }, + "object": { + "type": "Identifier", + "start": 13, + "end": 16, + "loc": { + "start": { + "line": 3, + "column": 0 + }, + "end": { + "line": 3, + "column": 3 + }, + "identifierName": "obj" + }, + "name": "obj" + }, + "property": { + "type": "Identifier", + "start": 19, + "end": 23, + "loc": { + "start": { + "line": 3, + "column": 6 + }, + "end": { + "line": 3, + "column": 10 + }, + "identifierName": "expr" + }, + "name": "expr" + }, + "computed": true, + "optional": true + }, + "property": { + "type": "Identifier", + "start": 27, + "end": 32, + "loc": { + "start": { + "line": 3, + "column": 14 + }, + "end": { + "line": 3, + "column": 19 + }, + "identifierName": "other" + }, + "name": "other" + }, + "computed": true, + "optional": true + } + }, + { + "type": "ExpressionStatement", + "start": 35, + "end": 46, + "loc": { + "start": { + "line": 5, + "column": 0 + }, + "end": { + "line": 5, + "column": 11 + } + }, + "expression": { + "type": "MemberExpression", + "start": 35, + "end": 46, + "loc": { + "start": { + "line": 5, + "column": 0 + }, + "end": { + "line": 5, + "column": 11 + } + }, + "object": { + "type": "Identifier", + "start": 35, + "end": 38, + "loc": { + "start": { + "line": 5, + "column": 0 + }, + "end": { + "line": 5, + "column": 3 + }, + "identifierName": "obj" + }, + "name": "obj" + }, + "property": { + "type": "BooleanLiteral", + "start": 41, + "end": 45, + "loc": { + "start": { + "line": 5, + "column": 6 + }, + "end": { + "line": 5, + "column": 10 + } + }, + "value": true + }, + "computed": true, + "optional": true + } + }, + { + "type": "ExpressionStatement", + "start": 48, + "end": 67, + "loc": { + "start": { + "line": 7, + "column": 0 + }, + "end": { + "line": 7, + "column": 19 + } + }, + "expression": { + "type": "MemberExpression", + "start": 48, + "end": 67, + "loc": { + "start": { + "line": 7, + "column": 0 + }, + "end": { + "line": 7, + "column": 19 + } + }, + "object": { + "type": "MemberExpression", + "start": 48, + "end": 59, + "loc": { + "start": { + "line": 7, + "column": 0 + }, + "end": { + "line": 7, + "column": 11 + } + }, + "object": { + "type": "Identifier", + "start": 48, + "end": 51, + "loc": { + "start": { + "line": 7, + "column": 0 + }, + "end": { + "line": 7, + "column": 3 + }, + "identifierName": "obj" + }, + "name": "obj" + }, + "property": { + "type": "BooleanLiteral", + "start": 54, + "end": 58, + "loc": { + "start": { + "line": 7, + "column": 6 + }, + "end": { + "line": 7, + "column": 10 + } + }, + "value": true + }, + "computed": true, + "optional": true + }, + "property": { + "type": "BooleanLiteral", + "start": 62, + "end": 66, + "loc": { + "start": { + "line": 7, + "column": 14 + }, + "end": { + "line": 7, + "column": 18 + } + }, + "value": true + }, + "computed": true, + "optional": true } } ], diff --git a/test/fixtures/experimental/optional-chaining/member-access/actual.js b/test/fixtures/experimental/optional-chaining/member-access/actual.js index 6ed5c83b93..8e44f57415 100644 --- a/test/fixtures/experimental/optional-chaining/member-access/actual.js +++ b/test/fixtures/experimental/optional-chaining/member-access/actual.js @@ -1 +1,3 @@ foo?.bar + +foo?.bar?.baz diff --git a/test/fixtures/experimental/optional-chaining/member-access/expected.json b/test/fixtures/experimental/optional-chaining/member-access/expected.json index 868d2a3e08..f3e110ea14 100644 --- a/test/fixtures/experimental/optional-chaining/member-access/expected.json +++ b/test/fixtures/experimental/optional-chaining/member-access/expected.json @@ -1,29 +1,29 @@ { "type": "File", "start": 0, - "end": 8, + "end": 23, "loc": { "start": { "line": 1, "column": 0 }, "end": { - "line": 1, - "column": 8 + "line": 3, + "column": 13 } }, "program": { "type": "Program", "start": 0, - "end": 8, + "end": 23, "loc": { "start": { "line": 1, "column": 0 }, "end": { - "line": 1, - "column": 8 + "line": 3, + "column": 13 } }, "sourceType": "script", @@ -93,6 +93,106 @@ "optional": true, "computed": false } + }, + { + "type": "ExpressionStatement", + "start": 10, + "end": 23, + "loc": { + "start": { + "line": 3, + "column": 0 + }, + "end": { + "line": 3, + "column": 13 + } + }, + "expression": { + "type": "MemberExpression", + "start": 10, + "end": 23, + "loc": { + "start": { + "line": 3, + "column": 0 + }, + "end": { + "line": 3, + "column": 13 + } + }, + "object": { + "type": "MemberExpression", + "start": 10, + "end": 18, + "loc": { + "start": { + "line": 3, + "column": 0 + }, + "end": { + "line": 3, + "column": 8 + } + }, + "object": { + "type": "Identifier", + "start": 10, + "end": 13, + "loc": { + "start": { + "line": 3, + "column": 0 + }, + "end": { + "line": 3, + "column": 3 + }, + "identifierName": "foo" + }, + "name": "foo" + }, + "property": { + "type": "Identifier", + "start": 15, + "end": 18, + "loc": { + "start": { + "line": 3, + "column": 5 + }, + "end": { + "line": 3, + "column": 8 + }, + "identifierName": "bar" + }, + "name": "bar" + }, + "optional": true, + "computed": false + }, + "property": { + "type": "Identifier", + "start": 20, + "end": 23, + "loc": { + "start": { + "line": 3, + "column": 10 + }, + "end": { + "line": 3, + "column": 13 + }, + "identifierName": "baz" + }, + "name": "baz" + }, + "optional": true, + "computed": false + } } ], "directives": []