fix(ngcc): always add exports for ModuleWithProviders references (#33875)

In #32902 a bug was supposedly fixed where internal classes as used
within `ModuleWithProviders` are publicly exported, even when the
typings file already contained the generic type on the
`ModuleWithProviders`. This fix turns out to have been incomplete, as
the `ModuleWithProviders` analysis is not done when not processing the
typings files.

The effect of this bug is that formats that are processed after the
initial format had been processed would not have exports for internal
symbols, resulting in "export '...' was not found in '...'" errors.

This commit fixes the bug by always running the `ModuleWithProviders`
analyzer. An integration test has been added that would fail prior to
this change.

Fixes #33701

PR Close #33875
This commit is contained in:
JoostK
2019-11-16 21:12:58 +01:00
committed by Alex Rickabaugh
parent a05e42ad09
commit f3d8f6adca
6 changed files with 126 additions and 42 deletions

View File

@ -30,7 +30,9 @@ export type ModuleWithProvidersAnalyses = Map<ts.SourceFile, ModuleWithProviders
export const ModuleWithProvidersAnalyses = Map;
export class ModuleWithProvidersAnalyzer {
constructor(private host: NgccReflectionHost, private referencesRegistry: ReferencesRegistry) {}
constructor(
private host: NgccReflectionHost, private referencesRegistry: ReferencesRegistry,
private processDts: boolean) {}
analyzeProgram(program: ts.Program): ModuleWithProvidersAnalyses {
const analyses = new ModuleWithProvidersAnalyses();
@ -43,16 +45,19 @@ export class ModuleWithProvidersAnalyzer {
this.referencesRegistry.add(fn.ngModule.node, new Reference(fn.ngModule.node));
}
const dtsFn = this.getDtsDeclarationForFunction(fn);
const typeParam = dtsFn.type && ts.isTypeReferenceNode(dtsFn.type) &&
dtsFn.type.typeArguments && dtsFn.type.typeArguments[0] ||
null;
if (!typeParam || isAnyKeyword(typeParam)) {
const ngModule = this.resolveNgModuleReference(fn);
const dtsFile = dtsFn.getSourceFile();
const analysis = analyses.has(dtsFile) ? analyses.get(dtsFile) : [];
analysis.push({declaration: dtsFn, ngModule});
analyses.set(dtsFile, analysis);
// Only when processing the dts files do we need to determine which declaration to update.
if (this.processDts) {
const dtsFn = this.getDtsDeclarationForFunction(fn);
const typeParam = dtsFn.type && ts.isTypeReferenceNode(dtsFn.type) &&
dtsFn.type.typeArguments && dtsFn.type.typeArguments[0] ||
null;
if (!typeParam || isAnyKeyword(typeParam)) {
const ngModule = this.resolveNgModuleReference(fn);
const dtsFile = dtsFn.getSourceFile();
const analysis = analyses.has(dtsFile) ? analyses.get(dtsFile) : [];
analysis.push({declaration: dtsFn, ngModule});
analyses.set(dtsFile, analysis);
}
}
});
});