From 1a26f6da6efd7d3e98d7d9df8eba5b357ceb408c Mon Sep 17 00:00:00 2001 From: Kristiyan Kostadinov Date: Fri, 20 Nov 2020 20:25:30 +0100 Subject: [PATCH] fix(core): migration error if program contains files outside of the project (#39790) Currently all of our migrations are set up to find the tsconfig paths within a project, create a `Program` out of each and migrate the files inside of the `Program`. The problem is that the `Program` can include files outside of the project and the CLI APIs that we use to interact with the file system assume that all files are within the project. These changes consolidate the logic, that determines whether a file can be migrated, in a single place and add an extra check to exclude files outside of the root. Fixes #39778. PR Close #39790 --- .../abstract-control-parent/index.ts | 6 +++--- .../migrations/dynamic-queries/index.ts | 6 +++--- .../google3/initialNavigationRule.ts | 2 +- .../migrations/initial-navigation/index.ts | 8 +++---- .../initial-navigation/transform.ts | 15 +------------ .../migrations/missing-injectable/index.ts | 6 +++--- .../migrations/module-with-providers/index.ts | 6 +++--- .../migrations/move-document/index.ts | 6 +++--- .../native-view-encapsulation/index.ts | 6 +++--- .../navigation-extras-omissions/index.ts | 6 +++--- .../relative-link-resolution/index.ts | 6 +++--- .../migrations/renderer-to-renderer2/index.ts | 6 +++--- .../router-preserve-query-params/index.ts | 6 +++--- .../migrations/static-queries/index.ts | 6 +++--- .../template-var-assignment/index.ts | 6 +++--- .../index.ts | 6 +++--- .../undecorated-classes-with-di/index.ts | 6 +++--- .../migrations/wait-for-async/index.ts | 6 +++--- .../utils/typescript/compiler_host.ts | 21 +++++++++++++++++++ 19 files changed, 72 insertions(+), 64 deletions(-) diff --git a/packages/core/schematics/migrations/abstract-control-parent/index.ts b/packages/core/schematics/migrations/abstract-control-parent/index.ts index 9aea59128b..31e701a98c 100644 --- a/packages/core/schematics/migrations/abstract-control-parent/index.ts +++ b/packages/core/schematics/migrations/abstract-control-parent/index.ts @@ -10,7 +10,7 @@ import {Rule, SchematicsException, Tree} from '@angular-devkit/schematics'; import {relative} from 'path'; import {getProjectTsConfigPaths} from '../../utils/project_tsconfig_paths'; -import {createMigrationProgram} from '../../utils/typescript/compiler_host'; +import {canMigrateFile, createMigrationProgram} from '../../utils/typescript/compiler_host'; import {findParentAccesses} from './util'; @@ -36,8 +36,8 @@ function runNativeAbstractControlParentMigration( tree: Tree, tsconfigPath: string, basePath: string) { const {program} = createMigrationProgram(tree, tsconfigPath, basePath); const typeChecker = program.getTypeChecker(); - const sourceFiles = program.getSourceFiles().filter( - f => !f.isDeclarationFile && !program.isSourceFileFromExternalLibrary(f)); + const sourceFiles = + program.getSourceFiles().filter(sourceFile => canMigrateFile(basePath, sourceFile, program)); sourceFiles.forEach(sourceFile => { // We sort the nodes based on their position in the file and we offset the positions by one diff --git a/packages/core/schematics/migrations/dynamic-queries/index.ts b/packages/core/schematics/migrations/dynamic-queries/index.ts index 40ff3013c9..45c96530d3 100644 --- a/packages/core/schematics/migrations/dynamic-queries/index.ts +++ b/packages/core/schematics/migrations/dynamic-queries/index.ts @@ -11,7 +11,7 @@ import {relative} from 'path'; import * as ts from 'typescript'; import {getProjectTsConfigPaths} from '../../utils/project_tsconfig_paths'; -import {createMigrationProgram} from '../../utils/typescript/compiler_host'; +import {canMigrateFile, createMigrationProgram} from '../../utils/typescript/compiler_host'; import {identifyDynamicQueryNodes, removeOptionsParameter, removeStaticFlag} from './util'; @@ -39,8 +39,8 @@ export default function(): Rule { function runDynamicQueryMigration(tree: Tree, tsconfigPath: string, basePath: string) { const {program} = createMigrationProgram(tree, tsconfigPath, basePath); const typeChecker = program.getTypeChecker(); - const sourceFiles = program.getSourceFiles().filter( - f => !f.isDeclarationFile && !program.isSourceFileFromExternalLibrary(f)); + const sourceFiles = + program.getSourceFiles().filter(sourceFile => canMigrateFile(basePath, sourceFile, program)); const printer = ts.createPrinter(); sourceFiles.forEach(sourceFile => { diff --git a/packages/core/schematics/migrations/google3/initialNavigationRule.ts b/packages/core/schematics/migrations/google3/initialNavigationRule.ts index 41a2750c97..8f566288a3 100644 --- a/packages/core/schematics/migrations/google3/initialNavigationRule.ts +++ b/packages/core/schematics/migrations/google3/initialNavigationRule.ts @@ -31,7 +31,7 @@ export class Rule extends Rules.TypedRule { sourceFiles.forEach(sourceFile => initialNavigationCollector.visitNode(sourceFile)); const {assignments} = initialNavigationCollector; - const transformer = new InitialNavigationTransform(typeChecker, getUpdateRecorder); + const transformer = new InitialNavigationTransform(getUpdateRecorder); const updateRecorders = new Map(); transformer.migrateInitialNavigationAssignments(Array.from(assignments)); diff --git a/packages/core/schematics/migrations/initial-navigation/index.ts b/packages/core/schematics/migrations/initial-navigation/index.ts index 1cab6ed87d..9c4a73b134 100644 --- a/packages/core/schematics/migrations/initial-navigation/index.ts +++ b/packages/core/schematics/migrations/initial-navigation/index.ts @@ -10,7 +10,7 @@ import {Rule, SchematicsException, Tree} from '@angular-devkit/schematics'; import {relative} from 'path'; import * as ts from 'typescript'; import {getProjectTsConfigPaths} from '../../utils/project_tsconfig_paths'; -import {createMigrationProgram} from '../../utils/typescript/compiler_host'; +import {canMigrateFile, createMigrationProgram} from '../../utils/typescript/compiler_host'; import {InitialNavigationCollector} from './collector'; import {InitialNavigationTransform} from './transform'; import {UpdateRecorder} from './update_recorder'; @@ -36,14 +36,14 @@ function runInitialNavigationMigration(tree: Tree, tsconfigPath: string, basePat const {program} = createMigrationProgram(tree, tsconfigPath, basePath); const typeChecker = program.getTypeChecker(); const initialNavigationCollector = new InitialNavigationCollector(typeChecker); - const sourceFiles = program.getSourceFiles().filter( - f => !f.isDeclarationFile && !program.isSourceFileFromExternalLibrary(f)); + const sourceFiles = + program.getSourceFiles().filter(sourceFile => canMigrateFile(basePath, sourceFile, program)); // Analyze source files by detecting all modules. sourceFiles.forEach(sourceFile => initialNavigationCollector.visitNode(sourceFile)); const {assignments} = initialNavigationCollector; - const transformer = new InitialNavigationTransform(typeChecker, getUpdateRecorder); + const transformer = new InitialNavigationTransform(getUpdateRecorder); const updateRecorders = new Map(); transformer.migrateInitialNavigationAssignments(Array.from(assignments)); diff --git a/packages/core/schematics/migrations/initial-navigation/transform.ts b/packages/core/schematics/migrations/initial-navigation/transform.ts index 32b105605d..cecd85ccba 100644 --- a/packages/core/schematics/migrations/initial-navigation/transform.ts +++ b/packages/core/schematics/migrations/initial-navigation/transform.ts @@ -13,9 +13,7 @@ import {UpdateRecorder} from './update_recorder'; export class InitialNavigationTransform { private printer = ts.createPrinter(); - constructor( - private typeChecker: ts.TypeChecker, - private getUpdateRecorder: (sf: ts.SourceFile) => UpdateRecorder) {} + constructor(private getUpdateRecorder: (sf: ts.SourceFile) => UpdateRecorder) {} /** Migrate the ExtraOptions#InitialNavigation property assignments. */ migrateInitialNavigationAssignments(literals: ts.PropertyAssignment[]) { @@ -62,14 +60,3 @@ function getUpdatedInitialNavigationValue(initializer: ts.Expression): ts.Expres return !!newText ? ts.createIdentifier(`'${newText}'`) : null; } - -/** - * Check whether the value assigned to an `initialNavigation` assignment - * conforms to the expected types for ExtraOptions#InitialNavigation - * @param node the property assignment to check - */ -function isValidInitialNavigationValue(node: ts.PropertyAssignment): boolean { - return ts.isStringLiteralLike(node.initializer) || - node.initializer.kind === ts.SyntaxKind.FalseKeyword || - node.initializer.kind === ts.SyntaxKind.TrueKeyword; -} diff --git a/packages/core/schematics/migrations/missing-injectable/index.ts b/packages/core/schematics/migrations/missing-injectable/index.ts index 51a6c1da5d..11c734e884 100644 --- a/packages/core/schematics/migrations/missing-injectable/index.ts +++ b/packages/core/schematics/migrations/missing-injectable/index.ts @@ -10,7 +10,7 @@ import {Rule, SchematicContext, SchematicsException, Tree} from '@angular-devkit import {relative} from 'path'; import * as ts from 'typescript'; import {getProjectTsConfigPaths} from '../../utils/project_tsconfig_paths'; -import {createMigrationProgram} from '../../utils/typescript/compiler_host'; +import {canMigrateFile, createMigrationProgram} from '../../utils/typescript/compiler_host'; import {NgDefinitionCollector} from './definition_collector'; import {MissingInjectableTransform} from './transform'; import {UpdateRecorder} from './update_recorder'; @@ -46,8 +46,8 @@ function runMissingInjectableMigration( const failures: string[] = []; const typeChecker = program.getTypeChecker(); const definitionCollector = new NgDefinitionCollector(typeChecker); - const sourceFiles = program.getSourceFiles().filter( - f => !f.isDeclarationFile && !program.isSourceFileFromExternalLibrary(f)); + const sourceFiles = + program.getSourceFiles().filter(sourceFile => canMigrateFile(basePath, sourceFile, program)); // Analyze source files by detecting all modules, directives and components. sourceFiles.forEach(sourceFile => definitionCollector.visitNode(sourceFile)); diff --git a/packages/core/schematics/migrations/module-with-providers/index.ts b/packages/core/schematics/migrations/module-with-providers/index.ts index 9798cd960c..feaa645541 100644 --- a/packages/core/schematics/migrations/module-with-providers/index.ts +++ b/packages/core/schematics/migrations/module-with-providers/index.ts @@ -11,7 +11,7 @@ import {relative} from 'path'; import * as ts from 'typescript'; import {getProjectTsConfigPaths} from '../../utils/project_tsconfig_paths'; -import {createMigrationProgram} from '../../utils/typescript/compiler_host'; +import {canMigrateFile, createMigrationProgram} from '../../utils/typescript/compiler_host'; import {Collector} from './collector'; import {AnalysisFailure, ModuleWithProvidersTransform} from './transform'; @@ -49,8 +49,8 @@ function runModuleWithProvidersMigration(tree: Tree, tsconfigPath: string, baseP const failures: string[] = []; const typeChecker = program.getTypeChecker(); const collector = new Collector(typeChecker); - const sourceFiles = program.getSourceFiles().filter( - f => !f.isDeclarationFile && !program.isSourceFileFromExternalLibrary(f)); + const sourceFiles = + program.getSourceFiles().filter(sourceFile => canMigrateFile(basePath, sourceFile, program)); // Analyze source files by detecting all modules. sourceFiles.forEach(sourceFile => collector.visitNode(sourceFile)); diff --git a/packages/core/schematics/migrations/move-document/index.ts b/packages/core/schematics/migrations/move-document/index.ts index 930ad9f3ad..bcfe1221d7 100644 --- a/packages/core/schematics/migrations/move-document/index.ts +++ b/packages/core/schematics/migrations/move-document/index.ts @@ -11,7 +11,7 @@ import {relative} from 'path'; import * as ts from 'typescript'; import {getProjectTsConfigPaths} from '../../utils/project_tsconfig_paths'; -import {createMigrationProgram} from '../../utils/typescript/compiler_host'; +import {canMigrateFile, createMigrationProgram} from '../../utils/typescript/compiler_host'; import {COMMON_IMPORT, DOCUMENT_TOKEN_NAME, DocumentImportVisitor, ResolvedDocumentImport} from './document_import_visitor'; import {addToImport, createImport, removeFromImport} from './move-import'; @@ -43,8 +43,8 @@ function runMoveDocumentMigration(tree: Tree, tsconfigPath: string, basePath: st const {program} = createMigrationProgram(tree, tsconfigPath, basePath); const typeChecker = program.getTypeChecker(); const visitor = new DocumentImportVisitor(typeChecker); - const sourceFiles = program.getSourceFiles().filter( - f => !f.isDeclarationFile && !program.isSourceFileFromExternalLibrary(f)); + const sourceFiles = + program.getSourceFiles().filter(sourceFile => canMigrateFile(basePath, sourceFile, program)); // Analyze source files by finding imports. sourceFiles.forEach(sourceFile => visitor.visitNode(sourceFile)); diff --git a/packages/core/schematics/migrations/native-view-encapsulation/index.ts b/packages/core/schematics/migrations/native-view-encapsulation/index.ts index 766e8c4ca2..83d7a8312f 100644 --- a/packages/core/schematics/migrations/native-view-encapsulation/index.ts +++ b/packages/core/schematics/migrations/native-view-encapsulation/index.ts @@ -10,7 +10,7 @@ import {Rule, SchematicsException, Tree} from '@angular-devkit/schematics'; import {relative} from 'path'; import {getProjectTsConfigPaths} from '../../utils/project_tsconfig_paths'; -import {createMigrationProgram} from '../../utils/typescript/compiler_host'; +import {canMigrateFile, createMigrationProgram} from '../../utils/typescript/compiler_host'; import {findNativeEncapsulationNodes} from './util'; @@ -35,8 +35,8 @@ export default function(): Rule { function runNativeViewEncapsulationMigration(tree: Tree, tsconfigPath: string, basePath: string) { const {program} = createMigrationProgram(tree, tsconfigPath, basePath); const typeChecker = program.getTypeChecker(); - const sourceFiles = program.getSourceFiles().filter( - f => !f.isDeclarationFile && !program.isSourceFileFromExternalLibrary(f)); + const sourceFiles = + program.getSourceFiles().filter(sourceFile => canMigrateFile(basePath, sourceFile, program)); sourceFiles.forEach(sourceFile => { const update = tree.beginUpdate(relative(basePath, sourceFile.fileName)); diff --git a/packages/core/schematics/migrations/navigation-extras-omissions/index.ts b/packages/core/schematics/migrations/navigation-extras-omissions/index.ts index c8e7fa8032..b027a24da1 100644 --- a/packages/core/schematics/migrations/navigation-extras-omissions/index.ts +++ b/packages/core/schematics/migrations/navigation-extras-omissions/index.ts @@ -11,7 +11,7 @@ import {relative} from 'path'; import * as ts from 'typescript'; import {getProjectTsConfigPaths} from '../../utils/project_tsconfig_paths'; -import {createMigrationProgram} from '../../utils/typescript/compiler_host'; +import {canMigrateFile, createMigrationProgram} from '../../utils/typescript/compiler_host'; import {findLiteralsToMigrate, migrateLiteral} from './util'; @@ -38,8 +38,8 @@ function runNavigationExtrasOmissionsMigration(tree: Tree, tsconfigPath: string, const {program} = createMigrationProgram(tree, tsconfigPath, basePath); const typeChecker = program.getTypeChecker(); const printer = ts.createPrinter(); - const sourceFiles = program.getSourceFiles().filter( - f => !f.isDeclarationFile && !program.isSourceFileFromExternalLibrary(f)); + const sourceFiles = + program.getSourceFiles().filter(sourceFile => canMigrateFile(basePath, sourceFile, program)); sourceFiles.forEach(sourceFile => { const literalsToMigrate = findLiteralsToMigrate(sourceFile, typeChecker); diff --git a/packages/core/schematics/migrations/relative-link-resolution/index.ts b/packages/core/schematics/migrations/relative-link-resolution/index.ts index 6c2f672c9e..dba0f51508 100644 --- a/packages/core/schematics/migrations/relative-link-resolution/index.ts +++ b/packages/core/schematics/migrations/relative-link-resolution/index.ts @@ -10,7 +10,7 @@ import {Rule, SchematicsException, Tree} from '@angular-devkit/schematics'; import {relative} from 'path'; import * as ts from 'typescript'; import {getProjectTsConfigPaths} from '../../utils/project_tsconfig_paths'; -import {createMigrationProgram} from '../../utils/typescript/compiler_host'; +import {canMigrateFile, createMigrationProgram} from '../../utils/typescript/compiler_host'; import {RelativeLinkResolutionCollector} from './collector'; import {RelativeLinkResolutionTransform} from './transform'; import {UpdateRecorder} from './update_recorder'; @@ -36,8 +36,8 @@ function runRelativeLinkResolutionMigration(tree: Tree, tsconfigPath: string, ba const {program} = createMigrationProgram(tree, tsconfigPath, basePath); const typeChecker = program.getTypeChecker(); const relativeLinkResolutionCollector = new RelativeLinkResolutionCollector(typeChecker); - const sourceFiles = program.getSourceFiles().filter( - f => !f.isDeclarationFile && !program.isSourceFileFromExternalLibrary(f)); + const sourceFiles = + program.getSourceFiles().filter(sourceFile => canMigrateFile(basePath, sourceFile, program)); // Analyze source files by detecting all modules. sourceFiles.forEach(sourceFile => relativeLinkResolutionCollector.visitNode(sourceFile)); diff --git a/packages/core/schematics/migrations/renderer-to-renderer2/index.ts b/packages/core/schematics/migrations/renderer-to-renderer2/index.ts index 79bf08a4cf..9caa76a98c 100644 --- a/packages/core/schematics/migrations/renderer-to-renderer2/index.ts +++ b/packages/core/schematics/migrations/renderer-to-renderer2/index.ts @@ -11,7 +11,7 @@ import {relative} from 'path'; import * as ts from 'typescript'; import {getProjectTsConfigPaths} from '../../utils/project_tsconfig_paths'; -import {createMigrationProgram} from '../../utils/typescript/compiler_host'; +import {canMigrateFile, createMigrationProgram} from '../../utils/typescript/compiler_host'; import {getImportSpecifier, replaceImport} from '../../utils/typescript/imports'; import {closestNode} from '../../utils/typescript/nodes'; @@ -59,8 +59,8 @@ function runRendererToRenderer2Migration(tree: Tree, tsconfigPath: string, baseP }, [MODULE_AUGMENTATION_FILENAME]); const typeChecker = program.getTypeChecker(); const printer = ts.createPrinter(); - const sourceFiles = program.getSourceFiles().filter( - f => !f.isDeclarationFile && !program.isSourceFileFromExternalLibrary(f)); + const sourceFiles = + program.getSourceFiles().filter(sourceFile => canMigrateFile(basePath, sourceFile, program)); sourceFiles.forEach(sourceFile => { const rendererImportSpecifier = getImportSpecifier(sourceFile, '@angular/core', 'Renderer'); diff --git a/packages/core/schematics/migrations/router-preserve-query-params/index.ts b/packages/core/schematics/migrations/router-preserve-query-params/index.ts index 973337f72c..79c4f125ac 100644 --- a/packages/core/schematics/migrations/router-preserve-query-params/index.ts +++ b/packages/core/schematics/migrations/router-preserve-query-params/index.ts @@ -11,7 +11,7 @@ import {relative} from 'path'; import * as ts from 'typescript'; import {getProjectTsConfigPaths} from '../../utils/project_tsconfig_paths'; -import {createMigrationProgram} from '../../utils/typescript/compiler_host'; +import {canMigrateFile, createMigrationProgram} from '../../utils/typescript/compiler_host'; import {findLiteralsToMigrate, migrateLiteral} from './util'; @@ -41,8 +41,8 @@ function runPreserveQueryParamsMigration(tree: Tree, tsconfigPath: string, baseP const {program} = createMigrationProgram(tree, tsconfigPath, basePath); const typeChecker = program.getTypeChecker(); const printer = ts.createPrinter(); - const sourceFiles = program.getSourceFiles().filter( - f => !f.isDeclarationFile && !program.isSourceFileFromExternalLibrary(f)); + const sourceFiles = + program.getSourceFiles().filter(sourceFile => canMigrateFile(basePath, sourceFile, program)); sourceFiles.forEach(sourceFile => { const literalsToMigrate = findLiteralsToMigrate(sourceFile, typeChecker); diff --git a/packages/core/schematics/migrations/static-queries/index.ts b/packages/core/schematics/migrations/static-queries/index.ts index 2a2c72b6a0..b0c684a78e 100644 --- a/packages/core/schematics/migrations/static-queries/index.ts +++ b/packages/core/schematics/migrations/static-queries/index.ts @@ -14,7 +14,7 @@ import * as ts from 'typescript'; import {NgComponentTemplateVisitor} from '../../utils/ng_component_template'; import {getProjectTsConfigPaths} from '../../utils/project_tsconfig_paths'; -import {createMigrationProgram} from '../../utils/typescript/compiler_host'; +import {canMigrateFile, createMigrationProgram} from '../../utils/typescript/compiler_host'; import {NgQueryResolveVisitor} from './angular/ng_query_visitor'; import {QueryTemplateStrategy} from './strategies/template_strategy/template_strategy'; @@ -123,8 +123,8 @@ function analyzeProject( } const typeChecker = program.getTypeChecker(); - const sourceFiles = program.getSourceFiles().filter( - f => !f.isDeclarationFile && !program.isSourceFileFromExternalLibrary(f)); + const sourceFiles = + program.getSourceFiles().filter(sourceFile => canMigrateFile(basePath, sourceFile, program)); const queryVisitor = new NgQueryResolveVisitor(typeChecker); // Analyze all project source-files and collect all queries that diff --git a/packages/core/schematics/migrations/template-var-assignment/index.ts b/packages/core/schematics/migrations/template-var-assignment/index.ts index b422c6b33c..8f9f7f79d2 100644 --- a/packages/core/schematics/migrations/template-var-assignment/index.ts +++ b/packages/core/schematics/migrations/template-var-assignment/index.ts @@ -12,7 +12,7 @@ import {relative} from 'path'; import {NgComponentTemplateVisitor} from '../../utils/ng_component_template'; import {getProjectTsConfigPaths} from '../../utils/project_tsconfig_paths'; -import {createMigrationProgram} from '../../utils/typescript/compiler_host'; +import {canMigrateFile, createMigrationProgram} from '../../utils/typescript/compiler_host'; import {analyzeResolvedTemplate} from './analyze_template'; @@ -48,8 +48,8 @@ function runTemplateVariableAssignmentCheck( const {program} = createMigrationProgram(tree, tsconfigPath, basePath); const typeChecker = program.getTypeChecker(); const templateVisitor = new NgComponentTemplateVisitor(typeChecker); - const sourceFiles = program.getSourceFiles().filter( - f => !f.isDeclarationFile && !program.isSourceFileFromExternalLibrary(f)); + const sourceFiles = + program.getSourceFiles().filter(sourceFile => canMigrateFile(basePath, sourceFile, program)); // Analyze source files by detecting HTML templates. sourceFiles.forEach(sourceFile => templateVisitor.visitNode(sourceFile)); diff --git a/packages/core/schematics/migrations/undecorated-classes-with-decorated-fields/index.ts b/packages/core/schematics/migrations/undecorated-classes-with-decorated-fields/index.ts index 4a3cd70bc1..0676ed5de0 100644 --- a/packages/core/schematics/migrations/undecorated-classes-with-decorated-fields/index.ts +++ b/packages/core/schematics/migrations/undecorated-classes-with-decorated-fields/index.ts @@ -11,7 +11,7 @@ import {relative} from 'path'; import * as ts from 'typescript'; import {getProjectTsConfigPaths} from '../../utils/project_tsconfig_paths'; -import {createMigrationProgram} from '../../utils/typescript/compiler_host'; +import {canMigrateFile, createMigrationProgram} from '../../utils/typescript/compiler_host'; import {UndecoratedClassesWithDecoratedFieldsTransform} from './transform'; import {UpdateRecorder} from './update_recorder'; @@ -49,8 +49,8 @@ function runUndecoratedClassesMigration( const failures: string[] = []; const {program} = createMigrationProgram(tree, tsconfigPath, basePath); const typeChecker = program.getTypeChecker(); - const sourceFiles = program.getSourceFiles().filter( - file => !file.isDeclarationFile && !program.isSourceFileFromExternalLibrary(file)); + const sourceFiles = + program.getSourceFiles().filter(sourceFile => canMigrateFile(basePath, sourceFile, program)); const updateRecorders = new Map(); const transform = new UndecoratedClassesWithDecoratedFieldsTransform(typeChecker, getUpdateRecorder); diff --git a/packages/core/schematics/migrations/undecorated-classes-with-di/index.ts b/packages/core/schematics/migrations/undecorated-classes-with-di/index.ts index c3a60b6d46..26d27102ff 100644 --- a/packages/core/schematics/migrations/undecorated-classes-with-di/index.ts +++ b/packages/core/schematics/migrations/undecorated-classes-with-di/index.ts @@ -16,7 +16,7 @@ import {relative} from 'path'; import * as ts from 'typescript'; import {getProjectTsConfigPaths} from '../../utils/project_tsconfig_paths'; -import {createMigrationCompilerHost} from '../../utils/typescript/compiler_host'; +import {canMigrateFile, createMigrationCompilerHost} from '../../utils/typescript/compiler_host'; import {createNgcProgram} from './create_ngc_program'; import {NgDeclarationCollector} from './ng_declaration_collector'; @@ -85,8 +85,8 @@ function runUndecoratedClassesMigration( const partialEvaluator = new PartialEvaluator( new TypeScriptReflectionHost(typeChecker), typeChecker, /* dependencyTracker */ null); const declarationCollector = new NgDeclarationCollector(typeChecker, partialEvaluator); - const sourceFiles = program.getSourceFiles().filter( - s => !s.isDeclarationFile && !program.isSourceFileFromExternalLibrary(s)); + const sourceFiles = + program.getSourceFiles().filter(sourceFile => canMigrateFile(basePath, sourceFile, program)); // Analyze source files by detecting all directives, components and providers. sourceFiles.forEach(sourceFile => declarationCollector.visitNode(sourceFile)); diff --git a/packages/core/schematics/migrations/wait-for-async/index.ts b/packages/core/schematics/migrations/wait-for-async/index.ts index 28254c5f7a..8c04faa58d 100644 --- a/packages/core/schematics/migrations/wait-for-async/index.ts +++ b/packages/core/schematics/migrations/wait-for-async/index.ts @@ -11,7 +11,7 @@ import {relative} from 'path'; import * as ts from 'typescript'; import {getProjectTsConfigPaths} from '../../utils/project_tsconfig_paths'; -import {createMigrationProgram} from '../../utils/typescript/compiler_host'; +import {canMigrateFile, createMigrationProgram} from '../../utils/typescript/compiler_host'; import {getImportSpecifier, replaceImport} from '../../utils/typescript/imports'; import {closestNode} from '../../utils/typescript/nodes'; @@ -54,8 +54,8 @@ function runWaitForAsyncMigration(tree: Tree, tsconfigPath: string, basePath: st }, [MODULE_AUGMENTATION_FILENAME]); const typeChecker = program.getTypeChecker(); const printer = ts.createPrinter(); - const sourceFiles = program.getSourceFiles().filter( - f => !f.isDeclarationFile && !program.isSourceFileFromExternalLibrary(f)); + const sourceFiles = + program.getSourceFiles().filter(sourceFile => canMigrateFile(basePath, sourceFile, program)); const deprecatedFunction = 'async'; const newFunction = 'waitForAsync'; diff --git a/packages/core/schematics/utils/typescript/compiler_host.ts b/packages/core/schematics/utils/typescript/compiler_host.ts index 03efd91c04..e39bdbc8ec 100644 --- a/packages/core/schematics/utils/typescript/compiler_host.ts +++ b/packages/core/schematics/utils/typescript/compiler_host.ts @@ -57,3 +57,24 @@ export function createMigrationCompilerHost( return host; } + +/** + * Checks whether a file can be migrate by our automated migrations. + * @param basePath Absolute path to the project. + * @param sourceFile File being checked. + * @param program Program that includes the source file. + */ +export function canMigrateFile( + basePath: string, sourceFile: ts.SourceFile, program: ts.Program): boolean { + // We shouldn't migrate .d.ts files or files from an external library. + if (sourceFile.isDeclarationFile || program.isSourceFileFromExternalLibrary(sourceFile)) { + return false; + } + + // Our migrations are set up to create a `Program` from the project's tsconfig and to migrate all + // the files within the program. This can include files that are outside of the Angular CLI + // project. We can't migrate files outside of the project, because our file system interactions + // go through the CLI's `Tree` which assumes that all files are within the project. See: + // https://github.com/angular/angular-cli/blob/0b0961c9c233a825b6e4bb59ab7f0790f9b14676/packages/angular_devkit/schematics/src/tree/host-tree.ts#L131 + return !relative(basePath, sourceFile.fileName).startsWith('..'); +}