Skip to content

Commit

Permalink
feat: add optional chaining support (?.)
Browse files Browse the repository at this point in the history
Standard syntax:
obj.val?.prop
obj.val?.[expr]
obj.arr?.[index]
obj.func?.(args)
  • Loading branch information
6utt3rfly committed Sep 26, 2021
1 parent 01b9efb commit 56d1e3d
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 11 deletions.
40 changes: 29 additions & 11 deletions src/jsep.js
Original file line number Diff line number Diff line change
Expand Up @@ -558,19 +558,20 @@ export class Jsep {
this.gobbleSpaces();

let ch = this.code;
while (ch === Jsep.PERIOD_CODE || ch === Jsep.OBRACK_CODE || ch === Jsep.OPAREN_CODE) {
this.index++;

if (ch === Jsep.PERIOD_CODE) {
while (ch === Jsep.PERIOD_CODE || ch === Jsep.OBRACK_CODE || ch === Jsep.OPAREN_CODE || ch === Jsep.QUMARK_CODE) {
let optional;
if (ch === Jsep.QUMARK_CODE) {
if (this.expr.charCodeAt(this.index + 1) !== Jsep.PERIOD_CODE) {
break;
}
optional = true;
this.index += 2;
this.gobbleSpaces();
node = {
type: Jsep.MEMBER_EXP,
computed: false,
object: node,
property: this.gobbleIdentifier(),
};
ch = this.code;
}
else if (ch === Jsep.OBRACK_CODE) {
this.index++;

if (ch === Jsep.OBRACK_CODE) {
node = {
type: Jsep.MEMBER_EXP,
computed: true,
Expand All @@ -592,6 +593,23 @@ export class Jsep {
callee: node
};
}
else if (ch === Jsep.PERIOD_CODE || optional) {
if (optional) {
this.index--;
}
this.gobbleSpaces();
node = {
type: Jsep.MEMBER_EXP,
computed: false,
object: node,
property: this.gobbleIdentifier(),
};
}

if (optional) {
node.optional = true;
} // else leave undefined for compatibility with esprima

this.gobbleSpaces();
ch = this.code;
}
Expand Down
4 changes: 4 additions & 0 deletions test/jsep.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ import {testParser, testOpExpression, esprimaComparisonTest, resetJsepDefaults}
},
}, assert);
testParser('Δέλτα', { name: 'Δέλτα' }, assert);
testParser('a?.b?.(arg)?.[c] ?. d', {
type: 'MemberExpression',
optional: true,
}, assert);
});

QUnit.test('Function Calls', function (assert) {
Expand Down

0 comments on commit 56d1e3d

Please sign in to comment.