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 7ffce12ee6039..801910df1ca2f 100644 --- a/packages/core/schematics/migrations/undecorated-classes-with-di/index.ts +++ b/packages/core/schematics/migrations/undecorated-classes-with-di/index.ts @@ -9,6 +9,7 @@ import {logging} from '@angular-devkit/core'; import {Rule, SchematicContext, SchematicsException, Tree} from '@angular-devkit/schematics'; import {AotCompiler} from '@angular/compiler'; +import {Diagnostic as NgDiagnostic} from '@angular/compiler-cli'; import {PartialEvaluator} from '@angular/compiler-cli/src/ngtsc/partial_evaluator'; import {TypeScriptReflectionHost} from '@angular/compiler-cli/src/ngtsc/reflection'; import {relative} from 'path'; @@ -84,10 +85,11 @@ function runUndecoratedClassesMigration( const partialEvaluator = new PartialEvaluator(new TypeScriptReflectionHost(typeChecker), typeChecker); const declarationCollector = new NgDeclarationCollector(typeChecker, partialEvaluator); - const rootSourceFiles = program.getRootFileNames().map(f => program.getSourceFile(f) !); + const sourceFiles = program.getSourceFiles().filter( + s => !s.isDeclarationFile && !program.isSourceFileFromExternalLibrary(s)); // Analyze source files by detecting all directives, components and providers. - rootSourceFiles.forEach(sourceFile => declarationCollector.visitNode(sourceFile)); + sourceFiles.forEach(sourceFile => declarationCollector.visitNode(sourceFile)); const {decoratedDirectives, decoratedProviders, undecoratedDeclarations} = declarationCollector; const transform = @@ -151,14 +153,28 @@ function runUndecoratedClassesMigration( } } +function getErrorDiagnostics(diagnostics: ReadonlyArray) { + return diagnostics.filter(d => d.category === ts.DiagnosticCategory.Error); +} + function gracefullyCreateProgram( tree: Tree, basePath: string, tsconfigPath: string, logger: logging.LoggerApi): {compiler: AotCompiler, program: ts.Program}|null { try { const {ngcProgram, host, program, compiler} = createNgcProgram( (options) => createMigrationCompilerHost(tree, options, basePath), tsconfigPath); - const syntacticDiagnostics = ngcProgram.getTsSyntacticDiagnostics(); - const structuralDiagnostics = ngcProgram.getNgStructuralDiagnostics(); + const syntacticDiagnostics = getErrorDiagnostics(ngcProgram.getTsSyntacticDiagnostics()); + const structuralDiagnostics = getErrorDiagnostics(ngcProgram.getNgStructuralDiagnostics()); + const configDiagnostics = getErrorDiagnostics( + [...program.getOptionsDiagnostics(), ...ngcProgram.getNgOptionDiagnostics()]); + + if (configDiagnostics.length) { + logger.warn( + `\nTypeScript project "${tsconfigPath}" has configuration errors. This could cause ` + + `an incomplete migration. Please fix the following failures and rerun the migration:`); + logger.error(ts.formatDiagnostics(configDiagnostics, host)); + return null; + } // Syntactic TypeScript errors can throw off the query analysis and therefore we want // to notify the developer that we couldn't analyze parts of the project. Developers diff --git a/packages/core/schematics/test/undecorated_classes_with_di_migration_spec.ts b/packages/core/schematics/test/undecorated_classes_with_di_migration_spec.ts index 15ea12c7f2b8e..beebaf81b4ff8 100644 --- a/packages/core/schematics/test/undecorated_classes_with_di_migration_spec.ts +++ b/packages/core/schematics/test/undecorated_classes_with_di_migration_spec.ts @@ -1495,5 +1495,32 @@ describe('Undecorated classes with DI migration', () => { expect(warnOutput.length).toBe(0); expect(errorOutput.length).toBe(0); }); + + it('should not throw if tsconfig references non-existent source file', async() => { + writeFile('/tsconfig.json', JSON.stringify({ + compilerOptions: { + lib: ['es2015'], + }, + files: [ + './non-existent.ts', + ] + })); + + let failed = false; + try { + await runMigration(); + } catch (e) { + failed = true; + } + + expect(failed).toBe(false, 'Expected the migration not to fail.'); + expect(warnOutput.length).toBe(1); + expect(errorOutput.length).toBe(1); + expect(warnOutput[0]) + .toContain( + 'TypeScript project "tsconfig.json" has configuration errors. This could cause an ' + + 'incomplete migration. Please fix the following failures and rerun the migration:'); + expect(errorOutput[0]).toMatch(/non-existent\.ts' not found/); + }); }); });