decaffeinate-parser
Version:
A better AST for CoffeeScript, inspired by CoffeeScriptRedux.
41 lines (40 loc) • 2.31 kB
JavaScript
import SourceType from 'coffee-lex/dist/SourceType';
import { Switch, SwitchCase } from '../nodes';
import getLocation from '../util/getLocation';
import mapAny from './mapAny';
import mapPossiblyEmptyBlock from './mapPossiblyEmptyBlock';
export default function mapSwitch(context, node) {
var _a = getLocation(context, node), line = _a.line, column = _a.column, start = _a.start, end = _a.end, raw = _a.raw;
var expression = node.subject ? mapAny(context, node.subject) : null;
var cases = node.cases.map(function (_a) {
var conditions = _a[0], body = _a[1];
if (!Array.isArray(conditions)) {
conditions = [conditions];
}
var switchConditions = conditions.map(function (condition) {
return mapAny(context, condition);
});
var consequent = mapPossiblyEmptyBlock(context, body);
var whenToken = getWhenTokenBeforeOffset(context, switchConditions[0].start, start);
var locationForIndex = context.linesAndColumns.locationForIndex(whenToken.start);
if (!locationForIndex) {
throw new Error("cannot map WHEN token start to line/column: " + whenToken.start);
}
var caseLine = locationForIndex.line, caseColumn = locationForIndex.column;
var end = getLocation(context, body).end;
return new SwitchCase(caseLine + 1, caseColumn + 1, whenToken.start, end, context.source.slice(whenToken.start, end), switchConditions, consequent);
});
return new Switch(line, column, start, end, raw, expression, cases, mapPossiblyEmptyBlock(context, node.otherwise));
}
function getWhenTokenBeforeOffset(context, offset, lowerBound) {
var offsetTokenIndex = context.sourceTokens.indexOfTokenNearSourceIndex(offset);
var lowerBoundTokenIndex = context.sourceTokens.indexOfTokenNearSourceIndex(lowerBound);
var whenTokenIndex = context.sourceTokens.lastIndexOfTokenMatchingPredicate(function (token) { return token.type === SourceType.WHEN; }, offsetTokenIndex, lowerBoundTokenIndex);
if (whenTokenIndex) {
var whenToken = context.sourceTokens.tokenAtIndex(whenTokenIndex);
if (whenToken) {
return whenToken;
}
}
throw new Error("unable to find WHEN token before " + offset + " (lower bound: " + lowerBound + ")");
}