feat(ivy): introduce type-checking context API (#26203)

This commit introduces the template type-checking context API, which manages
inlining of type constructors and type-check blocks into ts.SourceFiles.
This API will be used by ngtsc to generate a type-checking ts.Program.

An TypeCheckProgramHost is provided which can wrap a normal ts.CompilerHost
and intercept getSourceFile() calls. This can be used to provide source
files with type check blocks to a ts.Program for type-checking.

PR Close #26203
This commit is contained in:
Alex Rickabaugh
2018-09-25 14:59:10 -07:00
committed by Jason Aden
parent 355a7cae3c
commit 5f1273ba2e
6 changed files with 443 additions and 15 deletions

View File

@ -10,10 +10,10 @@ import * as path from 'path';
import * as ts from 'typescript';
export function makeProgram(
files: {name: string, contents: string}[],
options?: ts.CompilerOptions): {program: ts.Program, host: ts.CompilerHost} {
const host = new InMemoryHost();
files.forEach(file => host.writeFile(file.name, file.contents));
files: {name: string, contents: string}[], options?: ts.CompilerOptions,
host: ts.CompilerHost = new InMemoryHost(),
checkForErrors: boolean = true): {program: ts.Program, host: ts.CompilerHost} {
files.forEach(file => host.writeFile(file.name, file.contents, false, undefined, []));
const rootNames = files.map(file => host.getCanonicalFileName(file.name));
const program = ts.createProgram(
@ -23,17 +23,20 @@ export function makeProgram(
moduleResolution: ts.ModuleResolutionKind.NodeJs, ...options
},
host);
const diags = [...program.getSyntacticDiagnostics(), ...program.getSemanticDiagnostics()];
if (diags.length > 0) {
const errors = diags.map(diagnostic => {
let message = ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n');
if (diagnostic.file) {
const {line, character} = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start !);
message = `${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`;
}
return `Error: ${message}`;
});
throw new Error(`Typescript diagnostics failed! ${errors.join(', ')}`);
if (checkForErrors) {
const diags = [...program.getSyntacticDiagnostics(), ...program.getSemanticDiagnostics()];
if (diags.length > 0) {
const errors = diags.map(diagnostic => {
let message = ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n');
if (diagnostic.file) {
const {line, character} =
diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start !);
message = `${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`;
}
return `Error: ${message}`;
});
throw new Error(`Typescript diagnostics failed! ${errors.join(', ')}`);
}
}
return {program, host};
}