angular/packages/compiler-cli/src/ngtsc/synthetic_files_compiler_host.ts
Igor Minar 75748d6044 feat: add support for TypeScript 3.3 (and drop older versions) (#29004)
https://blogs.msdn.microsoft.com/typescript/2019/01/31/announcing-typescript-3-3/

BREAKING CHANGE: TypeScript 3.1 and 3.2 are no longer supported.

Please update your TypeScript version to 3.3

PR Close #29004
2019-03-13 10:38:37 -07:00

100 lines
3.6 KiB
TypeScript

/**
* @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 {PluginCompilerHost} from '@bazel/typescript/internal/tsc_wrapped/plugin_api';
import * as ts from 'typescript';
/**
* Extension of the TypeScript compiler host that supports files added to the Program which
* were never on disk.
*
* This is used for backwards-compatibility with the ViewEngine compiler, which used ngsummary
* and ngfactory files as inputs to the program. We call these inputs "synthetic".
*
* They need to be program inputs because user code may import from these generated files.
*
* TODO(alxhub): remove this after all ng_module users have migrated to Ivy
*/
export class SyntheticFilesCompilerHost implements PluginCompilerHost {
/**
* SourceFiles which are added to the program but which never existed on disk.
*/
syntheticFiles = new Map<string, ts.SourceFile>();
constructor(
private rootFiles: string[], private delegate: ts.CompilerHost,
generatedFiles: (rootFiles: string[]) => {
[fileName: string]: (host: ts.CompilerHost) => ts.SourceFile | undefined
}) {
// Allow ngtsc to contribute in-memory synthetic files, which will be loaded
// as if they existed on disk as action inputs.
const angularGeneratedFiles = generatedFiles !(rootFiles);
for (const f of Object.keys(angularGeneratedFiles)) {
const generator = angularGeneratedFiles[f];
const generated = generator(delegate);
if (generated) {
this.syntheticFiles.set(generated.fileName, generated);
}
}
if (delegate.getDirectories !== undefined) {
this.getDirectories = (path: string) => delegate.getDirectories !(path);
}
}
fileExists(filePath: string): boolean {
if (this.syntheticFiles.has(filePath)) {
return true;
}
return this.delegate.fileExists(filePath);
}
/** Loads a source file from in-memory map, or delegates. */
getSourceFile(
fileName: string, languageVersion: ts.ScriptTarget,
onError?: (message: string) => void): ts.SourceFile|undefined {
const syntheticFile = this.syntheticFiles.get(fileName);
if (syntheticFile) {
return syntheticFile !;
}
return this.delegate.getSourceFile(fileName, languageVersion, onError);
}
get inputFiles() { return [...this.rootFiles, ...Array.from(this.syntheticFiles.keys())]; }
fileNameToModuleId(fileName: string) {
return fileName; // TODO: Ivy logic. don't forget that the delegate has the google3 logic
}
// Delegate everything else to the original compiler host.
getDefaultLibFileName(options: ts.CompilerOptions): string {
return this.delegate.getDefaultLibFileName(options);
}
writeFile(
fileName: string, content: string, writeByteOrderMark: boolean,
onError: ((message: string) => void)|undefined,
sourceFiles: ReadonlyArray<ts.SourceFile>|undefined): void {
this.delegate.writeFile(fileName, content, writeByteOrderMark, onError, sourceFiles);
}
getCanonicalFileName(path: string) { return this.delegate.getCanonicalFileName(path); }
getCurrentDirectory(): string { return this.delegate.getCurrentDirectory(); }
useCaseSensitiveFileNames(): boolean { return this.delegate.useCaseSensitiveFileNames(); }
getNewLine(): string { return this.delegate.getNewLine(); }
getDirectories?: (path: string) => string[];
readFile(fileName: string): string|undefined { return this.delegate.readFile(fileName); }
trace(s: string): void { console.error(s); }
}