Merge pull request #545 from xtuc/feat-optional-chaining

Optional Chaining: Stage 1 plugin
This commit is contained in:
Sven SAULEAU 2017-06-05 23:13:16 +02:00 committed by GitHub
commit e064bb9135
25 changed files with 2134 additions and 3 deletions

View File

@ -140,6 +140,7 @@ require("babylon").parse("code", {
- `functionSent`
- `dynamicImport` ([proposal](https://github.com/tc39/proposal-dynamic-import))
- `numericSeparator` ([proposal](https://github.com/samuelgoto/proposal-numeric-separator))
- `optionalChaining` ([proposal](https://github.com/tc39/proposal-optional-chaining))
- `importMeta` ([proposal](https://github.com/tc39/proposal-import-meta))
### FAQ

View File

@ -859,10 +859,11 @@ interface MemberExpression <: Expression, Pattern {
object: Expression | Super;
property: Expression;
computed: boolean;
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`.
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 indicates 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
@ -896,6 +897,7 @@ interface CallExpression <: Expression {
type: "CallExpression";
callee: Expression | Super | Import;
arguments: [ Expression | SpreadElement ];
optional: boolean | null;
}
```
@ -906,6 +908,7 @@ A function or method call expression.
```js
interface NewExpression <: CallExpression {
type: "NewExpression";
optional: boolean | null;
}
```

View File

@ -301,6 +301,44 @@ export default class ExpressionParser extends LValParser {
node.object = base;
node.callee = this.parseNoCallExpr();
return this.parseSubscripts(this.finishNode(node, "BindExpression"), startPos, startLoc, noCalls);
} else if (this.match(tt.questionDot)) {
if (!this.hasPlugin("optionalChaining")) {
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.property = this.parseExpression();
node.computed = true;
node.optional = true;
this.expect(tt.bracketR);
base = this.finishNode(node, "MemberExpression");
} else if (this.eat(tt.parenL)) {
const possibleAsync = this.state.potentialArrowAt === base.start &&
base.type === "Identifier" &&
base.name === "async" &&
!this.canInsertSemicolon();
node.callee = base;
node.arguments = this.parseCallExpressionArguments(tt.parenR, possibleAsync);
node.optional = true;
base = this.finishNode(node, "CallExpression");
} else {
node.object = base;
node.property = this.parseIdentifier(true);
node.computed = false;
node.optional = true;
base = this.finishNode(node, "MemberExpression");
}
} else if (this.eat(tt.dot)) {
const node = this.startNodeAt(startPos, startLoc);
node.object = base;
@ -736,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);
@ -743,6 +782,9 @@ export default class ExpressionParser extends LValParser {
} else {
node.arguments = [];
}
if (optional) {
node.optional = true;
}
return this.finishNode(node, "NewExpression");
}

View File

@ -426,6 +426,18 @@ export default class Tokenizer extends LocationParser {
return this.finishOp(code === 61 ? tt.eq : tt.prefix, 1);
}
readToken_question() { // '?'
const next = this.input.charCodeAt(this.state.pos + 1);
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 {
++this.state.pos;
return this.finishToken(tt.question);
}
}
getTokenFromCode(code: number): void {
switch (code) {
@ -469,7 +481,7 @@ export default class Tokenizer extends LocationParser {
return this.finishToken(tt.colon);
}
case 63: ++this.state.pos; return this.finishToken(tt.question);
case 63: return this.readToken_question();
case 64: ++this.state.pos; return this.finishToken(tt.at);
case 96: // '`'
@ -917,7 +929,7 @@ export default class Tokenizer extends LocationParser {
const type = this.state.type;
let update;
if (type.keyword && prevType === tt.dot) {
if (type.keyword && (prevType === tt.dot || prevType === tt.questionDot)) {
this.state.exprAllowed = false;
} else if (update = type.updateContext) {
update.call(this, prevType);

View File

@ -102,6 +102,7 @@ export const types: { [name: string]: TokenType } = {
doubleColon: new TokenType("::", { beforeExpr }),
dot: new TokenType("."),
question: new TokenType("?", { beforeExpr }),
questionDot: new TokenType("?."),
arrow: new TokenType("=>", { beforeExpr }),
template: new TokenType("template"),
ellipsis: new TokenType("...", { beforeExpr }),

View File

@ -0,0 +1,9 @@
new C?.()
new C?.(a, b)
new B?.C?.()
new B?.C?.(a, b)
new B?.C

View File

@ -0,0 +1,450 @@
{
"type": "File",
"start": 0,
"end": 66,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 9,
"column": 8
}
},
"program": {
"type": "Program",
"start": 0,
"end": 66,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 9,
"column": 8
}
},
"sourceType": "script",
"body": [
{
"type": "ExpressionStatement",
"start": 0,
"end": 9,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 9
}
},
"expression": {
"type": "NewExpression",
"start": 0,
"end": 9,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 9
}
},
"callee": {
"type": "Identifier",
"start": 4,
"end": 5,
"loc": {
"start": {
"line": 1,
"column": 4
},
"end": {
"line": 1,
"column": 5
},
"identifierName": "C"
},
"name": "C"
},
"arguments": [],
"optional": true
}
},
{
"type": "ExpressionStatement",
"start": 11,
"end": 24,
"loc": {
"start": {
"line": 3,
"column": 0
},
"end": {
"line": 3,
"column": 13
}
},
"expression": {
"type": "NewExpression",
"start": 11,
"end": 24,
"loc": {
"start": {
"line": 3,
"column": 0
},
"end": {
"line": 3,
"column": 13
}
},
"callee": {
"type": "Identifier",
"start": 15,
"end": 16,
"loc": {
"start": {
"line": 3,
"column": 4
},
"end": {
"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": []
}
}

View File

@ -0,0 +1,3 @@
{
"plugins": ["optionalChaining"]
}

View File

@ -0,0 +1,3 @@
true?.3:0
true ? .3 : 0

View File

@ -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": []
}
}

View File

@ -0,0 +1,3 @@
{
"plugins": ["optionalChaining"]
}

View File

@ -0,0 +1,7 @@
func?.()
func?.(a, b)
a?.func?.()
a?.func?.(a, b)

View File

@ -0,0 +1,368 @@
{
"type": "File",
"start": 0,
"end": 52,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 7,
"column": 15
}
},
"program": {
"type": "Program",
"start": 0,
"end": 52,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 7,
"column": 15
}
},
"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
}
},
"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
}
},
{
"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
}
},
"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",
"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
}
},
{
"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": []
}
}

View File

@ -0,0 +1,3 @@
{
"plugins": ["optionalChaining"]
}

View File

@ -0,0 +1,7 @@
obj?.[expr]
obj?.[expr]?.[other]
obj?.[true]
obj?.[true]?.[true]

View File

@ -0,0 +1,363 @@
{
"type": "File",
"start": 0,
"end": 67,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 7,
"column": 19
}
},
"program": {
"type": "Program",
"start": 0,
"end": 67,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 7,
"column": 19
}
},
"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"
},
"property": {
"type": "Identifier",
"start": 6,
"end": 10,
"loc": {
"start": {
"line": 1,
"column": 6
},
"end": {
"line": 1,
"column": 10
},
"identifierName": "expr"
},
"name": "expr"
},
"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
}
}
],
"directives": []
}
}

