Skip to content

Commit

Permalink
Added ignoring symbols from "fake" namespace generation if they aren'…
Browse files Browse the repository at this point in the history
…t used by that namespace

Partially reverts eb862bf

Fixes #319
  • Loading branch information
timocov committed Apr 21, 2024
1 parent 54f8817 commit aa5a334
Show file tree
Hide file tree
Showing 8 changed files with 38 additions and 24 deletions.
6 changes: 6 additions & 0 deletions src/bundle-generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1002,6 +1002,12 @@ export function generateDtsBundle(entries: readonly EntryPointConfig[], options:

function createNamespaceForExports(exports: ts.SymbolTable, namespaceSymbol: ts.Symbol): string | null {
function addSymbolToNamespaceExports(namespaceExports: Map<string, string>, symbol: ts.Symbol): void {
// if a symbol isn't used by the namespace symbol it might mean that it shouldn't be included into the bundle because of tree-shaking
// in this case we shouldn't even try to add such symbol to the namespace
if (!typesUsageEvaluator.isSymbolUsedBySymbol(symbol, namespaceSymbol)) {
return;
}

const symbolKnownNames = collisionsResolver.namesForSymbol(symbol);
if (symbolKnownNames.size === 0) {
throw new Error(`Cannot get local names for symbol '${symbol.getName()}' while generating namespaced export`);
Expand Down
25 changes: 3 additions & 22 deletions src/types-usage-evaluator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -237,29 +237,12 @@ export class TypesUsageEvaluator {
}

private computeUsagesRecursively(parent: ts.Node, parentSymbol: ts.Symbol): void {
const processUsageForChild = (child: ts.Node) => {
ts.forEachChild(parent, (child: ts.Node) => {
if (child.kind === ts.SyntaxKind.JSDoc) {
return;
}

let recursionStartNode = child;
if (ts.isQualifiedName(child) && !ts.isQualifiedName(child.parent)) {
const leftmostSymbol = this.getNodeOwnSymbol(child.left);

// i.e. `import * as NS from './local-module'`
const namespaceImport = getDeclarationsForSymbol(leftmostSymbol).find(ts.isNamespaceImport);
if (namespaceImport !== undefined) {
// if a node is a qualified name and its top-level part was created by a namespaced import
// then we shouldn't add usages of that "namespaced import" to the parent symbol
// because we can just import the referenced symbol directly, without wrapping with a namespace
recursionStartNode = child.right;

// recursive processing doesn't process a node itself so we need to handle it separately
processUsageForChild(recursionStartNode);
}
}

this.computeUsagesRecursively(recursionStartNode, parentSymbol);
this.computeUsagesRecursively(child, parentSymbol);

if (ts.isIdentifier(child) || child.kind === ts.SyntaxKind.DefaultKeyword) {
// identifiers in labelled tuples don't have symbols for their labels
Expand Down Expand Up @@ -289,9 +272,7 @@ export class TypesUsageEvaluator {
}
}
}
};

ts.forEachChild(parent, processUsageForChild);
});
}

private addUsages(childSymbol: ts.Symbol, parentSymbol: ts.Symbol): void {
Expand Down
5 changes: 3 additions & 2 deletions tests/e2e/test-cases/names-collision-across-files/output.d.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import * as fakePackage from 'fake-package';
import { Interface as FPI1, Interface as FPI2, Interface as Interface$2 } from 'fake-package';

export type ExportEqNs = string;
Expand Down Expand Up @@ -67,7 +68,7 @@ export interface Inter {
field2: AnotherInterface$1;
field3: TypeName;
field4: AnotherInterface;
field5: FPI1;
field5: fakePackage.Interface;
field6: FPI1;
field7: Interface$2;
}
Expand All @@ -79,7 +80,7 @@ export interface Inter2 {
field2: AnotherInterface$1;
field3: TypeName;
field4: AnotherInterface;
field5: FPI1;
field5: fakePackage.Interface;
field6: FPI2;
field7: Interface$2;
field8: DefaultInterface;
Expand Down
5 changes: 5 additions & 0 deletions tests/e2e/test-cases/namespaced-import/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { TestCaseConfig } from '../../test-cases/test-case-config';

const config: TestCaseConfig = {};

export = config;
1 change: 1 addition & 0 deletions tests/e2e/test-cases/namespaced-import/index.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require('../run-test-case').runTestCase(__dirname);
6 changes: 6 additions & 0 deletions tests/e2e/test-cases/namespaced-import/input.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import * as fakePackage from 'fake-package';

export declare class MyClass {
static func(): fakePackage.InterfaceWithFields;
static field: fakePackage.Interface;
}
8 changes: 8 additions & 0 deletions tests/e2e/test-cases/namespaced-import/output.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import * as fakePackage from 'fake-package';

export declare class MyClass {
static func(): fakePackage.InterfaceWithFields;
static field: fakePackage.Interface;
}

export {};
6 changes: 6 additions & 0 deletions tests/e2e/test-cases/namespaced-import/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"extends": "../tsconfig.json",
"compilerOptions": {
"types": ["node"]
}
}

0 comments on commit aa5a334

Please sign in to comment.