UNPKG

ts-simple-ast

Version:

TypeScript compiler wrapper for static analysis and code manipulation.

278 lines (277 loc) 12.9 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 ImportDeclaration = /** @class */ (function (_super) { tslib_1.__extends(ImportDeclaration, _super); function ImportDeclaration() { return _super !== null && _super.apply(this, arguments) || this; } ImportDeclaration.prototype.setModuleSpecifier = function (textOrSourceFile) { var text = typeof textOrSourceFile === "string" ? textOrSourceFile : this.sourceFile.getRelativePathAsModuleSpecifierTo(textOrSourceFile); this.getModuleSpecifier().setLiteralValue(text); return this; }; /** * Gets the module specifier. */ ImportDeclaration.prototype.getModuleSpecifier = function () { var moduleSpecifier = this.getNodeFromCompilerNode(this.compilerNode.moduleSpecifier); 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 string literal value. */ ImportDeclaration.prototype.getModuleSpecifierValue = function () { return this.getModuleSpecifier().getLiteralValue(); }; /** * Gets the source file referenced in the module specifier or throws if it can't find it. */ ImportDeclaration.prototype.getModuleSpecifierSourceFileOrThrow = function () { return errors.throwIfNullOrUndefined(this.getModuleSpecifierSourceFile(), "A module specifier source file was expected."); }; /** * Gets the source file referenced in the module specifier or returns undefined if it can't find it. */ ImportDeclaration.prototype.getModuleSpecifierSourceFile = function () { var symbol = this.getModuleSpecifier().getSymbol(); if (symbol == null) return undefined; return utils_1.ModuleUtils.getReferencedSourceFileFromSymbol(symbol); }; /** * Gets if the module specifier starts with `./` or `../`. */ ImportDeclaration.prototype.isModuleSpecifierRelative = function () { return utils_1.ModuleUtils.isModuleSpecifierRelative(this.getModuleSpecifierValue()); }; /** * Sets the default import. * @param text - Text to set as the default import. */ ImportDeclaration.prototype.setDefaultImport = function (text) { errors.throwIfNotStringOrWhitespace(text, "text"); var defaultImport = this.getDefaultImport(); if (defaultImport != null) { defaultImport.rename(text); return this; } var importKeyword = this.getFirstChildByKindOrThrow(typescript_1.SyntaxKind.ImportKeyword); var importClause = this.getImportClause(); if (importClause == null) { manipulation_1.insertIntoParentTextRange({ insertPos: importKeyword.getEnd(), parent: this, newText: " " + text + " from" }); return this; } // a namespace import or named import must exist... insert it beforehand manipulation_1.insertIntoParentTextRange({ insertPos: importKeyword.getEnd(), parent: importClause, newText: " " + text + "," }); return this; }; /** * Gets the default import or throws if it doesn't exit. */ ImportDeclaration.prototype.getDefaultImportOrThrow = function () { return errors.throwIfNullOrUndefined(this.getDefaultImport(), "Expected to find a default import."); }; /** * Gets the default import or returns undefined if it doesn't exist. */ ImportDeclaration.prototype.getDefaultImport = function () { var importClause = this.getImportClause(); if (importClause == null) return undefined; var firstChild = importClause.getFirstChild(); if (firstChild == null || firstChild.getKind() !== typescript_1.SyntaxKind.Identifier) return undefined; return firstChild; }; /** * Sets the namespace import. * @param text - Text to set as the namespace import. * @throws - InvalidOperationError if a named import exists. */ ImportDeclaration.prototype.setNamespaceImport = function (text) { if (utils_1.StringUtils.isNullOrWhitespace(text)) return this.removeNamespaceImport(); var namespaceImport = this.getNamespaceImport(); if (namespaceImport != null) { namespaceImport.rename(text); return this; } if (this.getNamedImports().length > 0) throw new errors.InvalidOperationError("Cannot add a namespace import to an import declaration that has named imports."); var defaultImport = this.getDefaultImport(); if (defaultImport != null) { manipulation_1.insertIntoParentTextRange({ insertPos: defaultImport.getEnd(), parent: this.getImportClause(), newText: ", * as " + text }); return this; } manipulation_1.insertIntoParentTextRange({ insertPos: this.getFirstChildByKindOrThrow(typescript_1.SyntaxKind.ImportKeyword).getEnd(), parent: this, newText: " * as " + text + " from" }); return this; }; /** * Removes the namespace import. */ ImportDeclaration.prototype.removeNamespaceImport = function () { var namespaceImport = this.getNamespaceImport(); if (namespaceImport == null) return this; manipulation_1.removeChildren({ children: getChildrenToRemove.call(this), removePrecedingSpaces: true, removePrecedingNewLines: true }); return this; function getChildrenToRemove() { var defaultImport = this.getDefaultImport(); if (defaultImport == null) return [this.getImportClauseOrThrow(), this.getLastChildByKindOrThrow(typescript_1.SyntaxKind.FromKeyword)]; else return [defaultImport.getNextSiblingIfKindOrThrow(typescript_1.SyntaxKind.CommaToken), namespaceImport]; } }; /** * Gets the namespace import if it exists or throws. */ ImportDeclaration.prototype.getNamespaceImportOrThrow = function () { return errors.throwIfNullOrUndefined(this.getNamespaceImport(), "Expected to find a namespace import."); }; /** * Gets the namespace import, if it exists. */ ImportDeclaration.prototype.getNamespaceImport = function () { var importClause = this.getImportClause(); if (importClause == null) return undefined; var namespaceImport = importClause.getFirstChildByKind(typescript_1.SyntaxKind.NamespaceImport); if (namespaceImport == null) return undefined; return namespaceImport.getFirstChildByKind(typescript_1.SyntaxKind.Identifier); }; ImportDeclaration.prototype.addNamedImport = function (structureOrName) { return this.addNamedImports([structureOrName])[0]; }; /** * Adds named imports. * @param structuresOrNames - Structures or names that represent the named imports. */ ImportDeclaration.prototype.addNamedImports = function (structuresOrNames) { return this.insertNamedImports(this.getNamedImports().length, structuresOrNames); }; ImportDeclaration.prototype.insertNamedImport = function (index, structureOrName) { return this.insertNamedImports(index, [structureOrName])[0]; }; /** * Inserts named imports into the import declaration. * @param index - Index to insert at. * @param structuresOrNames - Structures or names that represent the named imports. */ ImportDeclaration.prototype.insertNamedImports = function (index, structuresOrNames) { if (utils_1.ArrayUtils.isNullOrEmpty(structuresOrNames)) return []; var namedImports = this.getNamedImports(); var writer = this.getWriterWithQueuedChildIndentation(); var namedImportStructurePrinter = this.global.structurePrinterFactory.forNamedImportExportSpecifier(); var importClause = this.getImportClause(); index = manipulation_1.verifyAndGetIndex(index, namedImports.length); if (namedImports.length === 0) { namedImportStructurePrinter.printTextsWithBraces(writer, structuresOrNames); if (importClause == null) manipulation_1.insertIntoParentTextRange({ insertPos: this.getFirstChildByKindOrThrow(typescript_1.SyntaxKind.ImportKeyword).getEnd(), parent: this, newText: " " + writer.toString() + " from" }); else if (this.getNamespaceImport() != null) throw new errors.InvalidOperationError("Cannot add a named import to an import declaration that has a namespace import."); else manipulation_1.insertIntoParentTextRange({ insertPos: this.getDefaultImport().getEnd(), parent: importClause, newText: ", " + writer.toString() }); } else { if (importClause == null) throw new errors.NotImplementedError("Expected to have an import clause."); namedImportStructurePrinter.printTexts(writer, structuresOrNames); manipulation_1.insertIntoCommaSeparatedNodes({ parent: importClause.getFirstChildByKindOrThrow(typescript_1.SyntaxKind.NamedImports).getFirstChildByKindOrThrow(typescript_1.SyntaxKind.SyntaxList), currentNodes: namedImports, insertIndex: index, newText: writer.toString(), surroundWithSpaces: this.global.getFormatCodeSettings().insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces }); } return manipulation_1.getNodesToReturn(this.getNamedImports(), index, structuresOrNames.length); }; /** * Gets the named imports. */ ImportDeclaration.prototype.getNamedImports = function () { var importClause = this.getImportClause(); if (importClause == null) return []; var namedImports = importClause.getFirstChildByKind(typescript_1.SyntaxKind.NamedImports); if (namedImports == null) return []; return namedImports.getChildSyntaxListOrThrow().getChildren().filter(function (c) { return utils_1.TypeGuards.isImportSpecifier(c); }); }; /** * Removes all the named imports. */ ImportDeclaration.prototype.removeNamedImports = function () { var importClause = this.getImportClause(); if (importClause == null) return this; var namedImportsNode = importClause.getFirstChildByKind(typescript_1.SyntaxKind.NamedImports); if (namedImportsNode == null) return this; // ex. import defaultExport, {Export1} from "module-name"; var defaultImport = this.getDefaultImport(); if (defaultImport != null) { var commaToken = defaultImport.getNextSiblingIfKindOrThrow(typescript_1.SyntaxKind.CommaToken); manipulation_1.removeChildren({ children: [commaToken, namedImportsNode] }); return this; } // ex. import {Export1} from "module-name"; var fromKeyword = importClause.getNextSiblingIfKindOrThrow(typescript_1.SyntaxKind.FromKeyword); manipulation_1.removeChildren({ children: [importClause, fromKeyword], removePrecedingSpaces: true }); return this; }; /** * Gets the import clause or throws if it doesn't exist. */ ImportDeclaration.prototype.getImportClauseOrThrow = function () { return errors.throwIfNullOrUndefined(this.getImportClause(), "Expected to find an import clause."); }; /** * Gets the import clause or returns undefined if it doesn't exist. */ ImportDeclaration.prototype.getImportClause = function () { return this.getNodeFromCompilerNodeIfExists(this.compilerNode.importClause); }; return ImportDeclaration; }(statement_1.Statement)); exports.ImportDeclaration = ImportDeclaration;