sucrase
Version:
Super-fast alternative to Babel for when you can target modern JS runtimes
91 lines (90 loc) • 3.54 kB
JavaScript
;
// The algorithm used to determine whether a regexp can appear at a
// given point in the program is loosely based on sweet.js' approach.
// See https://github.com/mozilla/sweet.js/wiki/design
Object.defineProperty(exports, "__esModule", { value: true });
const whitespace_1 = require("../util/whitespace");
const types_1 = require("./types");
class TokContext {
constructor(token, isExpr, preserveSpace, override = null) {
this.token = token;
this.isExpr = !!isExpr;
this.preserveSpace = !!preserveSpace;
this.override = override;
}
}
exports.TokContext = TokContext;
exports.types = {
braceStatement: new TokContext("{", false),
braceExpression: new TokContext("{", true),
templateQuasi: new TokContext("${", true),
parenStatement: new TokContext("(", false),
parenExpression: new TokContext("(", true),
template: new TokContext("`", true, true, (p) => {
p.readTmplToken();
}),
functionExpression: new TokContext("function", true),
};
// Token-specific context update code
const updateEnd = function () {
if (this.state.context.length === 1) {
this.state.exprAllowed = true;
return;
}
const out = this.state.context.pop();
if (out === exports.types.braceStatement && this.curContext() === exports.types.functionExpression) {
this.state.context.pop();
this.state.exprAllowed = false;
}
else if (out === exports.types.templateQuasi) {
this.state.exprAllowed = true;
}
else {
this.state.exprAllowed = !out.isExpr;
}
};
types_1.types.parenR.updateContext = updateEnd;
types_1.types.braceR.updateContext = updateEnd;
types_1.types.name.updateContext = function (prevType) {
if (this.state.value === "of" && this.curContext() === exports.types.parenStatement) {
this.state.exprAllowed = !prevType.beforeExpr;
return;
}
this.state.exprAllowed = false;
if (prevType === types_1.types._let || prevType === types_1.types._const || prevType === types_1.types._var) {
if (whitespace_1.lineBreak.test(this.input.slice(this.state.end))) {
this.state.exprAllowed = true;
}
}
};
types_1.types.braceL.updateContext = function (prevType) {
this.state.context.push(this.braceIsBlock(prevType) ? exports.types.braceStatement : exports.types.braceExpression);
this.state.exprAllowed = true;
};
types_1.types.dollarBraceL.updateContext = function () {
this.state.context.push(exports.types.templateQuasi);
this.state.exprAllowed = true;
};
types_1.types.parenL.updateContext = function (prevType) {
const statementParens = prevType === types_1.types._if || prevType === types_1.types._for || prevType === types_1.types._with || prevType === types_1.types._while;
this.state.context.push(statementParens ? exports.types.parenStatement : exports.types.parenExpression);
this.state.exprAllowed = true;
};
types_1.types.incDec.updateContext = function () {
// tokExprAllowed stays unchanged
};
types_1.types._function.updateContext = function () {
if (this.curContext() !== exports.types.braceStatement) {
this.state.context.push(exports.types.functionExpression);
}
this.state.exprAllowed = false;
};
types_1.types.backQuote.updateContext = function () {
if (this.curContext() === exports.types.template) {
this.state.context.pop();
}
else {
this.state.context.push(exports.types.template);
}
this.state.exprAllowed = false;
};