ts-simple-ast
Version:
TypeScript compiler wrapper for AST navigation and code generation.
197 lines (196 loc) • 8.61 kB
JavaScript
"use strict";
var __extends = (this && this.__extends)/* istanbul ignore next */ || (function () {
var 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 function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var __values = (this && this.__values)/* istanbul ignore next */ || function (o) {
var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0;
if (m) return m.call(o);
return {
next: function () {
if (o && i >= o.length) o = void 0;
return { value: o && o[i++], done: !o };
}
};
};
Object.defineProperty(exports, "__esModule", { value: true });
var ts = require("typescript");
var errors = require("./../../errors");
var manipulation_1 = require("./../../manipulation");
var utils_1 = require("./../../utils");
function ModifierableNode(Base) {
return /** @class */ (function (_super) {
__extends(class_1, _super);
function class_1() {
return _super !== null && _super.apply(this, arguments) || this;
}
class_1.prototype.getModifiers = function () {
var _this = this;
return this.compilerNode.modifiers == null ? [] : this.compilerNode.modifiers.map(function (m) { return _this.global.compilerFactory.getNodeFromCompilerNode(m, _this.sourceFile); });
};
class_1.prototype.getFirstModifierByKindOrThrow = function (kind) {
return errors.throwIfNullOrUndefined(this.getFirstModifierByKind(kind), "Expected a modifier of syntax kind: " + ts.SyntaxKind[kind]);
};
class_1.prototype.getFirstModifierByKind = function (kind) {
try {
for (var _a = __values(this.getModifiers()), _b = _a.next(); !_b.done; _b = _a.next()) {
var modifier = _b.value;
if (modifier.getKind() === kind)
return modifier;
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
}
finally { if (e_1) throw e_1.error; }
}
return undefined;
var e_1, _c;
};
class_1.prototype.hasModifier = function (textOrKind) {
if (typeof textOrKind === "string")
return this.getModifiers().some(function (m) { return m.getText() === textOrKind; });
else
return this.getModifiers().some(function (m) { return m.getKind() === textOrKind; });
};
class_1.prototype.toggleModifier = function (text, value) {
if (value == null)
value = !this.hasModifier(text);
if (value)
this.addModifier(text);
else
this.removeModifier(text);
return this;
};
class_1.prototype.addModifier = function (text) {
var modifiers = this.getModifiers();
var hasModifier = modifiers.some(function (m) { return m.getText() === text; });
if (hasModifier)
return utils_1.ArrayUtils.find(this.getModifiers(), function (m) { return m.getText() === text; });
// get insert position & index
var _a = getInsertInfo(this), insertPos = _a.insertPos, insertIndex = _a.insertIndex;
// insert setup
var startPos;
var newText;
var isFirstModifier = modifiers.length === 0 || insertPos === modifiers[0].getStart();
if (isFirstModifier) {
newText = text + " ";
startPos = insertPos;
}
else {
newText = " " + text;
startPos = insertPos + 1;
}
// insert
manipulation_1.insertIntoCreatableSyntaxList({
parent: this,
insertPos: insertPos,
newText: newText,
syntaxList: modifiers.length === 0 ? undefined : modifiers[0].getParentSyntaxListOrThrow(),
childIndex: insertIndex,
insertItemsCount: 1
});
return utils_1.ArrayUtils.find(this.getModifiers(), function (m) { return m.getStart() === startPos; });
function getInsertInfo(node) {
var pos = getInitialInsertPos();
var index = 0;
try {
for (var _a = __values(getAddAfterModifierTexts(text)), _b = _a.next(); !_b.done; _b = _a.next()) {
var addAfterText = _b.value;
for (var i = 0; i < modifiers.length; i++) {
var modifier = modifiers[i];
if (modifier.getText() === addAfterText) {
if (pos < modifier.getEnd()) {
pos = modifier.getEnd();
index = i + 1;
}
break;
}
}
}
}
catch (e_2_1) { e_2 = { error: e_2_1 }; }
finally {
try {
if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
}
finally { if (e_2) throw e_2.error; }
}
return { insertPos: pos, insertIndex: index };
function getInitialInsertPos() {
if (modifiers.length > 0)
return modifiers[0].getStart();
try {
for (var _a = __values(node.getChildrenIterator()), _b = _a.next(); !_b.done; _b = _a.next()) {
var child = _b.value;
// skip over any initial syntax lists (ex. decorators) or js docs
if (child.getKind() === ts.SyntaxKind.SyntaxList || ts.isJSDocCommentContainingNode(child.compilerNode))
continue;
return child.getStart();
}
}
catch (e_3_1) { e_3 = { error: e_3_1 }; }
finally {
try {
if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
}
finally { if (e_3) throw e_3.error; }
}
return node.getStart();
var e_3, _c;
}
var e_2, _c;
}
};
class_1.prototype.removeModifier = function (text) {
var modifier = utils_1.ArrayUtils.find(this.getModifiers(), function (m) { return m.getText() === text; });
if (modifier == null)
return false;
manipulation_1.removeChildrenWithFormattingFromCollapsibleSyntaxList({
children: [modifier],
getSiblingFormatting: function () { return manipulation_1.FormattingKind.Space; }
});
return true;
};
return class_1;
}(Base));
}
exports.ModifierableNode = ModifierableNode;
/**
* @returns The texts the specified text should appear after.
*/
function getAddAfterModifierTexts(text) {
switch (text) {
case "export":
return [];
case "default":
return ["export"];
case "declare":
return ["export", "default"];
case "abstract":
return ["export", "default", "declare", "public", "private", "protected"];
case "readonly":
return ["export", "default", "declare", "public", "private", "protected", "abstract", "static"];
case "public":
case "protected":
case "private":
return [];
case "static":
return ["public", "protected", "private"];
case "async":
return ["export", "public", "protected", "private", "static", "abstract"];
case "const":
return [];
/* istanbul ignore next */
default:
throw new errors.NotImplementedError("Not implemented modifier: " + text);
}
}