decaffeinate-parser
Version:
A better AST for CoffeeScript, inspired by CoffeeScriptRedux.
143 lines (142 loc) • 6.73 kB
JavaScript
;
exports.__esModule = true;
var decaffeinate_coffeescript_1 = require("decaffeinate-coffeescript");
var nodes_1 = require("decaffeinate-coffeescript/lib/coffee-script/nodes");
var nodes_2 = require("decaffeinate-coffeescript2/lib/coffeescript/nodes");
var nodeTypeMap = new Map();
nodeTypeMap.set(nodes_1.Base, nodes_2.Base);
nodeTypeMap.set(nodes_1.Block, nodes_2.Block);
nodeTypeMap.set(nodes_1.Literal, nodes_2.Literal);
nodeTypeMap.set(nodes_1.NumberLiteral, nodes_2.NumberLiteral);
nodeTypeMap.set(nodes_1.InfinityLiteral, nodes_2.InfinityLiteral);
nodeTypeMap.set(nodes_1.NaNLiteral, nodes_2.NaNLiteral);
nodeTypeMap.set(nodes_1.StringLiteral, nodes_2.StringLiteral);
nodeTypeMap.set(nodes_1.RegexLiteral, nodes_2.RegexLiteral);
nodeTypeMap.set(nodes_1.PassthroughLiteral, nodes_2.PassthroughLiteral);
nodeTypeMap.set(nodes_1.IdentifierLiteral, nodes_2.IdentifierLiteral);
nodeTypeMap.set(nodes_1.PropertyName, nodes_2.PropertyName);
nodeTypeMap.set(nodes_1.StatementLiteral, nodes_2.StatementLiteral);
nodeTypeMap.set(nodes_1.ThisLiteral, nodes_2.ThisLiteral);
nodeTypeMap.set(nodes_1.UndefinedLiteral, nodes_2.UndefinedLiteral);
nodeTypeMap.set(nodes_1.NullLiteral, nodes_2.NullLiteral);
nodeTypeMap.set(nodes_1.BooleanLiteral, nodes_2.BooleanLiteral);
nodeTypeMap.set(nodes_1.Return, nodes_2.Return);
nodeTypeMap.set(nodes_1.YieldReturn, nodes_2.YieldReturn);
nodeTypeMap.set(nodes_1.Value, nodes_2.Value);
nodeTypeMap.set(nodes_1.Call, nodes_2.Call);
nodeTypeMap.set(nodes_1.SuperCall, nodes_2.SuperCall);
nodeTypeMap.set(nodes_1.RegexWithInterpolations, nodes_2.RegexWithInterpolations);
nodeTypeMap.set(nodes_1.TaggedTemplateCall, nodes_2.TaggedTemplateCall);
nodeTypeMap.set(nodes_1.Extends, nodes_2.Extends);
nodeTypeMap.set(nodes_1.Access, nodes_2.Access);
nodeTypeMap.set(nodes_1.Index, nodes_2.Index);
nodeTypeMap.set(nodes_1.Range, nodes_2.Range);
nodeTypeMap.set(nodes_1.Slice, nodes_2.Slice);
nodeTypeMap.set(nodes_1.Obj, nodes_2.Obj);
nodeTypeMap.set(nodes_1.Arr, nodes_2.Arr);
nodeTypeMap.set(nodes_1.Class, nodes_2.Class);
nodeTypeMap.set(nodes_1.ModuleDeclaration, nodes_2.ModuleDeclaration);
nodeTypeMap.set(nodes_1.ImportDeclaration, nodes_2.ImportDeclaration);
nodeTypeMap.set(nodes_1.ImportClause, nodes_2.ImportClause);
nodeTypeMap.set(nodes_1.ExportDeclaration, nodes_2.ExportDeclaration);
nodeTypeMap.set(nodes_1.ExportNamedDeclaration, nodes_2.ExportNamedDeclaration);
nodeTypeMap.set(nodes_1.ExportDefaultDeclaration, nodes_2.ExportDefaultDeclaration);
nodeTypeMap.set(nodes_1.ExportAllDeclaration, nodes_2.ExportAllDeclaration);
nodeTypeMap.set(nodes_1.ModuleSpecifierList, nodes_2.ModuleSpecifierList);
nodeTypeMap.set(nodes_1.ImportSpecifierList, nodes_2.ImportSpecifierList);
nodeTypeMap.set(nodes_1.ExportSpecifierList, nodes_2.ExportSpecifierList);
nodeTypeMap.set(nodes_1.ModuleSpecifier, nodes_2.ModuleSpecifier);
nodeTypeMap.set(nodes_1.ImportSpecifier, nodes_2.ImportSpecifier);
nodeTypeMap.set(nodes_1.ImportDefaultSpecifier, nodes_2.ImportDefaultSpecifier);
nodeTypeMap.set(nodes_1.ImportNamespaceSpecifier, nodes_2.ImportNamespaceSpecifier);
nodeTypeMap.set(nodes_1.ExportSpecifier, nodes_2.ExportSpecifier);
nodeTypeMap.set(nodes_1.Assign, nodes_2.Assign);
nodeTypeMap.set(nodes_1.Code, nodes_2.Code);
nodeTypeMap.set(nodes_1.Param, nodes_2.Param);
nodeTypeMap.set(nodes_1.Splat, nodes_2.Splat);
nodeTypeMap.set(nodes_1.Expansion, nodes_2.Expansion);
nodeTypeMap.set(nodes_1.While, nodes_2.While);
nodeTypeMap.set(nodes_1.Op, nodes_2.Op);
nodeTypeMap.set(nodes_1.In, nodes_2.In);
nodeTypeMap.set(nodes_1.Try, nodes_2.Try);
nodeTypeMap.set(nodes_1.Throw, nodes_2.Throw);
nodeTypeMap.set(nodes_1.Existence, nodes_2.Existence);
nodeTypeMap.set(nodes_1.Parens, nodes_2.Parens);
nodeTypeMap.set(nodes_1.StringWithInterpolations, nodes_2.StringWithInterpolations);
nodeTypeMap.set(nodes_1.For, nodes_2.For);
nodeTypeMap.set(nodes_1.Switch, nodes_2.Switch);
nodeTypeMap.set(nodes_1.If, nodes_2.If);
/**
* Run the CS1 parser and convert the resulting AST into a CS2-compatible AST.
*/
function parseCS1AsCS2(source) {
var cs1AST = decaffeinate_coffeescript_1.nodes(source);
var cs2AST = convertCS1NodeToCS2(cs1AST);
if (!(cs2AST instanceof nodes_2.Block)) {
throw new Error('Expected top-level CS file to convert to a Block');
}
return cs2AST;
}
exports["default"] = parseCS1AsCS2;
function convertCS1NodeToCS2(node) {
if (node instanceof nodes_1.Comment) {
return makeCS2Comment(node);
}
var cs1Constructor = node.constructor;
var cs2Constructor = nodeTypeMap.get(cs1Constructor);
if (!cs2Constructor) {
throw new Error("Unexpected CS1 type for node " + node);
}
var result = Object.create(cs2Constructor.prototype);
for (var _i = 0, _a = Object.keys(node); _i < _a.length; _i++) {
var key = _a[_i];
var value = node[key];
if (Array.isArray(value) &&
value.length > 0 &&
value[0] instanceof nodes_1.Base) {
result[key] = value.map(function (child) { return convertCS1NodeToCS2(child); });
}
else if (key === 'cases') {
// Switch cases have a complex structure, so special-case those.
result[key] = value.map(function (_a) {
var switchCaseCondition = _a[0], block = _a[1];
if (Array.isArray(switchCaseCondition)) {
return [
switchCaseCondition.map(function (condition) {
return convertCS1NodeToCS2(condition);
}),
convertCS1NodeToCS2(block)
];
}
else {
return [
convertCS1NodeToCS2(switchCaseCondition),
convertCS1NodeToCS2(block)
];
}
});
}
else if (value instanceof nodes_1.Base) {
result[key] = convertCS1NodeToCS2(value);
}
else {
result[key] = value;
}
}
return result;
}
/**
* The CS2 comment format is an empty passthrough node with comments attached. We need to keep
* these nodes from CS1 in some cases so that we properly determine the end of functions ending
* in block comments.
*/
function makeCS2Comment(comment) {
var valueNode = Object.create(nodes_2.Value.prototype);
var passthroughNode = Object.create(nodes_2.PassthroughLiteral.prototype);
valueNode.properties = [];
valueNode.base = passthroughNode;
passthroughNode.value = '';
valueNode.locationData = comment.locationData;
passthroughNode.locationData = comment.locationData;
return valueNode;
}