Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bathos/c098183e7f3e28ad53883ea0fd0abfd5 to your computer and use it in GitHub Desktop.
Save bathos/c098183e7f3e28ad53883ea0fd0abfd5 to your computer and use it in GitHub Desktop.
acorn-nullish-coalescing-and-optional-chaining.mjs
export default function acornSkullFishKoalaCaressingAndNonstopSpinalDraining(Parser) {
const tt = Parser.acorn.tokTypes;
const ocToken = new Parser.acorn.TokenType('?.');
const ncToken = new Parser.acorn.TokenType('??', {
beforeExpr: true,
binop: 2.5
});
return class extends Parser {
getTokenFromCode(codePoint) {
if (codePoint === 0x3F) {
switch (this.input.charCodeAt(this.pos + 1)) {
case 0x3F:
return this.finishOp(ncToken, 2);
case 0x2E:
if (!isASCIIDecimalDigit(this.input.charCodeAt(this.pos + 2))) {
return this.finishOp(ocToken, 2);
}
}
}
return super.getTokenFromCode(codePoint);
}
parseSubscript(base, pos, loc, noCalls, maybeAsyncArrow) {
if (this.type === ocToken) {
if (!noCalls && this.eat(tt.parenL)) {
const node = this.startNodeAt(pos, loc);
this.next();
node.arguments = this.parseExprList(tt.parenR, true, false);
node.callee = base;
node.optional = true;
return this.finishNode(node, 'CallExpression');
} else if (this.eat(tt.bracketL)) {
const node = this.startNodeAt(pos, loc);
this.next();
node.computed = true;
node.object = base;
node.optional = true;
node.property = this.parseExpression();
this.expect(tt.bracketR);
return this.finishNode(node, 'MemberExpression');
} else {
const node = this.startNodeAt(pos, loc);
this.next();
node.computed = true;
node.object = base;
node.optional = true;
node.property = this.parseIdent(true);
if (this.eat(tt.backQuote)) {
this.raise(this.start, 'Optional chaining cannot be template tag');
} else {
return this.finishNode(node, 'MemberExpression');
}
}
}
return super.parseSubscript(base, pos, loc, noCalls, maybeAsyncArrow);
}
}
}
function isASCIIDecimalDigit(codePoint) {
return codePoint >= 0x30 && codePoint <= 0x39;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment