decaffeinate-parser
Version:
A better AST for CoffeeScript, inspired by CoffeeScriptRedux.
96 lines (95 loc) • 5.01 kB
JavaScript
;
exports.__esModule = true;
var coffee_lex_1 = require("coffee-lex");
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 UnsupportedNodeError_1 = require("../util/UnsupportedNodeError");
var mapAny_1 = require("./mapAny");
function mapValue(context, node) {
var location = getLocation_1["default"](context, node);
return node.properties.reduce(function (reduced, property) { return reduceProperty(context, location, reduced, property); }, mapAny_1["default"](context, node.base));
}
exports["default"] = mapValue;
function reduceProperty(context, location, reduced, property) {
if (property instanceof nodes_1.Access) {
var name = property.name;
if (!(name instanceof nodes_1.Literal)) {
throw new Error("unexpected non-Literal property access name: " + util_1.inspect(name));
}
var startTokenIndex = tokenIndexAtLocation(context, property.locationData);
var startToken = startTokenIndex && context.sourceTokens.tokenAtIndex(startTokenIndex);
if (startToken && property.soak) {
if (startToken.type !== coffee_lex_1.SourceType.EXISTENCE) {
throw new Error("expected EXISTENCE token ('?') but got " + coffee_lex_1.SourceType[startToken.type] + ": " + util_1.inspect(startToken));
}
startTokenIndex = startTokenIndex && startTokenIndex.next();
startToken =
startTokenIndex && context.sourceTokens.tokenAtIndex(startTokenIndex);
}
if (!startToken) {
throw new Error("cannot find token at start of property: " + util_1.inspect(property));
}
var last = context.linesAndColumns.indexForLocation({
line: property.locationData.last_line,
column: property.locationData.last_column
});
if (last === null) {
throw new Error("cannot find offset of last character of property: " + util_1.inspect(property));
}
var isPrototypeAccess = startToken.type === coffee_lex_1.SourceType.PROTO;
if (isPrototypeAccess) {
var AccessOp = property.soak
? nodes_2.SoakedProtoMemberAccessOp
: nodes_2.ProtoMemberAccessOp;
return new AccessOp(location.line, location.column, location.start, last + 1, context.source.slice(location.start, last + 1), reduced);
}
else {
var member = mapAny_1["default"](context, name);
if (!(member instanceof nodes_2.Identifier)) {
throw new Error("unexpected non-Identifier access member: " + util_1.inspect(member));
}
var AccessOp = property.soak ? nodes_2.SoakedMemberAccessOp : nodes_2.MemberAccessOp;
return new AccessOp(location.line, location.column, location.start, last + 1, context.source.slice(location.start, last + 1), reduced, member);
}
}
else if (property instanceof nodes_1.Index) {
var NodeClass = property.soak
? nodes_2.SoakedDynamicMemberAccessOp
: nodes_2.DynamicMemberAccessOp;
var last = context.linesAndColumns.indexForLocation({
line: property.locationData.last_line,
column: property.locationData.last_column
});
if (last === null) {
throw new Error("cannot find offset of last character of index: " + util_1.inspect(property));
}
return new NodeClass(location.line, location.column, location.start, last + 1, context.source.slice(location.start, last + 1), reduced, mapAny_1["default"](context, property.index));
}
else if (property instanceof nodes_1.Slice) {
var last = context.linesAndColumns.indexForLocation({
line: property.locationData.last_line,
column: property.locationData.last_column
});
if (last === null) {
throw new Error("cannot find offset of last character of slice: " + util_1.inspect(property));
}
var SliceClass = property.soak ? nodes_2.SoakedSlice : nodes_2.Slice;
return new SliceClass(location.line, location.column, location.start, last + 1, context.source.slice(location.start, last + 1), reduced, property.range.from ? mapAny_1["default"](context, property.range.from) : null, property.range.to ? mapAny_1["default"](context, property.range.to) : null, !property.range.exclusive);
}
else {
throw new UnsupportedNodeError_1["default"](property, 'Unexpected property access.');
}
}
exports.reduceProperty = reduceProperty;
function tokenIndexAtLocation(context, location) {
var start = context.linesAndColumns.indexForLocation({
line: location.first_line,
column: location.first_column
});
if (start === null) {
return null;
}
return context.sourceTokens.indexOfTokenContainingSourceIndex(start);
}