ts-simple-ast
Version:
TypeScript compiler wrapper for static analysis and code manipulation.
413 lines (412 loc) • 18.6 kB
JavaScript
"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.ImportDeclarationBase = statement_1.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.
* @remarks Use renameDefaultImport to rename.
*/
ImportDeclaration.prototype.setDefaultImport = function (text) {
if (utils_1.StringUtils.isNullOrWhitespace(text))
return this.removeDefaultImport();
var defaultImport = this.getDefaultImport();
if (defaultImport != null) {
defaultImport.replaceWithText(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;
};
/**
* Renames or sets the provided default import.
* @param text - Text to set or rename the default import with.
*/
ImportDeclaration.prototype.renameDefaultImport = function (text) {
if (utils_1.StringUtils.isNullOrWhitespace(text))
return this.removeDefaultImport();
var defaultImport = this.getDefaultImport();
if (defaultImport != null) {
defaultImport.rename(text);
return this;
}
this.setDefaultImport(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;
return importClause.getDefaultImport();
};
/**
* 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];
}
};
/**
* Removes the default import.
*/
ImportDeclaration.prototype.removeDefaultImport = function () {
var importClause = this.getImportClause();
if (importClause == null)
return this;
var defaultImport = importClause.getDefaultImport();
if (defaultImport == null)
return this;
var hasOnlyDefaultImport = importClause.getChildCount() === 1;
if (hasOnlyDefaultImport)
manipulation_1.removeChildren({
children: [importClause, importClause.getNextSiblingIfKindOrThrow(typescript_1.SyntaxKind.FromKeyword)],
removePrecedingSpaces: true,
removePrecedingNewLines: true
});
else
manipulation_1.removeChildren({
children: [defaultImport, defaultImport.getNextSiblingIfKindOrThrow(typescript_1.SyntaxKind.CommaToken)],
removePrecedingSpaces: true,
removePrecedingNewLines: true
});
return this;
};
/**
* 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 identifier, if it exists.
*/
ImportDeclaration.prototype.getNamespaceImport = function () {
var importClause = this.getImportClause();
if (importClause == null)
return undefined;
return importClause.getNamespaceImport();
};
/**
* Adds a named import.
* @param namedImport - Name, structure, or writer to write the named import with.
*/
ImportDeclaration.prototype.addNamedImport = function (namedImport) {
return this.addNamedImports([namedImport])[0];
};
/**
* Adds named imports.
* @param namedImport - Structures, names, or writer function to write the named import with.
*/
ImportDeclaration.prototype.addNamedImports = function (namedImports) {
return this.insertNamedImports(this.getNamedImports().length, namedImports);
};
/**
* Inserts a named import.
* @param index - Child index to insert at.
* @param namedImport - Structure, name, or writer function to write the named import with.
*/
ImportDeclaration.prototype.insertNamedImport = function (index, namedImport) {
return this.insertNamedImports(index, [namedImport])[0];
};
/**
* Inserts named imports into the import declaration.
* @param index - Child index to insert at.
* @param namedImports - Structures, names, or writer function to write the named import with.
*/
ImportDeclaration.prototype.insertNamedImports = function (index, namedImports) {
if (!(namedImports instanceof Function) && utils_1.ArrayUtils.isNullOrEmpty(namedImports))
return [];
var originalNamedImports = this.getNamedImports();
var writer = this._getWriterWithQueuedIndentation();
var namedImportStructurePrinter = this._context.structurePrinterFactory.forNamedImportExportSpecifier();
var importClause = this.getImportClause();
index = manipulation_1.verifyAndGetIndex(index, originalNamedImports.length);
if (originalNamedImports.length === 0) {
namedImportStructurePrinter.printTextsWithBraces(writer, namedImports);
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 getErrorWhenNamespaceImportsExist();
else if (importClause.getNamedBindings() != null) {
var namedBindings = importClause.getNamedBindingsOrThrow();
manipulation_1.insertIntoParentTextRange({
insertPos: namedBindings.getStart(),
replacing: {
textLength: namedBindings.getWidth()
},
parent: importClause,
newText: writer.toString()
});
}
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, namedImports);
manipulation_1.insertIntoCommaSeparatedNodes({
parent: importClause.getFirstChildByKindOrThrow(typescript_1.SyntaxKind.NamedImports).getFirstChildByKindOrThrow(typescript_1.SyntaxKind.SyntaxList),
currentNodes: originalNamedImports,
insertIndex: index,
newText: writer.toString(),
surroundWithSpaces: this._context.getFormatCodeSettings().insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces
});
}
var newNamedImports = this.getNamedImports();
return manipulation_1.getNodesToReturn(newNamedImports, index, newNamedImports.length - originalNamedImports.length);
};
/**
* Gets the named imports.
*/
ImportDeclaration.prototype.getNamedImports = function () {
var importClause = this.getImportClause();
if (importClause == null)
return [];
return importClause.getNamedImports();
};
/**
* Removes all the named imports.
*/
ImportDeclaration.prototype.removeNamedImports = function () {
var importClause = this.getImportClause();
if (importClause == null)
return this;
var namedImportsNode = importClause.getNamedBindings();
if (namedImportsNode == null || namedImportsNode.getKind() !== typescript_1.SyntaxKind.NamedImports)
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);
};
/**
* Sets the node from a structure.
* @param structure - Structure to set the node with.
*/
ImportDeclaration.prototype.set = function (structure) {
callBaseSet_1.callBaseSet(exports.ImportDeclarationBase.prototype, this, structure);
if (structure.defaultImport != null)
this.setDefaultImport(structure.defaultImport);
else if (structure.hasOwnProperty("defaultImport"))
this.removeDefaultImport();
if (structure.hasOwnProperty("namedImports"))
this.removeNamedImports();
if (structure.namespaceImport != null)
this.setNamespaceImport(structure.namespaceImport);
else if (structure.hasOwnProperty("namespaceImport"))
this.removeNamespaceImport();
if (structure.namedImports != null) {
setEmptyNamedImport(this);
this.addNamedImports(structure.namedImports);
}
if (structure.moduleSpecifier != null)
this.setModuleSpecifier(structure.moduleSpecifier);
return this;
};
/**
* Gets the structure equivalent to this node.
*/
ImportDeclaration.prototype.getStructure = function () {
var namespaceImport = this.getNamespaceImport();
var defaultImport = this.getDefaultImport();
return callBaseGetStructure_1.callBaseGetStructure(exports.ImportDeclarationBase.prototype, this, {
defaultImport: defaultImport ? defaultImport.getText() : undefined,
moduleSpecifier: this.getModuleSpecifier().getLiteralText(),
namedImports: this.getNamedImports().map(function (node) { return node.getStructure(); }),
namespaceImport: namespaceImport ? namespaceImport.getText() : undefined
});
};
return ImportDeclaration;
}(exports.ImportDeclarationBase));
exports.ImportDeclaration = ImportDeclaration;
function setEmptyNamedImport(node) {
var importClause = node.getNodeProperty("importClause");
var writer = node._getWriterWithQueuedChildIndentation();
var namedImportStructurePrinter = node._context.structurePrinterFactory.forNamedImportExportSpecifier();
namedImportStructurePrinter.printTextsWithBraces(writer, []);
var emptyBracesText = writer.toString();
if (node.getNamespaceImport() != null)
throw getErrorWhenNamespaceImportsExist();
if (importClause == null) {
manipulation_1.insertIntoParentTextRange({
insertPos: node.getFirstChildByKindOrThrow(typescript_1.SyntaxKind.ImportKeyword).getEnd(),
parent: node,
newText: " " + emptyBracesText + " from"
});
return;
}
var replaceNode = importClause.getNamedBindings();
if (replaceNode != null) {
manipulation_1.insertIntoParentTextRange({
parent: importClause,
newText: emptyBracesText,
insertPos: replaceNode.getStart(),
replacing: {
textLength: replaceNode.getWidth()
}
});
return;
}
var defaultImport = importClause.getDefaultImport();
if (defaultImport != null) {
manipulation_1.insertIntoParentTextRange({
insertPos: defaultImport.getEnd(),
parent: importClause,
newText: ", " + emptyBracesText
});
return;
}
}
function getErrorWhenNamespaceImportsExist() {
return new errors.InvalidOperationError("Cannot add a named import to an import declaration that has a namespace import.");
}