Skip to content

Commit

Permalink
Converge with Babel re optional chaining
Browse files Browse the repository at this point in the history
- Eliminate `SafeMemberExpression` node type; use `MemberExpression` with `optional = true` instead.
- Use `optional = true` for safe `CallExpression`s
- Allow proposed `x?.(arg, arg…)` syntax for safe calls
  • Loading branch information
wcjohnson committed Sep 23, 2017
1 parent 99f8c0b commit 926a863
Show file tree
Hide file tree
Showing 18 changed files with 169 additions and 50 deletions.
43 changes: 27 additions & 16 deletions src/parser/expression.js
Original file line number Diff line number Diff line change
Expand Up @@ -426,28 +426,39 @@ pp.parseSubscripts = function (base, startPos, startLoc, noCalls) {
if (this.hasPlugin("enforceSubscriptIndentation") && this.isNonIndentedBreakFrom(startPos)) {
this.unexpected(null, "Indentation required.");
}
// `x?.y`
const node = this.startNodeAt(startPos, startLoc);

const op = this.state.value;
this.next();
node.object = base;
if (op === "?.") {
// arr?.0 -> arr?[0]
if (this.match(tt.num)) {
node.property = this.parseLiteral(this.state.value, "NumericLiteral");

if (op === "?." && this.match(tt.parenL) && this.hasPlugin("safeCallExpression")) {
// x?.(...) = JS safe call proposal
const [next, canSubscript] = this.parseSafeCall(base, startPos, startLoc);
if (canSubscript) base = next; else return base;
} else {
// `x?.y` `x?[y]`
const node = this.startNodeAt(startPos, startLoc);
node.object = base;

if (op === "?.") {
if (this.match(tt.num)) {
// arr?.0 -> arr?[0]
node.property = this.parseLiteral(this.state.value, "NumericLiteral");
node.computed = true;
} else {
node.property = this.parseIdentifierOrPlaceholder(true);
node.computed = false;
}
} else if (op === "?[") {
node.property = this.parseExpression();
node.computed = true;
this.expect(tt.bracketR);
} else {
node.property = this.parseIdentifierOrPlaceholder(true);
node.computed = false;
this.unexpected();
}
} else if (op === "?[") {
node.property = this.parseExpression();
node.computed = true;
this.expect(tt.bracketR);
} else {
this.unexpected();

node.optional = true;
base = this.finishNode(node, "MemberExpression");
}
base = this.finishNode(node, "SafeMemberExpression");
} else if (
(this.hasPlugin("safeCallExpression") || this.hasPlugin("existentialExpression")) &&
this.match(tt.question) &&
Expand Down
2 changes: 1 addition & 1 deletion src/plugins/safeCallExistential.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export default function(parser) {
pp.parseSafeCall = function(expr, startPos, startLoc) {
const node = this.startNodeAt(startPos, startLoc);
node.callee = expr;
node.safe = true;
node.optional = true;

if (this.hasPlugin("bangCall") && this.isBang()) {
const canSubscript = this.parseBangCall(node, "CallExpression");
Expand Down
2 changes: 1 addition & 1 deletion src/plugins/tildeCall.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export default function(parser) {

// Allow safe tilde calls (a~b?(c))
if (this.hasPlugin("safeCallExpression") && this.eat(tt.question)) {
node.safe = true;
node.optional = true;
}

// Allow bang tilde calls
Expand Down
2 changes: 1 addition & 1 deletion test/fixtures/bang-call/safe/basic/expected.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@
},
"name": "a"
},
"safe": true,
"optional": true,
"arguments": [
{
"type": "Identifier",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
}
},
"expression": {
"type": "SafeMemberExpression",
"type": "MemberExpression",
"start": 0,
"end": 4,
"loc": {
Expand Down Expand Up @@ -90,7 +90,8 @@
},
"name": "y"
},
"computed": false
"computed": false,
"optional": true
}
}
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
}
},
"expression": {
"type": "SafeMemberExpression",
"type": "MemberExpression",
"start": 0,
"end": 26,
"loc": {
Expand Down Expand Up @@ -113,7 +113,7 @@
}
},
"object": {
"type": "SafeMemberExpression",
"type": "MemberExpression",
"start": 0,
"end": 9,
"loc": {
Expand All @@ -127,7 +127,7 @@
}
},
"object": {
"type": "SafeMemberExpression",
"type": "MemberExpression",
"start": 0,
"end": 6,
"loc": {
Expand Down Expand Up @@ -207,7 +207,8 @@
},
"name": "a"
},
"computed": false
"computed": false,
"optional": true
},
"property": {
"type": "Identifier",
Expand All @@ -226,7 +227,8 @@
},
"name": "b"
},
"computed": false
"computed": false,
"optional": true
},
"property": {
"type": "Identifier",
Expand Down Expand Up @@ -339,7 +341,8 @@
},
"name": "h"
},
"computed": false
"computed": false,
"optional": true
}
}
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
}
},
"expression": {
"type": "SafeMemberExpression",
"type": "MemberExpression",
"start": 0,
"end": 9,
"loc": {
Expand Down Expand Up @@ -123,7 +123,8 @@
"name": "y"
}
},
"computed": true
"computed": true,
"optional": true
}
}
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
}
},
"expression": {
"type": "SafeMemberExpression",
"type": "MemberExpression",
"start": 0,
"end": 4,
"loc": {
Expand Down Expand Up @@ -87,16 +87,17 @@
"column": 4
}
},
"value": 0,
"extra": {
"raw": "0",
"rawValue": 0
}
"rawValue": 0,
"raw": "0"
},
"value": 0
},
"computed": true
"computed": true,
"optional": true
}
}
],
"directives": []
}
}
}
1 change: 1 addition & 0 deletions test/fixtures/safe-call-expression/js/basic/actual.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
f?.(x)
101 changes: 101 additions & 0 deletions test/fixtures/safe-call-expression/js/basic/expected.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
{
"type": "File",
"start": 0,
"end": 6,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 6
}
},
"program": {
"type": "Program",
"start": 0,
"end": 6,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 6
}
},
"sourceType": "script",
"body": [
{
"type": "ExpressionStatement",
"start": 0,
"end": 6,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 6
}
},
"expression": {
"type": "CallExpression",
"start": 0,
"end": 6,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 6
}
},
"callee": {
"type": "Identifier",
"start": 0,
"end": 1,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 1
},
"identifierName": "f"
},
"name": "f"
},
"optional": true,
"arguments": [
{
"type": "Identifier",
"start": 4,
"end": 5,
"loc": {
"start": {
"line": 1,
"column": 4
},
"end": {
"line": 1,
"column": 5
},
"identifierName": "x"
},
"name": "x"
}
]
}
}
],
"directives": []
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
},
"name": "f"
},
"optional": true,
"arguments": [
{
"type": "Identifier",
Expand All @@ -91,8 +92,7 @@
},
"name": "x"
}
],
"safe": true
]
}
}
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,11 +87,11 @@
},
"name": "f"
},
"arguments": [],
"safe": true
"optional": true,
"arguments": []
},
"arguments": [],
"safe": true
"optional": true,
"arguments": []
}
}
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@
},
"name": "it"
},
"safe": true,
"optional": true,
"arguments": []
}
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@
},
"name": "it"
},
"safe": true,
"optional": true,
"arguments": [
{
"type": "Identifier",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@
},
"name": "c"
},
"optional": true,
"arguments": [
{
"type": "Identifier",
Expand All @@ -139,8 +140,7 @@
},
"name": "d"
}
],
"safe": true
]
}
}
}
Expand Down
Loading

0 comments on commit 926a863

Please sign in to comment.