From c4dd2d115bb0a2a0ca78ff08dc3424fcb7d69eca Mon Sep 17 00:00:00 2001 From: JoostK Date: Tue, 23 Apr 2019 20:37:42 +0200 Subject: [PATCH] fix(ivy): let ngtsc's shim host delegate `resolveModuleNames` method (#30068) Now that ngtsc performs type checking using a dedicated `__ng_typecheck__.ts` file, `NgtscProgram` always wraps its `ts.CompilerHost` in a shim host. This shim fails to delegate `resolveModuleNames` so no custom module resolution logic is considered. This introduces a problem for the CLI, as the compiler host it passes kicks of ngcc for any imported module such that Ivy's compatibility compiler runs automatically behind the scenes. This commit adds delegation of the `resolveModuleNames` to fix the issue. Fixes #30064 PR Close #30068 --- .../compiler-cli/src/ngtsc/shims/src/host.ts | 11 ++++++ .../src/ngtsc/shims/test/host_spec.ts | 37 +++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 packages/compiler-cli/src/ngtsc/shims/test/host_spec.ts diff --git a/packages/compiler-cli/src/ngtsc/shims/src/host.ts b/packages/compiler-cli/src/ngtsc/shims/src/host.ts index 91e06c6208..c5ee736033 100644 --- a/packages/compiler-cli/src/ngtsc/shims/src/host.ts +++ b/packages/compiler-cli/src/ngtsc/shims/src/host.ts @@ -32,6 +32,13 @@ export interface ShimGenerator { */ export class GeneratedShimsHostWrapper implements ts.CompilerHost { constructor(private delegate: ts.CompilerHost, private shimGenerators: ShimGenerator[]) { + if (delegate.resolveModuleNames !== undefined) { + this.resolveModuleNames = + (moduleNames: string[], containingFile: string, reusedNames?: string[], + redirectedReference?: ts.ResolvedProjectReference) => + delegate.resolveModuleNames !( + moduleNames, containingFile, reusedNames, redirectedReference); + } if (delegate.resolveTypeReferenceDirectives) { // Backward compatibility with TypeScript 2.9 and older since return // type has changed from (ts.ResolvedTypeReferenceDirective | undefined)[] @@ -50,6 +57,10 @@ export class GeneratedShimsHostWrapper implements ts.CompilerHost { } } + resolveModuleNames?: + (moduleNames: string[], containingFile: string, reusedNames?: string[], + redirectedReference?: ts.ResolvedProjectReference) => (ts.ResolvedModule | undefined)[]; + resolveTypeReferenceDirectives?: (names: string[], containingFile: string) => ts.ResolvedTypeReferenceDirective[]; diff --git a/packages/compiler-cli/src/ngtsc/shims/test/host_spec.ts b/packages/compiler-cli/src/ngtsc/shims/test/host_spec.ts new file mode 100644 index 0000000000..e047855eed --- /dev/null +++ b/packages/compiler-cli/src/ngtsc/shims/test/host_spec.ts @@ -0,0 +1,37 @@ +/** + * @license + * Copyright Google Inc. All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ +import * as ts from 'typescript'; + +import {GeneratedShimsHostWrapper} from '../src/host'; + +describe('shim host', () => { + it('should not have optional methods when delegate does not have them', function() { + const delegate = {} as unknown as ts.CompilerHost; + const shimsHost = new GeneratedShimsHostWrapper(delegate, []); + + expect(shimsHost.resolveModuleNames).not.toBeDefined(); + expect(shimsHost.resolveTypeReferenceDirectives).not.toBeDefined(); + expect(shimsHost.directoryExists).not.toBeDefined(); + expect(shimsHost.getDirectories).not.toBeDefined(); + }); + + it('should delegate optional methods if available', function() { + const delegate = { + resolveModuleNames: () => undefined, + resolveTypeReferenceDirectives: () => undefined, + directoryExists: () => undefined, + getDirectories: () => undefined, + } as unknown as ts.CompilerHost; + const shimsHost = new GeneratedShimsHostWrapper(delegate, []); + + expect(shimsHost.resolveModuleNames).toBeDefined(); + expect(shimsHost.resolveTypeReferenceDirectives).toBeDefined(); + expect(shimsHost.directoryExists).toBeDefined(); + expect(shimsHost.getDirectories).toBeDefined(); + }); +});