Skip to content

Commit

Permalink
feat: Add ExportDeclaration.removeModuleSpecifier()
Browse files Browse the repository at this point in the history
  • Loading branch information
dsherret committed Sep 18, 2018
1 parent 5f2f7c8 commit b64c665
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 2 deletions.
28 changes: 26 additions & 2 deletions src/compiler/file/ExportDeclaration.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import * as errors from "../../errors";
import { getNodesToReturn, insertIntoCommaSeparatedNodes, insertIntoParentTextRange, verifyAndGetIndex } from "../../manipulation";
import { getNodesToReturn, insertIntoCommaSeparatedNodes, insertIntoParentTextRange, verifyAndGetIndex, removeChildren } from "../../manipulation";
import { ExportSpecifierStructure, ExportDeclarationStructure } from "../../structures";
import { SyntaxKind, ts } from "../../typescript";
import { ArrayUtils, ModuleUtils, TypeGuards } from "../../utils";
import { ArrayUtils, ModuleUtils, TypeGuards, StringUtils } from "../../utils";
import { StringLiteral } from "../literal";
import { Statement } from "../statement";
import { ExportSpecifier } from "./ExportSpecifier";
Expand All @@ -22,6 +22,12 @@ export class ExportDeclaration extends Statement<ts.ExportDeclaration> {
setModuleSpecifier(sourceFile: SourceFile): this;
setModuleSpecifier(textOrSourceFile: string | SourceFile) {
const text = typeof textOrSourceFile === "string" ? textOrSourceFile : this.sourceFile.getRelativePathAsModuleSpecifierTo(textOrSourceFile);

if (StringUtils.isNullOrWhitespace(text)) {
this.removeModuleSpecifier();
return this;
}

const stringLiteral = this.getModuleSpecifier();

if (stringLiteral == null) {
Expand Down Expand Up @@ -92,6 +98,24 @@ export class ExportDeclaration extends Statement<ts.ExportDeclaration> {
return ModuleUtils.isModuleSpecifierRelative(moduleSpecifierValue);
}

/**
* Removes the module specifier.
*/
removeModuleSpecifier() {
const moduleSpecifier = this.getModuleSpecifier();
if (moduleSpecifier == null)
return this;
if (!this.hasNamedExports())
throw new errors.InvalidOperationError(`Cannot remove the module specifier from an export declaration that has no named exports.`);

removeChildren({
children: [this.getFirstChildByKindOrThrow(SyntaxKind.FromKeyword), moduleSpecifier],
removePrecedingNewLines: true,
removePrecedingSpaces: true
});
return this;
}

/**
* Gets if the module specifier exists
*/
Expand Down
21 changes: 21 additions & 0 deletions src/tests/compiler/file/exportDeclarationTests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,27 @@ describe(nameof(ExportDeclaration), () => {
});
});

describe(nameof<ExportDeclaration>(n => n.removeModuleSpecifier), () => {
function doTest(text: string, expected: string) {
const { firstChild, sourceFile } = getInfoFromText<ExportDeclaration>(text);
firstChild.removeModuleSpecifier();
expect(sourceFile.getFullText()).to.equal(expected);
}

it("should remove the module specifier when it's a named export", () => {
doTest(`export {name} from "./test";`, `export {name};`);
});

it("should do nothing when it doesn't exist", () => {
doTest(`export {name};`, `export {name};`);
});

it("should throw when removing from a namespace export", () => {
const { firstChild } = getInfoFromText<ExportDeclaration>("export * from './test';");
expect(() => firstChild.removeModuleSpecifier()).to.throw(errors.InvalidOperationError);
});
});

describe(nameof<ExportDeclaration>(n => n.getModuleSpecifierSourceFileOrThrow), () => {
it("should get the source file when it exists", () => {
const project = new Project({ useVirtualFileSystem: true });
Expand Down

0 comments on commit b64c665

Please sign in to comment.