From 3788ebb71456021e2d16611ef41e94bc9b465410 Mon Sep 17 00:00:00 2001 From: Pete Bacon Darwin Date: Wed, 26 Jun 2019 09:16:15 +0100 Subject: [PATCH] fix(ivy): ngcc - don't crash if entry-points have multiple invalid dependencies (#31276) If an entry-point has missing dependencies then it cannot be processed and is marked as invalid. Similarly, if an entry-point has dependencies that have been marked as invalid then that entry-point too is invalid. In all these cases, ngcc should quietly ignore these entry-points and continue processing what it can. Previously, if an entry-point had more than one entry-point that was transitively invalid then ngcc was crashing rather than ignoring the entry-point. PR Close #31276 --- .../ngcc/src/dependencies/dependency_resolver.ts | 13 +++++++------ .../test/dependencies/dependency_resolver_spec.ts | 15 +++++++++++++++ 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/packages/compiler-cli/ngcc/src/dependencies/dependency_resolver.ts b/packages/compiler-cli/ngcc/src/dependencies/dependency_resolver.ts index cd83402d2e..7db4692260 100644 --- a/packages/compiler-cli/ngcc/src/dependencies/dependency_resolver.ts +++ b/packages/compiler-cli/ngcc/src/dependencies/dependency_resolver.ts @@ -130,12 +130,13 @@ export class DependencyResolver { removeNodes(entryPoint, Array.from(missing)); } else { dependencies.forEach(dependencyPath => { - if (graph.hasNode(dependencyPath)) { - if (graph.hasNode(entryPoint.path)) { - // The entry-point is still valid (i.e. has no missing dependencies) and - // the dependency maps to an entry point that exists in the graph so add it - graph.addDependency(entryPoint.path, dependencyPath); - } + if (!graph.hasNode(entryPoint.path)) { + // The entry-point has already been identified as invalid so we don't need + // to do any further work on it. + } else if (graph.hasNode(dependencyPath)) { + // The entry-point is still valid (i.e. has no missing dependencies) and + // the dependency maps to an entry point that exists in the graph so add it + graph.addDependency(entryPoint.path, dependencyPath); } else if (invalidEntryPoints.some(i => i.entryPoint.path === dependencyPath)) { // The dependency path maps to an entry-point that was previously removed // from the graph, so remove this entry-point as well. diff --git a/packages/compiler-cli/ngcc/test/dependencies/dependency_resolver_spec.ts b/packages/compiler-cli/ngcc/test/dependencies/dependency_resolver_spec.ts index c8c31b3ff4..abb47d0fef 100644 --- a/packages/compiler-cli/ngcc/test/dependencies/dependency_resolver_spec.ts +++ b/packages/compiler-cli/ngcc/test/dependencies/dependency_resolver_spec.ts @@ -125,6 +125,21 @@ runInEachFileSystem(() => { ]); }); + it('should cope with entry points having multiple indirect missing dependencies', () => { + spyOn(host, 'findDependencies').and.callFake(createFakeComputeDependencies({ + [_('/first/index.js')]: {resolved: [], missing: ['/missing1']}, + [_('/second/sub/index.js')]: {resolved: [], missing: ['/missing2']}, + [_('/third/index.js')]: {resolved: [first.path, second.path], missing: []}, + })); + const result = resolver.sortEntryPointsByDependency([first, second, third]); + expect(result.entryPoints).toEqual([]); + expect(result.invalidEntryPoints).toEqual([ + {entryPoint: first, missingDependencies: ['/missing1']}, + {entryPoint: second, missingDependencies: ['/missing2']}, + {entryPoint: third, missingDependencies: [first.path]}, + ]); + }); + it('should error if the entry point does not have a suitable format', () => { expect(() => resolver.sortEntryPointsByDependency([ { path: '/first', packageJson: {}, compiledByAngular: true } as EntryPoint