UNPKG

ts-simple-ast

Version:

TypeScript compiler wrapper for AST navigation and code generation.

220 lines (218 loc) 8.29 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const ts = require("typescript"); const errors = require("./../../errors"); const manipulation_1 = require("./../../manipulation"); const utils_1 = require("./../../utils"); const common_1 = require("./../common"); const ImportSpecifier_1 = require("./ImportSpecifier"); class ImportDeclaration extends common_1.Node { /** * Sets the import specifier. * @param text - Text to set as the import specifier. */ setModuleSpecifier(text) { const stringLiteral = this.getLastChildByKindOrThrow(ts.SyntaxKind.StringLiteral); manipulation_1.insertIntoParent({ parent: this, newText: text, insertPos: stringLiteral.getStart() + 1, childIndex: stringLiteral.getChildIndex(), insertItemsCount: 1, replacing: { length: stringLiteral.getWidth() - 2, nodes: [stringLiteral] } }); return this; } /** * Gets the module specifier. */ getModuleSpecifier() { const stringLiteral = this.getLastChildByKindOrThrow(ts.SyntaxKind.StringLiteral); const text = stringLiteral.getText(); return text.substring(1, text.length - 1); } /** * Sets the default import. * @param text - Text to set as the default import. */ setDefaultImport(text) { const defaultImport = this.getDefaultImport(); if (defaultImport != null) { defaultImport.rename(text); return this; } const importKeyword = this.getFirstChildByKindOrThrow(ts.SyntaxKind.ImportKeyword); const importClause = this.getImportClause(); if (importClause == null) { manipulation_1.insertIntoParent({ insertPos: importKeyword.getEnd(), childIndex: importKeyword.getChildIndex() + 1, insertItemsCount: 2, parent: this, newText: ` ${text} from` }); return this; } // a namespace import or named import must exist... insert it beforehand manipulation_1.insertIntoParent({ insertPos: importKeyword.getEnd(), childIndex: 0, insertItemsCount: 2, parent: importClause, newText: ` ${text},` }); return this; } /** * Gets the default import, if it exists. */ getDefaultImport() { const importClause = this.getImportClause(); if (importClause == null) return undefined; const firstChild = importClause.getFirstChild(); if (firstChild == null || firstChild.getKind() !== ts.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. */ setNamespaceImport(text) { const 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."); const defaultImport = this.getDefaultImport(); if (defaultImport != null) { manipulation_1.insertIntoParent({ insertPos: defaultImport.getEnd(), childIndex: defaultImport.getChildIndex() + 1, insertItemsCount: 2, parent: this.getImportClause(), newText: `, * as ${text}` }); return this; } const importKeyword = this.getFirstChildByKindOrThrow(ts.SyntaxKind.ImportKeyword); manipulation_1.insertIntoParent({ insertPos: importKeyword.getEnd(), childIndex: importKeyword.getChildIndex() + 1, insertItemsCount: 2, parent: this, newText: ` * as ${text} from` }); return this; } /** * Gets the namespace import, if it exists. */ getNamespaceImport() { const importClause = this.getImportClause(); if (importClause == null) return undefined; const namespaceImport = importClause.getFirstChildByKind(ts.SyntaxKind.NamespaceImport); if (namespaceImport == null) return undefined; return namespaceImport.getFirstChildByKind(ts.SyntaxKind.Identifier); } /** * Add a named import. * @param structure - Structure that represents the named import. */ addNamedImport(structure) { return this.addNamedImports([structure])[0]; } /** * Add named imports. * @param structures - Structures that represent the named imports. */ addNamedImports(structures) { return this.insertNamedImports(this.getNamedImports().length, structures); } /** * Insert a named import. * @param index - Index to insert at. * @param structure - Structure that represents the named import. */ insertNamedImport(index, structure) { return this.insertNamedImports(index, [structure])[0]; } /** * Inserts named imports into the import declaration. * @param index - Index to insert at. * @param structures - Structures that represent the named imports. */ insertNamedImports(index, structures) { if (utils_1.ArrayUtils.isNullOrEmpty(structures)) return []; const namedImports = this.getNamedImports(); const codes = structures.map(s => { let text = s.name; if (s.alias != null && s.alias.length > 0) text += ` as ${s.alias}`; return text; }); index = manipulation_1.verifyAndGetIndex(index, namedImports.length); if (namedImports.length === 0) { const importClause = this.getImportClause(); if (importClause == null) { const importKeyword = this.getFirstChildByKindOrThrow(ts.SyntaxKind.ImportKeyword); manipulation_1.insertIntoParent({ insertPos: importKeyword.getEnd(), childIndex: importKeyword.getChildIndex() + 1, insertItemsCount: 2, parent: this, newText: ` {${codes.join(", ")}} 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 { const defaultImport = this.getDefaultImport(); manipulation_1.insertIntoParent({ insertPos: defaultImport.getEnd(), childIndex: defaultImport.getChildIndex() + 1, insertItemsCount: 2, parent: importClause, newText: `, {${codes.join(", ")}}` }); } } else { manipulation_1.insertIntoCommaSeparatedNodes({ parent: this, currentNodes: namedImports, insertIndex: index, newTexts: codes }); } return this.getNamedImports().slice(index, index + structures.length); } /** * Gets the named imports. */ getNamedImports() { const importClause = this.getImportClause(); if (importClause == null) return []; const namedImports = importClause.getFirstChildByKind(ts.SyntaxKind.NamedImports); if (namedImports == null) return []; return namedImports.getChildSyntaxListOrThrow().getChildren().filter(c => c instanceof ImportSpecifier_1.ImportSpecifier); } /** * Removes this import declaration. */ remove() { manipulation_1.removeStatementedNodeChild(this); } getImportClause() { return this.getFirstChildByKind(ts.SyntaxKind.ImportClause); } } exports.ImportDeclaration = ImportDeclaration; //# sourceMappingURL=ImportDeclaration.js.map