refactor(ivy): generate ngFactoryDef for injectables (#32433)

With #31953 we moved the factories for components, directives and pipes into a new field called `ngFactoryDef`, however I decided not to do it for injectables, because they needed some extra logic. These changes set up the `ngFactoryDef` for injectables as well.

For reference, the extra logic mentioned above is that for injectables we have two code paths:

1. For injectables that don't configure how they should be instantiated, we create a `factory` that proxies to `ngFactoryDef`:

```
// Source
@Injectable()
class Service {}

// Output
class Service {
  static ngInjectableDef = defineInjectable({
    factory: () => Service.ngFactoryFn(),
  });

  static ngFactoryFn: (t) => new (t || Service)();
}
```

2. For injectables that do configure how they're created, we keep the `ngFactoryDef` and generate the factory based on the metadata:

```
// Source
@Injectable({
  useValue: DEFAULT_IMPL,
})
class Service {}

// Output
export class Service {
  static ngInjectableDef = defineInjectable({
    factory: () => DEFAULT_IMPL,
  });

  static ngFactoryFn: (t) => new (t || Service)();
}
```

PR Close #32433
This commit is contained in:
crisbeto
2019-09-01 12:26:04 +02:00
committed by atscott
parent 2729747225
commit 4e35e348af
33 changed files with 695 additions and 295 deletions

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/
import {ChangeDetectorRef, EventEmitter, Injectable, OnDestroy, Pipe, PipeTransform, WrappedValue, ɵisObservable, ɵisPromise, ɵlooseIdentical} from '@angular/core';
import {ChangeDetectorRef, EventEmitter, OnDestroy, Pipe, PipeTransform, WrappedValue, ɵisObservable, ɵisPromise, ɵlooseIdentical} from '@angular/core';
import {Observable, SubscriptionLike} from 'rxjs';
import {invalidPipeArgumentError} from './invalid_pipe_argument_error';
@ -67,7 +67,6 @@ const _observableStrategy = new ObservableStrategy();
*
* @publicApi
*/
@Injectable()
@Pipe({name: 'async', pure: false})
export class AsyncPipe implements OnDestroy, PipeTransform {
private _latestValue: any = null;

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/
import {Injectable, Pipe, PipeTransform} from '@angular/core';
import {Pipe, PipeTransform} from '@angular/core';
import {invalidPipeArgumentError} from './invalid_pipe_argument_error';
/**
@ -24,7 +24,6 @@ import {invalidPipeArgumentError} from './invalid_pipe_argument_error';
* @ngModule CommonModule
* @publicApi
*/
@Injectable()
@Pipe({name: 'lowercase'})
export class LowerCasePipe implements PipeTransform {
/**
@ -68,7 +67,6 @@ const unicodeWordMatch =
* @ngModule CommonModule
* @publicApi
*/
@Injectable()
@Pipe({name: 'titlecase'})
export class TitleCasePipe implements PipeTransform {
/**
@ -93,7 +91,6 @@ export class TitleCasePipe implements PipeTransform {
* @ngModule CommonModule
* @publicApi
*/
@Injectable()
@Pipe({name: 'uppercase'})
export class UpperCasePipe implements PipeTransform {
/**

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/
import {Inject, Injectable, LOCALE_ID, Pipe, PipeTransform} from '@angular/core';
import {Inject, LOCALE_ID, Pipe, PipeTransform} from '@angular/core';
import {formatDate} from '../i18n/format_date';
import {invalidPipeArgumentError} from './invalid_pipe_argument_error';
@ -150,7 +150,6 @@ import {invalidPipeArgumentError} from './invalid_pipe_argument_error';
* @publicApi
*/
// clang-format on
@Injectable()
@Pipe({name: 'date', pure: true})
export class DatePipe implements PipeTransform {
constructor(@Inject(LOCALE_ID) private locale: string) {}

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/
import {Injectable, LOCALE_ID, Pipe, PipeTransform} from '@angular/core';
import {Pipe, PipeTransform} from '@angular/core';
import {NgLocalization, getPluralCategory} from '../i18n/localization';
import {invalidPipeArgumentError} from './invalid_pipe_argument_error';
@ -26,7 +26,6 @@ const _INTERPOLATION_REGEXP: RegExp = /#/g;
*
* @publicApi
*/
@Injectable()
@Pipe({name: 'i18nPlural', pure: true})
export class I18nPluralPipe implements PipeTransform {
constructor(private _localization: NgLocalization) {}

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/
import {Injectable, Pipe, PipeTransform} from '@angular/core';
import {Pipe, PipeTransform} from '@angular/core';
import {invalidPipeArgumentError} from './invalid_pipe_argument_error';
/**
@ -26,7 +26,6 @@ import {invalidPipeArgumentError} from './invalid_pipe_argument_error';
*
* @publicApi
*/
@Injectable()
@Pipe({name: 'i18nSelect', pure: true})
export class I18nSelectPipe implements PipeTransform {
/**

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/
import {Injectable, Pipe, PipeTransform} from '@angular/core';
import {Pipe, PipeTransform} from '@angular/core';
/**
* @ngModule CommonModule
@ -23,7 +23,6 @@ import {Injectable, Pipe, PipeTransform} from '@angular/core';
*
* @publicApi
*/
@Injectable()
@Pipe({name: 'json', pure: false})
export class JsonPipe implements PipeTransform {
/**

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/
import {Injectable, KeyValueChangeRecord, KeyValueChanges, KeyValueDiffer, KeyValueDiffers, Pipe, PipeTransform} from '@angular/core';
import {KeyValueChangeRecord, KeyValueChanges, KeyValueDiffer, KeyValueDiffers, Pipe, PipeTransform} from '@angular/core';
function makeKeyValuePair<K, V>(key: K, value: V): KeyValue<K, V> {
return {key: key, value: value};
@ -43,7 +43,6 @@ export interface KeyValue<K, V> {
*
* @publicApi
*/
@Injectable()
@Pipe({name: 'keyvalue', pure: false})
export class KeyValuePipe implements PipeTransform {
constructor(private readonly differs: KeyValueDiffers) {}

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/
import {Inject, Injectable, LOCALE_ID, Pipe, PipeTransform} from '@angular/core';
import {Inject, LOCALE_ID, Pipe, PipeTransform} from '@angular/core';
import {formatCurrency, formatNumber, formatPercent} from '../i18n/format_number';
import {getCurrencySymbol} from '../i18n/locale_data_api';
import {invalidPipeArgumentError} from './invalid_pipe_argument_error';
@ -46,7 +46,6 @@ import {invalidPipeArgumentError} from './invalid_pipe_argument_error';
*
* @publicApi
*/
@Injectable()
@Pipe({name: 'number'})
export class DecimalPipe implements PipeTransform {
constructor(@Inject(LOCALE_ID) private _locale: string) {}
@ -100,7 +99,6 @@ export class DecimalPipe implements PipeTransform {
*
* @publicApi
*/
@Injectable()
@Pipe({name: 'percent'})
export class PercentPipe implements PipeTransform {
constructor(@Inject(LOCALE_ID) private _locale: string) {}
@ -155,7 +153,6 @@ export class PercentPipe implements PipeTransform {
*
* @publicApi
*/
@Injectable()
@Pipe({name: 'currency'})
export class CurrencyPipe implements PipeTransform {
constructor(@Inject(LOCALE_ID) private _locale: string) {}

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/
import {Injectable, Pipe, PipeTransform} from '@angular/core';
import {Pipe, PipeTransform} from '@angular/core';
import {invalidPipeArgumentError} from './invalid_pipe_argument_error';
/**
@ -44,7 +44,6 @@ import {invalidPipeArgumentError} from './invalid_pipe_argument_error';
*
* @publicApi
*/
@Injectable()
@Pipe({name: 'slice', pure: false})
export class SlicePipe implements PipeTransform {
/**