View File

@ -0,0 +1,3 @@
{
"plugins": ["optionalChaining"]
}

View File

@ -0,0 +1,3 @@
foo?.bar
foo?.bar?.baz

View File

@ -0,0 +1,200 @@
{
"type": "File",
"start": 0,
"end": 23,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 3,
"column": 13
}
},
"program": {
"type": "Program",
"start": 0,
"end": 23,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 3,
"column": 13
}
},
"sourceType": "script",
"body": [
{
"type": "ExpressionStatement",
"start": 0,
"end": 8,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 8
}
},
"expression": {
"type": "MemberExpression",
"start": 0,
"end": 8,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 8
}
},
"object": {
"type": "Identifier",
"start": 0,
"end": 3,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 3
},
"identifierName": "foo"
},
"name": "foo"
},
"property": {
"type": "Identifier",
"start": 5,
"end": 8,
"loc": {
"start": {
"line": 1,
"column": 5
},
"end": {
"line": 1,
"column": 8
},
"identifierName": "bar"
},
"name": "bar"
},
"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": []
}
}

View File

@ -0,0 +1,3 @@
{
"plugins": ["optionalChaining"]
}

View File

@ -0,0 +1 @@
a?.b

View File

@ -0,0 +1,3 @@
{
"throws": "You can only use optional-chaining when the 'optionalChaining' plugin is enabled. (1:0)"
}

View File

@ -0,0 +1,3 @@
a?.b.c.d.e?.f
a.b.c?.d.e.f

View File

