UNPKG

ts-simple-ast

Version:

TypeScript compiler wrapper for static analysis and code manipulation.

257 lines (256 loc) 11.7 kB
"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() } }); }