diff --git a/src/service/transformer/declaration-bundler/statement-merger/statement-merger.ts b/src/service/transformer/declaration-bundler/statement-merger/statement-merger.ts index 28d9e49e..7e4420da 100644 --- a/src/service/transformer/declaration-bundler/statement-merger/statement-merger.ts +++ b/src/service/transformer/declaration-bundler/statement-merger/statement-merger.ts @@ -1,8 +1,11 @@ import {createExportDeclaration, createNamedExports, SourceFile, TransformerFactory, updateSourceFileNode} from "typescript"; + import {DeclarationBundlerOptions} from "../declaration-bundler-options"; import {normalize} from "path"; import {mergeExports} from "../util/merge-exports/merge-exports"; import {mergeImports} from "../util/merge-imports/merge-imports"; +import {mergeTypeReferenceDirectives} from "../util/merge-file-references/merge-type-reference-directives"; +import {mergeLibReferenceDirectives} from "../util/merge-file-references/merge-lib-reference-directives"; export function statementMerger({declarationFilename, ...options}: DeclarationBundlerOptions): TransformerFactory { return _ => { @@ -27,9 +30,9 @@ export function statementMerger({declarationFilename, ...options}: DeclarationBu : mergedStatements, sourceFile.isDeclarationFile, sourceFile.referencedFiles, - sourceFile.typeReferenceDirectives, + mergeTypeReferenceDirectives(sourceFile), sourceFile.hasNoDefaultLib, - sourceFile.libReferenceDirectives + mergeLibReferenceDirectives(sourceFile) ); if (options.pluginOptions.debug) { diff --git a/src/service/transformer/declaration-bundler/util/merge-file-references/merge-lib-reference-directives.ts b/src/service/transformer/declaration-bundler/util/merge-file-references/merge-lib-reference-directives.ts new file mode 100644 index 00000000..252028ba --- /dev/null +++ b/src/service/transformer/declaration-bundler/util/merge-file-references/merge-lib-reference-directives.ts @@ -0,0 +1,23 @@ +import {FileReference, SourceFile} from "typescript"; + +function formatLibReferenceDirective(libName: string): string { + return `/// `; +} + +/** + * Merges the lib file references of the SourceFile + * @param {SourceFile} sourceFile + * @return {FileReference[]} + */ +export function mergeLibReferenceDirectives(sourceFile: SourceFile): FileReference[] { + return ( + [...new Set(sourceFile.libReferenceDirectives.map(({fileName}) => fileName))] + // Don't include those that are already part of the SourceFile + .filter(fileName => !sourceFile.text.includes(formatLibReferenceDirective(fileName))) + .map(fileName => ({ + fileName, + pos: -1, + end: -1 + })) + ); +} diff --git a/src/service/transformer/declaration-bundler/util/merge-file-references/merge-type-reference-directives.ts b/src/service/transformer/declaration-bundler/util/merge-file-references/merge-type-reference-directives.ts new file mode 100644 index 00000000..dc774f4a --- /dev/null +++ b/src/service/transformer/declaration-bundler/util/merge-file-references/merge-type-reference-directives.ts @@ -0,0 +1,23 @@ +import {FileReference, SourceFile} from "typescript"; + +function formatTypeReferenceDirective(fileName: string): string { + return `/// `; +} + +/** + * Merges the type file references of the SourceFile + * @param {SourceFile} sourceFile + * @return {FileReference[]} + */ +export function mergeTypeReferenceDirectives(sourceFile: SourceFile): FileReference[] { + return ( + [...new Set(sourceFile.typeReferenceDirectives.map(({fileName}) => fileName))] + // Don't include those that are already part of the SourceFile + .filter(fileName => !sourceFile.text.includes(formatTypeReferenceDirective(fileName))) + .map(fileName => ({ + fileName, + pos: -1, + end: -1 + })) + ); +} diff --git a/test/statement-merge.test.ts b/test/statement-merge.test.ts new file mode 100644 index 00000000..41048466 --- /dev/null +++ b/test/statement-merge.test.ts @@ -0,0 +1,30 @@ +import test from "ava"; +import {formatCode} from "./util/format-code"; +import {generateRollupBundle} from "./setup/setup-rollup"; +// tslint:disable:no-duplicate-string + +test("Merges identical statements correctly. #1", async t => { + const bundle = await generateRollupBundle( + [ + { + entry: true, + fileName: "index.ts", + text: `\ + export function foo (_arg: Buffer): void {} + ` + } + ], + {debug: true} + ); + const { + declarations: [file] + } = bundle; + t.deepEqual( + formatCode(file.code), + formatCode(`\ + /// + declare function foo(_arg: Buffer): void; + export { foo }; + `) + ); +});