Pete Bacon Darwin ae364864f6 fix(ngcc): do not scan import expressions in d.ts files (#37503)
It is quite common for the TS compiler to have to add synthetic
types to function signatures, where the developer has not
explicitly provided them.  This results in `import(...)` expressions
appearing in typings files.  For example in `@ngrx/data` there is a
class with a getter that has an implicit type:

```ts
export declare class EntityCollectionServiceBase<...> {
  ...
  get store() {
    return this.dispatcher.store;
  }
  ...
}
```

In the d.ts file for this we get:

```ts
get store(): Store<import("@ngrx/data").EntityCache>;
```

Given that this file is within the `@ngrx/data` package already,
this caused ngcc to believe that there was a circular dependency,
causing it to fail to process the package - and in fact crash!

This commit resolves this problem by ignoring `import()` expressions
when scanning typings programs for dependencies. This ability was
only introduced very recently in a 10.0.0 RC release, and so it has
limited benefit given that up till now ngcc has been able to process
libraries effectively without it. Moreover, in the rare case that a
package does have such a dependency, it should get picked up
by the sync ngcc+CLI integration point.

PR Close #37503
2020-06-10 11:51:18 -07:00

34 lines
1.3 KiB
TypeScript

/**
* @license
* Copyright Google LLC 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 {AbsoluteFsPath, FileSystem} from '../../../src/ngtsc/file_system';
import {PathMappings} from '../path_mappings';
import {EsmDependencyHost} from './esm_dependency_host';
import {ModuleResolver} from './module_resolver';
/**
* Helper functions for computing dependencies via typings files.
*/
export class DtsDependencyHost extends EsmDependencyHost {
constructor(fs: FileSystem, pathMappings?: PathMappings) {
super(
fs, new ModuleResolver(fs, pathMappings, ['', '.d.ts', '/index.d.ts', '.js', '/index.js']),
false);
}
/**
* Attempts to process the `importPath` directly and also inside `@types/...`.
*/
protected processImport(
importPath: string, file: AbsoluteFsPath, dependencies: Set<AbsoluteFsPath>,
missing: Set<string>, deepImports: Set<string>, alreadySeen: Set<AbsoluteFsPath>): boolean {
return super.processImport(importPath, file, dependencies, missing, deepImports, alreadySeen) ||
super.processImport(
`@types/${importPath}`, file, dependencies, missing, deepImports, alreadySeen);
}
}