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
This commit is contained in:
Pete Bacon Darwin 2019-06-26 17:01:43 +01:00 committed by Alex Rickabaugh
parent 19e8570ac0
commit d171006083
3 changed files with 47 additions and 1 deletions

View File

@ -58,7 +58,7 @@ export class NgtscCompilerHost implements ts.CompilerHost {
fileExists(fileName: string): boolean { fileExists(fileName: string): boolean {
const absPath = this.fs.resolve(fileName); 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 { readFile(fileName: string): string|undefined {

View File

@ -12,6 +12,7 @@ ts_library(
"//packages:types", "//packages:types",
"//packages/compiler-cli/src/ngtsc/file_system", "//packages/compiler-cli/src/ngtsc/file_system",
"//packages/compiler-cli/src/ngtsc/file_system/testing", "//packages/compiler-cli/src/ngtsc/file_system/testing",
"@npm//typescript",
], ],
) )

View File

@ -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);
});
});
});
});