babel/babylon#328 babel/babylon#205 ?. as nullPropagation. For now it only works for member access. (.? or ?.[) If the object is undefined this will return undefined. If the object on which you want to access the property is defined, the value of the propery will be given back.

This commit is contained in:
Kristof Degrave 2017-02-11 21:09:27 +01:00
parent b902fe6c7b
commit 1eaf01661b
6 changed files with 68 additions and 75 deletions

View File

@ -857,7 +857,7 @@ interface MemberExpression <: Expression, Pattern {
object: Expression | Super;
property: Expression;
computed: boolean;
nullPropagation: boolean;
nullPropagation: boolean | null;
}
```

View File

@ -284,27 +284,29 @@ pp.parseSubscripts = function (base, startPos, startLoc, noCalls) {
node.object = base;
node.callee = this.parseNoCallExpr();
return this.parseSubscripts(this.finishNode(node, "BindExpression"), startPos, startLoc, noCalls);
} else if (this.eat(tt.questionDot)) {
let node = this.startNodeAt(startPos, startLoc);
node.object = base;
node.property = this.parseIdentifier(true);
node.computed = false;
node.nullPropagation = true;
base = this.finishNode(node, "MemberExpression");
} else if (this.eat(tt.questionDot)) {
base.nullPropagation = true;
if (this.eat(tt.bracketL)) {
const node = this.startNodeAt(startPos, startLoc);
node.object = base;
node.property = this.parseExpression();
node.computed = true;
this.expect(tt.bracketR);
base = this.finishNode(node, "MemberExpression");
}
else {
const node = this.startNodeAt(startPos, startLoc);
node.object = base;
node.property = this.parseIdentifier(true);
node.computed = false;
base = this.finishNode(node, "MemberExpression");
}
} else if (this.eat(tt.dot)) {
const node = this.startNodeAt(startPos, startLoc);
node.object = base;
node.property = this.parseIdentifier(true);
node.computed = false;
node.nullPropagation = false;
base = this.finishNode(node, "MemberExpression");
} else if (this.eat(tt.questionBracketL)) {
let node = this.startNodeAt(startPos, startLoc);
node.object = base;
node.property = this.parseExpression();
node.computed = true;
node.nullPropagation = true;
this.expect(tt.bracketR);
} else if (this.eat(tt.bracketL)) {
const node = this.startNodeAt(startPos, startLoc);
node.object = base;

View File

@ -392,20 +392,16 @@ export default class Tokenizer {
}
readToken_question() { // '?'
let next = this.input.charCodeAt(this.state.pos + 1);
if(next === 46){ // 46 = question '.'
this.state.pos += 2;
return this.finishToken(tt.questionDot);
}
else if(next === 91){ // 91 = question '['
this.state.pos += 2;
return this.finishToken(tt.questionBracketL);
}
else {
++this.state.pos;
return this.finishToken(tt.question);
}
}
const next = this.input.charCodeAt(this.state.pos + 1);
if (next === 46) { // 46 = question '.'
this.state.pos += 2;
return this.finishToken(tt.questionDot);
}
else {
++this.state.pos;
return this.finishToken(tt.question);
}
}
getTokenFromCode(code) {
switch (code) {
@ -825,7 +821,7 @@ export default class Tokenizer {
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

@ -75,8 +75,7 @@ export const types = {
doubleColon: new TokenType("::", { beforeExpr }),
dot: new TokenType("."),
question: new TokenType("?", { beforeExpr }),
questionBracketL: new TokenType("?[", { beforeExpr, startsExpr }),
questionBracketL: new TokenType("?."),
questionDot: new TokenType("?."),
arrow: new TokenType("=>", { beforeExpr }),
template: new TokenType("template"),
ellipsis: new TokenType("...", { beforeExpr }),

View File

@ -2,4 +2,4 @@ o?.x?.y
o?.x ? o.x.z?.w : o.y?.z?.w
o?[0]?[1]?.x
o?.[0]?.["1"]?.x

View File

@ -1,7 +1,7 @@
{
"type": "File",
"start": 0,
"end": 50,
"end": 54,
"loc": {
"start": {
"line": 1,
@ -9,13 +9,13 @@
},
"end": {
"line": 5,
"column": 12
"column": 16
}
},
"program": {
"type": "Program",
"start": 0,
"end": 50,
"end": 54,
"loc": {
"start": {
"line": 1,
@ -23,7 +23,7 @@
},
"end": {
"line": 5,
"column": 12
"column": 16
}
},
"sourceType": "script",
@ -85,7 +85,7 @@
}
},
"name": "o",
"existentialOperator": true
"nullPropagation": true
},
"property": {
"type": "Identifier",
@ -104,7 +104,7 @@
"name": "x"
},
"computed": false,
"existentialOperator": true
"nullPropagation": true
},
"property": {
"type": "Identifier",
@ -182,7 +182,7 @@
}
},
"name": "o",
"existentialOperator": true
"nullPropagation": true
},
"property": {
"type": "Identifier",
@ -295,7 +295,7 @@
"name": "z"
},
"computed": false,
"existentialOperator": true
"nullPropagation": true
},
"property": {
"type": "Identifier",
@ -390,7 +390,7 @@
"name": "y"
},
"computed": false,
"existentialOperator": true
"nullPropagation": true
},
"property": {
"type": "Identifier",
@ -409,7 +409,7 @@
"name": "z"
},
"computed": false,
"existentialOperator": true
"nullPropagation": true
},
"property": {
"type": "Identifier",
@ -434,7 +434,7 @@
{
"type": "ExpressionStatement",
"start": 38,
"end": 50,
"end": 54,
"loc": {
"start": {
"line": 5,
@ -442,13 +442,13 @@
},
"end": {
"line": 5,
"column": 12
"column": 16
}
},
"expression": {
"type": "MemberExpression",
"start": 38,
"end": 50,
"end": 54,
"loc": {
"start": {
"line": 5,
@ -456,13 +456,13 @@
},
"end": {
"line": 5,
"column": 12
"column": 16
}
},
"object": {
"type": "MemberExpression",
"start": 38,
"end": 47,
"end": 51,
"loc": {
"start": {
"line": 5,
@ -470,13 +470,13 @@
},
"end": {
"line": 5,
"column": 9
"column": 13
}
},
"object": {
"type": "MemberExpression",
"start": 38,
"end": 43,
"end": 44,
"loc": {
"start": {
"line": 5,
@ -484,7 +484,7 @@
},
"end": {
"line": 5,
"column": 5
"column": 6
}
},
"object": {
@ -502,62 +502,58 @@
}
},
"name": "o",
"existentialOperator": true
"nullPropagation": true
},
"property": {
"type": "Literal",
"start": 41,
"end": 42,
"type": "NumericLiteral",
"start": 42,
"end": 43,
"loc": {
"start": {
"line": 5,
"column": 3
"column": 4
},
"end": {
"line": 5,
"column": 4
"column": 5
}
},
"value": 0,
"rawValue": 0,
"raw": "0"
"value": 0
},
"computed": true,
"existentialOperator": true
"nullPropagation": true
},
"property": {
"type": "Literal",
"start": 45,
"end": 46,
"type": "StringLiteral",
"start": 47,
"end": 50,
"loc": {
"start": {
"line": 5,
"column": 7
"column": 9
},
"end": {
"line": 5,
"column": 8
"column": 12
}
},
"value": 1,
"rawValue": 1,
"raw": "1"
"value": "1"
},
"computed": true,
"existentialOperator": true
"nullPropagation": true
},
"property": {
"type": "Identifier",
"start": 49,
"end": 50,
"start": 53,
"end": 54,
"loc": {
"start": {
"line": 5,
"column": 11
"column": 15
},
"end": {
"line": 5,
"column": 12
"column": 16
}
},
"name": "x"