ts-simple-ast
Version:
TypeScript compiler wrapper for static analysis and code manipulation.
257 lines (256 loc) • 11.7 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
var errors = require("../../../errors");
var manipulation_1 = require("../../../manipulation");
var typescript_1 = require("../../../typescript");
var utils_1 = require("../../../utils");
var statement_1 = require("../statement");
var callBaseGetStructure_1 = require("../callBaseGetStructure");
var callBaseSet_1 = require("../callBaseSet");
exports.ExportDeclarationBase = statement_1.Statement;
var ExportDeclaration = /** @class */ (function (_super) {
tslib_1.__extends(ExportDeclaration, _super);
function ExportDeclaration() {
return _super !== null && _super.apply(this, arguments) || this;
}
ExportDeclaration.prototype.setModuleSpecifier = function (textOrSourceFile) {
var text = typeof textOrSourceFile === "string" ? textOrSourceFile : this._sourceFile.getRelativePathAsModuleSpecifierTo(textOrSourceFile);
if (utils_1.StringUtils.isNullOrEmpty(text)) {
this.removeModuleSpecifier();
return this;
}
var stringLiteral = this.getModuleSpecifier();
if (stringLiteral == null) {
var semiColonToken = this.getLastChildIfKind(typescript_1.SyntaxKind.SemicolonToken);
var quoteKind = this._context.manipulationSettings.getQuoteKind();
manipulation_1.insertIntoParentTextRange({
insertPos: semiColonToken != null ? semiColonToken.getPos() : this.getEnd(),
parent: this,
newText: " from " + quoteKind + text + quoteKind
});
}
else
stringLiteral.setLiteralValue(text);
return this;
};
/**
* Gets the module specifier or undefined if it doesn't exist.
*/
ExportDeclaration.prototype.getModuleSpecifier = function () {
var moduleSpecifier = this._getNodeFromCompilerNodeIfExists(this.compilerNode.moduleSpecifier);
if (moduleSpecifier == null)
return undefined;
if (!utils_1.TypeGuards.isStringLiteral(moduleSpecifier))
throw new errors.InvalidOperationError("Expected the module specifier to be a string literal.");
return moduleSpecifier;
};
/**
* Gets the module specifier value or undefined if it doesn't exist.
*/
ExportDeclaration.prototype.getModuleSpecifierValue = function () {
var moduleSpecifier = this.getModuleSpecifier();
return moduleSpecifier == null ? undefined : moduleSpecifier.getLiteralValue();
};
/**
* Gets the source file referenced in the module specifier or throws if it can't find it or it doesn't exist.
*/
ExportDeclaration.prototype.getModuleSpecifierSourceFileOrThrow = function () {
return errors.throwIfNullOrUndefined(this.getModuleSpecifierSourceFile(), "A module specifier source file was expected.");
};
/**
* Gets the source file referenced in the module specifier.
*/
ExportDeclaration.prototype.getModuleSpecifierSourceFile = function () {
var stringLiteral = this.getLastChildByKind(typescript_1.SyntaxKind.StringLiteral);
if (stringLiteral == null)
return undefined;
var symbol = stringLiteral.getSymbol();
if (symbol == null)
return undefined;
var declaration = symbol.getDeclarations()[0];
return declaration != null && utils_1.TypeGuards.isSourceFile(declaration) ? declaration : undefined;
};
/**
* Gets if the module specifier starts with `./` or `../`.
*/
ExportDeclaration.prototype.isModuleSpecifierRelative = function () {
var moduleSpecifierValue = this.getModuleSpecifierValue();
if (moduleSpecifierValue == null)
return false;
return utils_1.ModuleUtils.isModuleSpecifierRelative(moduleSpecifierValue);
};
/**
* Removes the module specifier.
*/
ExportDeclaration.prototype.removeModuleSpecifier = function () {
var moduleSpecifier = this.getModuleSpecifier();
if (moduleSpecifier == null)
return this;
if (!this.hasNamedExports())
throw new errors.InvalidOperationError("Cannot remove the module specifier from an export declaration that has no named exports.");
manipulation_1.removeChildren({
children: [this.getFirstChildByKindOrThrow(typescript_1.SyntaxKind.FromKeyword), moduleSpecifier],
removePrecedingNewLines: true,
removePrecedingSpaces: true
});
return this;
};
/**
* Gets if the module specifier exists
*/
ExportDeclaration.prototype.hasModuleSpecifier = function () {
return this.getLastChildByKind(typescript_1.SyntaxKind.StringLiteral) != null;
};
/**
* Gets if this export declaration is a namespace export.
*/
ExportDeclaration.prototype.isNamespaceExport = function () {
return !this.hasNamedExports();
};
/**
* Gets if the export declaration has named exports.
*/
ExportDeclaration.prototype.hasNamedExports = function () {
return this.compilerNode.exportClause != null;
};
/**
* Adds a named export.
* @param namedExport - Structure, name, or writer function to write the named export.
*/
ExportDeclaration.prototype.addNamedExport = function (namedExport) {
return this.addNamedExports([namedExport])[0];
};
/**
* Adds named exports.
* @param namedExports - Structures, names, or writer function to write the named exports.
*/
ExportDeclaration.prototype.addNamedExports = function (namedExports) {
return this.insertNamedExports(this.getNamedExports().length, namedExports);
};
/**
* Inserts a named export.
* @param index - Child index to insert at.
* @param namedExport - Structure, name, or writer function to write the named export.
*/
ExportDeclaration.prototype.insertNamedExport = function (index, namedExport) {
return this.insertNamedExports(index, [namedExport])[0];
};
/**
* Inserts named exports into the export declaration.
* @param index - Child index to insert at.
* @param namedExports - Structures, names, or writer funciton to write the named exports.
*/
ExportDeclaration.prototype.insertNamedExports = function (index, namedExports) {
if (!(namedExports instanceof Function) && utils_1.ArrayUtils.isNullOrEmpty(namedExports))
return [];
var originalNamedExports = this.getNamedExports();
var writer = this._getWriterWithIndentation();
var namedExportStructurePrinter = this._context.structurePrinterFactory.forNamedImportExportSpecifier();
index = manipulation_1.verifyAndGetIndex(index, originalNamedExports.length);
if (this.getNodeProperty("exportClause") == null) {
namedExportStructurePrinter.printTextsWithBraces(writer, namedExports);
var asteriskToken = this.getFirstChildByKindOrThrow(typescript_1.SyntaxKind.AsteriskToken);
manipulation_1.insertIntoParentTextRange({
insertPos: asteriskToken.getStart(),
parent: this,
newText: writer.toString(),
replacing: {
textLength: 1
}
});
}
else {
namedExportStructurePrinter.printTexts(writer, namedExports);
manipulation_1.insertIntoCommaSeparatedNodes({
parent: this.getFirstChildByKindOrThrow(typescript_1.SyntaxKind.NamedExports).getFirstChildByKindOrThrow(typescript_1.SyntaxKind.SyntaxList),
currentNodes: originalNamedExports,
insertIndex: index,
newText: writer.toString(),
surroundWithSpaces: this._context.getFormatCodeSettings().insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces
});
}
var newNamedExports = this.getNamedExports();
return manipulation_1.getNodesToReturn(newNamedExports, index, newNamedExports.length - originalNamedExports.length);
};
/**
* Gets the named exports.
*/
ExportDeclaration.prototype.getNamedExports = function () {
var _this = this;
var namedExports = this.compilerNode.exportClause;
if (namedExports == null)
return [];
return namedExports.elements.map(function (e) { return _this._getNodeFromCompilerNode(e); });
};
/**
* Changes the export declaration to namespace export. Removes all the named exports.
*/
ExportDeclaration.prototype.toNamespaceExport = function () {
if (!this.hasModuleSpecifier())
throw new errors.InvalidOperationError("Cannot change to a namespace export when no module specifier exists.");
var namedExportsNode = this.getNodeProperty("exportClause");
if (namedExportsNode == null)
return this;
manipulation_1.insertIntoParentTextRange({
parent: this,
newText: "*",
insertPos: namedExportsNode.getStart(),
replacing: {
textLength: namedExportsNode.getWidth()
}
});
return this;
};
/**
* Sets the node from a structure.
* @param structure - Structure to set the node with.
*/
ExportDeclaration.prototype.set = function (structure) {
callBaseSet_1.callBaseSet(exports.ExportDeclarationBase.prototype, this, structure);
if (structure.namedExports != null) {
setEmptyNamedExport(this);
this.addNamedExports(structure.namedExports);
}
else if (structure.hasOwnProperty("namedExports") && structure.moduleSpecifier == null)
this.toNamespaceExport();
if (structure.moduleSpecifier != null)
this.setModuleSpecifier(structure.moduleSpecifier);
else if (structure.hasOwnProperty("moduleSpecifier"))
this.removeModuleSpecifier();
if (structure.namedExports == null && structure.hasOwnProperty("namedExports"))
this.toNamespaceExport();
return this;
};
/**
* Gets the structure equivalent to this node.
*/
ExportDeclaration.prototype.getStructure = function () {
var moduleSpecifier = this.getModuleSpecifier();
return callBaseGetStructure_1.callBaseGetStructure(exports.ExportDeclarationBase.prototype, this, {
moduleSpecifier: moduleSpecifier ? moduleSpecifier.getLiteralText() : undefined,
namedExports: this.getNamedExports().map(function (node) { return node.getStructure(); })
});
};
return ExportDeclaration;
}(exports.ExportDeclarationBase));
exports.ExportDeclaration = ExportDeclaration;
function setEmptyNamedExport(node) {
var namedExportsNode = node.getNodeProperty("exportClause");
var replaceNode;
if (namedExportsNode != null) {
if (node.getNamedExports().length === 0)
return;
replaceNode = namedExportsNode;
}
else
replaceNode = node.getFirstChildByKindOrThrow(typescript_1.SyntaxKind.AsteriskToken);
manipulation_1.insertIntoParentTextRange({
parent: node,
newText: "{ }",
insertPos: replaceNode.getStart(),
replacing: {
textLength: replaceNode.getWidth()
}
});
}