From b2fdd944fe740a86122776f71d027fc2f1ecefac Mon Sep 17 00:00:00 2001 From: Sven SAULEAU Date: Mon, 17 Apr 2017 13:33:00 +0200 Subject: [PATCH] feat: add tests --- ast/spec.md | 4 +- src/parser/expression.js | 5 +- .../class-contructor-call/actual.js | 1 + .../optional-chaining/function-call/actual.js | 1 + .../member-access-bracket/actual.js | 1 + .../member-access-bracket/expected.json | 100 ++++ .../member-access/expected.json | 2 +- .../experimental/uncategorised/63/actual.js | 5 - .../uncategorised/63/expected.json | 566 ------------------ 9 files changed, 108 insertions(+), 577 deletions(-) create mode 100644 test/fixtures/es2017/optional-chaining/class-contructor-call/actual.js create mode 100644 test/fixtures/es2017/optional-chaining/function-call/actual.js create mode 100644 test/fixtures/es2017/optional-chaining/member-access-bracket/actual.js create mode 100644 test/fixtures/es2017/optional-chaining/member-access-bracket/expected.json delete mode 100644 test/fixtures/experimental/uncategorised/63/actual.js delete mode 100644 test/fixtures/experimental/uncategorised/63/expected.json diff --git a/ast/spec.md b/ast/spec.md index 72562cb48c..96425d2fa4 100644 --- a/ast/spec.md +++ b/ast/spec.md @@ -845,11 +845,11 @@ interface MemberExpression <: Expression, Pattern { object: Expression | Super; property: Expression; computed: boolean; - nullPropagation: boolean | null; + optional: boolean | null; } ``` -A member expression. If `computed` is `true`, the node corresponds to a computed (`a[b]`) member expression and `property` is an `Expression`. If `computed` is `false`, the node corresponds to a static (`a.b`) member expression and `property` is an `Identifier`. The `nullPropagation` flags indecates that the member expression can be called even if the object is null or undefined. If this is the object value (null/undefined) should be returned. +A member expression. If `computed` is `true`, the node corresponds to a computed (`a[b]`) member expression and `property` is an `Expression`. If `computed` is `false`, the node corresponds to a static (`a.b`) member expression and `property` is an `Identifier`. The `optional` flags indecates that the member expression can be called even if the object is null or undefined. If this is the object value (null/undefined) should be returned. ### BindExpression diff --git a/src/parser/expression.js b/src/parser/expression.js index e8532ae1a9..8bcb0422cb 100644 --- a/src/parser/expression.js +++ b/src/parser/expression.js @@ -285,11 +285,10 @@ pp.parseSubscripts = function (base, startPos, startLoc, noCalls) { node.callee = this.parseNoCallExpr(); return this.parseSubscripts(this.finishNode(node, "BindExpression"), startPos, startLoc, noCalls); } else if (this.eat(tt.questionDot)) { - base.optional = true; - if (this.eat(tt.bracketL)) { const node = this.startNodeAt(startPos, startLoc); node.object = base; + node.optional = true; node.property = this.parseExpression(); node.computed = true; this.expect(tt.bracketR); @@ -298,6 +297,7 @@ pp.parseSubscripts = function (base, startPos, startLoc, noCalls) { const node = this.startNodeAt(startPos, startLoc); node.object = base; node.property = this.parseIdentifier(true); + node.optional = true; node.computed = false; base = this.finishNode(node, "MemberExpression"); } @@ -312,7 +312,6 @@ pp.parseSubscripts = function (base, startPos, startLoc, noCalls) { node.object = base; node.property = this.parseExpression(); node.computed = true; - delete node.nullPropagation; this.expect(tt.bracketR); base = this.finishNode(node, "MemberExpression"); } else if (!noCalls && this.match(tt.parenL)) { diff --git a/test/fixtures/es2017/optional-chaining/class-contructor-call/actual.js b/test/fixtures/es2017/optional-chaining/class-contructor-call/actual.js new file mode 100644 index 0000000000..8e9b00d27f --- /dev/null +++ b/test/fixtures/es2017/optional-chaining/class-contructor-call/actual.js @@ -0,0 +1 @@ +new C?.() diff --git a/test/fixtures/es2017/optional-chaining/function-call/actual.js b/test/fixtures/es2017/optional-chaining/function-call/actual.js new file mode 100644 index 0000000000..4488735365 --- /dev/null +++ b/test/fixtures/es2017/optional-chaining/function-call/actual.js @@ -0,0 +1 @@ +func?.() diff --git a/test/fixtures/es2017/optional-chaining/member-access-bracket/actual.js b/test/fixtures/es2017/optional-chaining/member-access-bracket/actual.js new file mode 100644 index 0000000000..faf3fc3ac0 --- /dev/null +++ b/test/fixtures/es2017/optional-chaining/member-access-bracket/actual.js @@ -0,0 +1 @@ +obj?.[expr] diff --git a/test/fixtures/es2017/optional-chaining/member-access-bracket/expected.json b/test/fixtures/es2017/optional-chaining/member-access-bracket/expected.json new file mode 100644 index 0000000000..cd6a6d9c88 --- /dev/null +++ b/test/fixtures/es2017/optional-chaining/member-access-bracket/expected.json @@ -0,0 +1,100 @@ +{ + "type": "File", + "start": 0, + "end": 11, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 11 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 11, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 11 + } + }, + "sourceType": "script", + "body": [ + { + "type": "ExpressionStatement", + "start": 0, + "end": 11, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 11 + } + }, + "expression": { + "type": "MemberExpression", + "start": 0, + "end": 11, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 11 + } + }, + "object": { + "type": "Identifier", + "start": 0, + "end": 3, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 3 + }, + "identifierName": "obj" + }, + "name": "obj" + }, + "optional": true, + "property": { + "type": "Identifier", + "start": 6, + "end": 10, + "loc": { + "start": { + "line": 1, + "column": 6 + }, + "end": { + "line": 1, + "column": 10 + }, + "identifierName": "expr" + }, + "name": "expr" + }, + "computed": true + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/test/fixtures/es2017/optional-chaining/member-access/expected.json b/test/fixtures/es2017/optional-chaining/member-access/expected.json index cb6ced4220..868d2a3e08 100644 --- a/test/fixtures/es2017/optional-chaining/member-access/expected.json +++ b/test/fixtures/es2017/optional-chaining/member-access/expected.json @@ -73,7 +73,6 @@ }, "name": "foo" }, - "optional": true, "property": { "type": "Identifier", "start": 5, @@ -91,6 +90,7 @@ }, "name": "bar" }, + "optional": true, "computed": false } } diff --git a/test/fixtures/experimental/uncategorised/63/actual.js b/test/fixtures/experimental/uncategorised/63/actual.js deleted file mode 100644 index eeb713af30..0000000000 --- a/test/fixtures/experimental/uncategorised/63/actual.js +++ /dev/null @@ -1,5 +0,0 @@ -o?.x?.y - -o?.x ? o.x.z?.w : o.y?.z?.w - -o?.[0]?.["1"]?.x \ No newline at end of file diff --git a/test/fixtures/experimental/uncategorised/63/expected.json b/test/fixtures/experimental/uncategorised/63/expected.json deleted file mode 100644 index 7f36efbc14..0000000000 --- a/test/fixtures/experimental/uncategorised/63/expected.json +++ /dev/null @@ -1,566 +0,0 @@ -{ - "type": "File", - "start": 0, - "end": 54, - "loc": { - "start": { - "line": 1, - "column": 0 - }, - "end": { - "line": 5, - "column": 16 - } - }, - "program": { - "type": "Program", - "start": 0, - "end": 54, - "loc": { - "start": { - "line": 1, - "column": 0 - }, - "end": { - "line": 5, - "column": 16 - } - }, - "sourceType": "script", - "body": [ - { - "type": "ExpressionStatement", - "start": 0, - "end": 7, - "loc": { - "start": { - "line": 1, - "column": 0 - }, - "end": { - "line": 1, - "column": 7 - } - }, - "expression": { - "type": "MemberExpression", - "start": 0, - "end": 7, - "loc": { - "start": { - "line": 1, - "column": 0 - }, - "end": { - "line": 1, - "column": 7 - } - }, - "object": { - "type": "MemberExpression", - "start": 0, - "end": 4, - "loc": { - "start": { - "line": 1, - "column": 0 - }, - "end": { - "line": 1, - "column": 4 - } - }, - "object": { - "type": "Identifier", - "start": 0, - "end": 1, - "loc": { - "start": { - "line": 1, - "column": 0 - }, - "end": { - "line": 1, - "column": 1 - } - }, - "name": "o", - "nullPropagation": true - }, - "property": { - "type": "Identifier", - "start": 3, - "end": 4, - "loc": { - "start": { - "line": 1, - "column": 3 - }, - "end": { - "line": 1, - "column": 4 - } - }, - "name": "x" - }, - "computed": false, - "nullPropagation": true - }, - "property": { - "type": "Identifier", - "start": 6, - "end": 7, - "loc": { - "start": { - "line": 1, - "column": 6 - }, - "end": { - "line": 1, - "column": 7 - } - }, - "name": "y" - }, - "computed": false - } - }, - { - "type": "ExpressionStatement", - "start": 9, - "end": 36, - "loc": { - "start": { - "line": 3, - "column": 0 - }, - "end": { - "line": 3, - "column": 27 - } - }, - "expression": { - "type": "ConditionalExpression", - "start": 9, - "end": 36, - "loc": { - "start": { - "line": 3, - "column": 0 - }, - "end": { - "line": 3, - "column": 27 - } - }, - "test": { - "type": "MemberExpression", - "start": 9, - "end": 13, - "loc": { - "start": { - "line": 3, - "column": 0 - }, - "end": { - "line": 3, - "column": 4 - } - }, - "object": { - "type": "Identifier", - "start": 9, - "end": 10, - "loc": { - "start": { - "line": 3, - "column": 0 - }, - "end": { - "line": 3, - "column": 1 - } - }, - "name": "o", - "nullPropagation": true - }, - "property": { - "type": "Identifier", - "start": 12, - "end": 13, - "loc": { - "start": { - "line": 3, - "column": 3 - }, - "end": { - "line": 3, - "column": 4 - } - }, - "name": "x" - }, - "computed": false - }, - "consequent": { - "type": "MemberExpression", - "start": 16, - "end": 24, - "loc": { - "start": { - "line": 3, - "column": 7 - }, - "end": { - "line": 3, - "column": 15 - } - }, - "object": { - "type": "MemberExpression", - "start": 16, - "end": 21, - "loc": { - "start": { - "line": 3, - "column": 7 - }, - "end": { - "line": 3, - "column": 12 - } - }, - "object": { - "type": "MemberExpression", - "start": 16, - "end": 19, - "loc": { - "start": { - "line": 3, - "column": 7 - }, - "end": { - "line": 3, - "column": 10 - } - }, - "object": { - "type": "Identifier", - "start": 16, - "end": 17, - "loc": { - "start": { - "line": 3, - "column": 7 - }, - "end": { - "line": 3, - "column": 8 - } - }, - "name": "o" - }, - "property": { - "type": "Identifier", - "start": 18, - "end": 19, - "loc": { - "start": { - "line": 3, - "column": 9 - }, - "end": { - "line": 3, - "column": 10 - } - }, - "name": "x" - }, - "computed": false - }, - "property": { - "type": "Identifier", - "start": 20, - "end": 21, - "loc": { - "start": { - "line": 3, - "column": 11 - }, - "end": { - "line": 3, - "column": 12 - } - }, - "name": "z" - }, - "computed": false, - "nullPropagation": true - }, - "property": { - "type": "Identifier", - "start": 23, - "end": 24, - "loc": { - "start": { - "line": 3, - "column": 14 - }, - "end": { - "line": 3, - "column": 15 - } - }, - "name": "w" - }, - "computed": false - }, - "alternate": { - "type": "MemberExpression", - "start": 27, - "end": 36, - "loc": { - "start": { - "line": 3, - "column": 18 - }, - "end": { - "line": 3, - "column": 27 - } - }, - "object": { - "type": "MemberExpression", - "start": 27, - "end": 33, - "loc": { - "start": { - "line": 3, - "column": 18 - }, - "end": { - "line": 3, - "column": 24 - } - }, - "object": { - "type": "MemberExpression", - "start": 27, - "end": 30, - "loc": { - "start": { - "line": 3, - "column": 18 - }, - "end": { - "line": 3, - "column": 21 - } - }, - "object": { - "type": "Identifier", - "start": 27, - "end": 28, - "loc": { - "start": { - "line": 3, - "column": 18 - }, - "end": { - "line": 3, - "column": 19 - } - }, - "name": "o" - }, - "property": { - "type": "Identifier", - "start": 29, - "end": 30, - "loc": { - "start": { - "line": 3, - "column": 20 - }, - "end": { - "line": 3, - "column": 21 - } - }, - "name": "y" - }, - "computed": false, - "nullPropagation": true - }, - "property": { - "type": "Identifier", - "start": 32, - "end": 33, - "loc": { - "start": { - "line": 3, - "column": 23 - }, - "end": { - "line": 3, - "column": 24 - } - }, - "name": "z" - }, - "computed": false, - "nullPropagation": true - }, - "property": { - "type": "Identifier", - "start": 35, - "end": 36, - "loc": { - "start": { - "line": 3, - "column": 26 - }, - "end": { - "line": 3, - "column": 27 - } - }, - "name": "w" - }, - "computed": false - } - } - }, - { - "type": "ExpressionStatement", - "start": 38, - "end": 54, - "loc": { - "start": { - "line": 5, - "column": 0 - }, - "end": { - "line": 5, - "column": 16 - } - }, - "expression": { - "type": "MemberExpression", - "start": 38, - "end": 54, - "loc": { - "start": { - "line": 5, - "column": 0 - }, - "end": { - "line": 5, - "column": 16 - } - }, - "object": { - "type": "MemberExpression", - "start": 38, - "end": 51, - "loc": { - "start": { - "line": 5, - "column": 0 - }, - "end": { - "line": 5, - "column": 13 - } - }, - "object": { - "type": "MemberExpression", - "start": 38, - "end": 44, - "loc": { - "start": { - "line": 5, - "column": 0 - }, - "end": { - "line": 5, - "column": 6 - } - }, - "object": { - "type": "Identifier", - "start": 38, - "end": 39, - "loc": { - "start": { - "line": 5, - "column": 0 - }, - "end": { - "line": 5, - "column": 1 - } - }, - "name": "o", - "nullPropagation": true - }, - "property": { - "type": "NumericLiteral", - "start": 42, - "end": 43, - "loc": { - "start": { - "line": 5, - "column": 4 - }, - "end": { - "line": 5, - "column": 5 - } - }, - "value": 0 - }, - "computed": true, - "nullPropagation": true - }, - "property": { - "type": "StringLiteral", - "start": 47, - "end": 50, - "loc": { - "start": { - "line": 5, - "column": 9 - }, - "end": { - "line": 5, - "column": 12 - } - }, - "value": "1" - }, - "computed": true, - "nullPropagation": true - }, - "property": { - "type": "Identifier", - "start": 53, - "end": 54, - "loc": { - "start": { - "line": 5, - "column": 15 - }, - "end": { - "line": 5, - "column": 16 - } - }, - "name": "x" - }, - "computed": false - } - } - ] - } -} \ No newline at end of file