From 42edc491a8c51c8ccf35b045abc0038be0db35d2 Mon Sep 17 00:00:00 2001 From: Alan Agius Date: Tue, 18 Feb 2020 19:31:46 +0100 Subject: [PATCH] fix(@ngtools/webpack): elide imports for `implements` keywords Running the `remove-ivy-jit-support-calls` and `remove_decorators` transformers causes the following TS bug https://github.com/microsoft/TypeScript/issues/17552 which is why the `elide-imports` transformer exists in the first place. However, when having a syntax like the below; ```ts import { AccountComponentChild } from '../@types'; export class SignUpComponent implements AccountComponentChild{} ``` The `implements` parts of the class is called a `HeritageClause` with child statements of `ExpressionWithTypeArguments` also the same is for `abstract`. With this change we check the token of the `HeritageClause` and if it's an `ImplementsKeyword` we elide the import. Closes #16907 --- .../webpack/src/transformers/elide_imports.ts | 7 +++++++ .../src/transformers/elide_imports_spec.ts | 21 +++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/packages/ngtools/webpack/src/transformers/elide_imports.ts b/packages/ngtools/webpack/src/transformers/elide_imports.ts index 21303f45b847..9107926876c9 100644 --- a/packages/ngtools/webpack/src/transformers/elide_imports.ts +++ b/packages/ngtools/webpack/src/transformers/elide_imports.ts @@ -39,6 +39,13 @@ export function elideImports( return; } + // Consider types for 'implements' as unused. + // A HeritageClause token can also be an 'AbstractKeyword' + // which in that case we should not elide the import. + if (ts.isHeritageClause(node) && node.token === ts.SyntaxKind.ImplementsKeyword) { + return; + } + // Record import and skip if (ts.isImportDeclaration(node)) { imports.push(node); diff --git a/packages/ngtools/webpack/src/transformers/elide_imports_spec.ts b/packages/ngtools/webpack/src/transformers/elide_imports_spec.ts index 2311cadc7a48..d037e77d3f6e 100644 --- a/packages/ngtools/webpack/src/transformers/elide_imports_spec.ts +++ b/packages/ngtools/webpack/src/transformers/elide_imports_spec.ts @@ -317,6 +317,27 @@ describe('@ngtools/webpack transformers', () => { }); }); + it(`should remove import for 'ExpressionWithTypeArguments' implements token`, () => { + const input = tags.stripIndent` + import { Bar, Buz, Unused } from './bar'; + + export class Foo extends Bar implements Buz { } + + ${dummyNode} + `; + + const output = tags.stripIndent` + import { Bar } from './bar'; + + export class Foo extends Bar { } + `; + + const { program, compilerHost } = createTypescriptContext(input); + const result = transformTypescript(undefined, [transformer(program)], program, compilerHost); + + expect(tags.oneLine`${result}`).toEqual(tags.oneLine`${output}`); + }); + describe('should not elide imports decorator type references when emitDecoratorMetadata is true', () => { const extraCompilerOptions: ts.CompilerOptions = { emitDecoratorMetadata: true,