decaffeinate-parser
Version:
A better AST for CoffeeScript, inspired by CoffeeScriptRedux.
1,574 lines (1,553 loc) • 122 kB
JavaScript
// src/parser.ts
import lex from "coffee-lex";
// src/ext/coffee-script.ts
import {
Base as CS1Base,
Op as CS1Op
} from "decaffeinate-coffeescript/lib/coffee-script/nodes.js";
import { Base, Op } from "decaffeinate-coffeescript2/lib/coffeescript/nodes.js";
function patchCoffeeScript() {
CS1Op.prototype.invert = invert;
CS1Base.prototype.invert = invert;
Op.prototype.invert = invert;
Base.prototype.invert = invert;
}
function invert() {
this.inverted = !this.inverted;
return this;
}
// src/nodes.ts
var Node = class {
constructor(type, line, column, start, end, raw) {
this.type = type;
this.line = line;
this.column = column;
this.start = start;
this.end = end;
this.raw = raw;
this.parentNode = null;
}
getChildren() {
const children = [];
for (const childField of this.getChildFields()) {
if (Array.isArray(childField)) {
children.push(...childField.filter((node) => node !== null));
} else if (childField) {
children.push(childField);
}
}
return children;
}
getChildFields() {
return this.getChildNames().map((name) => this[name]);
}
};
var Identifier = class extends Node {
constructor(line, column, start, end, raw, data) {
super("Identifier", line, column, start, end, raw);
this.data = data;
}
getChildNames() {
return [];
}
};
var Bool = class extends Node {
constructor(line, column, start, end, raw, data) {
super("Bool", line, column, start, end, raw);
this.data = data;
}
static true() {
return new Bool(0, 0, 0, 0, "", true);
}
static false() {
return new Bool(0, 0, 0, 0, "", false);
}
getChildNames() {
return [];
}
};
var JavaScript = class extends Node {
constructor(line, column, start, end, raw, data) {
super("JavaScript", line, column, start, end, raw);
this.data = data;
}
getChildNames() {
return [];
}
};
var Number = class extends Node {
constructor(type, line, column, start, end, raw, data) {
super(type, line, column, start, end, raw);
this.data = data;
}
getChildNames() {
return [];
}
};
var Float = class extends Number {
constructor(line, column, start, end, raw, data) {
super("Float", line, column, start, end, raw, data);
}
};
var Int = class extends Number {
constructor(line, column, start, end, raw, data) {
super("Int", line, column, start, end, raw, data);
}
};
var AccessOp = class extends Node {
constructor(type, line, column, start, end, raw, expression) {
super(type, line, column, start, end, raw);
this.expression = expression;
}
};
var MemberAccessOp = class extends AccessOp {
constructor(line, column, start, end, raw, expression, member) {
super("MemberAccessOp", line, column, start, end, raw, expression);
this.member = member;
}
getChildNames() {
return ["expression", "member"];
}
};
var ProtoMemberAccessOp = class extends AccessOp {
constructor(line, column, start, end, raw, expression) {
super("ProtoMemberAccessOp", line, column, start, end, raw, expression);
}
getChildNames() {
return ["expression"];
}
};
var SoakedMemberAccessOp = class extends AccessOp {
constructor(line, column, start, end, raw, expression, member) {
super("SoakedMemberAccessOp", line, column, start, end, raw, expression);
this.member = member;
}
getChildNames() {
return ["expression", "member"];
}
};
var SoakedProtoMemberAccessOp = class extends AccessOp {
constructor(line, column, start, end, raw, expression) {
super("SoakedProtoMemberAccessOp", line, column, start, end, raw, expression);
}
getChildNames() {
return ["expression"];
}
};
var DynamicMemberAccessOp = class extends AccessOp {
constructor(line, column, start, end, raw, expression, indexingExpr) {
super("DynamicMemberAccessOp", line, column, start, end, raw, expression);
this.indexingExpr = indexingExpr;
}
getChildNames() {
return ["expression", "indexingExpr"];
}
};
var SoakedDynamicMemberAccessOp = class extends AccessOp {
constructor(line, column, start, end, raw, expression, indexingExpr) {
super("SoakedDynamicMemberAccessOp", line, column, start, end, raw, expression);
this.indexingExpr = indexingExpr;
}
getChildNames() {
return ["expression", "indexingExpr"];
}
};
var Quasi = class extends Node {
constructor(line, column, start, end, raw, data) {
super("Quasi", line, column, start, end, raw);
this.data = data;
}
getChildNames() {
return [];
}
};
var String = class extends Node {
constructor(line, column, start, end, raw, quasis, expressions) {
super("String", line, column, start, end, raw);
this.quasis = quasis;
this.expressions = expressions;
}
getChildNames() {
return ["quasis", "expressions"];
}
};
var TaggedTemplateLiteral = class extends Node {
constructor(line, column, start, end, raw, tag, template) {
super("TaggedTemplateLiteral", line, column, start, end, raw);
this.tag = tag;
this.template = template;
}
getChildNames() {
return ["tag", "template"];
}
};
var ObjectInitialiser = class extends Node {
constructor(line, column, start, end, raw, members) {
super("ObjectInitialiser", line, column, start, end, raw);
this.members = members;
}
getChildNames() {
return ["members"];
}
};
var ObjectInitialiserMember = class extends Node {
constructor(line, column, start, end, raw, key, expression, isComputed) {
super("ObjectInitialiserMember", line, column, start, end, raw);
this.key = key;
this.expression = expression;
this.isComputed = isComputed;
}
getChildNames() {
return ["key", "expression"];
}
};
var Conditional = class extends Node {
constructor(line, column, start, end, raw, condition, consequent, alternate, isUnless) {
super("Conditional", line, column, start, end, raw);
this.condition = condition;
this.consequent = consequent;
this.alternate = alternate;
this.isUnless = isUnless;
}
getChildNames() {
return ["condition", "consequent", "alternate"];
}
};
var Program = class extends Node {
constructor(line, column, start, end, raw, body, context) {
super("Program", line, column, start, end, raw);
this.body = body;
this.context = context;
}
getChildNames() {
return ["body"];
}
};
var Block = class extends Node {
constructor(line, column, start, end, raw, statements, inline) {
super("Block", line, column, start, end, raw);
this.statements = statements;
this.inline = inline;
}
getChildNames() {
return ["statements"];
}
withInline(inline) {
return new Block(this.line, this.column, this.start, this.end, this.raw, this.statements, inline);
}
};
var Loop = class extends Node {
constructor(line, column, start, end, raw, body) {
super("Loop", line, column, start, end, raw);
this.body = body;
}
getChildNames() {
return ["body"];
}
};
var While = class extends Node {
constructor(line, column, start, end, raw, condition, guard, body, isUntil) {
super("While", line, column, start, end, raw);
this.condition = condition;
this.guard = guard;
this.body = body;
this.isUntil = isUntil;
}
getChildNames() {
return ["condition", "guard", "body"];
}
};
var For = class extends Node {
constructor(type, line, column, start, end, raw, keyAssignee, valAssignee, target, filter, body) {
super(type, line, column, start, end, raw);
this.keyAssignee = keyAssignee;
this.valAssignee = valAssignee;
this.target = target;
this.filter = filter;
this.body = body;
}
};
var ForOf = class extends For {
constructor(line, column, start, end, raw, keyAssignee, valAssignee, target, filter, body, isOwn) {
super("ForOf", line, column, start, end, raw, keyAssignee, valAssignee, target, filter, body);
this.isOwn = isOwn;
}
getChildNames() {
return ["keyAssignee", "valAssignee", "target", "filter", "body"];
}
};
var ForIn = class extends For {
constructor(line, column, start, end, raw, keyAssignee, valAssignee, target, filter, body, step) {
super("ForIn", line, column, start, end, raw, keyAssignee, valAssignee, target, filter, body);
this.step = step;
}
getChildNames() {
return ["keyAssignee", "valAssignee", "target", "step", "filter", "body"];
}
};
var ForFrom = class extends For {
constructor(line, column, start, end, raw, valAssignee, target, filter, body) {
super("ForFrom", line, column, start, end, raw, null, valAssignee, target, filter, body);
}
getChildNames() {
return ["keyAssignee", "valAssignee", "target", "filter", "body"];
}
};
var Switch = class extends Node {
constructor(line, column, start, end, raw, expression, cases, alternate) {
super("Switch", line, column, start, end, raw);
this.expression = expression;
this.cases = cases;
this.alternate = alternate;
}
getChildNames() {
return ["expression", "cases", "alternate"];
}
};
var SwitchCase = class extends Node {
constructor(line, column, start, end, raw, conditions, consequent) {
super("SwitchCase", line, column, start, end, raw);
this.conditions = conditions;
this.consequent = consequent;
}
getChildNames() {
return ["conditions", "consequent"];
}
};
var RegexFlags = class {
constructor(global, ignoreCase, multiline, unicode, sticky) {
this.global = global;
this.ignoreCase = ignoreCase;
this.multiline = multiline;
this.unicode = unicode;
this.sticky = sticky;
this.g = global;
this.i = ignoreCase;
this.m = multiline;
this.u = unicode;
this.y = sticky;
}
static parse(flags) {
let global = false;
let ignoreCase = false;
let multiline = false;
let unicode = false;
let sticky = false;
for (let i = 0; i < flags.length; i++) {
switch (flags.charCodeAt(i)) {
case 103:
global = true;
break;
case 105:
ignoreCase = true;
break;
case 109:
multiline = true;
break;
case 117:
unicode = true;
break;
case 121:
sticky = true;
break;
default:
throw new Error(`invalid regular expression flags: ${flags}`);
}
}
return new RegexFlags(global, ignoreCase, multiline, unicode, sticky);
}
};
var Heregex = class extends Node {
constructor(line, column, start, end, raw, quasis, expressions, flags) {
super("Heregex", line, column, start, end, raw);
this.quasis = quasis;
this.expressions = expressions;
this.flags = flags;
}
getChildNames() {
return ["quasis", "expressions"];
}
};
var Null = class extends Node {
constructor(line, column, start, end, raw) {
super("Null", line, column, start, end, raw);
}
getChildNames() {
return [];
}
};
var Undefined = class extends Node {
constructor(line, column, start, end, raw) {
super("Undefined", line, column, start, end, raw);
}
getChildNames() {
return [];
}
};
var Regex = class extends Node {
constructor(line, column, start, end, raw, pattern, flags) {
super("Regex", line, column, start, end, raw);
this.pattern = pattern;
this.flags = flags;
}
getChildNames() {
return [];
}
};
var Return = class extends Node {
constructor(line, column, start, end, raw, expression) {
super("Return", line, column, start, end, raw);
this.expression = expression;
}
getChildNames() {
return ["expression"];
}
};
var YieldReturn = class extends Node {
constructor(line, column, start, end, raw, expression) {
super("YieldReturn", line, column, start, end, raw);
this.expression = expression;
}
getChildNames() {
return ["expression"];
}
};
var AwaitReturn = class extends Node {
constructor(line, column, start, end, raw, expression) {
super("AwaitReturn", line, column, start, end, raw);
this.expression = expression;
}
getChildNames() {
return ["expression"];
}
};
var This = class extends Node {
constructor(line, column, start, end, raw) {
super("This", line, column, start, end, raw);
}
getChildNames() {
return [];
}
};
var Throw = class extends Node {
constructor(line, column, start, end, raw, expression) {
super("Throw", line, column, start, end, raw);
this.expression = expression;
}
getChildNames() {
return ["expression"];
}
};
var ArrayInitialiser = class extends Node {
constructor(line, column, start, end, raw, members) {
super("ArrayInitialiser", line, column, start, end, raw);
this.members = members;
}
getChildNames() {
return ["members"];
}
};
var DefaultParam = class extends Node {
constructor(line, column, start, end, raw, param, defaultValue) {
super("DefaultParam", line, column, start, end, raw);
this.param = param;
this.default = defaultValue;
}
getChildNames() {
return ["param", "default"];
}
};
var Rest = class extends Node {
constructor(line, column, start, end, raw, expression) {
super("Rest", line, column, start, end, raw);
this.expression = expression;
}
getChildNames() {
return ["expression"];
}
};
var Expansion = class extends Node {
constructor(line, column, start, end, raw) {
super("Expansion", line, column, start, end, raw);
}
getChildNames() {
return [];
}
};
var Elision = class extends Node {
constructor(line, column, start, end, raw) {
super("Elision", line, column, start, end, raw);
}
getChildNames() {
return [];
}
};
var Break = class extends Node {
constructor(line, column, start, end, raw) {
super("Break", line, column, start, end, raw);
}
getChildNames() {
return [];
}
};
var Continue = class extends Node {
constructor(line, column, start, end, raw) {
super("Continue", line, column, start, end, raw);
}
getChildNames() {
return [];
}
};
var Debugger = class extends Node {
constructor(line, column, start, end, raw) {
super("Debugger", line, column, start, end, raw);
}
getChildNames() {
return [];
}
};
var Spread = class extends Node {
constructor(line, column, start, end, raw, expression) {
super("Spread", line, column, start, end, raw);
this.expression = expression;
}
getChildNames() {
return ["expression"];
}
};
var Range = class extends Node {
constructor(line, column, start, end, raw, left, right, isInclusive) {
super("Range", line, column, start, end, raw);
this.left = left;
this.right = right;
this.isInclusive = isInclusive;
}
getChildNames() {
return ["left", "right"];
}
};
var BinaryOp = class extends Node {
constructor(type, line, column, start, end, raw, left, right) {
super(type, line, column, start, end, raw);
this.left = left;
this.right = right;
}
getChildNames() {
return ["left", "right"];
}
};
var UnaryOp = class extends Node {
constructor(type, line, column, start, end, raw, expression) {
super(type, line, column, start, end, raw);
this.expression = expression;
}
getChildNames() {
return ["expression"];
}
};
var ChainedComparisonOp = class extends Node {
constructor(line, column, start, end, raw, operands, operators) {
super("ChainedComparisonOp", line, column, start, end, raw);
this.operands = operands;
this.operators = operators;
}
getChildNames() {
return ["operands"];
}
};
var OperatorInfo = class {
constructor(operator, token) {
this.operator = operator;
this.token = token;
}
};
var EQOp = class extends BinaryOp {
constructor(line, column, start, end, raw, left, right) {
super("EQOp", line, column, start, end, raw, left, right);
}
};
var NEQOp = class extends BinaryOp {
constructor(line, column, start, end, raw, left, right) {
super("NEQOp", line, column, start, end, raw, left, right);
}
};
var LTOp = class extends BinaryOp {
constructor(line, column, start, end, raw, left, right) {
super("LTOp", line, column, start, end, raw, left, right);
}
};
var LTEOp = class extends BinaryOp {
constructor(line, column, start, end, raw, left, right) {
super("LTEOp", line, column, start, end, raw, left, right);
}
};
var GTOp = class extends BinaryOp {
constructor(line, column, start, end, raw, left, right) {
super("GTOp", line, column, start, end, raw, left, right);
}
};
var GTEOp = class extends BinaryOp {
constructor(line, column, start, end, raw, left, right) {
super("GTEOp", line, column, start, end, raw, left, right);
}
};
var LogicalNotOp = class extends UnaryOp {
constructor(line, column, start, end, raw, expression) {
super("LogicalNotOp", line, column, start, end, raw, expression);
}
};
var LogicalAndOp = class extends BinaryOp {
constructor(line, column, start, end, raw, left, right) {
super("LogicalAndOp", line, column, start, end, raw, left, right);
}
};
var LogicalOrOp = class extends BinaryOp {
constructor(line, column, start, end, raw, left, right) {
super("LogicalOrOp", line, column, start, end, raw, left, right);
}
};
var SubtractOp = class extends BinaryOp {
constructor(line, column, start, end, raw, left, right) {
super("SubtractOp", line, column, start, end, raw, left, right);
}
};
var PlusOp = class extends BinaryOp {
constructor(line, column, start, end, raw, left, right) {
super("PlusOp", line, column, start, end, raw, left, right);
}
};
var UnaryPlusOp = class extends UnaryOp {
constructor(line, column, start, end, raw, expression) {
super("UnaryPlusOp", line, column, start, end, raw, expression);
}
};
var MultiplyOp = class extends BinaryOp {
constructor(line, column, start, end, raw, left, right) {
super("MultiplyOp", line, column, start, end, raw, left, right);
}
};
var DivideOp = class extends BinaryOp {
constructor(line, column, start, end, raw, left, right) {
super("DivideOp", line, column, start, end, raw, left, right);
}
};
var FloorDivideOp = class extends BinaryOp {
constructor(line, column, start, end, raw, left, right) {
super("FloorDivideOp", line, column, start, end, raw, left, right);
}
};
var ExistsOp = class extends BinaryOp {
constructor(line, column, start, end, raw, left, right) {
super("ExistsOp", line, column, start, end, raw, left, right);
}
};
var UnaryExistsOp = class extends UnaryOp {
constructor(line, column, start, end, raw, expression) {
super("UnaryExistsOp", line, column, start, end, raw, expression);
}
};
var UnaryNegateOp = class extends UnaryOp {
constructor(line, column, start, end, raw, expression) {
super("UnaryNegateOp", line, column, start, end, raw, expression);
}
};
var BitNotOp = class extends UnaryOp {
constructor(line, column, start, end, raw, expression) {
super("BitNotOp", line, column, start, end, raw, expression);
}
};
var BitAndOp = class extends BinaryOp {
constructor(line, column, start, end, raw, left, right) {
super("BitAndOp", line, column, start, end, raw, left, right);
}
};
var BitOrOp = class extends BinaryOp {
constructor(line, column, start, end, raw, left, right) {
super("BitOrOp", line, column, start, end, raw, left, right);
}
};
var BitXorOp = class extends BinaryOp {
constructor(line, column, start, end, raw, left, right) {
super("BitXorOp", line, column, start, end, raw, left, right);
}
};
var LeftShiftOp = class extends BinaryOp {
constructor(line, column, start, end, raw, left, right) {
super("LeftShiftOp", line, column, start, end, raw, left, right);
}
};
var SignedRightShiftOp = class extends BinaryOp {
constructor(line, column, start, end, raw, left, right) {
super("SignedRightShiftOp", line, column, start, end, raw, left, right);
}
};
var UnsignedRightShiftOp = class extends BinaryOp {
constructor(line, column, start, end, raw, left, right) {
super("UnsignedRightShiftOp", line, column, start, end, raw, left, right);
}
};
var PreDecrementOp = class extends UnaryOp {
constructor(line, column, start, end, raw, expression) {
super("PreDecrementOp", line, column, start, end, raw, expression);
}
};
var PreIncrementOp = class extends UnaryOp {
constructor(line, column, start, end, raw, expression) {
super("PreIncrementOp", line, column, start, end, raw, expression);
}
};
var PostDecrementOp = class extends UnaryOp {
constructor(line, column, start, end, raw, expression) {
super("PostDecrementOp", line, column, start, end, raw, expression);
}
};
var PostIncrementOp = class extends UnaryOp {
constructor(line, column, start, end, raw, expression) {
super("PostIncrementOp", line, column, start, end, raw, expression);
}
};
var ExpOp = class extends BinaryOp {
constructor(line, column, start, end, raw, left, right) {
super("ExpOp", line, column, start, end, raw, left, right);
}
};
var RemOp = class extends BinaryOp {
constructor(line, column, start, end, raw, left, right) {
super("RemOp", line, column, start, end, raw, left, right);
}
};
var ModuloOp = class extends BinaryOp {
constructor(line, column, start, end, raw, left, right) {
super("ModuloOp", line, column, start, end, raw, left, right);
}
};
var InOp = class extends BinaryOp {
constructor(line, column, start, end, raw, left, right, isNot) {
super("InOp", line, column, start, end, raw, left, right);
this.isNot = isNot;
}
};
var BaseAssignOp = class extends Node {
constructor(type, line, column, start, end, raw, assignee, expression) {
super(type, line, column, start, end, raw);
this.assignee = assignee;
this.expression = expression;
}
getChildNames() {
return ["assignee", "expression"];
}
};
var AssignOp = class extends BaseAssignOp {
constructor(line, column, start, end, raw, assignee, expression) {
super("AssignOp", line, column, start, end, raw, assignee, expression);
}
withExpression(expression) {
return new AssignOp(this.line, this.column, this.start, this.end, this.raw, this.assignee, expression);
}
};
var CompoundAssignOp = class extends BaseAssignOp {
constructor(line, column, start, end, raw, assignee, expression, op) {
super("CompoundAssignOp", line, column, start, end, raw, assignee, expression);
this.op = op;
}
};
var ExtendsOp = class extends BinaryOp {
constructor(line, column, start, end, raw, left, right) {
super("ExtendsOp", line, column, start, end, raw, left, right);
}
};
var SeqOp = class extends BinaryOp {
constructor(line, column, start, end, raw, left, right) {
super("SeqOp", line, column, start, end, raw, left, right);
}
};
var TypeofOp = class extends UnaryOp {
constructor(line, column, start, end, raw, expression) {
super("TypeofOp", line, column, start, end, raw, expression);
}
};
var InstanceofOp = class extends BinaryOp {
constructor(line, column, start, end, raw, left, right, isNot) {
super("InstanceofOp", line, column, start, end, raw, left, right);
this.isNot = isNot;
}
};
var OfOp = class extends BinaryOp {
constructor(line, column, start, end, raw, left, right, isNot) {
super("OfOp", line, column, start, end, raw, left, right);
this.isNot = isNot;
}
};
var DeleteOp = class extends UnaryOp {
constructor(line, column, start, end, raw, expression) {
super("DeleteOp", line, column, start, end, raw, expression);
}
};
var Yield = class extends Node {
constructor(line, column, start, end, raw, expression) {
super("Yield", line, column, start, end, raw);
this.expression = expression;
}
getChildNames() {
return ["expression"];
}
};
var YieldFrom = class extends Node {
constructor(line, column, start, end, raw, expression) {
super("YieldFrom", line, column, start, end, raw);
this.expression = expression;
}
getChildNames() {
return ["expression"];
}
};
var Await = class extends Node {
constructor(line, column, start, end, raw, expression) {
super("Await", line, column, start, end, raw);
this.expression = expression;
}
getChildNames() {
return ["expression"];
}
};
var Slice = class extends Node {
constructor(line, column, start, end, raw, expression, left, right, isInclusive) {
super("Slice", line, column, start, end, raw);
this.expression = expression;
this.left = left;
this.right = right;
this.isInclusive = isInclusive;
}
getChildNames() {
return ["expression", "left", "right"];
}
};
var SoakedSlice = class extends Node {
constructor(line, column, start, end, raw, expression, left, right, isInclusive) {
super("SoakedSlice", line, column, start, end, raw);
this.expression = expression;
this.left = left;
this.right = right;
this.isInclusive = isInclusive;
}
getChildNames() {
return ["expression", "left", "right"];
}
};
var BaseFunction = class extends Node {
constructor(type, line, column, start, end, raw, parameters, body) {
super(type, line, column, start, end, raw);
this.parameters = parameters;
this.body = body;
}
getChildNames() {
return ["parameters", "body"];
}
};
var Function = class extends BaseFunction {
constructor(line, column, start, end, raw, parameters, body) {
super("Function", line, column, start, end, raw, parameters, body);
}
withParameters(parameters) {
return new Function(this.line, this.column, this.start, this.end, this.raw, parameters, this.body);
}
};
var BoundFunction = class extends BaseFunction {
constructor(line, column, start, end, raw, parameters, body) {
super("BoundFunction", line, column, start, end, raw, parameters, body);
}
withParameters(parameters) {
return new BoundFunction(this.line, this.column, this.start, this.end, this.raw, parameters, this.body);
}
};
var GeneratorFunction = class extends BaseFunction {
constructor(line, column, start, end, raw, parameters, body) {
super("GeneratorFunction", line, column, start, end, raw, parameters, body);
}
withParameters(parameters) {
return new GeneratorFunction(this.line, this.column, this.start, this.end, this.raw, parameters, this.body);
}
};
var BoundGeneratorFunction = class extends BaseFunction {
constructor(line, column, start, end, raw, parameters, body) {
super("BoundGeneratorFunction", line, column, start, end, raw, parameters, body);
}
withParameters(parameters) {
return new BoundGeneratorFunction(this.line, this.column, this.start, this.end, this.raw, parameters, this.body);
}
};
var AsyncFunction = class extends BaseFunction {
constructor(line, column, start, end, raw, parameters, body) {
super("AsyncFunction", line, column, start, end, raw, parameters, body);
}
withParameters(parameters) {
return new AsyncFunction(this.line, this.column, this.start, this.end, this.raw, parameters, this.body);
}
};
var BoundAsyncFunction = class extends BaseFunction {
constructor(line, column, start, end, raw, parameters, body) {
super("BoundAsyncFunction", line, column, start, end, raw, parameters, body);
}
withParameters(parameters) {
return new BoundAsyncFunction(this.line, this.column, this.start, this.end, this.raw, parameters, this.body);
}
};
var Try = class extends Node {
constructor(line, column, start, end, raw, body, catchAssignee, catchBody, finallyBody) {
super("Try", line, column, start, end, raw);
this.body = body;
this.catchAssignee = catchAssignee;
this.catchBody = catchBody;
this.finallyBody = finallyBody;
}
getChildNames() {
return ["body", "catchAssignee", "catchBody", "finallyBody"];
}
};
var Constructor = class extends BaseAssignOp {
constructor(line, column, start, end, raw, assignee, expression) {
super("Constructor", line, column, start, end, raw, assignee, expression);
}
};
var ClassProtoAssignOp = class extends BaseAssignOp {
constructor(line, column, start, end, raw, assignee, expression) {
super("ClassProtoAssignOp", line, column, start, end, raw, assignee, expression);
}
};
var Class = class extends Node {
constructor(line, column, start, end, raw, nameAssignee, name, body, boundMembers, parent, ctor) {
super("Class", line, column, start, end, raw);
this.nameAssignee = nameAssignee;
this.name = name;
this.body = body;
this.boundMembers = boundMembers;
this.parent = parent;
this.ctor = ctor;
}
getChildNames() {
return ["nameAssignee", "parent", "body"];
}
};
var FunctionApplication = class extends Node {
constructor(line, column, start, end, raw, fn, args) {
super("FunctionApplication", line, column, start, end, raw);
this.function = fn;
this.arguments = args;
}
getChildNames() {
return ["function", "arguments"];
}
};
var SoakedFunctionApplication = class extends Node {
constructor(line, column, start, end, raw, fn, args) {
super("SoakedFunctionApplication", line, column, start, end, raw);
this.function = fn;
this.arguments = args;
}
getChildNames() {
return ["function", "arguments"];
}
};
var Super = class extends Node {
constructor(line, column, start, end, raw) {
super("Super", line, column, start, end, raw);
}
getChildNames() {
return [];
}
};
var BareSuperFunctionApplication = class extends Node {
constructor(line, column, start, end, raw) {
super("BareSuperFunctionApplication", line, column, start, end, raw);
}
getChildNames() {
return [];
}
};
var NewOp = class extends Node {
constructor(line, column, start, end, raw, ctor, args) {
super("NewOp", line, column, start, end, raw);
this.ctor = ctor;
this.arguments = args;
}
getChildNames() {
return ["ctor", "arguments"];
}
};
var SoakedNewOp = class extends Node {
constructor(line, column, start, end, raw, ctor, args) {
super("SoakedNewOp", line, column, start, end, raw);
this.ctor = ctor;
this.arguments = args;
}
getChildNames() {
return ["ctor", "arguments"];
}
};
var DoOp = class extends Node {
constructor(line, column, start, end, raw, expression) {
super("DoOp", line, column, start, end, raw);
this.expression = expression;
}
getChildNames() {
return ["expression"];
}
};
var ImportDeclaration = class extends Node {
constructor(line, column, start, end, raw, defaultBinding, namespaceImport, namedImports, source) {
super("ImportDeclaration", line, column, start, end, raw);
this.defaultBinding = defaultBinding;
this.namespaceImport = namespaceImport;
this.namedImports = namedImports;
this.source = source;
}
getChildNames() {
return ["defaultBinding", "namespaceImport", "namedImports", "source"];
}
};
var ExportNamedDeclaration = class extends Node {
constructor(line, column, start, end, raw, expression) {
super("ExportNamedDeclaration", line, column, start, end, raw);
this.expression = expression;
}
getChildNames() {
return ["expression"];
}
};
var ExportBindingsDeclaration = class extends Node {
constructor(line, column, start, end, raw, namedExports, source) {
super("ExportBindingsDeclaration", line, column, start, end, raw);
this.namedExports = namedExports;
this.source = source;
}
getChildNames() {
return ["namedExports", "source"];
}
};
var ExportDefaultDeclaration = class extends Node {
constructor(line, column, start, end, raw, expression) {
super("ExportDefaultDeclaration", line, column, start, end, raw);
this.expression = expression;
}
getChildNames() {
return ["expression"];
}
};
var ExportAllDeclaration = class extends Node {
constructor(line, column, start, end, raw, source) {
super("ExportAllDeclaration", line, column, start, end, raw);
this.source = source;
}
getChildNames() {
return ["source"];
}
};
var ModuleSpecifier = class extends Node {
constructor(line, column, start, end, raw, original, alias) {
super("ModuleSpecifier", line, column, start, end, raw);
this.original = original;
this.alias = alias;
}
getChildNames() {
return ["original", "alias"];
}
};
var CSXElement = class extends Node {
constructor(line, column, start, end, raw, properties, children) {
super("CSXElement", line, column, start, end, raw);
this.properties = properties;
this.children = children;
}
getChildNames() {
return ["properties", "children"];
}
};
// src/util/isCommentOnlyNode.ts
import {
PassthroughLiteral,
Value
} from "decaffeinate-coffeescript2/lib/coffeescript/nodes.js";
function isCommentOnlyNode(base) {
return base instanceof Value && base.base instanceof PassthroughLiteral && base.base.value === "";
}
// src/mappers/mapBlock.ts
import { SourceType as SourceType14 } from "coffee-lex";
import {
Assign as Assign4,
Obj as Obj4,
Value as Value10
} from "decaffeinate-coffeescript2/lib/coffeescript/nodes.js";
import { inspect as inspect8 } from "util";
// src/util/getLocation.ts
import { SourceType } from "coffee-lex";
import { inspect } from "util";
function getLocation(context, node) {
const loc = node.locationData;
let start = context.linesAndColumns.indexForLocation({
line: loc.first_line,
column: loc.first_column
});
const last = context.linesAndColumns.indexForLocation({
line: loc.last_line,
column: loc.last_column
});
if (start === null || last === null) {
throw new Error(`unable to determine range for location: ${inspect(loc)}}`);
}
const line = loc.first_line + 1;
const column = loc.first_column + 1;
let end = last + 1;
if (start < 0) {
start = 0;
}
if (end > context.source.length) {
end = context.source.length;
}
const firstTokenOfNode = requireToken(firstSemanticTokenAfter(context, start), node);
const lastTokenOfNode = requireToken(firstSemanticTokenBefore(context, end), node);
start = firstTokenOfNode.start;
end = lastTokenOfNode.end;
const raw = context.source.slice(start, end);
return { line, column, start, end, raw };
}
function firstSemanticTokenAfter(context, index) {
const tokenIndex = context.sourceTokens.indexOfTokenMatchingPredicate((token) => {
return token.start >= index && token.type !== SourceType.NEWLINE && token.type !== SourceType.COMMENT;
}, context.sourceTokens.indexOfTokenNearSourceIndex(index));
return tokenIndex === null ? null : context.sourceTokens.tokenAtIndex(tokenIndex);
}
function firstSemanticTokenBefore(context, index) {
const tokenIndex = context.sourceTokens.lastIndexOfTokenMatchingPredicate((token) => {
return token.end <= index && token.type !== SourceType.NEWLINE && token.type !== SourceType.COMMENT;
}, context.sourceTokens.indexOfTokenNearSourceIndex(index));
return tokenIndex === null ? null : context.sourceTokens.tokenAtIndex(tokenIndex);
}
function requireToken(token, node) {
if (token === null) {
throw new Error(`unable to find token for node: ${inspect(node)}`);
}
return token;
}
// src/mappers/mapAny.ts
import {
Arr as Arr2,
Assign as Assign3,
Block as Block3,
Call as Call4,
Class as Class2,
Code,
ComputedPropertyName as ComputedPropertyName2,
Elision as Elision2,
Existence,
Expansion as Expansion2,
Extends,
For as For3,
If,
In,
Literal as Literal8,
ModuleDeclaration as ModuleDeclaration2,
Obj as Obj3,
Op as Op7,
Param,
Parens as Parens2,
Range as Range2,
Return as Return2,
Splat as Splat4,
StringWithInterpolations as StringWithInterpolations4,
Super as Super2,
Switch as Switch2,
TaggedTemplateCall,
Throw as Throw2,
Try as Try2,
Value as Value9,
While as While2
} from "decaffeinate-coffeescript2/lib/coffeescript/nodes.js";
// src/util/UnsupportedNodeError.ts
import { inspect as inspect2 } from "util";
var UnsupportedNodeError = class extends Error {
constructor(node, message = null) {
const prefix = message ? `${message}
` : "";
super(`${prefix}node type '${node.constructor.name}' is not supported: ${inspect2(node)}`);
Object.setPrototypeOf(this, UnsupportedNodeError.prototype);
this.node = node;
}
};
// src/mappers/mapArr.ts
function mapArr(context, node) {
const { line, column, start, end, raw } = getLocation(context, node);
const members = node.objects.map((object) => mapAny(context, object));
return new ArrayInitialiser(line, column, start, end, raw, members);
}
// src/mappers/mapAssign.ts
var COMPOUND_ASSIGN_OPS = {
"-=": SubtractOp.name,
"+=": PlusOp.name,
"/=": DivideOp.name,
"*=": MultiplyOp.name,
"%=": RemOp.name,
"||=": LogicalOrOp.name,
"&&=": LogicalAndOp.name,
"?=": ExistsOp.name,
"<<=": LeftShiftOp.name,
">>=": SignedRightShiftOp.name,
">>>=": UnsignedRightShiftOp.name,
"&=": BitAndOp.name,
"^=": BitXorOp.name,
"|=": BitOrOp.name,
"**=": ExpOp.name,
"//=": FloorDivideOp.name,
"%%=": ModuloOp.name
};
function mapAssign(context, node) {
if (node.context === "object") {
throw new UnsupportedNodeError(node, "Unexpected object context when mapping regular assign op.");
}
const { line, column, start, end, raw } = getLocation(context, node);
if (node.context) {
const opName = COMPOUND_ASSIGN_OPS[node.context];
if (!opName) {
throw new UnsupportedNodeError(node, "Unexpected operator context for assign op.");
}
return new CompoundAssignOp(line, column, start, end, raw, mapAny(context, node.variable), mapAny(context, node.value), opName);
} else {
return new AssignOp(line, column, start, end, raw, mapAny(context, node.variable), mapAny(context, node.value));
}
}
// src/mappers/mapCall.ts
import { SourceType as SourceType5 } from "coffee-lex";
import {
Literal as Literal3,
Splat as Splat2,
StringWithInterpolations as StringWithInterpolations2,
SuperCall,
Value as Value5
} from "decaffeinate-coffeescript2/lib/coffeescript/nodes.js";
import { inspect as inspect3 } from "util";
// src/util/isHeregexTemplateNode.ts
import { SourceType as SourceType2 } from "coffee-lex";
import {
Call,
Literal,
Value as Value2
} from "decaffeinate-coffeescript2/lib/coffeescript/nodes.js";
function isHeregexTemplateNode(node, context) {
if (!(node instanceof Call) || !node.variable || !(node.variable instanceof Value2) || !node.variable.base || !(node.variable.base instanceof Literal) || node.variable.base.value !== "RegExp") {
return false;
}
const { sourceTokens, linesAndColumns } = context;
const start = linesAndColumns.indexForLocation({
line: node.locationData.first_line,
column: node.locationData.first_column
});
if (start === null) {
return false;
}
const startTokenIndex = sourceTokens.indexOfTokenContainingSourceIndex(start);
if (startTokenIndex === null) {
return false;
}
const startToken = sourceTokens.tokenAtIndex(startTokenIndex);
if (startToken === null) {
return false;
}
return startToken.type === SourceType2.HEREGEXP_START;
}
// src/util/locationsEqual.ts
function locationsEqual(first, second) {
return first.first_line === second.first_line && first.first_column === second.first_column && first.last_line === second.last_line && first.last_column === second.last_column;
}
// src/util/getTemplateLiteralComponents.ts
import {
SourceType as SourceType4
} from "coffee-lex";
import {
Literal as Literal2,
Op as Op2,
Value as Value3
} from "decaffeinate-coffeescript2/lib/coffeescript/nodes.js";
// src/util/isPlusTokenBetweenRanges.ts
import { SourceType as SourceType3 } from "coffee-lex";
function isPlusTokenBetweenRanges(leftRange, rightRange, context) {
const tokens = context.sourceTokens;
const leftEnd = tokens.indexOfTokenContainingSourceIndex(leftRange[1] - 1);
const rightStart = tokens.indexOfTokenContainingSourceIndex(rightRange[0]);
if (!leftEnd || !rightStart) {
return false;
}
const afterLeftEnd = leftEnd.next();
if (!afterLeftEnd) {
return false;
}
const tokensBetweenOperands = tokens.slice(afterLeftEnd, rightStart);
let foundPlusToken = false;
tokensBetweenOperands.forEach(({ type, start, end }) => {
if (type === SourceType3.OPERATOR && context.source.slice(start, end) === "+") {
foundPlusToken = true;
}
});
return foundPlusToken;
}
// src/util/isImplicitPlusOp.ts
function isImplicitPlusOp(op, context) {
if (op.operator !== "+" || !op.second) {
return false;
}
const firstRange = context.getRange(op.first);
const secondRange = context.getRange(op.second);
if (!firstRange || !secondRange) {
throw new Error("Expected valid location data on plus operation.");
}
return !isPlusTokenBetweenRanges(firstRange, secondRange, context);
}
// src/util/parseString.ts
import { parse } from "@codemod/parser";
function parseString(string) {
const expressionStatement = parse(`(${string})`).program.body[0];
const literal = expressionStatement.expression;
return literal.value;
}
// src/util/getTemplateLiteralComponents.ts
function getTemplateLiteralComponents(context, node) {
const tokens = context.sourceTokens;
const quasis = [];
const unmappedExpressions = [];
const elements = getElements(node, context);
const nodeRange = context.getRange(node);
if (!nodeRange) {
throw new Error("Expected valid range on template literal node.");
}
const { startTokenIndex, startToken } = getStartToken(nodeRange[0], tokens);
let depth = 0;
let lastToken = startToken;
for (let tokenIndex = startTokenIndex; tokenIndex; tokenIndex = tokenIndex.next()) {
const token = tokens.tokenAtIndex(tokenIndex);
if (!token) {
break;
}
if (token.type === SourceType4.INTERPOLATION_START || token.type === SourceType4.CSX_OPEN_TAG_START) {
depth++;
if (depth === 1) {
quasis.push(findQuasi(lastToken, token, context, elements));
lastToken = token;
}
} else if (token.type === SourceType4.INTERPOLATION_END || token.type === SourceType4.CSX_SELF_CLOSING_TAG_END || token.type === SourceType4.CSX_CLOSE_TAG_END) {
depth--;
if (depth === 0) {
unmappedExpressions.push(findExpression(lastToken, token, context, elements));
lastToken = token;
}
} else if (depth === 0 && isTemplateLiteralEnd(token)) {
quasis.push(findQuasi(lastToken, token, context, elements));
lastToken = token;
break;
}
}
return {
quasis,
unmappedExpressions,
start: startToken.start,
end: lastToken.end
};
}
function getElements(node, context) {
if (node instanceof Op2 && isImplicitPlusOp(node, context)) {
if (!node.second) {
throw new Error("Expected second operand on plus op.");
}
return [
...getElements(node.first, context),
...getElements(node.second, context)
];
}
return [node];
}
function getStartToken(start, tokens) {
let tokenIndex = tokens.indexOfTokenNearSourceIndex(start);
for (let i = 0; i < 5; i++) {
const token = tokens.tokenAtIndex(tokenIndex);
if (!token) {
throw new Error("Expected to find a start token in a template literal.");
}
if (isTemplateLiteralStart(token)) {
return { startToken: token, startTokenIndex: tokenIndex };
}
const prevToken = tokenIndex.previous();
if (!prevToken) {
throw new Error("Expected a previous token when searching for a template start.");
}
tokenIndex = prevToken;
}
throw new Error("Expected a template literal start token.");
}
function findQuasi(leftToken, rightToken, context, elements) {
const matchingElements = elements.filter((elem) => {
const range = context.getRange(elem);
if (!range) {
throw new Error("Unexpected invalid range.");
}
return range[0] >= leftToken.start && range[1] <= rightToken.end;
});
const start = leftToken.end;
const end = rightToken.start;
const startLoc = context.linesAndColumns.locationForIndex(leftToken.end);
if (!startLoc) {
throw new Error(`Expected to find a location for index ${leftToken.end}.`);
}
const raw = context.source.slice(start, end);
if (matchingElements.length === 0) {
return new Quasi(startLoc.line + 1, startLoc.column + 1, start, end, raw, "");
} else if (matchingElements.length === 1) {
const element = matchingElements[0];
let literal;
if (element instanceof Literal2) {
literal = element;
} else if (element instanceof Value3 && element.properties.length === 0 && element.base instanceof Literal2) {
literal = element.base;
} else {
throw new Error("Expected quasi element to be either a literal or a value containing only a literal.");
}
const stringValue = parseString(literal.value);
return new Quasi(startLoc.line + 1, startLoc.column + 1, start, end, raw, stringValue !== void 0 ? stringValue : literal.value);
} else {
throw new Error("Unexpectedly found multiple elements in string interpolation.");
}
}
function findExpression(leftToken, rightToken, context, elements) {
const matchingElements = elements.filter((elem) => {
const range = context.getRange(elem);
if (!range) {
throw new Error("Unexpected invalid range.");
}
return range[0] >= leftToken.start && range[1] <= rightToken.end;
});
if (matchingElements.length === 0) {
return null;
} else if (matchingElements.length === 1) {
return matchingElements[0];
} else {
throw new Error("Unexpectedly found multiple elements in string interpolation.");
}
}
function isTemplateLiteralStart(token) {
return [
SourceType4.DSTRING_START,
SourceType4.SSTRING_START,
SourceType4.TDSTRING_START,
SourceType4.TSSTRING_START,
SourceType4.HEREGEXP_START,
SourceType4.CSX_OPEN_TAG_END
].indexOf(token.type) >= 0;
}
function isTemplateLiteralEnd(token) {
return [
SourceType4.DSTRING_END,
SourceType4.SSTRING_END,
SourceType4.TDSTRING_END,
SourceType4.TSSTRING_END,
SourceType4.HEREGEXP_END,
SourceType4.CSX_CLOSE_TAG_START
].indexOf(token.type) >= 0;
}
// src/util/makeHeregex.ts
function makeHeregex(context, node, flags) {
const { quasis, unmappedExpressions, start, end } = getTemplateLiteralComponents(context, node);
const startLoc = context.linesAndColumns.locationForIndex(start);
if (!startLoc) {
throw new Error(`Expected to find a location for index ${start}.`);
}
const raw = context.source.slice(start, end);
return new Heregex(startLoc.line + 1, startLoc.column + 1, start, end, raw, quasis, unmappedExpressions.map((expr) => expr ? mapAny(context, expr) : null), RegexFlags.parse(flags));
}
// src/mappers/mapCSX.ts
import {
Arr,
Assign,
IdentifierLiteral,
Obj,
Splat,
StringLiteral,
StringWithInterpolations,
Value as Value4
} from "decaffeinate-coffeescript2/lib/coffeescript/nodes.js";
function mapCSX(context, node) {
const { line, column, start, end, raw } = getLocation(context, node);
const [properties, children] = node.args;
const mappedProperties = mapCSXProperties(context, properties);
const mappedChildren = mapCSXChildren(context, children);
return new CSXElement(line, column, start, end, raw, mappedProperties, mappedChildren);
}
function mapCSXProperties(context, properties) {
if (!(properties instanceof Value4) || !(properties.base instanceof Arr)) {
throw new Error("Expected a value for the CSX properties arg.");
}
const values = properties.base.objects;
const resultProperties = [];
for (const value of values) {
if (!(value instanceof Value4)) {
throw new Error("Expected value for CSX property.");
}
if (value.base instanceof Obj) {
for (const propertyAssignment of value.base.objects) {
if (propertyAssignment instanceof Splat) {
resultProperties.push(mapAny(context, propertyAssignment));
} else if (propertyAssignment instanceof Assign) {
if (!(propertyAssignment.value instanceof Value4)) {
throw new Error("Unexpected property assignment value.");
}
if (!(propertyAssignment.value.base instanceof StringLiteral)) {
resultProperties.push(mapAny(context, propertyAssignment.value));
}
} else {
throw new Error("Unexpected property assignment object field in CSX.");
}
}
} else if (value.base instanceof IdentifierLiteral) {
} else {
throw new Error("Unexpected property assignment in CSX.");
}
}
return resultProperties;
}
function mapCSXChildren(context, children) {
if (!children) {
return [];
}
if (!(children instanceof Value4)) {
throw new Error("Expected a value for the CSX children arg.");
}
if (children.base instanceof StringLiteral) {
return [];
} else if (!(children.base instanceof StringWithInterpolations)) {
throw new Error("Expected a valid CSX children arg.");
}
const childInterpolatedString = children.base.body.expressions[0];
const { unmappedExpressions } = getTemplateLiteralComponents(context, childInterpolatedString);
return unmappedExpressions.map((child) => child ? mapAny(context, child) : null);
}
// src/mappers/mapCall.ts
function mapCall(context, node) {
const { line, column, start, end, raw } = getLocation(context, node);
if (node.csx) {
return mapCSX(context, node);
}
if (isHeregexTemplateNode(node, context)) {
const firstArg = node.args[0];
if (!(firstArg instanceof Value5) || !(firstArg.base instanceof StringWithInterpolations2)) {
throw new Error("Expected a valid first heregex arg in the AST.");
}
const strNode = firstArg.base.body.expressions[0];
let flags;
if (node.args.length > 1) {
const secondArg = node.args[1];
if (!(secondArg instanceof Value5) || !(secondArg.base instanceof Literal3)) {
throw new Error("Expected a string flags value in the heregex AST.");
}
flags = parseString(secondArg.base.value);
} else {
flags = "";
}
return makeHeregex(context, strNode, flags);
}
const args = node.args.map((arg) => mapAny(context, arg));
if (node instanceof SuperCall)