ts-simple-ast
Version:
TypeScript compiler wrapper for AST navigation and code generation.
1,271 lines • 52.4 kB
JavaScript
"use strict";
var __generator = (this && this.__generator)/* istanbul ignore next */ || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [0, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
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 };
}
};
};
var __read = (this && this.__read)/* istanbul ignore next */ || function (o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
}
catch (error) { e = { error: error }; }
finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
}
finally { if (e) throw e.error; }
}
return ar;
};
var __spread = (this && this.__spread)/* istanbul ignore next */ || function () {
for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i]));
return ar;
};
Object.defineProperty(exports, "__esModule", { value: true });
var ts = require("typescript");
var code_block_writer_1 = require("code-block-writer");
var errors = require("./../../errors");
var ManipulationSettings_1 = require("./../../ManipulationSettings");
var textSeek_1 = require("./../../manipulation/textSeek");
var insertion_1 = require("./../../manipulation/insertion");
var utils_1 = require("./../../utils");
var QuoteType_1 = require("./../literal/QuoteType");
var Node = /** @class */ (function () {
/**
* Initializes a new instance.
* @internal
* @param global - Global container.
* @param node - Underlying node.
* @param sourceFile - Source file for the node.
*/
function Node(global, node, sourceFile) {
this.global = global;
this._compilerNode = node;
this.sourceFile = sourceFile;
}
Object.defineProperty(Node.prototype, "compilerNode", {
/**
* Gets the underlying compiler node.
*/
get: function () {
if (this._compilerNode == null)
throw new errors.InvalidOperationError("Attempted to get information from a node that was removed or forgotten.");
return this._compilerNode;
},
enumerable: true,
configurable: true
});
/**
* Releases the node and all its descendants from the underlying node cache and ast.
*
* This is useful if you want to improve the performance of manipulation by not tracking this node anymore.
*/
Node.prototype.forget = function () {
if (this.wasForgotten())
return;
try {
for (var _a = __values(this.getChildrenInCacheIterator()), _b = _a.next(); !_b.done; _b = _a.next()) {
var child = _b.value;
child.forget();
}
}
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; }
}
this.forgetOnlyThis();
var e_1, _c;
};
/**
* Only forgets this node.
* @internal
*/
Node.prototype.forgetOnlyThis = function () {
if (this.wasForgotten())
return;
this.global.compilerFactory.removeNodeFromCache(this);
this._compilerNode = undefined;
};
/**
* Gets if the node was forgotten.
* @internal
*/
Node.prototype.wasForgotten = function () {
return this._compilerNode == null;
};
/**
* Gets the syntax kind.
*/
Node.prototype.getKind = function () {
return this.compilerNode.kind;
};
/**
* Gets the syntax kind name.
*/
Node.prototype.getKindName = function () {
return ts.SyntaxKind[this.compilerNode.kind];
};
/**
* Gets the symbol or throws an error if it doesn't exist.
*/
Node.prototype.getSymbolOrThrow = function () {
return errors.throwIfNullOrUndefined(this.getSymbol(), "Could not find the node symbol.");
};
/**
* Gets the compiler symbol or undefined if it doesn't exist.
*/
Node.prototype.getSymbol = function () {
var boundSymbol = this.compilerNode.symbol;
if (boundSymbol != null)
return this.global.compilerFactory.getSymbol(boundSymbol);
var typeChecker = this.global.typeChecker;
var typeCheckerSymbol = typeChecker.getSymbolAtLocation(this);
if (typeCheckerSymbol != null)
return typeCheckerSymbol;
var nameNode = this.compilerNode.name;
if (nameNode != null)
return getWrappedNode(this, nameNode).getSymbol();
return undefined;
};
/**
* If the node contains the provided range (inclusive).
* @param pos - Start position.
* @param end - End position.
*/
Node.prototype.containsRange = function (pos, end) {
return this.getPos() <= pos && end <= this.getEnd();
};
/**
* Gets if the specified position is within a string.
* @param pos - Position.
*/
Node.prototype.isInStringAtPos = function (pos) {
errors.throwIfOutOfRange(pos, [this.getPos(), this.getEnd()], "pos");
if (this._childStringRanges == null) {
this._childStringRanges = [];
try {
for (var _a = __values(this.getCompilerDescendantsIterator()), _b = _a.next(); !_b.done; _b = _a.next()) {
var descendant = _b.value;
if (utils_1.isStringKind(descendant.kind))
this._childStringRanges.push([descendant.getStart(this.sourceFile.compilerNode), descendant.getEnd()]);
}
}
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 utils_1.ArrayUtils.binarySearch(this._childStringRanges, function (range) { return range[0] < pos && pos < range[1] - 1; }, function (range) { return range[0] > pos; }) !== -1;
var e_2, _c;
};
/**
* Gets the first child by a condition or throws.
* @param condition - Condition.
*/
Node.prototype.getFirstChildOrThrow = function (condition) {
return errors.throwIfNullOrUndefined(this.getFirstChild(condition), "Could not find a child that matched the specified condition.");
};
/**
* Gets the first child by a condition.
* @param condition - Condition.
*/
Node.prototype.getFirstChild = function (condition) {
var firstChild = this.getCompilerFirstChild(getWrappedCondition(this, condition));
return firstChild == null ? undefined : getWrappedNode(this, firstChild);
};
/**
* Gets the last child by a condition or throws.
* @param condition - Condition.
*/
Node.prototype.getLastChildOrThrow = function (condition) {
return errors.throwIfNullOrUndefined(this.getLastChild(condition), "Could not find a child that matched the specified condition.");
};
/**
* Gets the last child by a condition.
* @param condition - Condition.
*/
Node.prototype.getLastChild = function (condition) {
var lastChild = this.getCompilerLastChild(getWrappedCondition(this, condition));
return lastChild == null ? undefined : getWrappedNode(this, lastChild);
};
/**
* Gets the first descendant by a condition or throws.
* @param condition - Condition.
*/
Node.prototype.getFirstDescendantOrThrow = function (condition) {
return errors.throwIfNullOrUndefined(this.getFirstDescendant(condition), "Could not find a descendant that matched the specified condition.");
};
/**
* Gets the first descendant by a condition.
* @param condition - Condition.
*/
Node.prototype.getFirstDescendant = function (condition) {
try {
for (var _a = __values(this.getDescendantsIterator()), _b = _a.next(); !_b.done; _b = _a.next()) {
var descendant = _b.value;
if (condition == null || condition(descendant))
return descendant;
}
}
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 undefined;
var e_3, _c;
};
/**
* Offset this node's positions (pos and end) and all of its children by the given offset.
* @internal
* @param offset - Offset.
*/
Node.prototype.offsetPositions = function (offset) {
this.compilerNode.pos += offset;
this.compilerNode.end += offset;
try {
for (var _a = __values(this.getChildren()), _b = _a.next(); !_b.done; _b = _a.next()) {
var child = _b.value;
child.offsetPositions(offset);
}
}
catch (e_4_1) { e_4 = { error: e_4_1 }; }
finally {
try {
if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
}
finally { if (e_4) throw e_4.error; }
}
var e_4, _c;
};
/**
* Gets the previous sibling or throws.
* @param condition - Optional condition for getting the previous sibling.
*/
Node.prototype.getPreviousSiblingOrThrow = function (condition) {
return errors.throwIfNullOrUndefined(this.getPreviousSibling(condition), "Could not find the previous sibling.");
};
/**
* Gets the previous sibling.
* @param condition - Optional condition for getting the previous sibling.
*/
Node.prototype.getPreviousSibling = function (condition) {
var previousSibling = this.getCompilerPreviousSibling(getWrappedCondition(this, condition));
return previousSibling == null ? undefined : getWrappedNode(this, previousSibling);
};
/**
* Gets the next sibling or throws.
* @param condition - Optional condition for getting the next sibling.
*/
Node.prototype.getNextSiblingOrThrow = function (condition) {
return errors.throwIfNullOrUndefined(this.getNextSibling(condition), "Could not find the next sibling.");
};
/**
* Gets the next sibling.
* @param condition - Optional condition for getting the previous sibling.
*/
Node.prototype.getNextSibling = function (condition) {
var nextSibling = this.getCompilerNextSibling(getWrappedCondition(this, condition));
return nextSibling == null ? undefined : getWrappedNode(this, nextSibling);
};
/**
* Gets the previous siblings.
*
* Note: Closest sibling is the zero index.
*/
Node.prototype.getPreviousSiblings = function () {
var _this = this;
return this.getCompilerPreviousSiblings().map(function (n) { return getWrappedNode(_this, n); });
};
/**
* Gets the next siblings.
*
* Note: Closest sibling is the zero index.
*/
Node.prototype.getNextSiblings = function () {
var _this = this;
return this.getCompilerNextSiblings().map(function (n) { return getWrappedNode(_this, n); });
};
/**
* Gets the children of the node.
*/
Node.prototype.getChildren = function () {
var _this = this;
return this.getCompilerChildren().map(function (n) { return getWrappedNode(_this, n); });
};
/**
* Gets the child at the specified index.
* @param index - Index of the child.
*/
Node.prototype.getChildAtIndex = function (index) {
return getWrappedNode(this, this.getCompilerChildAtIndex(index));
};
/**
* @internal
*/
Node.prototype.getChildrenIterator = function () {
var _a, _b, compilerChild, e_5_1, e_5, _c;
return __generator(this, function (_d) {
switch (_d.label) {
case 0:
_d.trys.push([0, 5, 6, 7]);
_a = __values(this.getCompilerChildren()), _b = _a.next();
_d.label = 1;
case 1:
if (!!_b.done) return [3 /*break*/, 4];
compilerChild = _b.value;
return [4 /*yield*/, getWrappedNode(this, compilerChild)];
case 2:
_d.sent();
_d.label = 3;
case 3:
_b = _a.next();
return [3 /*break*/, 1];
case 4: return [3 /*break*/, 7];
case 5:
e_5_1 = _d.sent();
e_5 = { error: e_5_1 };
return [3 /*break*/, 7];
case 6:
try {
if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
}
finally { if (e_5) throw e_5.error; }
return [7 /*endfinally*/];
case 7: return [2 /*return*/];
}
});
};
/**
* @internal
*/
Node.prototype.getChildrenInCacheIterator = function () {
var _a, _b, child, e_6_1, e_6, _c;
return __generator(this, function (_d) {
switch (_d.label) {
case 0:
_d.trys.push([0, 7, 8, 9]);
_a = __values(this.getCompilerChildren()), _b = _a.next();
_d.label = 1;
case 1:
if (!!_b.done) return [3 /*break*/, 6];
child = _b.value;
if (!this.global.compilerFactory.hasCompilerNode(child)) return [3 /*break*/, 3];
return [4 /*yield*/, this.global.compilerFactory.getExistingCompilerNode(child)];
case 2:
_d.sent();
return [3 /*break*/, 5];
case 3:
if (!(child.kind === ts.SyntaxKind.SyntaxList)) return [3 /*break*/, 5];
// always return syntax lists because their children could be in the cache
return [4 /*yield*/, getWrappedNode(this, child)];
case 4:
// always return syntax lists because their children could be in the cache
_d.sent();
_d.label = 5;
case 5:
_b = _a.next();
return [3 /*break*/, 1];
case 6: return [3 /*break*/, 9];
case 7:
e_6_1 = _d.sent();
e_6 = { error: e_6_1 };
return [3 /*break*/, 9];
case 8:
try {
if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
}
finally { if (e_6) throw e_6.error; }
return [7 /*endfinally*/];
case 9: return [2 /*return*/];
}
});
};
/**
* Gets the child syntax list or throws if it doesn't exist.
*/
Node.prototype.getChildSyntaxListOrThrow = function () {
return errors.throwIfNullOrUndefined(this.getChildSyntaxList(), "A child syntax list was expected.");
};
/**
* Gets the child syntax list if it exists.
*/
Node.prototype.getChildSyntaxList = function () {
var node = this;
if (utils_1.TypeGuards.isBodyableNode(node) || utils_1.TypeGuards.isBodiedNode(node)) {
do {
node = utils_1.TypeGuards.isBodyableNode(node) ? node.getBodyOrThrow() : node.getBody();
} while ((utils_1.TypeGuards.isBodyableNode(node) || utils_1.TypeGuards.isBodiedNode(node)) && node.compilerNode.statements == null);
}
if (utils_1.TypeGuards.isSourceFile(node) || utils_1.TypeGuards.isBodyableNode(this) || utils_1.TypeGuards.isBodiedNode(this))
return node.getFirstChildByKind(ts.SyntaxKind.SyntaxList);
var passedBrace = false;
try {
for (var _a = __values(node.getCompilerChildren()), _b = _a.next(); !_b.done; _b = _a.next()) {
var child = _b.value;
if (!passedBrace)
passedBrace = child.kind === ts.SyntaxKind.FirstPunctuation;
else if (child.kind === ts.SyntaxKind.SyntaxList)
return getWrappedNode(this, child);
}
}
catch (e_7_1) { e_7 = { error: e_7_1 }; }
finally {
try {
if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
}
finally { if (e_7) throw e_7.error; }
}
return undefined;
var e_7, _c;
};
/**
* Gets the node's descendants.
*/
Node.prototype.getDescendants = function () {
return utils_1.ArrayUtils.from(this.getDescendantsIterator());
};
/**
* Gets the node's descendants as an iterator.
* @internal
*/
Node.prototype.getDescendantsIterator = function () {
var _a, _b, descendant, e_8_1, e_8, _c;
return __generator(this, function (_d) {
switch (_d.label) {
case 0:
_d.trys.push([0, 5, 6, 7]);
_a = __values(this.getCompilerDescendantsIterator()), _b = _a.next();
_d.label = 1;
case 1:
if (!!_b.done) return [3 /*break*/, 4];
descendant = _b.value;
return [4 /*yield*/, getWrappedNode(this, descendant)];
case 2:
_d.sent();
_d.label = 3;
case 3:
_b = _a.next();
return [3 /*break*/, 1];
case 4: return [3 /*break*/, 7];
case 5:
e_8_1 = _d.sent();
e_8 = { error: e_8_1 };
return [3 /*break*/, 7];
case 6:
try {
if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
}
finally { if (e_8) throw e_8.error; }
return [7 /*endfinally*/];
case 7: return [2 /*return*/];
}
});
};
/**
* Gets the child count.
*/
Node.prototype.getChildCount = function () {
return this.compilerNode.getChildCount(this.sourceFile.compilerNode);
};
/**
* Gets the child at the provided position, or undefined if not found.
* @param pos - Position to search for.
*/
Node.prototype.getChildAtPos = function (pos) {
if (pos < this.getPos() || pos >= this.getEnd())
return undefined;
try {
for (var _a = __values(this.getCompilerChildren()), _b = _a.next(); !_b.done; _b = _a.next()) {
var child = _b.value;
if (pos >= child.pos && pos < child.end)
return getWrappedNode(this, child);
}
}
catch (e_9_1) { e_9 = { error: e_9_1 }; }
finally {
try {
if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
}
finally { if (e_9) throw e_9.error; }
}
return undefined;
var e_9, _c;
};
/**
* Gets the most specific descendant at the provided position, or undefined if not found.
* @param pos - Position to search for.
*/
Node.prototype.getDescendantAtPos = function (pos) {
var node;
while (true) {
var nextNode = (node || this).getChildAtPos(pos);
if (nextNode == null)
return node;
else
node = nextNode;
}
};
/**
* Gets the most specific descendant at the provided start position with the specified width, or undefined if not found.
* @param start - Start position to search for.
* @param width - Width of the node to search for.
*/
Node.prototype.getDescendantAtStartWithWidth = function (start, width) {
var nextNode = this.getSourceFile();
var foundNode;
do {
nextNode = nextNode.getChildAtPos(start);
if (nextNode != null) {
if (nextNode.getStart() === start && nextNode.getWidth() === width)
foundNode = nextNode;
else if (foundNode != null)
break; // no need to keep looking
}
} while (nextNode != null);
return foundNode;
};
/**
* Gets the start position with leading trivia.
*/
Node.prototype.getPos = function () {
return this.compilerNode.pos;
};
/**
* Gets the end position.
*/
Node.prototype.getEnd = function () {
return this.compilerNode.end;
};
/**
* Gets the start position without leading trivia.
*/
Node.prototype.getStart = function () {
return this.compilerNode.getStart(this.sourceFile.compilerNode);
};
/**
* Gets the first position from the pos that is not whitespace.
*/
Node.prototype.getNonWhitespaceStart = function () {
return textSeek_1.getNextNonWhitespacePos(this.sourceFile.getFullText(), this.getPos());
};
/**
* Gets the width of the node (length without trivia).
*/
Node.prototype.getWidth = function () {
return this.compilerNode.getWidth(this.sourceFile.compilerNode);
};
/**
* Gets the full width of the node (length with trivia).
*/
Node.prototype.getFullWidth = function () {
return this.compilerNode.getFullWidth();
};
/**
* Gets the text without leading trivia.
*/
Node.prototype.getText = function () {
return this.compilerNode.getText(this.sourceFile.compilerNode);
};
/**
* Gets the full text with leading trivia.
*/
Node.prototype.getFullText = function () {
return this.compilerNode.getFullText(this.sourceFile.compilerNode);
};
/**
* Gets the combined modifier flags.
*/
Node.prototype.getCombinedModifierFlags = function () {
return ts.getCombinedModifierFlags(this.compilerNode);
};
/**
* @internal
*
* WARNING: This should only be called by the compiler factory!
*/
Node.prototype.replaceCompilerNodeFromFactory = function (compilerNode) {
this._compilerNode = compilerNode;
this._childStringRanges = undefined;
};
/**
* Gets the source file.
*/
Node.prototype.getSourceFile = function () {
return this.sourceFile;
};
/**
* Gets a compiler node property wrapped in a Node.
* @param propertyName - Property name.
*/
Node.prototype.getNodeProperty = function (propertyName) {
// todo: once filtering keys by type is supported need to (1) make this only show keys that are of type ts.Node and (2) have ability to return an array of nodes.
if (this.compilerNode[propertyName].kind == null)
throw new errors.InvalidOperationError("Attempted to get property '" + propertyName + "', but " + "getNodeProperty" + " " +
"only works with properties that return a node.");
return getWrappedNode(this, this.compilerNode[propertyName]);
};
/**
* Goes up the tree getting all the parents in ascending order.
*/
Node.prototype.getAncestors = function () {
return utils_1.ArrayUtils.from(this.getAncestorsIterator());
};
/**
* @internal
*/
Node.prototype.getAncestorsIterator = function () {
var parent;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
parent = this.getParent();
_a.label = 1;
case 1:
if (!(parent != null)) return [3 /*break*/, 3];
return [4 /*yield*/, parent];
case 2:
_a.sent();
parent = parent.getParent();
return [3 /*break*/, 1];
case 3: return [2 /*return*/];
}
});
};
/**
* Get the node's parent.
*/
Node.prototype.getParent = function () {
return this.compilerNode.parent == null ? undefined : getWrappedNode(this, this.compilerNode.parent);
};
/**
* Gets the parent or throws an error if it doesn't exist.
*/
Node.prototype.getParentOrThrow = function () {
return errors.throwIfNullOrUndefined(this.getParent(), "A parent is required to do this operation.");
};
/**
* Goes up the parents (ancestors) of the node while a condition is true.
* Throws if the initial parent doesn't match the condition.
* @param condition - Condition that tests the parent to see if the expression is true.
*/
Node.prototype.getParentWhileOrThrow = function (condition) {
return errors.throwIfNullOrUndefined(this.getParentWhile(condition), "The initial parent did not match the provided condition.");
};
/**
* Goes up the parents (ancestors) of the node while a condition is true.
* Returns undefined if the initial parent doesn't match the condition.
* @param condition - Condition that tests the parent to see if the expression is true.
*/
Node.prototype.getParentWhile = function (condition) {
var node = undefined;
var nextParent = this.getParent();
while (nextParent != null && condition(nextParent)) {
node = nextParent;
nextParent = nextParent.getParent();
}
return node;
};
/**
* Goes up the parents (ancestors) of the node while the parent is the specified syntax kind.
* Throws if the initial parent is not the specified syntax kind.
* @param kind - Syntax kind to check for.
*/
Node.prototype.getParentWhileKindOrThrow = function (kind) {
return errors.throwIfNullOrUndefined(this.getParentWhileKind(kind), "The initial parent was not a syntax kind of " + ts.SyntaxKind[kind] + ".");
};
/**
* Goes up the parents (ancestors) of the node while the parent is the specified syntax kind.
* Returns undefined if the initial parent is not the specified syntax kind.
* @param kind - Syntax kind to check for.
*/
Node.prototype.getParentWhileKind = function (kind) {
return this.getParentWhile(function (n) { return n.getKind() === kind; });
};
/**
* Gets the last token of this node. Usually this is a close brace.
*/
Node.prototype.getLastToken = function () {
var lastToken = this.compilerNode.getLastToken(this.sourceFile.compilerNode);
if (lastToken == null)
throw new errors.NotImplementedError("Not implemented scenario where the last token does not exist.");
return getWrappedNode(this, lastToken);
};
/**
* Gets if this node is in a syntax list.
*/
Node.prototype.isInSyntaxList = function () {
return this.getParentSyntaxList() != null;
};
/**
* Gets the parent if it's a syntax list or throws an error otherwise.
*/
Node.prototype.getParentSyntaxListOrThrow = function () {
return errors.throwIfNullOrUndefined(this.getParentSyntaxList(), "Expected the parent to be a syntax list.");
};
/**
* Gets the parent if it's a syntax list.
*/
Node.prototype.getParentSyntaxList = function () {
var parent = this.getParent();
if (parent == null)
return undefined;
var pos = this.getPos();
var end = this.getEnd();
try {
for (var _a = __values(parent.getCompilerChildren()), _b = _a.next(); !_b.done; _b = _a.next()) {
var child = _b.value;
if (child.pos > pos || child === this.compilerNode)
return undefined;
if (child.kind === ts.SyntaxKind.SyntaxList && child.pos <= pos && child.end >= end)
return getWrappedNode(this, child);
}
}
catch (e_10_1) { e_10 = { error: e_10_1 }; }
finally {
try {
if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
}
finally { if (e_10) throw e_10.error; }
}
return undefined; // shouldn't happen
var e_10, _c;
};
/**
* Gets the child index of this node relative to the parent.
*/
Node.prototype.getChildIndex = function () {
var parent = this.getParentSyntaxList() || this.getParentOrThrow();
var i = 0;
try {
for (var _a = __values(parent.getCompilerChildren()), _b = _a.next(); !_b.done; _b = _a.next()) {
var child = _b.value;
if (child === this.compilerNode)
return i;
i++;
}
}
catch (e_11_1) { e_11 = { error: e_11_1 }; }
finally {
try {
if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
}
finally { if (e_11) throw e_11.error; }
}
/* istanbul ignore next */
throw new errors.NotImplementedError("For some reason the child's parent did not contain the child.");
var e_11, _c;
};
/**
* Gets the indentation text.
*/
Node.prototype.getIndentationText = function () {
var sourceFileText = this.sourceFile.getFullText();
var startLinePos = this.getStartLinePos();
var startPos = this.getStart();
var text = "";
for (var i = startPos - 1; i >= startLinePos; i--) {
var currentChar = sourceFileText[i];
switch (currentChar) {
case " ":
case "\t":
text = currentChar + text;
break;
case "\n":
return text;
default:
text = "";
}
}
return text;
};
/**
* Gets the next indentation level text.
*/
Node.prototype.getChildIndentationText = function () {
if (utils_1.TypeGuards.isSourceFile(this))
return "";
return this.getIndentationText() + this.global.manipulationSettings.getIndentationText();
};
/**
* Gets the position of the start of the line that this node starts on.
*/
Node.prototype.getStartLinePos = function () {
var sourceFileText = this.sourceFile.getFullText();
return textSeek_1.getPreviousMatchingPos(sourceFileText, this.getStart(), function (char) { return char === "\n"; });
};
/**
* Gets if this is the first node on the current line.
*/
Node.prototype.isFirstNodeOnLine = function () {
var sourceFileText = this.sourceFile.getFullText();
var startPos = this.getNonWhitespaceStart();
for (var i = startPos - 1; i >= 0; i--) {
var currentChar = sourceFileText[i];
if (currentChar === " " || currentChar === "\t")
continue;
if (currentChar === "\n")
return true;
return false;
}
return true; // first node on the first line
};
Node.prototype.replaceWithText = function (textOrWriterFunction) {
var newText = utils_1.getTextFromStringOrWriter(this.global.manipulationSettings, textOrWriterFunction);
if (utils_1.TypeGuards.isSourceFile(this)) {
this.replaceText([this.getPos(), this.getEnd()], newText);
return this;
}
var parent = this.getParentSyntaxList() || this.getParentOrThrow();
var childIndex = this.getChildIndex();
try {
var nodes = getNodes(this);
var start = nodes[0].getStart();
insertion_1.insertIntoParent({
parent: parent,
childIndex: childIndex,
insertItemsCount: 1,
insertPos: start,
newText: newText,
replacing: {
nodes: nodes,
textLength: this.getEnd() - start
}
});
}
catch (err) {
throw new errors.InvalidOperationError("replaceWithText" + " currently only supports replacing the current node " +
"with a single new node. If you need the ability to replace it with multiple nodes, then please open an issue.\n\nInner error: " + err);
}
return parent.getChildren()[childIndex];
function getNodes(node) {
var nodes = [];
if (utils_1.TypeGuards.isDocumentationableNode(node) && node.getDocNodes().length > 0)
nodes.push.apply(nodes, __spread(node.getDocNodes()));
nodes.push(node);
return nodes;
}
};
/**
* Gets the children based on a kind.
* @param kind - Syntax kind.
*/
Node.prototype.getChildrenOfKind = function (kind) {
var _this = this;
return this.getCompilerChildren().filter(function (c) { return c.kind === kind; }).map(function (c) { return getWrappedNode(_this, c); });
};
/**
* Gets the first child by syntax kind or throws an error if not found.
* @param kind - Syntax kind.
*/
Node.prototype.getFirstChildByKindOrThrow = function (kind) {
return errors.throwIfNullOrUndefined(this.getFirstChildByKind(kind), "A child of the kind " + ts.SyntaxKind[kind] + " was expected.");
};
/**
* Gets the first child by syntax kind.
* @param kind - Syntax kind.
*/
Node.prototype.getFirstChildByKind = function (kind) {
var child = this.getCompilerFirstChild(function (c) { return c.kind === kind; });
return child == null ? undefined : getWrappedNode(this, child);
};
/**
* Gets the first child if it matches the specified syntax kind or throws an error if not found.
* @param kind - Syntax kind.
*/
Node.prototype.getFirstChildIfKindOrThrow = function (kind) {
return errors.throwIfNullOrUndefined(this.getFirstChildIfKind(kind), "A first child of the kind " + ts.SyntaxKind[kind] + " was expected.");
};
/**
* Gets the first child if it matches the specified syntax kind.
* @param kind - Syntax kind.
*/
Node.prototype.getFirstChildIfKind = function (kind) {
var firstChild = this.getCompilerFirstChild();
return firstChild != null && firstChild.kind === kind ? getWrappedNode(this, firstChild) : undefined;
};
/**
* Gets the last child by syntax kind or throws an error if not found.
* @param kind - Syntax kind.
*/
Node.prototype.getLastChildByKindOrThrow = function (kind) {
return errors.throwIfNullOrUndefined(this.getLastChildByKind(kind), "A child of the kind " + ts.SyntaxKind[kind] + " was expected.");
};
/**
* Gets the last child by syntax kind.
* @param kind - Syntax kind.
*/
Node.prototype.getLastChildByKind = function (kind) {
var lastChild = this.getCompilerLastChild(function (c) { return c.kind === kind; });
return lastChild == null ? undefined : getWrappedNode(this, lastChild);
};
/**
* Gets the last child if it matches the specified syntax kind or throws an error if not found.
* @param kind - Syntax kind.
*/
Node.prototype.getLastChildIfKindOrThrow = function (kind) {
return errors.throwIfNullOrUndefined(this.getLastChildIfKind(kind), "A last child of the kind " + ts.SyntaxKind[kind] + " was expected.");
};
/**
* Gets the last child if it matches the specified syntax kind.
* @param kind - Syntax kind.
*/
Node.prototype.getLastChildIfKind = function (kind) {
var lastChild = this.getCompilerLastChild();
return lastChild != null && lastChild.kind === kind ? getWrappedNode(this, lastChild) : undefined;
};
/**
* Gets the child at the specified index if it's the specified kind or throws an exception.
* @param index - Index to get.
* @param kind - Expected kind.
*/
Node.prototype.getChildAtIndexIfKindOrThrow = function (index, kind) {
return errors.throwIfNullOrUndefined(this.getChildAtIndexIfKind(index, kind), "Child at index " + index + " was expected to be " + ts.SyntaxKind[kind]);
};
/**
* Gets the child at the specified index if it's the specified kind or returns undefined.
* @param index - Index to get.
* @param kind - Expected kind.
*/
Node.prototype.getChildAtIndexIfKind = function (index, kind) {
var node = this.getCompilerChildAtIndex(index);
return node.kind === kind ? getWrappedNode(this, node) : undefined;
};
/**
* Gets the previous sibiling if it matches the specified kind, or throws.
* @param kind - Kind to check.
*/
Node.prototype.getPreviousSiblingIfKindOrThrow = function (kind) {
return errors.throwIfNullOrUndefined(this.getPreviousSiblingIfKind(kind), "A previous sibling of kind " + ts.SyntaxKind[kind] + " was expected.");
};
/**
* Gets the next sibiling if it matches the specified kind, or throws.
* @param kind - Kind to check.
*/
Node.prototype.getNextSiblingIfKindOrThrow = function (kind) {
return errors.throwIfNullOrUndefined(this.getNextSiblingIfKind(kind), "A next sibling of kind " + ts.SyntaxKind[kind] + " was expected.");
};
/**
* Gets the previous sibling if it matches the specified kind.
* @param kind - Kind to check.
*/
Node.prototype.getPreviousSiblingIfKind = function (kind) {
var previousSibling = this.getCompilerPreviousSibling();
return previousSibling != null && previousSibling.kind === kind ? getWrappedNode(this, previousSibling) : undefined;
};
/**
* Gets the next sibling if it matches the specified kind.
* @param kind - Kind to check.
*/
Node.prototype.getNextSiblingIfKind = function (kind) {
var nextSibling = this.getCompilerNextSibling();
return nextSibling != null && nextSibling.kind === kind ? getWrappedNode(this, nextSibling) : undefined;
};
/**
* Gets the parent if it's a certain syntax kind.
*/
Node.prototype.getParentIfKind = function (kind) {
var parentNode = this.getParent();
return parentNode == null || parentNode.getKind() !== kind ? undefined : parentNode;
};
/**
* Gets the parent if it's a certain syntax kind of throws.
*/
Node.prototype.getParentIfKindOrThrow = function (kind) {
return errors.throwIfNullOrUndefined(this.getParentIfKind(kind), "A parent with a syntax kind of " + ts.SyntaxKind[kind] + " is required to do this operation.");
};
/**
* Gets the first ancestor by syntax kind or throws if not found.
* @param kind - Syntax kind.
*/
Node.prototype.getFirstAncestorByKindOrThrow = function (kind) {
return errors.throwIfNullOrUndefined(this.getFirstAncestorByKind(kind), "A parent of kind " + ts.SyntaxKind[kind] + " is required to do this operation.");
};
/**
* Get the first ancestor by syntax kind.
* @param kind - Syntax kind.
*/
Node.prototype.getFirstAncestorByKind = function (kind) {
try {
for (var _a = __values(this.getAncestors()), _b = _a.next(); !_b.done; _b = _a.next()) {
var parent = _b.value;
if (parent.getKind() === kind)
return parent;
}
}
catch (e_12_1) { e_12 = { error: e_12_1 }; }
finally {
try {
if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
}
finally { if (e_12) throw e_12.error; }
}
return undefined;
var e_12, _c;
};
/**
* Gets the descendants that match a specified syntax kind.
* @param kind - Kind to check.
*/
Node.prototype.getDescendantsOfKind = function (kind) {
var descendants = [];
try {
for (var _a = __values(this.getCompilerDescendantsIterator()), _b = _a.next(); !_b.done; _b = _a.next()) {
var descendant = _b.value;
if (descendant.kind === kind)
descendants.push(getWrappedNode(this, descendant));
}
}
catch (e_13_1) { e_13 = { error: e_13_1 }; }
finally {
try {
if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
}
finally { if (e_13) throw e_13.error; }
}
return descendants;
var e_13, _c;
};
/**
* Gets the first descendant by syntax kind or throws.
* @param kind - Syntax kind.
*/
Node.prototype.getFirstDescendantByKindOrThrow = function (kind) {
return errors.throwIfNullOrUndefined(this.getFirstDescendantByKind(kind), "A descendant of kind " + ts.SyntaxKind[kind] + " is required to do this operation.");
};
/**
* Gets the first descendant by syntax kind.
* @param kind - Syntax kind.
*/
Node.prototype.getFirstDescendantByKind = function (kind) {
try {
for (var _a = __values(this.getCompilerDescendantsIterator()), _b = _a.next(); !_b.done; _b = _a.next()) {
var descendant = _b.value;
if (descendant.kind === kind)
return getWrappedNode(this, descendant);
}
}
catch (e_14_1) { e_14 = { error: e_14_1 }; }
finally {
try {
if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
}
finally { if (e_14) throw e_14.error; }
}
return undefined;
var e_14, _c;
};
/**
* Gets the compiler children of the node.
* @internal
*/
Node.prototype.getCompilerChildren = function () {
return this.compilerNode.getChildren(this.sourceFile.compilerNode);
};
/**
* Gets the node's descendant compiler nodes as an iterator.
* @internal
*/
Node.prototype.getCompilerDescendantsIterator = function () {
var compilerSourceFile = this.sourceFile.compilerNode;
return getDescendantsIterator(this.compilerNode);
function getDescendantsIterator(node) {
var _a, _b, child, e_15_1, e_15, _c;
return __generator(this, function (_d) {
switch (_d.label) {
case 0:
_d.trys.push([0, 6, 7, 8]);
_a = __values(node.getChildren(compilerSourceFile)), _b = _a.next();
_d.label = 1;
case 1:
if (!!_b.done) return [3 /*break*/, 5];
child = _b.value;
return [4 /*yield*/, child];
case 2:
_d.sent();
return [5 /*yield**/, __values(getDescendantsIterator(child))];
case 3:
_d.sent();
_d.label = 4;
case 4:
_b = _a.next();
return [3 /*break*/, 1];
case 5: return [3 /*break*/, 8];
case 6:
e_15_1 = _d.sent();
e_15 = { error: e_15_1 };
return [3 /*break*/, 8];
case 7:
try {
if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
}
finally { if (e_15) throw e_15.error; }
return [7 /*endfinally*/];
case 8: return [2 /*return*/];
}
});
}
};
/**
* Gets the first compiler node child that matches the condition.
* @param condition - Condition.
* @internal
*/
Node.prototype.getCompilerFirstChild = function (condition) {
try {
for (var _a = __values(this.getCompilerChildren()), _b = _a.next(); !_b.done; _b = _a.next()) {
var child = _b.value;
if (condition == null || condition(child))
return child;
}
}
catch (e_16_1) { e_16 = { error: e_16_1 }; }
finally {
try {
if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
}
finally { if (e_16) throw e_16.error; }
}
return undefined;
var e_16, _c;
};
/**
* Gets the last compiler node child that matches the condition.
* @param condition - Condition.
* @internal
*/
Node.prototype.getCompilerLastChild = function (condition) {
var children = this.getCompilerChildren();
for (var i = children.length - 1; i >= 0; i--) {
var child = children[i];
if (condition == null || condition(child))
return child;
}
return undefined;
};
/**
* Gets the previous compiler siblings.
*
* Note: Closest sibling is the zero index.
* @internal
*/
Node.prototype.getCompilerPreviousSiblings = function () {
var parent = this.getParentSyntaxList() || this.getParentOrThrow();
var previousSiblings = [];
try {
for (var _a = __values(parent.getCompilerChildren()), _b = _a.next(); !_b.done; _b = _a.next()) {
var child = _b.value;
if (child === this.compilerNode)
break;
previousSiblings.unshift(child);
}
}
catch (e_17_1) { e_17 = { error: e_17_1 }; }
finally {
try {
if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
}
finally { if (e_17) throw e_17.error; }
}
return previousSiblings;
var e_17, _c;
};
/**
* Gets the next compiler siblings.
*
* Note: Closest sibling is the zero index.
* @internal
*/
Node.prototype.getCompilerNextSiblings = function () {
var foundChild = false;
var parent = this.getParentSyntaxList() || this.getParentOrThrow();
var nextSiblings = [];
try {
for (var _a = __values(parent.getCompilerChildren()), _b = _a.next(); !_b.done; _b = _a.next()) {
var child = _b.value;
if (!foundChild) {
foundChild = child === this.compilerNode;
continue;
}
nextSiblings.push(child);
}
}
catch (e_18_1) { e_18 = { error: e_18_1 }; }
finally {
try {
if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
}
finally { if (e_18) throw e_18.error; }
}
return nextSiblings;
var e_18, _c;
};
/**
* Gets the previous compiler sibling.
* @param condition - Optional condition for getting the previous sibling.
* @internal
*/
Node.prototype.getCompilerPreviousSibling = function (condition) {
try {
for (var _a = __values(this.getCompilerPreviousSiblings()), _b = _a.next(); !_b.done; _b = _a.next()) {
var sibling = _b.value;
if (condition == null || condition(sibling))
return sibling;
}
}
catch (e_19_1) { e_19 = { error: e_19_1 }; }
finally {
try {
if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
}
finally { if (e_19) throw e_19.error; }
}
return undefined;
var e_19, _c;
};
/**
* Gets the next compiler sibling.
* @param conditio