UNPKG

ts-simple-ast

Version:

TypeScript compiler wrapper for AST navigation and code generation.

275 lines (274 loc) 11.9 kB
"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 statement_1 = require("./../statement"); var ImportDeclaration = /** @class */ (function (_super) { __extends(ImportDeclaration, _super); function ImportDeclaration() { return _super !== null && _super.apply(this, arguments) || this; } /** * Sets the import specifier. * @param text - Text to set as the import specifier. */ ImportDeclaration.prototype.setModuleSpecifier = function (text) { var stringLiteral = this.getLastChildByKindOrThrow(typescript_1.SyntaxKind.StringLiteral); manipulation_1.insertIntoParent({ parent: this, newText: text, insertPos: stringLiteral.getStart() + 1, childIndex: stringLiteral.getChildIndex(), insertItemsCount: 1, replacing: { textLength: stringLiteral.getWidth() - 2, nodes: [stringLiteral] } }); return this; }; /** * Gets the module specifier. */ ImportDeclaration.prototype.getModuleSpecifier = function () { var moduleSpecifier = this.getNodeFromCompilerNode(this.compilerNode.moduleSpecifier); var text = moduleSpecifier.getText(); return text.substring(1, text.length - 1); }; /** * 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 moduleSpecifier = this.getNodeFromCompilerNode(this.compilerNode.moduleSpecifier); var symbol = moduleSpecifier.getSymbol(); if (symbol == null) return undefined; var declarations = symbol.getDeclarations(); if (declarations.length === 0 || declarations[0].getKind() !== typescript_1.SyntaxKind.SourceFile) return undefined; return declarations[0]; }; /** * 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.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. */ 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) { 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.insertIntoParent({ insertPos: defaultImport.getEnd(), childIndex: defaultImport.getChildIndex() + 1, insertItemsCount: 2, parent: this.getImportClause(), newText: ", * as " + text }); return this; } var importKeyword = this.getFirstChildByKindOrThrow(typescript_1.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. */ 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); }; /** * Add a named import. * @param structure - Structure that represents the named import. */ ImportDeclaration.prototype.addNamedImport = function (structure) { return this.addNamedImports([structure])[0]; }; /** * Add named imports. * @param structures - Structures that represent the named imports. */ ImportDeclaration.prototype.addNamedImports = function (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. */ ImportDeclaration.prototype.insertNamedImport = function (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. */ ImportDeclaration.prototype.insertNamedImports = function (index, structures) { if (utils_1.ArrayUtils.isNullOrEmpty(structures)) return []; var namedImports = this.getNamedImports(); var codes = structures.map(function (s) { var text = s.name; if (s.alias != null && s.alias.length > 0) text += " as " + s.alias; return text; }); var importClause = this.getImportClause(); index = manipulation_1.verifyAndGetIndex(index, namedImports.length); if (namedImports.length === 0) { if (importClause == null) { var importKeyword = this.getFirstChildByKindOrThrow(typescript_1.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 { var defaultImport = this.getDefaultImport(); manipulation_1.insertIntoParent({ insertPos: defaultImport.getEnd(), childIndex: defaultImport.getChildIndex() + 1, insertItemsCount: 2, parent: importClause, newText: ", {" + codes.join(", ") + "}" }); } } else { if (importClause == null) throw new errors.NotImplementedError("Expected to have an import clause."); manipulation_1.insertIntoCommaSeparatedNodes({ parent: importClause.getFirstChildByKindOrThrow(typescript_1.SyntaxKind.NamedImports).getFirstChildByKindOrThrow(typescript_1.SyntaxKind.SyntaxList), currentNodes: namedImports, insertIndex: index, newTexts: codes }); } return this.getNamedImports().slice(index, index + structures.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; }; ImportDeclaration.prototype.getImportClause = function () { return this.getNodeFromCompilerNodeIfExists(this.compilerNode.importClause); }; return ImportDeclaration; }(statement_1.Statement)); exports.ImportDeclaration = ImportDeclaration;