sucrase
Version:
Super-fast alternative to Babel for when you can target modern JS runtimes
95 lines (94 loc) • 3.52 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tokenizer_1 = require("../tokenizer");
const types_1 = require("../tokenizer/types");
const util_1 = require("./util");
class LValParser extends util_1.default {
// Parses spread element.
parseSpread() {
this.next();
this.parseMaybeAssign(false);
}
parseRest(isBlockScope) {
this.next();
this.parseBindingAtom(isBlockScope);
}
parseBindingIdentifier() {
this.parseIdentifier();
}
// Parses lvalue (assignable) atom.
parseBindingAtom(isBlockScope) {
switch (this.state.type) {
case types_1.types._yield:
case types_1.types.name: {
this.state.type = types_1.types.name;
this.parseBindingIdentifier();
this.state.tokens[this.state.tokens.length - 1].identifierRole = isBlockScope
? tokenizer_1.IdentifierRole.BlockScopedDeclaration
: tokenizer_1.IdentifierRole.FunctionScopedDeclaration;
return;
}
case types_1.types.bracketL: {
this.next();
this.parseBindingList(types_1.types.bracketR, isBlockScope, true /* allowEmpty */);
return;
}
case types_1.types.braceL:
this.parseObj(true, isBlockScope);
return;
default:
throw this.unexpected();
}
}
parseBindingList(close, isBlockScope, allowEmpty, allowModifiers = null) {
let first = true;
let hasRemovedComma = false;
const firstItemTokenIndex = this.state.tokens.length;
while (!this.eat(close)) {
if (first) {
first = false;
}
else {
this.expect(types_1.types.comma);
// After a "this" type in TypeScript, we need to set the following comma (if any) to also be
// a type token so that it will be removed.
if (!hasRemovedComma && this.state.tokens[firstItemTokenIndex].isType) {
this.state.tokens[this.state.tokens.length - 1].isType = true;
hasRemovedComma = true;
}
}
if (allowEmpty && this.match(types_1.types.comma)) {
// Empty item; nothing further to parse for this item.
}
else if (this.eat(close)) {
break;
}
else if (this.match(types_1.types.ellipsis)) {
this.parseRest(isBlockScope);
this.parseAssignableListItemTypes();
this.expect(close);
break;
}
else {
this.parseAssignableListItem(allowModifiers, isBlockScope);
}
}
}
parseAssignableListItem(allowModifiers, isBlockScope) {
this.parseMaybeDefault(isBlockScope);
this.parseAssignableListItemTypes();
this.parseMaybeDefault(isBlockScope, true /* leftAlreadyParsed */);
}
parseAssignableListItemTypes() { }
// Parses assignment pattern around given atom if possible.
parseMaybeDefault(isBlockScope, leftAlreadyParsed = false) {
if (!leftAlreadyParsed) {
this.parseBindingAtom(isBlockScope);
}
if (!this.eat(types_1.types.eq)) {
return;
}
this.parseMaybeAssign();
}
}
exports.default = LValParser;