ts-simple-ast
Version:
TypeScript compiler wrapper for AST navigation and code generation.
250 lines (249 loc) • 10.2 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 __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var typescript_1 = require("./../../typescript");
var errors = require("./../../errors");
var manipulation_1 = require("./../../manipulation");
var utils_1 = require("./../../utils");
var common_1 = require("./../common");
exports.DecoratorBase = common_1.Node;
var Decorator = /** @class */ (function (_super) {
__extends(Decorator, _super);
function Decorator() {
return _super !== null && _super.apply(this, arguments) || this;
}
/**
* Gets the decorator name.
*/
Decorator.prototype.getName = function () {
return this.getNameNode().getText();
};
/**
* Gets the name node of the decorator.
*/
Decorator.prototype.getNameNode = function () {
var sourceFile = this.getSourceFile();
if (this.isDecoratorFactory()) {
var callExpression = this.getCallExpression();
return getIdentifierFromName(callExpression.getExpression());
}
return getIdentifierFromName(this.getExpression());
function getIdentifierFromName(expression) {
var identifier = getNameFromExpression(expression);
if (!utils_1.TypeGuards.isIdentifier(identifier)) {
throw new errors.NotImplementedError("Expected the decorator expression '" + identifier.getText() + "' to be an identifier, " +
"but it wasn't. Please report this as a bug.");
}
return identifier;
}
function getNameFromExpression(expression) {
if (utils_1.TypeGuards.isPropertyAccessExpression(expression))
return expression.getNameNode();
return expression;
}
};
/**
* Gets the full decorator name.
*/
Decorator.prototype.getFullName = function () {
var sourceFile = this.getSourceFile();
if (this.isDecoratorFactory())
return this.getCallExpression().getExpression().getText();
return this.compilerNode.expression.getText(sourceFile.compilerNode);
};
/**
* Gets if the decorator is a decorator factory.
*/
Decorator.prototype.isDecoratorFactory = function () {
return this.compilerNode.expression.kind === typescript_1.SyntaxKind.CallExpression;
};
/**
* Set if this decorator is a decorator factory.
* @param isDecoratorFactory - If it should be a decorator factory or not.
*/
Decorator.prototype.setIsDecoratorFactory = function (isDecoratorFactory) {
if (this.isDecoratorFactory() === isDecoratorFactory)
return this;
if (isDecoratorFactory) {
var expression_1 = this.getExpression();
var expressionText = expression_1.getText();
manipulation_1.insertIntoParent({
parent: this,
childIndex: expression_1.getChildIndex(),
insertItemsCount: 1,
insertPos: expression_1.getStart(),
newText: expressionText + "()",
replacing: {
nodes: [expression_1],
textLength: expressionText.length
},
customMappings: function (newParent) {
// the expression will move into the call expression
var callExpression = newParent.getCallExpressionOrThrow();
var newExpression = callExpression.getExpression();
return [{ currentNode: expression_1, newNode: newExpression }];
}
});
}
else {
var callExpression = this.getCallExpressionOrThrow();
var expression_2 = callExpression.getExpression();
var expressionText = expression_2.getText();
manipulation_1.insertIntoParent({
parent: this,
childIndex: callExpression.getChildIndex(),
insertItemsCount: 1,
insertPos: callExpression.getStart(),
newText: "" + expressionText,
replacing: {
nodes: [callExpression],
textLength: callExpression.getWidth()
},
customMappings: function (newParent) {
// the expression will move out of the call expression
var newExpression = newParent.getExpression();
return [{ currentNode: expression_2, newNode: newExpression }];
}
});
}
return this;
};
/**
* Gets the call expression if a decorator factory, or throws.
*/
Decorator.prototype.getCallExpressionOrThrow = function () {
return errors.throwIfNullOrUndefined(this.getCallExpression(), "Expected to find a call expression.");
};
/**
* Gets the call expression if a decorator factory.
*/
Decorator.prototype.getCallExpression = function () {
if (!this.isDecoratorFactory())
return undefined;
return this.getExpression();
};
/**
* Gets the expression.
*/
Decorator.prototype.getExpression = function () {
return this.getNodeFromCompilerNode(this.compilerNode.expression);
};
/**
* Gets the decorator's arguments from its call expression.
*/
Decorator.prototype.getArguments = function () {
var callExpression = this.getCallExpression();
return callExpression == null ? [] : callExpression.getArguments();
};
/**
* Gets the decorator's type arguments from its call expression.
*/
Decorator.prototype.getTypeArguments = function () {
var callExpression = this.getCallExpression();
return callExpression == null ? [] : callExpression.getTypeArguments();
};
/**
* Adds a type argument.
* @param argumentTexts - Argument text.
*/
Decorator.prototype.addTypeArgument = function (argumentText) {
return this.getCallExpressionOrThrow().addTypeArgument(argumentText);
};
/**
* Adds type arguments.
* @param argumentTexts - Argument texts.
*/
Decorator.prototype.addTypeArguments = function (argumentTexts) {
return this.getCallExpressionOrThrow().addTypeArguments(argumentTexts);
};
/**
* Inserts a type argument.
* @param index - Index to insert at.
* @param argumentTexts - Argument text.
*/
Decorator.prototype.insertTypeArgument = function (index, argumentText) {
return this.getCallExpressionOrThrow().insertTypeArgument(index, argumentText);
};
/**
* Inserts type arguments.
* @param index - Index to insert at.
* @param argumentTexts - Argument texts.
*/
Decorator.prototype.insertTypeArguments = function (index, argumentTexts) {
return this.getCallExpressionOrThrow().insertTypeArguments(index, argumentTexts);
};
Decorator.prototype.removeTypeArgument = function (typeArgOrIndex) {
var callExpression = this.getCallExpression();
if (callExpression == null)
throw new errors.InvalidOperationError("Cannot remove a type argument from a decorator that has no type arguments.");
callExpression.removeTypeArgument(typeArgOrIndex);
return this;
};
/**
* Adds an argument.
* @param argumentTexts - Argument text.
*/
Decorator.prototype.addArgument = function (argumentText) {
return this.addArguments([argumentText])[0];
};
/**
* Adds arguments.
* @param argumentTexts - Argument texts.
*/
Decorator.prototype.addArguments = function (argumentTexts) {
return this.insertArguments(this.getArguments().length, argumentTexts);
};
/**
* Inserts an argument.
* @param index - Index to insert at.
* @param argumentTexts - Argument text.
*/
Decorator.prototype.insertArgument = function (index, argumentText) {
return this.insertArguments(index, [argumentText])[0];
};
/**
* Inserts arguments.
* @param index - Index to insert at.
* @param argumentTexts - Argument texts.
*/
Decorator.prototype.insertArguments = function (index, argumentTexts) {
this.setIsDecoratorFactory(true);
return this.getCallExpressionOrThrow().insertArguments(index, argumentTexts);
};
Decorator.prototype.removeArgument = function (argOrIndex) {
var callExpression = this.getCallExpression();
if (callExpression == null)
throw new errors.InvalidOperationError("Cannot remove an argument from a decorator that has no arguments.");
callExpression.removeArgument(argOrIndex);
return this;
};
/**
* Removes this decorator.
*/
Decorator.prototype.remove = function () {
var thisStartLinePos = this.getStartLinePos();
var previousDecorator = this.getPreviousSiblingIfKind(typescript_1.SyntaxKind.Decorator);
if (previousDecorator != null && previousDecorator.getStartLinePos() === thisStartLinePos) {
manipulation_1.removeChildren({
children: [this],
removePrecedingSpaces: true
});
}
else
manipulation_1.removeChildrenWithFormattingFromCollapsibleSyntaxList({
children: [this],
getSiblingFormatting: function (parent, sibling) { return sibling.getStartLinePos() === thisStartLinePos ? manipulation_1.FormattingKind.Space : manipulation_1.FormattingKind.Newline; }
});
};
return Decorator;
}(exports.DecoratorBase));
exports.Decorator = Decorator;