UNPKG

decaffeinate-parser

Version:

A better AST for CoffeeScript, inspired by CoffeeScriptRedux.

107 lines (106 loc) 4.07 kB
var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); import { Base } from 'decaffeinate-coffeescript2/lib/coffeescript/nodes'; import LinesAndColumns from 'lines-and-columns'; var ParseError = /** @class */ (function (_super) { __extends(ParseError, _super); function ParseError(syntaxError) { var _this = _super.call(this, syntaxError.message) || this; _this.syntaxError = syntaxError; return _this; } return ParseError; }(Error)); /** * Any information we need to know about the current state of parsing. While the * hope is that this is mostly immutable, with replace operations as we walk the * AST, it is partially mutable to collect bound method names in a class. */ var ParseState = /** @class */ (function () { function ParseState(currentClassBoundMethods) { this.currentClassBoundMethods = currentClassBoundMethods; this.currentClassCtor = null; } ParseState.prototype.isInClassBody = function () { return this.currentClassBoundMethods !== null; }; ParseState.prototype.recordBoundMethod = function (method) { if (!this.currentClassBoundMethods) { throw new Error('Cannot assign a bound method name when there is no current class.'); } this.currentClassBoundMethods.push(method); }; ParseState.prototype.recordConstructor = function (ctor) { this.currentClassCtor = ctor; }; ParseState.prototype.pushCurrentClass = function () { return new ParseState([]); }; ParseState.prototype.dropCurrentClass = function () { return new ParseState(null); }; ParseState.initialState = function () { return new ParseState(null); }; return ParseState; }()); export { ParseState }; var ParseContext = /** @class */ (function () { function ParseContext(source, linesAndColumns, sourceTokens, ast, parseState) { this.source = source; this.linesAndColumns = linesAndColumns; this.sourceTokens = sourceTokens; this.ast = ast; this.parseState = parseState; } ParseContext.prototype.getRange = function (locatable) { if (locatable instanceof Base) { return this.getRange(locatable.locationData); } else { var locationData = locatable; var start = this.linesAndColumns.indexForLocation({ line: locationData.first_line, column: locationData.first_column }); var end = this.linesAndColumns.indexForLocation({ line: locationData.last_line, column: locationData.last_column }); if (start === null || end === null) { return null; } return [start, end + 1]; } }; ParseContext.fromSource = function (source, sourceLex, parse) { try { var sourceTokens = sourceLex(source); return new ParseContext(source, new LinesAndColumns(source), sourceTokens, parse(source), ParseState.initialState()); } catch (ex) { if (ex instanceof SyntaxError) { throw new ParseError(ex); } else { throw ex; } } }; ParseContext.prototype.updateState = function (updater) { return new ParseContext(this.source, this.linesAndColumns, this.sourceTokens, this.ast, updater(this.parseState)); }; return ParseContext; }()); export default ParseContext;