Skip to content

Commit d9cc4b0

Browse files
committed
fix(@ngtools/webpack): elide unused type references
In the case the import declaration has an unused import we did not properly elide type references when `emitDecoratorMetadata` is disabled. Closes #24295 (cherry picked from commit 856720b)
1 parent 2891d5b commit d9cc4b0

File tree

2 files changed

+66
-23
lines changed

2 files changed

+66
-23
lines changed

packages/ngtools/webpack/src/transformers/elide_imports.ts

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -54,31 +54,34 @@ export function elideImports(
5454
return;
5555
}
5656

57-
if (!ts.isTypeReferenceNode(node)) {
58-
let symbol: ts.Symbol | undefined;
59-
switch (node.kind) {
60-
case ts.SyntaxKind.Identifier:
61-
const parent = node.parent;
62-
if (parent && ts.isShorthandPropertyAssignment(parent)) {
63-
const shorthandSymbol = typeChecker.getShorthandAssignmentValueSymbol(parent);
64-
if (shorthandSymbol) {
65-
symbol = shorthandSymbol;
66-
}
67-
} else {
68-
symbol = typeChecker.getSymbolAtLocation(node);
57+
// Type reference imports do not need to be emitted when emitDecoratorMetadata is disabled.
58+
if (ts.isTypeReferenceNode(node) && !compilerOptions.emitDecoratorMetadata) {
59+
return;
60+
}
61+
62+
let symbol: ts.Symbol | undefined;
63+
switch (node.kind) {
64+
case ts.SyntaxKind.Identifier:
65+
const parent = node.parent;
66+
if (parent && ts.isShorthandPropertyAssignment(parent)) {
67+
const shorthandSymbol = typeChecker.getShorthandAssignmentValueSymbol(parent);
68+
if (shorthandSymbol) {
69+
symbol = shorthandSymbol;
6970
}
70-
break;
71-
case ts.SyntaxKind.ExportSpecifier:
72-
symbol = typeChecker.getExportSpecifierLocalTargetSymbol(node as ts.ExportSpecifier);
73-
break;
74-
case ts.SyntaxKind.ShorthandPropertyAssignment:
75-
symbol = typeChecker.getShorthandAssignmentValueSymbol(node);
76-
break;
77-
}
71+
} else {
72+
symbol = typeChecker.getSymbolAtLocation(node);
73+
}
74+
break;
75+
case ts.SyntaxKind.ExportSpecifier:
76+
symbol = typeChecker.getExportSpecifierLocalTargetSymbol(node as ts.ExportSpecifier);
77+
break;
78+
case ts.SyntaxKind.ShorthandPropertyAssignment:
79+
symbol = typeChecker.getShorthandAssignmentValueSymbol(node);
80+
break;
81+
}
7882

79-
if (symbol) {
80-
usedSymbols.add(symbol);
81-
}
83+
if (symbol) {
84+
usedSymbols.add(symbol);
8285
}
8386

8487
ts.forEachChild(node, visit);

packages/ngtools/webpack/src/transformers/elide_imports_spec.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ describe('@ngtools/webpack transformers', () => {
6666
`,
6767
'service.ts': `
6868
export class Service { }
69+
export class Service2 { }
6970
`,
7071
'type.ts': `
7172
export interface OnChanges {
@@ -385,6 +386,45 @@ describe('@ngtools/webpack transformers', () => {
385386

386387
expect(tags.oneLine`${result}`).toEqual(tags.oneLine`${output}`);
387388
});
389+
390+
it('should remove ctor parameter type reference and unused named import from same declaration', () => {
391+
const input = tags.stripIndent`
392+
import { Decorator } from './decorator';
393+
import { Service, Service2 as ServiceUnused } from './service';
394+
395+
@Decorator()
396+
export class Foo {
397+
constructor(param: Service) {
398+
}
399+
}
400+
401+
${dummyNode}
402+
`;
403+
404+
const output = tags.stripIndent`
405+
import { __decorate } from "tslib";
406+
import { Decorator } from './decorator';
407+
408+
let Foo = class Foo { constructor(param) { } };
409+
Foo = __decorate([ Decorator() ], Foo);
410+
export { Foo };
411+
`;
412+
413+
const { program, compilerHost } = createTypescriptContext(
414+
input,
415+
additionalFiles,
416+
true,
417+
extraCompilerOptions,
418+
);
419+
const result = transformTypescript(
420+
undefined,
421+
[transformer(program)],
422+
program,
423+
compilerHost,
424+
);
425+
426+
expect(tags.oneLine`${result}`).toEqual(tags.oneLine`${output}`);
427+
});
388428
});
389429

390430
it('keeps jsxFactory imports when configured', () => {

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy