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:
parent
b682bd1916
commit
a10c126692
|
@ -731,7 +731,7 @@ export class NgCompiler {
|
||||||
|
|
||||||
const templateTypeChecker = new TemplateTypeChecker(
|
const templateTypeChecker = new TemplateTypeChecker(
|
||||||
this.tsProgram, this.typeCheckingProgramStrategy, traitCompiler,
|
this.tsProgram, this.typeCheckingProgramStrategy, traitCompiler,
|
||||||
this.getTypeCheckingConfig(), refEmitter, reflector, this.incrementalDriver);
|
this.getTypeCheckingConfig(), refEmitter, reflector, this.host, this.incrementalDriver);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
isCore,
|
isCore,
|
||||||
|
|
|
@ -39,6 +39,7 @@ export class TemplateTypeChecker {
|
||||||
private typeCheckingStrategy: TypeCheckingProgramStrategy,
|
private typeCheckingStrategy: TypeCheckingProgramStrategy,
|
||||||
private typeCheckAdapter: ProgramTypeCheckAdapter, private config: TypeCheckingConfig,
|
private typeCheckAdapter: ProgramTypeCheckAdapter, private config: TypeCheckingConfig,
|
||||||
private refEmitter: ReferenceEmitter, private reflector: ReflectionHost,
|
private refEmitter: ReferenceEmitter, private reflector: ReflectionHost,
|
||||||
|
private compilerHost: ts.CompilerHost,
|
||||||
private priorBuild: IncrementalBuild<unknown, FileTypeCheckingData>) {}
|
private priorBuild: IncrementalBuild<unknown, FileTypeCheckingData>) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -49,7 +50,7 @@ export class TemplateTypeChecker {
|
||||||
this.files.clear();
|
this.files.clear();
|
||||||
|
|
||||||
const ctx =
|
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.
|
// Typecheck all the files.
|
||||||
for (const sf of this.originalProgram.getSourceFiles()) {
|
for (const sf of this.originalProgram.getSourceFiles()) {
|
||||||
|
|
|
@ -113,7 +113,7 @@ export class TypeCheckContext {
|
||||||
private fileMap = new Map<AbsoluteFsPath, PendingFileTypeCheckingData>();
|
private fileMap = new Map<AbsoluteFsPath, PendingFileTypeCheckingData>();
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private config: TypeCheckingConfig, private program: ts.Program,
|
private config: TypeCheckingConfig, private compilerHost: ts.CompilerHost,
|
||||||
private refEmitter: ReferenceEmitter, private reflector: ReflectionHost) {}
|
private refEmitter: ReferenceEmitter, private reflector: ReflectionHost) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -320,7 +320,8 @@ export class TypeCheckContext {
|
||||||
domSchemaChecker: new RegistryDomSchemaChecker(sourceManager),
|
domSchemaChecker: new RegistryDomSchemaChecker(sourceManager),
|
||||||
oobRecorder: new OutOfBandDiagnosticRecorderImpl(sourceManager),
|
oobRecorder: new OutOfBandDiagnosticRecorderImpl(sourceManager),
|
||||||
typeCheckFile: new TypeCheckFile(
|
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,
|
hasInlines: false,
|
||||||
sourceManager,
|
sourceManager,
|
||||||
};
|
};
|
||||||
|
|
|
@ -34,10 +34,11 @@ export class TypeCheckFile extends Environment {
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
readonly fileName: AbsoluteFsPath, config: TypeCheckingConfig, refEmitter: ReferenceEmitter,
|
readonly fileName: AbsoluteFsPath, config: TypeCheckingConfig, refEmitter: ReferenceEmitter,
|
||||||
reflector: ReflectionHost) {
|
reflector: ReflectionHost, compilerHost: ts.CompilerHost) {
|
||||||
super(
|
super(
|
||||||
config, new ImportManager(new NoopImportRewriter(), 'i'), refEmitter, reflector,
|
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(
|
addTypeCheckBlock(
|
||||||
|
@ -49,7 +50,7 @@ export class TypeCheckFile extends Environment {
|
||||||
}
|
}
|
||||||
|
|
||||||
render(): string {
|
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}';`)
|
.map(i => `import * as ${i.qualifier} from '${i.specifier}';`)
|
||||||
.join('\n') +
|
.join('\n') +
|
||||||
'\n\n';
|
'\n\n';
|
||||||
|
|
|
@ -302,7 +302,7 @@ export function typecheck(
|
||||||
|
|
||||||
const programStrategy = new ReusedProgramStrategy(program, host, options, []);
|
const programStrategy = new ReusedProgramStrategy(program, host, options, []);
|
||||||
const templateTypeChecker = new TemplateTypeChecker(
|
const templateTypeChecker = new TemplateTypeChecker(
|
||||||
program, programStrategy, checkAdapter, fullConfig, emitter, reflectionHost,
|
program, programStrategy, checkAdapter, fullConfig, emitter, reflectionHost, host,
|
||||||
NOOP_INCREMENTAL_BUILD);
|
NOOP_INCREMENTAL_BUILD);
|
||||||
templateTypeChecker.refresh();
|
templateTypeChecker.refresh();
|
||||||
return templateTypeChecker.getDiagnosticsForFile(sf);
|
return templateTypeChecker.getDiagnosticsForFile(sf);
|
||||||
|
|
|
@ -43,7 +43,7 @@ runInEachFileSystem(() => {
|
||||||
const host = new NgtscCompilerHost(getFileSystem());
|
const host = new NgtscCompilerHost(getFileSystem());
|
||||||
const file = new TypeCheckFile(
|
const file = new TypeCheckFile(
|
||||||
_('/_typecheck_.ts'), ALL_ENABLED_CONFIG, new ReferenceEmitter([]),
|
_('/_typecheck_.ts'), ALL_ENABLED_CONFIG, new ReferenceEmitter([]),
|
||||||
/* reflector */ null!);
|
/* reflector */ null!, host);
|
||||||
const sf = file.render();
|
const sf = file.render();
|
||||||
expect(sf).toContain('export const IS_A_MODULE = true;');
|
expect(sf).toContain('export const IS_A_MODULE = true;');
|
||||||
});
|
});
|
||||||
|
@ -73,10 +73,10 @@ TestClass.ngTypeCtor({value: 'test'});
|
||||||
new AbsoluteModuleStrategy(program, checker, moduleResolver, reflectionHost),
|
new AbsoluteModuleStrategy(program, checker, moduleResolver, reflectionHost),
|
||||||
new LogicalProjectStrategy(reflectionHost, logicalFs),
|
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 =
|
const TestClass =
|
||||||
getDeclaration(program, _('/main.ts'), 'TestClass', isNamedClassDeclaration);
|
getDeclaration(program, _('/main.ts'), 'TestClass', isNamedClassDeclaration);
|
||||||
const pendingFile = makePendingFile(reflectionHost);
|
const pendingFile = makePendingFile(reflectionHost, host);
|
||||||
ctx.addInlineTypeCtor(
|
ctx.addInlineTypeCtor(
|
||||||
pendingFile, getSourceFileOrError(program, _('/main.ts')), new Reference(TestClass), {
|
pendingFile, getSourceFileOrError(program, _('/main.ts')), new Reference(TestClass), {
|
||||||
fnName: 'ngTypeCtor',
|
fnName: 'ngTypeCtor',
|
||||||
|
@ -109,8 +109,8 @@ TestClass.ngTypeCtor({value: 'test'});
|
||||||
new AbsoluteModuleStrategy(program, checker, moduleResolver, reflectionHost),
|
new AbsoluteModuleStrategy(program, checker, moduleResolver, reflectionHost),
|
||||||
new LogicalProjectStrategy(reflectionHost, logicalFs),
|
new LogicalProjectStrategy(reflectionHost, logicalFs),
|
||||||
]);
|
]);
|
||||||
const pendingFile = makePendingFile(reflectionHost);
|
const pendingFile = makePendingFile(reflectionHost, host);
|
||||||
const ctx = new TypeCheckContext(ALL_ENABLED_CONFIG, program, emitter, reflectionHost);
|
const ctx = new TypeCheckContext(ALL_ENABLED_CONFIG, host, emitter, reflectionHost);
|
||||||
const TestClass =
|
const TestClass =
|
||||||
getDeclaration(program, _('/main.ts'), 'TestClass', isNamedClassDeclaration);
|
getDeclaration(program, _('/main.ts'), 'TestClass', isNamedClassDeclaration);
|
||||||
ctx.addInlineTypeCtor(
|
ctx.addInlineTypeCtor(
|
||||||
|
@ -152,8 +152,8 @@ TestClass.ngTypeCtor({value: 'test'});
|
||||||
new AbsoluteModuleStrategy(program, checker, moduleResolver, reflectionHost),
|
new AbsoluteModuleStrategy(program, checker, moduleResolver, reflectionHost),
|
||||||
new LogicalProjectStrategy(reflectionHost, logicalFs),
|
new LogicalProjectStrategy(reflectionHost, logicalFs),
|
||||||
]);
|
]);
|
||||||
const pendingFile = makePendingFile(reflectionHost);
|
const pendingFile = makePendingFile(reflectionHost, host);
|
||||||
const ctx = new TypeCheckContext(ALL_ENABLED_CONFIG, program, emitter, reflectionHost);
|
const ctx = new TypeCheckContext(ALL_ENABLED_CONFIG, host, emitter, reflectionHost);
|
||||||
const TestClass =
|
const TestClass =
|
||||||
getDeclaration(program, _('/main.ts'), 'TestClass', isNamedClassDeclaration);
|
getDeclaration(program, _('/main.ts'), 'TestClass', isNamedClassDeclaration);
|
||||||
ctx.addInlineTypeCtor(
|
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();
|
const manager = new TemplateSourceManager();
|
||||||
return {
|
return {
|
||||||
domSchemaChecker: new RegistryDomSchemaChecker(manager),
|
domSchemaChecker: new RegistryDomSchemaChecker(manager),
|
||||||
|
@ -192,6 +193,7 @@ function makePendingFile(reflector: ReflectionHost): PendingFileTypeCheckingData
|
||||||
oobRecorder: new NoopOobRecorder(),
|
oobRecorder: new NoopOobRecorder(),
|
||||||
sourceManager: manager,
|
sourceManager: manager,
|
||||||
typeCheckFile: new TypeCheckFile(
|
typeCheckFile: new TypeCheckFile(
|
||||||
absoluteFrom('/typecheck.ts'), ALL_ENABLED_CONFIG, new ReferenceEmitter([]), reflector)
|
absoluteFrom('/typecheck.ts'), ALL_ENABLED_CONFIG, new ReferenceEmitter([]), reflector,
|
||||||
|
compilerHost)
|
||||||
};
|
};
|
||||||
}
|
}
|
Loading…
Reference in New Issue