@ -0,0 +1,431 @@
{
"type": "File",
"start": 0,
"end": 27,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 3,
"column": 12
}
},
"program": {
"type": "Program",
"start": 0,
"end": 27,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 3,
"column": 12
}
},
"sourceType": "script",
"body": [
{
"type": "ExpressionStatement",
"start": 0,
"end": 13,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 13
}
},
"expression": {
"type": "MemberExpression",
"start": 0,
"end": 13,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 13
}
},
"object": {
"type": "MemberExpression",
"start": 0,
"end": 10,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 10
}
},
"object": {
"type": "MemberExpression",
"start": 0,
"end": 8,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 8
}
},
"object": {
"type": "MemberExpression",
"start": 0,
"end": 6,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 6
}
},
"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
},
"identifierName": "a"
},
"name": "a"
},
"property": {
"type": "Identifier",
"start": 3,
"end": 4,
"loc": {
"start": {
"line": 1,
"column": 3
},
"end": {
"line": 1,
"column": 4
},
"identifierName": "b"
},
"name": "b"
},
"computed": false,
"optional": true
},
"property": {
"type": "Identifier",
"start": 5,
"end": 6,
"loc": {
"start": {
"line": 1,
"column": 5
},
"end": {
"line": 1,
"column": 6
},
"identifierName": "c"
},
"name": "c"
},
"computed": false
},
"property": {
"type": "Identifier",
"start": 7,
"end": 8,
"loc": {
"start": {
"line": 1,
"column": 7
},
"end": {
"line": 1,
"column": 8
},
"identifierName": "d"
},
"name": "d"
},
"computed": false
},
"property": {
"type": "Identifier",
"start": 9,
"end": 10,
"loc": {
"start": {
"line": 1,
"column": 9
},
"end": {
"line": 1,
"column": 10
},
"identifierName": "e"
},
"name": "e"
},
"computed": false
},
"property": {
"type": "Identifier",
"start": 12,
"end": 13,
"loc": {
"start": {
"line": 1,
"column": 12
},
"end": {
"line": 1,
"column": 13
},
"identifierName": "f"
},
"name": "f"
},
"computed": false,
"optional": true
}
},
{
"type": "ExpressionStatement",
"start": 15,
"end": 27,
"loc": {
"start": {
"line": 3,
"column": 0
},
"end": {
"line": 3,
"column": 12
}
},
"expression": {
"type": "MemberExpression",
"start": 15,
"end": 27,
"loc": {
"start": {
"line": 3,
"column": 0
},
"end": {
"line": 3,
"column": 12
}
},
"object": {
"type": "MemberExpression",
"start": 15,
"end": 25,
"loc": {
"start": {
"line": 3,
"column": 0
},
"end": {
"line": 3,
"column": 10
}
},
"object": {
"type": "MemberExpression",
"start": 15,
"end": 23,
"loc": {
"start": {
"line": 3,
"column": 0
},
"end": {
"line": 3,
"column": 8
}
},
"object": {
"type": "MemberExpression",
"start": 15,
"end": 20,
"loc": {
"start": {
"line": 3,
"column": 0
},
"end": {
"line": 3,
"column": 5
}
},
"object": {
"type": "MemberExpression",
"start": 15,
"end": 18,
"loc": {
"start": {
"line": 3,
"column": 0
},
"end": {
"line": 3,
"column": 3
}
},
"object": {
"type": "Identifier",
"start": 15,
"end": 16,
"loc": {
"start": {
"line": 3,
"column": 0
},
"end": {
"line": 3,
"column": 1
},
"identifierName": "a"
},
"name": "a"
},
"property": {
"type": "Identifier",
"start": 17,
"end": 18,
"loc": {
"start": {
"line": 3,
"column": 2
},
"end": {
"line": 3,
"column": 3
},
"identifierName": "b"
},
"name": "b"
},
"computed": false
},
"property": {
"type": "Identifier",
"start": 19,
"end": 20,
"loc": {
"start": {
"line": 3,
"column": 4
},
"end": {
"line": 3,
"column": 5
},
"identifierName": "c"
},
"name": "c"
},
"computed": false
},
"property": {
"type": "Identifier",
"start": 22,
"end": 23,
"loc": {
"start": {
"line": 3,
"column": 7
},
"end": {
"line": 3,
"column": 8
},
"identifierName": "d"
},
"name": "d"
},
"computed": false,
"optional": true
},
"property": {
"type": "Identifier",
"start": 24,
"end": 25,
"loc": {
"start": {
"line": 3,
"column": 9
},
"end": {
"line": 3,
"column": 10
},
"identifierName": "e"
},
"name": "e"
},
"computed": false
},
"property": {
"type": "Identifier",
"start": 26,
"end": 27,
"loc": {
"start": {
"line": 3,
"column": 11
},
"end": {
"line": 3,
"column": 12
},
"identifierName": "f"
},
"name": "f"
},
"computed": false
}
}
],
"directives": []
}
}

View File

@ -0,0 +1,3 @@
{
"plugins": ["optionalChaining"]
}