decaffeinate-parser
Version:
A better AST for CoffeeScript, inspired by CoffeeScriptRedux.
107 lines (106 loc) • 4.07 kB
JavaScript
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;