fix(compiler-cli): use CompilerHost to ensure canonical file paths (#36859)

The type checking infrastrure uses file-paths that may come from the
TS compiler. Such paths will have been canonicalized, and so the type
checking classes must also canonicalize paths when matching.

PR Close #36859
This commit is contained in:
Pete Bacon Darwin 2020-05-06 22:18:47 +01:00 committed by Alex Rickabaugh
parent b682bd1916
commit a10c126692
6 changed files with 22 additions and 17 deletions

View File

@ -731,7 +731,7 @@ export class NgCompiler {
const templateTypeChecker = new TemplateTypeChecker(
this.tsProgram, this.typeCheckingProgramStrategy, traitCompiler,
this.getTypeCheckingConfig(), refEmitter, reflector, this.incrementalDriver);
this.getTypeCheckingConfig(), refEmitter, reflector, this.host, this.incrementalDriver);
return {
isCore,

View File

@ -39,6 +39,7 @@ export class TemplateTypeChecker {
private typeCheckingStrategy: TypeCheckingProgramStrategy,
private typeCheckAdapter: ProgramTypeCheckAdapter, private config: TypeCheckingConfig,
private refEmitter: ReferenceEmitter, private reflector: ReflectionHost,
private compilerHost: ts.CompilerHost,
private priorBuild: IncrementalBuild<unknown, FileTypeCheckingData>) {}
/**
@ -49,7 +50,7 @@ export class TemplateTypeChecker {
this.files.clear();
const ctx =
new TypeCheckContext(this.config, this.originalProgram, this.refEmitter, this.reflector);
new TypeCheckContext(this.config, this.compilerHost, this.refEmitter, this.reflector);
// Typecheck all the files.
for (const sf of this.originalProgram.getSourceFiles()) {

View File

@ -113,7 +113,7 @@ export class TypeCheckContext {
private fileMap = new Map<AbsoluteFsPath, PendingFileTypeCheckingData>();
constructor(
private config: TypeCheckingConfig, private program: ts.Program,
private config: TypeCheckingConfig, private compilerHost: ts.CompilerHost,
private refEmitter: ReferenceEmitter, private reflector: ReflectionHost) {}
/**
@ -320,7 +320,8 @@ export class TypeCheckContext {
domSchemaChecker: new RegistryDomSchemaChecker(sourceManager),
oobRecorder: new OutOfBandDiagnosticRecorderImpl(sourceManager),
typeCheckFile: new TypeCheckFile(
TypeCheckShimGenerator.shimFor(sfPath), this.config, this.refEmitter, this.reflector),
TypeCheckShimGenerator.shimFor(sfPath), this.config, this.refEmitter, this.reflector,
this.compilerHost),
hasInlines: false,
sourceManager,
};

View File

@ -34,10 +34,11 @@ export class TypeCheckFile extends Environment {
constructor(
readonly fileName: AbsoluteFsPath, config: TypeCheckingConfig, refEmitter: ReferenceEmitter,
reflector: ReflectionHost) {
reflector: ReflectionHost, compilerHost: ts.CompilerHost) {
super(
config, new ImportManager(new NoopImportRewriter(), 'i'), refEmitter, reflector,
ts.createSourceFile(fileName, '', ts.ScriptTarget.Latest, true));
ts.createSourceFile(
compilerHost.getCanonicalFileName(fileName), '', ts.ScriptTarget.Latest, true));
}
addTypeCheckBlock(
@ -49,7 +50,7 @@ export class TypeCheckFile extends Environment {
}
render(): string {
let source: string = this.importManager.getAllImports(this.fileName)
let source: string = this.importManager.getAllImports(this.contextFile.fileName)
.map(i => `import * as ${i.qualifier} from '${i.specifier}';`)
.join('\n') +
'\n\n';

View File

@ -302,7 +302,7 @@ export function typecheck(
const programStrategy = new ReusedProgramStrategy(program, host, options, []);
const templateTypeChecker = new TemplateTypeChecker(
program, programStrategy, checkAdapter, fullConfig, emitter, reflectionHost,
program, programStrategy, checkAdapter, fullConfig, emitter, reflectionHost, host,
NOOP_INCREMENTAL_BUILD);
templateTypeChecker.refresh();
return templateTypeChecker.getDiagnosticsForFile(sf);

View File

@ -43,7 +43,7 @@ runInEachFileSystem(() => {
const host = new NgtscCompilerHost(getFileSystem());
const file = new TypeCheckFile(
_('/_typecheck_.ts'), ALL_ENABLED_CONFIG, new ReferenceEmitter([]),
/* reflector */ null!);
/* reflector */ null!, host);
const sf = file.render();
expect(sf).toContain('export const IS_A_MODULE = true;');
});
@ -73,10 +73,10 @@ TestClass.ngTypeCtor({value: 'test'});
new AbsoluteModuleStrategy(program, checker, moduleResolver, reflectionHost),
new LogicalProjectStrategy(reflectionHost, logicalFs),
]);
const ctx = new TypeCheckContext(ALL_ENABLED_CONFIG, program, emitter, reflectionHost);
const ctx = new TypeCheckContext(ALL_ENABLED_CONFIG, host, emitter, reflectionHost);
const TestClass =
getDeclaration(program, _('/main.ts'), 'TestClass', isNamedClassDeclaration);
const pendingFile = makePendingFile(reflectionHost);
const pendingFile = makePendingFile(reflectionHost, host);
ctx.addInlineTypeCtor(
pendingFile, getSourceFileOrError(program, _('/main.ts')), new Reference(TestClass), {
fnName: 'ngTypeCtor',
@ -109,8 +109,8 @@ TestClass.ngTypeCtor({value: 'test'});
new AbsoluteModuleStrategy(program, checker, moduleResolver, reflectionHost),
new LogicalProjectStrategy(reflectionHost, logicalFs),
]);
const pendingFile = makePendingFile(reflectionHost);
const ctx = new TypeCheckContext(ALL_ENABLED_CONFIG, program, emitter, reflectionHost);
const pendingFile = makePendingFile(reflectionHost, host);
const ctx = new TypeCheckContext(ALL_ENABLED_CONFIG, host, emitter, reflectionHost);
const TestClass =
getDeclaration(program, _('/main.ts'), 'TestClass', isNamedClassDeclaration);
ctx.addInlineTypeCtor(
@ -152,8 +152,8 @@ TestClass.ngTypeCtor({value: 'test'});
new AbsoluteModuleStrategy(program, checker, moduleResolver, reflectionHost),
new LogicalProjectStrategy(reflectionHost, logicalFs),
]);
const pendingFile = makePendingFile(reflectionHost);
const ctx = new TypeCheckContext(ALL_ENABLED_CONFIG, program, emitter, reflectionHost);
const pendingFile = makePendingFile(reflectionHost, host);
const ctx = new TypeCheckContext(ALL_ENABLED_CONFIG, host, emitter, reflectionHost);
const TestClass =
getDeclaration(program, _('/main.ts'), 'TestClass', isNamedClassDeclaration);
ctx.addInlineTypeCtor(
@ -184,7 +184,8 @@ TestClass.ngTypeCtor({value: 'test'});
}
});
function makePendingFile(reflector: ReflectionHost): PendingFileTypeCheckingData {
function makePendingFile(
reflector: ReflectionHost, compilerHost: ts.CompilerHost): PendingFileTypeCheckingData {
const manager = new TemplateSourceManager();
return {
domSchemaChecker: new RegistryDomSchemaChecker(manager),
@ -192,6 +193,7 @@ function makePendingFile(reflector: ReflectionHost): PendingFileTypeCheckingData
oobRecorder: new NoopOobRecorder(),
sourceManager: manager,
typeCheckFile: new TypeCheckFile(
absoluteFrom('/typecheck.ts'), ALL_ENABLED_CONFIG, new ReferenceEmitter([]), reflector)
absoluteFrom('/typecheck.ts'), ALL_ENABLED_CONFIG, new ReferenceEmitter([]), reflector,
compilerHost)
};
}