Skip to content

Commit

Permalink
SafeMemberExpression
Browse files Browse the repository at this point in the history
  • Loading branch information
rattrayalex committed Mar 1, 2017
1 parent a5d418b commit f59a365
Show file tree
Hide file tree
Showing 10 changed files with 612 additions and 2 deletions.
17 changes: 17 additions & 0 deletions src/parser/expression.js
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,23 @@ pp.parseSubscripts = function (base, startPos, startLoc, noCalls) {
node.property = this.parseIdentifier(true);
node.computed = false;
base = this.finishNode(node, "MemberExpression");
} else if (this.hasPlugin("lightscript") && this.match(tt.elvis)) {
// `x?.y`
const node = this.startNodeAt(startPos, startLoc);
const op = this.state.value;
this.next();
node.object = base;
if (op === "?.") {
node.property = this.parseIdentifier(true);
node.computed = false;
} else if (op === "?[") {
node.property = this.parseExpression();
node.computed = true;
this.expect(tt.bracketR);
} else {
this.unexpected();
}
base = this.finishNode(node, "SafeMemberExpression");
} else if (this.hasPlugin("lightscript") && !noCalls && this.eat(tt.tilde)) {
const node = this.startNodeAt(startPos, startLoc);
node.left = base;
Expand Down
3 changes: 2 additions & 1 deletion src/plugins/lightscript.js
Original file line number Diff line number Diff line change
Expand Up @@ -450,7 +450,8 @@ pp.parseAwaitArrow = function (left) {
};

pp.tryParseNamedArrowDeclaration = function () {
let node = this.startNode(), call = this.startNode();
let node = this.startNode();
const call = this.startNode();

if (!this.match(tt.name)) return null;
if (this.state.value === "type") return null;
Expand Down
11 changes: 10 additions & 1 deletion src/tokenizer/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -523,7 +523,16 @@ export default class Tokenizer {
return this.finishToken(tt.colon);
}

case 63: ++this.state.pos; return this.finishToken(tt.question);
case 63:
if (this.hasPlugin("lightscript")) {
const next = this.input.charCodeAt(this.state.pos + 1);
// `?.` or `?[`
if (next === 46 || next === 91) {
return this.finishOp(tt.elvis, 2);
}
}
++this.state.pos;
return this.finishToken(tt.question);
case 64: ++this.state.pos; return this.finishToken(tt.at);

case 96: // '`'
Expand Down
1 change: 1 addition & 0 deletions src/tokenizer/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ export const types = {
colonEq: new TokenType(":=", { beforeExpr, isAssign }),
tilde: new TokenType("~"),
awaitArrow: new TokenType("<-", { beforeExpr, isAssign }),
elvis: new TokenType("?."),

num: new TokenType("num", { startsExpr }),
regexp: new TokenType("regexp", { startsExpr }),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
x?.y
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
{
"type": "File",
"start": 0,
"end": 4,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 4
}
},
"program": {
"type": "Program",
"start": 0,
"end": 4,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 4
}
},
"sourceType": "script",
"body": [
{
"type": "ExpressionStatement",
"start": 0,
"end": 4,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 4
}
},
"expression": {
"type": "SafeMemberExpression",
"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": "x"
},
"name": "x"
},
"property": {
"type": "Identifier",
"start": 3,
"end": 4,
"loc": {
"start": {
"line": 1,
"column": 3
},
"end": {
"line": 1,
"column": 4
},
"identifierName": "y"
},
"name": "y"
},
"computed": false
}
}
],
"directives": []
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
x.y?.a?.b.c[d](e, f)[g]?.h
Loading

0 comments on commit f59a365

Please sign in to comment.