From d171006083fbcf30c2912cdb5f224e7cfa987c15 Mon Sep 17 00:00:00 2001 From: Pete Bacon Darwin Date: Wed, 26 Jun 2019 17:01:43 +0100 Subject: [PATCH] fix(ivy): ngtsc - NgtscCompilerHost should cope with directories that look like files (#31289) The TS compiler is likely to test paths with extensions and try to load them as files. Therefore `fileExists()` and methods that rely on it need to be able to distinguish between real files and directories that have paths that look like files. This came up as a bug in ngcc when trying to process `ngx-virtual-scroller`, which relies upon a library called `@tweenjs/tween.js`. PR Close #31289 --- .../ngtsc/file_system/src/compiler_host.ts | 2 +- .../src/ngtsc/file_system/test/BUILD.bazel | 1 + .../file_system/test/compiler_host_spec.ts | 45 +++++++++++++++++++ 3 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 packages/compiler-cli/src/ngtsc/file_system/test/compiler_host_spec.ts diff --git a/packages/compiler-cli/src/ngtsc/file_system/src/compiler_host.ts b/packages/compiler-cli/src/ngtsc/file_system/src/compiler_host.ts index df5c072ce2..3c7b62b26d 100644 --- a/packages/compiler-cli/src/ngtsc/file_system/src/compiler_host.ts +++ b/packages/compiler-cli/src/ngtsc/file_system/src/compiler_host.ts @@ -58,7 +58,7 @@ export class NgtscCompilerHost implements ts.CompilerHost { fileExists(fileName: string): boolean { const absPath = this.fs.resolve(fileName); - return this.fs.exists(absPath); + return this.fs.exists(absPath) && this.fs.stat(absPath).isFile(); } readFile(fileName: string): string|undefined { diff --git a/packages/compiler-cli/src/ngtsc/file_system/test/BUILD.bazel b/packages/compiler-cli/src/ngtsc/file_system/test/BUILD.bazel index 1354f78b48..84ea6a2849 100644 --- a/packages/compiler-cli/src/ngtsc/file_system/test/BUILD.bazel +++ b/packages/compiler-cli/src/ngtsc/file_system/test/BUILD.bazel @@ -12,6 +12,7 @@ ts_library( "//packages:types", "//packages/compiler-cli/src/ngtsc/file_system", "//packages/compiler-cli/src/ngtsc/file_system/testing", + "@npm//typescript", ], ) diff --git a/packages/compiler-cli/src/ngtsc/file_system/test/compiler_host_spec.ts b/packages/compiler-cli/src/ngtsc/file_system/test/compiler_host_spec.ts new file mode 100644 index 0000000000..6f53351737 --- /dev/null +++ b/packages/compiler-cli/src/ngtsc/file_system/test/compiler_host_spec.ts @@ -0,0 +1,45 @@ +/** + * @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 {NgtscCompilerHost} from '../src/compiler_host'; +import {absoluteFrom, getFileSystem} from '../src/helpers'; +import {runInEachFileSystem} from '../testing'; + +runInEachFileSystem(() => { + describe('NgtscCompilerHost', () => { + describe('fileExists()', () => { + it('should return `false` for an existing directory', () => { + const directory = absoluteFrom('/a/b/c'); + const fs = getFileSystem(); + fs.ensureDir(directory); + const host = new NgtscCompilerHost(fs); + expect(host.fileExists(directory)).toBe(false); + }); + }); + + describe('readFile()', () => { + it('should return `undefined` for an existing directory', () => { + const directory = absoluteFrom('/a/b/c'); + const fs = getFileSystem(); + fs.ensureDir(directory); + const host = new NgtscCompilerHost(fs); + expect(host.readFile(directory)).toBe(undefined); + }); + }); + + describe('getSourceFile()', () => { + it('should return `undefined` for an existing directory', () => { + const directory = absoluteFrom('/a/b/c'); + const fs = getFileSystem(); + fs.ensureDir(directory); + const host = new NgtscCompilerHost(fs); + expect(host.getSourceFile(directory, ts.ScriptTarget.ES2015)).toBe(undefined); + }); + }); + }); +});