fix(compiler): also create `.ngfactory.js` files in non obvious cases (#19301)

E.g. when an exported class contains a ctor argument which is
from another compilation unit.

PR Close #19301
This commit is contained in:
Tobias Bosch 2017-09-20 16:31:02 -07:00 committed by Igor Minar
parent c76da27240
commit 1a647c399b
2 changed files with 29 additions and 16 deletions

View File

@ -840,6 +840,7 @@ describe('ngc transformer command-line', () => {
})
export class Module {}
`);
write('lib1/class1.ts', `export class Class1 {}`);
// Lib 2
write('lib2/tsconfig-lib2.json', `{
@ -855,6 +856,13 @@ describe('ngc transformer command-line', () => {
write('lib2/module.ts', `
export {Module} from 'lib1_built/module';
`);
write('lib2/class2.ts', `
import {Class1} from 'lib1_built/class1';
export class Class2 {
constructor(class1: Class1) {}
}
`);
// Application
write('app/tsconfig-app.json', `{
@ -904,6 +912,12 @@ describe('ngc transformer command-line', () => {
shouldExist('lib2_built/module.ngfactory.js');
shouldExist('lib2_built/module.ngfactory.d.ts');
shouldExist('lib2_built/class2.ngsummary.json');
shouldNotExist('lib2_built/class2.ngsummary.js');
shouldNotExist('lib2_built/class2.ngsummary.d.ts');
shouldExist('lib2_built/class2.ngfactory.js');
shouldExist('lib2_built/class2.ngfactory.d.ts');
// app
// make `shouldExist` / `shouldNotExist` relative to `built`
outDir = path.resolve(basePath, 'built');

View File

@ -34,7 +34,7 @@ import {ResolvedStaticSymbol, StaticSymbolResolver} from './static_symbol_resolv
import {createForJitStub, serializeSummaries} from './summary_serializer';
import {ngfactoryFilePath, splitTypescriptSuffix, summaryFileName, summaryForJitFileName, summaryForJitName} from './util';
export enum StubEmitFlags {
enum StubEmitFlags {
Basic = 1 << 0,
TypeCheck = 1 << 1,
All = TypeCheck | Basic
@ -170,22 +170,14 @@ export class AotCompiler {
}
});
// make sure we create a .ngfactory if we have a least one component
// in the file.
// Make sure we create a .ngfactory if we have a injectable/directive/pipe/NgModule
// or a reference to a non source file.
// Note: This is overestimating the required .ngfactory files as the real calculation is harder.
// Only do this for StubEmitFlags.Basic, as adding a type check block
// does not change this file (as we generate type check blocks based on NgModules).
if (outputCtx.statements.length === 0 && (emitFlags & StubEmitFlags.Basic) &&
file.directives.some(
dir => this._metadataResolver.getNonNormalizedDirectiveMetadata(
dir) !.metadata.isComponent)) {
_createEmptyStub(outputCtx);
}
// make sure we create a .ngfactory if we reexport a non source file.
// Only do this for StubEmitFlags.Basic, as adding a type check block
// does not change this file (as we generate type check blocks based on NgModules).
if (outputCtx.statements.length === 0 && (emitFlags & StubEmitFlags.Basic) &&
file.exportsNonSourceFiles) {
(file.directives.length || file.pipes.length || file.injectables.length ||
file.ngModules.length || file.exportsNonSourceFiles)) {
_createEmptyStub(outputCtx);
}
@ -648,22 +640,29 @@ export function analyzeFile(
if (!symbolMeta || symbolMeta.__symbolic === 'error') {
return;
}
exportsNonSourceFiles =
exportsNonSourceFiles || isValueExportingNonSourceFile(host, symbolMeta);
let isNgSymbol = false;
if (symbolMeta.__symbolic === 'class') {
if (metadataResolver.isDirective(symbol)) {
isNgSymbol = true;
directives.push(symbol);
} else if (metadataResolver.isPipe(symbol)) {
isNgSymbol = true;
pipes.push(symbol);
} else if (metadataResolver.isInjectable(symbol)) {
isNgSymbol = true;
injectables.push(symbol);
} else {
const ngModule = metadataResolver.getNgModuleMetadata(symbol, false);
if (ngModule) {
isNgSymbol = true;
ngModules.push(ngModule);
}
}
}
if (!isNgSymbol) {
exportsNonSourceFiles =
exportsNonSourceFiles || isValueExportingNonSourceFile(host, symbolMeta);
}
});
}
return {