UNPKG

decaffeinate-parser

Version:

A better AST for CoffeeScript, inspired by CoffeeScriptRedux.

124 lines (123 loc) 6.03 kB
"use strict"; exports.__esModule = true; var SourceType_1 = require("coffee-lex/dist/SourceType"); var nodes_1 = require("decaffeinate-coffeescript2/lib/coffeescript/nodes"); var util_1 = require("util"); var nodes_2 = require("../nodes"); var getLocation_1 = require("../util/getLocation"); var isHeregexTemplateNode_1 = require("../util/isHeregexTemplateNode"); var locationsEqual_1 = require("../util/locationsEqual"); var makeHeregex_1 = require("../util/makeHeregex"); var parseString_1 = require("../util/parseString"); var UnsupportedNodeError_1 = require("../util/UnsupportedNodeError"); var mapAny_1 = require("./mapAny"); var mapCSX_1 = require("./mapCSX"); function mapCall(context, node) { var _a = getLocation_1["default"](context, node), line = _a.line, column = _a.column, start = _a.start, end = _a.end, raw = _a.raw; if (node.csx) { return mapCSX_1["default"](context, node); } if (isHeregexTemplateNode_1["default"](node, context)) { var firstArg = node.args[0]; if (!(firstArg instanceof nodes_1.Value) || !(firstArg.base instanceof nodes_1.StringWithInterpolations)) { throw new Error('Expected a valid first heregex arg in the AST.'); } var strNode = firstArg.base.body.expressions[0]; var flags = void 0; if (node.args.length > 1) { var secondArg = node.args[1]; if (!(secondArg instanceof nodes_1.Value) || !(secondArg.base instanceof nodes_1.Literal)) { throw new Error('Expected a string flags value in the heregex AST.'); } flags = parseString_1["default"](secondArg.base.value); } else { flags = ''; } return makeHeregex_1["default"](context, strNode, flags); } var args = node.args.map(function (arg) { return mapAny_1["default"](context, arg); }); if (node instanceof nodes_1.SuperCall) { if (node.args.length === 1 && node.args[0] instanceof nodes_1.Splat && locationsEqual_1["default"](node.args[0].locationData, node.locationData)) { return new nodes_2.BareSuperFunctionApplication(line, column, start, end, raw); } var superIndex = context.sourceTokens.indexOfTokenStartingAtSourceIndex(start); var superToken = superIndex && context.sourceTokens.tokenAtIndex(superIndex); if (!superToken || superToken.type !== SourceType_1["default"].SUPER) { throw new Error("unable to find SUPER token in 'super' function call: " + util_1.inspect(node)); } var superLocation = context.linesAndColumns.locationForIndex(superToken.start); if (!superLocation) { throw new Error("unable to locate SUPER token for 'super' function call: " + util_1.inspect(node)); } return new nodes_2.FunctionApplication(line, column, start, end, raw, new nodes_2.Super(superLocation.line + 1, superLocation.column + 1, superToken.start, superToken.end, context.source.slice(superToken.start, superToken.end)), args); } if (!node.variable) { throw new Error('Expected non-super call to have a variable defined.'); } var callee = mapAny_1["default"](context, node.variable); if (node.isNew) { return mapNewOp(context, node); } if (node.soak) { return new nodes_2.SoakedFunctionApplication(line, column, start, end, raw, callee, args); } if (node["do"]) { return mapDoOp(context, node); } return new nodes_2.FunctionApplication(line, column, start, end, raw, callee, args); } exports["default"] = mapCall; function mapNewOp(context, node) { if (!node.variable) { // This should only happen when `isSuper` is true. throw new UnsupportedNodeError_1["default"](node); } var _a = getLocation_1["default"](context, node), line = _a.line, column = _a.column, start = _a.start, end = _a.end, raw = _a.raw; var callee = mapAny_1["default"](context, node.variable); var args = node.args.map(function (arg) { return mapAny_1["default"](context, arg); }); if (node.soak) { return new nodes_2.SoakedNewOp(line, column, start, end, raw, callee, args); } else { return new nodes_2.NewOp(line, column, start, end, raw, callee, args); } } function mapDoOp(context, node) { if (!node.variable) { // This should only happen when `isSuper` is true. throw new UnsupportedNodeError_1["default"](node); } var _a = getLocation_1["default"](context, node), line = _a.line, column = _a.column, start = _a.start, end = _a.end, raw = _a.raw; var expression = mapAny_1["default"](context, node.variable); var args = node.args.map(function (arg) { return mapAny_1["default"](context, arg); }); if (expression instanceof nodes_2.BaseFunction) { expression = augmentDoFunctionWithArgs(context, expression, args); } else if (expression instanceof nodes_2.AssignOp && expression.expression instanceof nodes_2.BaseFunction) { var newRhs = augmentDoFunctionWithArgs(context, expression.expression, args); expression = expression.withExpression(newRhs); } return new nodes_2.DoOp(line, column, start, end, raw, expression); } function augmentDoFunctionWithArgs(context, func, args) { var newParameters = func.parameters.map(function (param, i) { var arg = args[i]; // If there's a parameter with no default, CoffeeScript will insert a fake // arg with the same value and location. if (arg instanceof nodes_2.Identifier && param instanceof nodes_2.Identifier && arg.data === param.data && arg.start === param.start && arg.end === param.end) { return param; } return new nodes_2.DefaultParam(param.line, param.column, param.start, arg.end, context.source.slice(param.start, arg.end), param, arg); }); return func.withParameters(newParameters); }