refactor(core): add createMigrationCompilerHost
(#32827)
Current we need to create and override certain compiler host methods in every schematic because schematics use a virtual fs. We this change we extract this logic to a common util. PR Close #32827
This commit is contained in:
parent
60047037a3
commit
01677b21b6
@ -11,10 +11,13 @@ import {dirname, relative} from 'path';
|
|||||||
import * as ts from 'typescript';
|
import * as ts from 'typescript';
|
||||||
|
|
||||||
import {getProjectTsConfigPaths} from '../../utils/project_tsconfig_paths';
|
import {getProjectTsConfigPaths} from '../../utils/project_tsconfig_paths';
|
||||||
|
import {createMigrationCompilerHost} from '../../utils/typescript/compiler_host';
|
||||||
import {parseTsconfigFile} from '../../utils/typescript/parse_tsconfig';
|
import {parseTsconfigFile} from '../../utils/typescript/parse_tsconfig';
|
||||||
|
|
||||||
import {identifyDynamicQueryNodes, removeOptionsParameter, removeStaticFlag} from './util';
|
import {identifyDynamicQueryNodes, removeOptionsParameter, removeStaticFlag} from './util';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Runs the dynamic queries migration for all TypeScript projects in the current CLI workspace.
|
* Runs the dynamic queries migration for all TypeScript projects in the current CLI workspace.
|
||||||
*/
|
*/
|
||||||
@ -39,20 +42,7 @@ export default function(): Rule {
|
|||||||
|
|
||||||
function runDynamicQueryMigration(tree: Tree, tsconfigPath: string, basePath: string) {
|
function runDynamicQueryMigration(tree: Tree, tsconfigPath: string, basePath: string) {
|
||||||
const parsed = parseTsconfigFile(tsconfigPath, dirname(tsconfigPath));
|
const parsed = parseTsconfigFile(tsconfigPath, dirname(tsconfigPath));
|
||||||
const host = ts.createCompilerHost(parsed.options, true);
|
const host = createMigrationCompilerHost(tree, parsed.options, basePath);
|
||||||
|
|
||||||
// We need to overwrite the host "readFile" method, as we want the TypeScript
|
|
||||||
// program to be based on the file contents in the virtual file tree. Otherwise
|
|
||||||
// if we run the migration for multiple tsconfig files which have intersecting
|
|
||||||
// source files, it can end up updating query definitions multiple times.
|
|
||||||
host.readFile = fileName => {
|
|
||||||
const buffer = tree.read(relative(basePath, fileName));
|
|
||||||
// Strip BOM as otherwise TSC methods (Ex: getWidth) will return an offset which
|
|
||||||
// which breaks the CLI UpdateRecorder.
|
|
||||||
// See: https://github.com/angular/angular/pull/30719
|
|
||||||
return buffer ? buffer.toString().replace(/^\uFEFF/, '') : undefined;
|
|
||||||
};
|
|
||||||
|
|
||||||
const program = ts.createProgram(parsed.fileNames, parsed.options, host);
|
const program = ts.createProgram(parsed.fileNames, parsed.options, host);
|
||||||
const typeChecker = program.getTypeChecker();
|
const typeChecker = program.getTypeChecker();
|
||||||
const sourceFiles = program.getSourceFiles().filter(
|
const sourceFiles = program.getSourceFiles().filter(
|
||||||
|
@ -9,10 +9,9 @@
|
|||||||
import {Rule, SchematicContext, SchematicsException, Tree} from '@angular-devkit/schematics';
|
import {Rule, SchematicContext, SchematicsException, Tree} from '@angular-devkit/schematics';
|
||||||
import {dirname, relative} from 'path';
|
import {dirname, relative} from 'path';
|
||||||
import * as ts from 'typescript';
|
import * as ts from 'typescript';
|
||||||
|
|
||||||
import {getProjectTsConfigPaths} from '../../utils/project_tsconfig_paths';
|
import {getProjectTsConfigPaths} from '../../utils/project_tsconfig_paths';
|
||||||
|
import {createMigrationCompilerHost} from '../../utils/typescript/compiler_host';
|
||||||
import {parseTsconfigFile} from '../../utils/typescript/parse_tsconfig';
|
import {parseTsconfigFile} from '../../utils/typescript/parse_tsconfig';
|
||||||
|
|
||||||
import {NgModuleCollector} from './module_collector';
|
import {NgModuleCollector} from './module_collector';
|
||||||
import {MissingInjectableTransform} from './transform';
|
import {MissingInjectableTransform} from './transform';
|
||||||
import {UpdateRecorder} from './update_recorder';
|
import {UpdateRecorder} from './update_recorder';
|
||||||
@ -49,20 +48,9 @@ export default function(): Rule {
|
|||||||
function runMissingInjectableMigration(
|
function runMissingInjectableMigration(
|
||||||
tree: Tree, tsconfigPath: string, basePath: string): string[] {
|
tree: Tree, tsconfigPath: string, basePath: string): string[] {
|
||||||
const parsed = parseTsconfigFile(tsconfigPath, dirname(tsconfigPath));
|
const parsed = parseTsconfigFile(tsconfigPath, dirname(tsconfigPath));
|
||||||
const host = ts.createCompilerHost(parsed.options, true);
|
const host = createMigrationCompilerHost(tree, parsed.options, basePath);
|
||||||
const failures: string[] = [];
|
const failures: string[] = [];
|
||||||
|
|
||||||
// We need to overwrite the host "readFile" method, as we want the TypeScript
|
|
||||||
// program to be based on the file contents in the virtual file tree.
|
|
||||||
host.readFile = fileName => {
|
|
||||||
const buffer = tree.read(relative(basePath, fileName));
|
|
||||||
// Strip BOM because TypeScript respects this character and it ultimately
|
|
||||||
// results in shifted offsets since the CLI UpdateRecorder tries to
|
|
||||||
// automatically account for the BOM character.
|
|
||||||
// https://github.com/angular/angular-cli/issues/14558
|
|
||||||
return buffer ? buffer.toString().replace(/^\uFEFF/, '') : undefined;
|
|
||||||
};
|
|
||||||
|
|
||||||
const program = ts.createProgram(parsed.fileNames, parsed.options, host);
|
const program = ts.createProgram(parsed.fileNames, parsed.options, host);
|
||||||
const typeChecker = program.getTypeChecker();
|
const typeChecker = program.getTypeChecker();
|
||||||
const moduleCollector = new NgModuleCollector(typeChecker);
|
const moduleCollector = new NgModuleCollector(typeChecker);
|
||||||
|
@ -11,11 +11,14 @@ import {dirname, relative} from 'path';
|
|||||||
import * as ts from 'typescript';
|
import * as ts from 'typescript';
|
||||||
|
|
||||||
import {getProjectTsConfigPaths} from '../../utils/project_tsconfig_paths';
|
import {getProjectTsConfigPaths} from '../../utils/project_tsconfig_paths';
|
||||||
|
import {createMigrationCompilerHost} from '../../utils/typescript/compiler_host';
|
||||||
import {parseTsconfigFile} from '../../utils/typescript/parse_tsconfig';
|
import {parseTsconfigFile} from '../../utils/typescript/parse_tsconfig';
|
||||||
|
|
||||||
import {COMMON_IMPORT, DOCUMENT_TOKEN_NAME, DocumentImportVisitor, ResolvedDocumentImport} from './document_import_visitor';
|
import {COMMON_IMPORT, DOCUMENT_TOKEN_NAME, DocumentImportVisitor, ResolvedDocumentImport} from './document_import_visitor';
|
||||||
import {addToImport, createImport, removeFromImport} from './move-import';
|
import {addToImport, createImport, removeFromImport} from './move-import';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** Entry point for the V8 move-document migration. */
|
/** Entry point for the V8 move-document migration. */
|
||||||
export default function(): Rule {
|
export default function(): Rule {
|
||||||
return (tree: Tree) => {
|
return (tree: Tree) => {
|
||||||
@ -40,19 +43,7 @@ export default function(): Rule {
|
|||||||
*/
|
*/
|
||||||
function runMoveDocumentMigration(tree: Tree, tsconfigPath: string, basePath: string) {
|
function runMoveDocumentMigration(tree: Tree, tsconfigPath: string, basePath: string) {
|
||||||
const parsed = parseTsconfigFile(tsconfigPath, dirname(tsconfigPath));
|
const parsed = parseTsconfigFile(tsconfigPath, dirname(tsconfigPath));
|
||||||
const host = ts.createCompilerHost(parsed.options, true);
|
const host = createMigrationCompilerHost(tree, parsed.options, basePath);
|
||||||
|
|
||||||
// We need to overwrite the host "readFile" method, as we want the TypeScript
|
|
||||||
// program to be based on the file contents in the virtual file tree. Otherwise
|
|
||||||
// if we run the migration for multiple tsconfig files which have intersecting
|
|
||||||
// source files, it can end up updating query definitions multiple times.
|
|
||||||
host.readFile = fileName => {
|
|
||||||
const buffer = tree.read(relative(basePath, fileName));
|
|
||||||
// Strip BOM as otherwise TSC methods (Ex: getWidth) will return an offset which
|
|
||||||
// which breaks the CLI UpdateRecorder.
|
|
||||||
// See: https://github.com/angular/angular/pull/30719
|
|
||||||
return buffer ? buffer.toString().replace(/^\uFEFF/, '') : undefined;
|
|
||||||
};
|
|
||||||
|
|
||||||
const program = ts.createProgram(parsed.fileNames, parsed.options, host);
|
const program = ts.createProgram(parsed.fileNames, parsed.options, host);
|
||||||
const typeChecker = program.getTypeChecker();
|
const typeChecker = program.getTypeChecker();
|
||||||
|
@ -11,6 +11,7 @@ import {dirname, relative} from 'path';
|
|||||||
import * as ts from 'typescript';
|
import * as ts from 'typescript';
|
||||||
|
|
||||||
import {getProjectTsConfigPaths} from '../../utils/project_tsconfig_paths';
|
import {getProjectTsConfigPaths} from '../../utils/project_tsconfig_paths';
|
||||||
|
import {createMigrationCompilerHost} from '../../utils/typescript/compiler_host';
|
||||||
import {parseTsconfigFile} from '../../utils/typescript/parse_tsconfig';
|
import {parseTsconfigFile} from '../../utils/typescript/parse_tsconfig';
|
||||||
|
|
||||||
import {HelperFunction, getHelper} from './helpers';
|
import {HelperFunction, getHelper} from './helpers';
|
||||||
@ -18,6 +19,7 @@ import {migrateExpression, replaceImport} from './migration';
|
|||||||
import {findCoreImport, findRendererReferences} from './util';
|
import {findCoreImport, findRendererReferences} from './util';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Migration that switches from `Renderer` to `Renderer2`. More information on how it works:
|
* Migration that switches from `Renderer` to `Renderer2`. More information on how it works:
|
||||||
* https://hackmd.angular.io/UTzUZTnPRA-cSa_4mHyfYw
|
* https://hackmd.angular.io/UTzUZTnPRA-cSa_4mHyfYw
|
||||||
@ -46,17 +48,7 @@ export default function(): Rule {
|
|||||||
|
|
||||||
function runRendererToRenderer2Migration(tree: Tree, tsconfigPath: string, basePath: string) {
|
function runRendererToRenderer2Migration(tree: Tree, tsconfigPath: string, basePath: string) {
|
||||||
const parsed = parseTsconfigFile(tsconfigPath, dirname(tsconfigPath));
|
const parsed = parseTsconfigFile(tsconfigPath, dirname(tsconfigPath));
|
||||||
const host = ts.createCompilerHost(parsed.options, true);
|
const host = createMigrationCompilerHost(tree, parsed.options, basePath);
|
||||||
|
|
||||||
// We need to overwrite the host "readFile" method, as we want the TypeScript
|
|
||||||
// program to be based on the file contents in the virtual file tree. Otherwise
|
|
||||||
// if we run the migration for multiple tsconfig files which have intersecting
|
|
||||||
// source files, it can end up updating query definitions multiple times.
|
|
||||||
host.readFile = fileName => {
|
|
||||||
const buffer = tree.read(relative(basePath, fileName));
|
|
||||||
return buffer ? buffer.toString() : undefined;
|
|
||||||
};
|
|
||||||
|
|
||||||
const program = ts.createProgram(parsed.fileNames, parsed.options, host);
|
const program = ts.createProgram(parsed.fileNames, parsed.options, host);
|
||||||
const typeChecker = program.getTypeChecker();
|
const typeChecker = program.getTypeChecker();
|
||||||
const printer = ts.createPrinter();
|
const printer = ts.createPrinter();
|
||||||
|
@ -14,6 +14,7 @@ import * as ts from 'typescript';
|
|||||||
|
|
||||||
import {NgComponentTemplateVisitor} from '../../utils/ng_component_template';
|
import {NgComponentTemplateVisitor} from '../../utils/ng_component_template';
|
||||||
import {getProjectTsConfigPaths} from '../../utils/project_tsconfig_paths';
|
import {getProjectTsConfigPaths} from '../../utils/project_tsconfig_paths';
|
||||||
|
import {createMigrationCompilerHost} from '../../utils/typescript/compiler_host';
|
||||||
import {parseTsconfigFile} from '../../utils/typescript/parse_tsconfig';
|
import {parseTsconfigFile} from '../../utils/typescript/parse_tsconfig';
|
||||||
|
|
||||||
import {NgQueryResolveVisitor} from './angular/ng_query_visitor';
|
import {NgQueryResolveVisitor} from './angular/ng_query_visitor';
|
||||||
@ -117,20 +118,7 @@ function analyzeProject(
|
|||||||
logger: logging.LoggerApi):
|
logger: logging.LoggerApi):
|
||||||
AnalyzedProject|null {
|
AnalyzedProject|null {
|
||||||
const parsed = parseTsconfigFile(tsconfigPath, dirname(tsconfigPath));
|
const parsed = parseTsconfigFile(tsconfigPath, dirname(tsconfigPath));
|
||||||
const host = ts.createCompilerHost(parsed.options, true);
|
const host = createMigrationCompilerHost(tree, parsed.options, basePath);
|
||||||
|
|
||||||
// We need to overwrite the host "readFile" method, as we want the TypeScript
|
|
||||||
// program to be based on the file contents in the virtual file tree. Otherwise
|
|
||||||
// if we run the migration for multiple tsconfig files which have intersecting
|
|
||||||
// source files, it can end up updating query definitions multiple times.
|
|
||||||
host.readFile = fileName => {
|
|
||||||
const buffer = tree.read(relative(basePath, fileName));
|
|
||||||
// Strip BOM as otherwise TSC methods (Ex: getWidth) will return an offset which
|
|
||||||
// which breaks the CLI UpdateRecorder.
|
|
||||||
// See: https://github.com/angular/angular/pull/30719
|
|
||||||
return buffer ? buffer.toString().replace(/^\uFEFF/, '') : undefined;
|
|
||||||
};
|
|
||||||
|
|
||||||
const program = ts.createProgram(parsed.fileNames, parsed.options, host);
|
const program = ts.createProgram(parsed.fileNames, parsed.options, host);
|
||||||
const syntacticDiagnostics = program.getSyntacticDiagnostics();
|
const syntacticDiagnostics = program.getSyntacticDiagnostics();
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@ import * as ts from 'typescript';
|
|||||||
|
|
||||||
import {NgComponentTemplateVisitor} from '../../utils/ng_component_template';
|
import {NgComponentTemplateVisitor} from '../../utils/ng_component_template';
|
||||||
import {getProjectTsConfigPaths} from '../../utils/project_tsconfig_paths';
|
import {getProjectTsConfigPaths} from '../../utils/project_tsconfig_paths';
|
||||||
|
import {createMigrationCompilerHost} from '../../utils/typescript/compiler_host';
|
||||||
import {parseTsconfigFile} from '../../utils/typescript/parse_tsconfig';
|
import {parseTsconfigFile} from '../../utils/typescript/parse_tsconfig';
|
||||||
|
|
||||||
import {analyzeResolvedTemplate} from './analyze_template';
|
import {analyzeResolvedTemplate} from './analyze_template';
|
||||||
@ -47,18 +48,7 @@ export default function(): Rule {
|
|||||||
function runTemplateVariableAssignmentCheck(
|
function runTemplateVariableAssignmentCheck(
|
||||||
tree: Tree, tsconfigPath: string, basePath: string, logger: Logger) {
|
tree: Tree, tsconfigPath: string, basePath: string, logger: Logger) {
|
||||||
const parsed = parseTsconfigFile(tsconfigPath, dirname(tsconfigPath));
|
const parsed = parseTsconfigFile(tsconfigPath, dirname(tsconfigPath));
|
||||||
const host = ts.createCompilerHost(parsed.options, true);
|
const host = createMigrationCompilerHost(tree, parsed.options, basePath);
|
||||||
|
|
||||||
// We need to overwrite the host "readFile" method, as we want the TypeScript
|
|
||||||
// program to be based on the file contents in the virtual file tree.
|
|
||||||
host.readFile = fileName => {
|
|
||||||
const buffer = tree.read(relative(basePath, fileName));
|
|
||||||
// Strip BOM as otherwise TSC methods (Ex: getWidth) will return an offset which
|
|
||||||
// which breaks the CLI UpdateRecorder.
|
|
||||||
// See: https://github.com/angular/angular/pull/30719
|
|
||||||
return buffer ? buffer.toString().replace(/^\uFEFF/, '') : undefined;
|
|
||||||
};
|
|
||||||
|
|
||||||
const program = ts.createProgram(parsed.fileNames, parsed.options, host);
|
const program = ts.createProgram(parsed.fileNames, parsed.options, host);
|
||||||
const typeChecker = program.getTypeChecker();
|
const typeChecker = program.getTypeChecker();
|
||||||
const templateVisitor = new NgComponentTemplateVisitor(typeChecker);
|
const templateVisitor = new NgComponentTemplateVisitor(typeChecker);
|
||||||
|
@ -9,8 +9,8 @@
|
|||||||
import {Rule, SchematicContext, SchematicsException, Tree} from '@angular-devkit/schematics';
|
import {Rule, SchematicContext, SchematicsException, Tree} from '@angular-devkit/schematics';
|
||||||
import {dirname, relative} from 'path';
|
import {dirname, relative} from 'path';
|
||||||
import * as ts from 'typescript';
|
import * as ts from 'typescript';
|
||||||
|
|
||||||
import {getProjectTsConfigPaths} from '../../utils/project_tsconfig_paths';
|
import {getProjectTsConfigPaths} from '../../utils/project_tsconfig_paths';
|
||||||
|
import {createMigrationCompilerHost} from '../../utils/typescript/compiler_host';
|
||||||
import {parseTsconfigFile} from '../../utils/typescript/parse_tsconfig';
|
import {parseTsconfigFile} from '../../utils/typescript/parse_tsconfig';
|
||||||
import {FALLBACK_DECORATOR, addImport, getNamedImports, getUndecoratedClassesWithDecoratedFields, hasNamedImport} from './utils';
|
import {FALLBACK_DECORATOR, addImport, getNamedImports, getUndecoratedClassesWithDecoratedFields, hasNamedImport} from './utils';
|
||||||
|
|
||||||
@ -44,20 +44,7 @@ export default function(): Rule {
|
|||||||
|
|
||||||
function runUndecoratedClassesMigration(tree: Tree, tsconfigPath: string, basePath: string) {
|
function runUndecoratedClassesMigration(tree: Tree, tsconfigPath: string, basePath: string) {
|
||||||
const parsed = parseTsconfigFile(tsconfigPath, dirname(tsconfigPath));
|
const parsed = parseTsconfigFile(tsconfigPath, dirname(tsconfigPath));
|
||||||
const host = ts.createCompilerHost(parsed.options, true);
|
const host = createMigrationCompilerHost(tree, parsed.options, basePath);
|
||||||
|
|
||||||
// We need to overwrite the host "readFile" method, as we want the TypeScript
|
|
||||||
// program to be based on the file contents in the virtual file tree. Otherwise
|
|
||||||
// if we run the migration for multiple tsconfig files which have intersecting
|
|
||||||
// source files, it can end up updating them multiple times.
|
|
||||||
host.readFile = fileName => {
|
|
||||||
const buffer = tree.read(relative(basePath, fileName));
|
|
||||||
// Strip BOM as otherwise TSC methods (Ex: getWidth) will return an offset which
|
|
||||||
// which breaks the CLI UpdateRecorder.
|
|
||||||
// See: https://github.com/angular/angular/pull/30719
|
|
||||||
return buffer ? buffer.toString().replace(/^\uFEFF/, '') : undefined;
|
|
||||||
};
|
|
||||||
|
|
||||||
const program = ts.createProgram(parsed.fileNames, parsed.options, host);
|
const program = ts.createProgram(parsed.fileNames, parsed.options, host);
|
||||||
const typeChecker = program.getTypeChecker();
|
const typeChecker = program.getTypeChecker();
|
||||||
const printer = ts.createPrinter();
|
const printer = ts.createPrinter();
|
||||||
|
@ -9,12 +9,14 @@
|
|||||||
import {logging} from '@angular-devkit/core';
|
import {logging} from '@angular-devkit/core';
|
||||||
import {Rule, SchematicContext, SchematicsException, Tree} from '@angular-devkit/schematics';
|
import {Rule, SchematicContext, SchematicsException, Tree} from '@angular-devkit/schematics';
|
||||||
import {AotCompiler} from '@angular/compiler';
|
import {AotCompiler} from '@angular/compiler';
|
||||||
|
import {createCompilerHost} from '@angular/compiler-cli';
|
||||||
import {PartialEvaluator} from '@angular/compiler-cli/src/ngtsc/partial_evaluator';
|
import {PartialEvaluator} from '@angular/compiler-cli/src/ngtsc/partial_evaluator';
|
||||||
import {TypeScriptReflectionHost} from '@angular/compiler-cli/src/ngtsc/reflection';
|
import {TypeScriptReflectionHost} from '@angular/compiler-cli/src/ngtsc/reflection';
|
||||||
import {relative} from 'path';
|
import {relative} from 'path';
|
||||||
import * as ts from 'typescript';
|
import * as ts from 'typescript';
|
||||||
|
|
||||||
import {getProjectTsConfigPaths} from '../../utils/project_tsconfig_paths';
|
import {getProjectTsConfigPaths} from '../../utils/project_tsconfig_paths';
|
||||||
|
import {createMigrationCompilerHost} from '../../utils/typescript/compiler_host';
|
||||||
|
|
||||||
import {createNgcProgram} from './create_ngc_program';
|
import {createNgcProgram} from './create_ngc_program';
|
||||||
import {NgDeclarationCollector} from './ng_declaration_collector';
|
import {NgDeclarationCollector} from './ng_declaration_collector';
|
||||||
@ -146,21 +148,8 @@ function gracefullyCreateProgram(
|
|||||||
tree: Tree, basePath: string, tsconfigPath: string,
|
tree: Tree, basePath: string, tsconfigPath: string,
|
||||||
logger: logging.LoggerApi): {compiler: AotCompiler, program: ts.Program}|null {
|
logger: logging.LoggerApi): {compiler: AotCompiler, program: ts.Program}|null {
|
||||||
try {
|
try {
|
||||||
const {ngcProgram, host, program, compiler} = createNgcProgram((options) => {
|
const {ngcProgram, host, program, compiler} = createNgcProgram(
|
||||||
const host = ts.createCompilerHost(options, true);
|
(options) => createMigrationCompilerHost(tree, options, basePath), tsconfigPath);
|
||||||
|
|
||||||
// We need to overwrite the host "readFile" method, as we want the TypeScript
|
|
||||||
// program to be based on the file contents in the virtual file tree.
|
|
||||||
host.readFile = fileName => {
|
|
||||||
const buffer = tree.read(relative(basePath, fileName));
|
|
||||||
// Strip BOM as otherwise TSC methods (Ex: getWidth) will return an offset which
|
|
||||||
// which breaks the CLI UpdateRecorder.
|
|
||||||
// See: https://github.com/angular/angular/pull/30719
|
|
||||||
return buffer ? buffer.toString().replace(/^\uFEFF/, '') : undefined;
|
|
||||||
};
|
|
||||||
|
|
||||||
return host;
|
|
||||||
}, tsconfigPath);
|
|
||||||
const syntacticDiagnostics = ngcProgram.getTsSyntacticDiagnostics();
|
const syntacticDiagnostics = ngcProgram.getTsSyntacticDiagnostics();
|
||||||
const structuralDiagnostics = ngcProgram.getNgStructuralDiagnostics();
|
const structuralDiagnostics = ngcProgram.getNgStructuralDiagnostics();
|
||||||
|
|
||||||
|
29
packages/core/schematics/utils/typescript/compiler_host.ts
Normal file
29
packages/core/schematics/utils/typescript/compiler_host.ts
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
/**
|
||||||
|
* @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 {Tree} from '@angular-devkit/schematics';
|
||||||
|
import {relative} from 'path';
|
||||||
|
import * as ts from 'typescript';
|
||||||
|
|
||||||
|
export function createMigrationCompilerHost(
|
||||||
|
tree: Tree, options: ts.CompilerOptions, basePath: string): ts.CompilerHost {
|
||||||
|
const host = ts.createCompilerHost(options, true);
|
||||||
|
|
||||||
|
// We need to overwrite the host "readFile" method, as we want the TypeScript
|
||||||
|
// program to be based on the file contents in the virtual file tree. Otherwise
|
||||||
|
// if we run multiple migrations we might have intersecting changes and
|
||||||
|
// source files.
|
||||||
|
host.readFile = fileName => {
|
||||||
|
const buffer = tree.read(relative(basePath, fileName));
|
||||||
|
// Strip BOM as otherwise TSC methods (Ex: getWidth) will return an offset which
|
||||||
|
// which breaks the CLI UpdateRecorder.
|
||||||
|
// See: https://github.com/angular/angular/pull/30719
|
||||||
|
return buffer ? buffer.toString().replace(/^\uFEFF/, '') : undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
return host;
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user