ts-simple-ast
Version:
TypeScript compiler wrapper for AST navigation and code generation.
220 lines (218 loc) • 8.29 kB
JavaScript
"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