refactor(ivy): remove unnecessary fac wrapper (#34076)
For injectables, we currently generate a factory function in the injectable def (prov) that delegates to the factory function in the factory def (fac). It looks something like this: ``` factory: function(t) { return Svc.fac(t); } ``` The extra wrapper function is unnecessary since the args for the factory functions are the same. This commit changes the compiler to generate this instead: ``` factory: Svc.fac ``` Because we are generating less code for each injectable, we should see some modest code size savings. AIO's main bundle is about 1 KB smaller. PR Close #34076
This commit is contained in:

committed by
Miško Hevery

parent
7504543962
commit
ce79cacd03
@ -94,6 +94,11 @@ export class DecorationAnalyzer {
|
||||
new DirectiveDecoratorHandler(
|
||||
this.reflectionHost, this.evaluator, this.fullRegistry, NOOP_DEFAULT_IMPORT_RECORDER,
|
||||
this.isCore, /* annotateForClosureCompiler */ false),
|
||||
// Pipe handler must be before injectable handler in list so pipe factories are printed
|
||||
// before injectable factories (so injectable factories can delegate to them)
|
||||
new PipeDecoratorHandler(
|
||||
this.reflectionHost, this.evaluator, this.metaRegistry, NOOP_DEFAULT_IMPORT_RECORDER,
|
||||
this.isCore),
|
||||
new InjectableDecoratorHandler(
|
||||
this.reflectionHost, NOOP_DEFAULT_IMPORT_RECORDER, this.isCore,
|
||||
/* strictCtorDeps */ false, /* errorOnDuplicateProv */ false),
|
||||
@ -101,9 +106,6 @@ export class DecorationAnalyzer {
|
||||
this.reflectionHost, this.evaluator, this.fullMetaReader, this.fullRegistry,
|
||||
this.scopeRegistry, this.referencesRegistry, this.isCore, /* routeAnalyzer */ null,
|
||||
this.refEmitter, NOOP_DEFAULT_IMPORT_RECORDER, /* annotateForClosureCompiler */ false),
|
||||
new PipeDecoratorHandler(
|
||||
this.reflectionHost, this.evaluator, this.metaRegistry, NOOP_DEFAULT_IMPORT_RECORDER,
|
||||
this.isCore),
|
||||
];
|
||||
migrations: Migration[] = [
|
||||
new UndecoratedParentMigration(),
|
||||
|
@ -205,13 +205,43 @@ runInEachFileSystem(() => {
|
||||
expect(countOccurrences(after, 'ɵfac')).toEqual(1);
|
||||
});
|
||||
|
||||
// This is necessary to ensure XPipeDef.fac is defined when delegated from injectable def
|
||||
it('should always generate factory def (fac) before injectable def (prov)', () => {
|
||||
compileIntoFlatEs5Package('test-package', {
|
||||
'/index.ts': `
|
||||
import {Injectable, Pipe, PipeTransform} from '@angular/core';
|
||||
|
||||
@Injectable()
|
||||
@Pipe({
|
||||
name: 'myTestPipe'
|
||||
})
|
||||
export class TestClass implements PipeTransform {
|
||||
transform(value: any) { return value; }
|
||||
}
|
||||
`,
|
||||
});
|
||||
|
||||
mainNgcc({
|
||||
basePath: '/node_modules',
|
||||
targetEntryPointPath: 'test-package',
|
||||
propertiesToConsider: ['main'],
|
||||
});
|
||||
|
||||
const jsContents = fs.readFile(_(`/node_modules/test-package/index.js`));
|
||||
expect(jsContents)
|
||||
.toContain(
|
||||
`TestClass.ɵfac = function TestClass_Factory(t) { return new (t || TestClass)(); };\n` +
|
||||
`TestClass.ɵpipe = ɵngcc0.ɵɵdefinePipe({ name: "myTestPipe", type: TestClass, pure: true });\n` +
|
||||
`TestClass.ɵprov = ɵngcc0.ɵɵdefineInjectable({`);
|
||||
});
|
||||
|
||||
it('should add generic type for ModuleWithProviders and generate exports for private modules',
|
||||
() => {
|
||||
compileIntoApf('test-package', {
|
||||
'/index.ts': `
|
||||
import {ModuleWithProviders} from '@angular/core';
|
||||
import {InternalFooModule} from './internal';
|
||||
|
||||
|
||||
export class FooModule {
|
||||
static forRoot(): ModuleWithProviders {
|
||||
return {
|
||||
@ -222,7 +252,7 @@ runInEachFileSystem(() => {
|
||||
`,
|
||||
'/internal.ts': `
|
||||
import {NgModule} from '@angular/core';
|
||||
|
||||
|
||||
@NgModule()
|
||||
export class InternalFooModule {}
|
||||
`,
|
||||
|
Reference in New Issue
Block a user