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:
@ -40,9 +40,7 @@ export interface CompilerFacade {
|
||||
compileBase(angularCoreEnv: CoreEnvironment, sourceMapUrl: string, meta: R3BaseMetadataFacade):
|
||||
any;
|
||||
compileFactory(
|
||||
angularCoreEnv: CoreEnvironment, sourceMapUrl: string,
|
||||
meta: R3PipeMetadataFacade|R3DirectiveMetadataFacade|R3ComponentMetadataFacade,
|
||||
isPipe?: boolean): any;
|
||||
angularCoreEnv: CoreEnvironment, sourceMapUrl: string, meta: R3FactoryDefMetadataFacade): any;
|
||||
|
||||
createParseSourceSpan(kind: string, typeName: string, sourceUrl: string): ParseSourceSpan;
|
||||
|
||||
@ -94,7 +92,6 @@ export interface R3InjectableMetadataFacade {
|
||||
name: string;
|
||||
type: any;
|
||||
typeArgumentCount: number;
|
||||
ctorDeps: R3DependencyMetadataFacade[]|null;
|
||||
providedIn: any;
|
||||
useClass?: any;
|
||||
useFactory?: any;
|
||||
@ -164,6 +161,15 @@ export interface R3BaseMetadataFacade {
|
||||
viewQueries?: R3QueryMetadataFacade[];
|
||||
}
|
||||
|
||||
export interface R3FactoryDefMetadataFacade {
|
||||
name: string;
|
||||
type: any;
|
||||
typeArgumentCount: number;
|
||||
deps: R3DependencyMetadataFacade[]|null;
|
||||
injectFn: 'directiveInject'|'inject';
|
||||
isPipe: boolean;
|
||||
}
|
||||
|
||||
export type ViewEncapsulation = number;
|
||||
|
||||
export type ChangeDetectionStrategy = number;
|
||||
|
@ -8,7 +8,9 @@
|
||||
|
||||
import {R3InjectableMetadataFacade, getCompilerFacade} from '../../compiler/compiler_facade';
|
||||
import {Type} from '../../interface/type';
|
||||
import {NG_FACTORY_DEF} from '../../render3/fields';
|
||||
import {getClosureSafeProperty} from '../../util/property';
|
||||
import {resolveForwardRef} from '../forward_ref';
|
||||
import {Injectable} from '../injectable';
|
||||
import {NG_INJECTABLE_DEF} from '../interface/defs';
|
||||
import {ClassSansProvider, ExistingSansProvider, FactorySansProvider, ValueProvider, ValueSansProvider} from '../interface/provider';
|
||||
@ -23,59 +25,45 @@ import {convertDependencies, reflectDependencies} from './util';
|
||||
* `ngInjectableDef` onto the injectable type.
|
||||
*/
|
||||
export function compileInjectable(type: Type<any>, srcMeta?: Injectable): void {
|
||||
let def: any = null;
|
||||
let ngInjectableDef: any = null;
|
||||
let ngFactoryDef: any = null;
|
||||
|
||||
// if NG_INJECTABLE_DEF is already defined on this class then don't overwrite it
|
||||
if (type.hasOwnProperty(NG_INJECTABLE_DEF)) return;
|
||||
|
||||
Object.defineProperty(type, NG_INJECTABLE_DEF, {
|
||||
get: () => {
|
||||
if (def === null) {
|
||||
// Allow the compilation of a class with a `@Injectable()` decorator without parameters
|
||||
const meta: Injectable = srcMeta || {providedIn: null};
|
||||
const hasAProvider = isUseClassProvider(meta) || isUseFactoryProvider(meta) ||
|
||||
isUseValueProvider(meta) || isUseExistingProvider(meta);
|
||||
|
||||
|
||||
const compilerMeta: R3InjectableMetadataFacade = {
|
||||
name: type.name,
|
||||
type: type,
|
||||
typeArgumentCount: 0,
|
||||
providedIn: meta.providedIn,
|
||||
ctorDeps: reflectDependencies(type),
|
||||
userDeps: undefined,
|
||||
};
|
||||
if ((isUseClassProvider(meta) || isUseFactoryProvider(meta)) && meta.deps !== undefined) {
|
||||
compilerMeta.userDeps = convertDependencies(meta.deps);
|
||||
if (!type.hasOwnProperty(NG_INJECTABLE_DEF)) {
|
||||
Object.defineProperty(type, NG_INJECTABLE_DEF, {
|
||||
get: () => {
|
||||
if (ngInjectableDef === null) {
|
||||
ngInjectableDef = getCompilerFacade().compileInjectable(
|
||||
angularCoreDiEnv, `ng:///${type.name}/ngInjectableDef.js`,
|
||||
getInjectableMetadata(type, srcMeta));
|
||||
}
|
||||
if (!hasAProvider) {
|
||||
// In the case the user specifies a type provider, treat it as {provide: X, useClass: X}.
|
||||
// The deps will have been reflected above, causing the factory to create the class by
|
||||
// calling
|
||||
// its constructor with injected deps.
|
||||
compilerMeta.useClass = type;
|
||||
} else if (isUseClassProvider(meta)) {
|
||||
// The user explicitly specified useClass, and may or may not have provided deps.
|
||||
compilerMeta.useClass = meta.useClass;
|
||||
} else if (isUseValueProvider(meta)) {
|
||||
// The user explicitly specified useValue.
|
||||
compilerMeta.useValue = meta.useValue;
|
||||
} else if (isUseFactoryProvider(meta)) {
|
||||
// The user explicitly specified useFactory.
|
||||
compilerMeta.useFactory = meta.useFactory;
|
||||
} else if (isUseExistingProvider(meta)) {
|
||||
// The user explicitly specified useExisting.
|
||||
compilerMeta.useExisting = meta.useExisting;
|
||||
} else {
|
||||
// Can't happen - either hasAProvider will be false, or one of the providers will be set.
|
||||
throw new Error(`Unreachable state.`);
|
||||
return ngInjectableDef;
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
// if NG_FACTORY_DEF is already defined on this class then don't overwrite it
|
||||
if (!type.hasOwnProperty(NG_FACTORY_DEF)) {
|
||||
Object.defineProperty(type, NG_FACTORY_DEF, {
|
||||
get: () => {
|
||||
if (ngFactoryDef === null) {
|
||||
const metadata = getInjectableMetadata(type, srcMeta);
|
||||
ngFactoryDef = getCompilerFacade().compileFactory(
|
||||
angularCoreDiEnv, `ng:///${type.name}/ngFactoryDef.js`, {
|
||||
name: metadata.name,
|
||||
type: metadata.type,
|
||||
typeArgumentCount: metadata.typeArgumentCount,
|
||||
deps: reflectDependencies(type),
|
||||
injectFn: 'inject',
|
||||
isPipe: false
|
||||
});
|
||||
}
|
||||
def = getCompilerFacade().compileInjectable(
|
||||
angularCoreDiEnv, `ng:///${type.name}/ngInjectableDef.js`, compilerMeta);
|
||||
}
|
||||
return def;
|
||||
},
|
||||
});
|
||||
return ngFactoryDef;
|
||||
},
|
||||
// Leave this configurable so that the factories from directives or pipes can take precedence.
|
||||
configurable: true
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
type UseClassProvider = Injectable & ClassSansProvider & {deps?: any[]};
|
||||
@ -98,3 +86,32 @@ function isUseFactoryProvider(meta: Injectable): meta is Injectable&FactorySansP
|
||||
function isUseExistingProvider(meta: Injectable): meta is Injectable&ExistingSansProvider {
|
||||
return (meta as ExistingSansProvider).useExisting !== undefined;
|
||||
}
|
||||
|
||||
function getInjectableMetadata(type: Type<any>, srcMeta?: Injectable): R3InjectableMetadataFacade {
|
||||
// Allow the compilation of a class with a `@Injectable()` decorator without parameters
|
||||
const meta: Injectable = srcMeta || {providedIn: null};
|
||||
const compilerMeta: R3InjectableMetadataFacade = {
|
||||
name: type.name,
|
||||
type: type,
|
||||
typeArgumentCount: 0,
|
||||
providedIn: meta.providedIn,
|
||||
userDeps: undefined,
|
||||
};
|
||||
if ((isUseClassProvider(meta) || isUseFactoryProvider(meta)) && meta.deps !== undefined) {
|
||||
compilerMeta.userDeps = convertDependencies(meta.deps);
|
||||
}
|
||||
if (isUseClassProvider(meta)) {
|
||||
// The user explicitly specified useClass, and may or may not have provided deps.
|
||||
compilerMeta.useClass = resolveForwardRef(meta.useClass);
|
||||
} else if (isUseValueProvider(meta)) {
|
||||
// The user explicitly specified useValue.
|
||||
compilerMeta.useValue = resolveForwardRef(meta.useValue);
|
||||
} else if (isUseFactoryProvider(meta)) {
|
||||
// The user explicitly specified useFactory.
|
||||
compilerMeta.useFactory = meta.useFactory;
|
||||
} else if (isUseExistingProvider(meta)) {
|
||||
// The user explicitly specified useExisting.
|
||||
compilerMeta.useExisting = resolveForwardRef(meta.useExisting);
|
||||
}
|
||||
return compilerMeta;
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ export {ɵɵinject} from './di/injector_compatibility';
|
||||
export {ɵɵInjectableDef, ɵɵInjectorDef, ɵɵdefineInjectable, ɵɵdefineInjector} from './di/interface/defs';
|
||||
export {NgModuleDef, ɵɵNgModuleDefWithMeta} from './metadata/ng_module';
|
||||
export {ɵɵdefineNgModule} from './render3/definition';
|
||||
export {ɵɵFactoryDef} from './render3/interfaces/definition';
|
||||
export {setClassMetadata} from './render3/metadata';
|
||||
export {NgModuleFactory} from './render3/ng_module_ref';
|
||||
|
||||
|
@ -753,11 +753,11 @@ export function getBaseDef<T>(type: any): ɵɵBaseDef<T>|null {
|
||||
export function getFactoryDef<T>(type: any, throwNotFound: true): FactoryFn<T>;
|
||||
export function getFactoryDef<T>(type: any): FactoryFn<T>|null;
|
||||
export function getFactoryDef<T>(type: any, throwNotFound?: boolean): FactoryFn<T>|null {
|
||||
const factoryFn = type[NG_FACTORY_DEF] || null;
|
||||
if (!factoryFn && throwNotFound === true && ngDevMode) {
|
||||
const hasFactoryDef = type.hasOwnProperty(NG_FACTORY_DEF);
|
||||
if (!hasFactoryDef && throwNotFound === true && ngDevMode) {
|
||||
throw new Error(`Type ${stringify(type)} does not have 'ngFactoryDef' property.`);
|
||||
}
|
||||
return factoryFn;
|
||||
return hasFactoryDef ? type[NG_FACTORY_DEF] : null;
|
||||
}
|
||||
|
||||
export function getNgModuleDef<T>(type: any, throwNotFound: true): NgModuleDef<T>;
|
||||
|
@ -16,7 +16,7 @@ import {Type} from '../interface/type';
|
||||
import {assertDefined, assertEqual} from '../util/assert';
|
||||
|
||||
import {getFactoryDef} from './definition';
|
||||
import {NG_ELEMENT_ID} from './fields';
|
||||
import {NG_ELEMENT_ID, NG_FACTORY_DEF} from './fields';
|
||||
import {DirectiveDef, FactoryFn} from './interfaces/definition';
|
||||
import {NO_PARENT_INJECTOR, NodeInjectorFactory, PARENT_INJECTOR, RelativeInjectorLocation, RelativeInjectorLocationFlags, TNODE, isFactory} from './interfaces/injector';
|
||||
import {AttributeMarker, TContainerNode, TElementContainerNode, TElementNode, TNode, TNodeFlags, TNodeProviderIndexes, TNodeType} from './interfaces/node';
|
||||
@ -642,9 +642,11 @@ export function ɵɵgetFactoryOf<T>(type: Type<any>): FactoryFn<T>|null {
|
||||
}) as any;
|
||||
}
|
||||
|
||||
// TODO(crisbeto): unify injectable factories with getFactory.
|
||||
const def = getInjectableDef<T>(typeAny) || getInjectorDef<T>(typeAny);
|
||||
const factory = def && def.factory || getFactoryDef<T>(typeAny);
|
||||
let factory = getFactoryDef<T>(typeAny);
|
||||
if (factory === null) {
|
||||
const injectorDef = getInjectorDef<T>(typeAny);
|
||||
factory = injectorDef && injectorDef.factory;
|
||||
}
|
||||
return factory || null;
|
||||
}
|
||||
|
||||
@ -653,7 +655,7 @@ export function ɵɵgetFactoryOf<T>(type: Type<any>): FactoryFn<T>|null {
|
||||
*/
|
||||
export function ɵɵgetInheritedFactory<T>(type: Type<any>): (type: Type<T>) => T {
|
||||
const proto = Object.getPrototypeOf(type.prototype).constructor as Type<any>;
|
||||
const factory = ɵɵgetFactoryOf<T>(proto);
|
||||
const factory = (proto as any)[NG_FACTORY_DEF] || ɵɵgetFactoryOf<T>(proto);
|
||||
if (factory !== null) {
|
||||
return factory;
|
||||
} else {
|
||||
|
@ -7,9 +7,8 @@
|
||||
*/
|
||||
|
||||
import {R3DirectiveMetadataFacade, getCompilerFacade} from '../../compiler/compiler_facade';
|
||||
import {CompilerFacade, R3BaseMetadataFacade, R3ComponentMetadataFacade, R3QueryMetadataFacade} from '../../compiler/compiler_facade_interface';
|
||||
import {R3BaseMetadataFacade, R3ComponentMetadataFacade, R3QueryMetadataFacade} from '../../compiler/compiler_facade_interface';
|
||||
import {resolveForwardRef} from '../../di/forward_ref';
|
||||
import {compileInjectable} from '../../di/jit/injectable';
|
||||
import {getReflect, reflectDependencies} from '../../di/jit/util';
|
||||
import {Type} from '../../interface/type';
|
||||
import {Query} from '../../metadata/di';
|
||||
@ -43,31 +42,52 @@ export function compileComponent(type: Type<any>, metadata: Component): void {
|
||||
(typeof ngDevMode === 'undefined' || ngDevMode) && initNgDevMode();
|
||||
|
||||
let ngComponentDef: any = null;
|
||||
let ngFactoryDef: any = null;
|
||||
|
||||
// Metadata may have resources which need to be resolved.
|
||||
maybeQueueResolutionOfComponentResources(type, metadata);
|
||||
|
||||
Object.defineProperty(type, NG_FACTORY_DEF, {
|
||||
get: () => {
|
||||
if (ngFactoryDef === null) {
|
||||
const compiler = getCompilerFacade();
|
||||
const meta = getComponentMetadata(compiler, type, metadata);
|
||||
ngFactoryDef = compiler.compileFactory(
|
||||
angularCoreEnv, `ng:///${type.name}/ngFactory.js`, meta.metadata);
|
||||
}
|
||||
return ngFactoryDef;
|
||||
},
|
||||
// Make the property configurable in dev mode to allow overriding in tests
|
||||
configurable: !!ngDevMode,
|
||||
});
|
||||
// Note that we're using the same function as `Directive`, because that's only subset of metadata
|
||||
// that we need to create the ngFactoryDef. We're avoiding using the component metadata
|
||||
// because we'd have to resolve the asynchronous templates.
|
||||
addDirectiveFactoryDef(type, metadata);
|
||||
|
||||
Object.defineProperty(type, NG_COMPONENT_DEF, {
|
||||
get: () => {
|
||||
if (ngComponentDef === null) {
|
||||
const compiler = getCompilerFacade();
|
||||
const meta = getComponentMetadata(compiler, type, metadata);
|
||||
ngComponentDef = compiler.compileComponent(angularCoreEnv, meta.templateUrl, meta.metadata);
|
||||
|
||||
if (componentNeedsResolution(metadata)) {
|
||||
const error = [`Component '${type.name}' is not resolved:`];
|
||||
if (metadata.templateUrl) {
|
||||
error.push(` - templateUrl: ${metadata.templateUrl}`);
|
||||
}
|
||||
if (metadata.styleUrls && metadata.styleUrls.length) {
|
||||
error.push(` - styleUrls: ${JSON.stringify(metadata.styleUrls)}`);
|
||||
}
|
||||
error.push(`Did you run and wait for 'resolveComponentResources()'?`);
|
||||
throw new Error(error.join('\n'));
|
||||
}
|
||||
|
||||
const templateUrl = metadata.templateUrl || `ng:///${type.name}/template.html`;
|
||||
const meta: R3ComponentMetadataFacade = {
|
||||
...directiveMetadata(type, metadata),
|
||||
typeSourceSpan: compiler.createParseSourceSpan('Component', type.name, templateUrl),
|
||||
template: metadata.template || '',
|
||||
preserveWhitespaces: metadata.preserveWhitespaces || false,
|
||||
styles: metadata.styles || EMPTY_ARRAY,
|
||||
animations: metadata.animations,
|
||||
directives: [],
|
||||
changeDetection: metadata.changeDetection,
|
||||
pipes: new Map(),
|
||||
encapsulation: metadata.encapsulation || ViewEncapsulation.Emulated,
|
||||
interpolation: metadata.interpolation,
|
||||
viewProviders: metadata.viewProviders || null,
|
||||
};
|
||||
if (meta.usesInheritance) {
|
||||
addBaseDefToUndecoratedParents(type);
|
||||
}
|
||||
|
||||
ngComponentDef = compiler.compileComponent(angularCoreEnv, templateUrl, meta);
|
||||
|
||||
// When NgModule decorator executed, we enqueued the module definition such that
|
||||
// it would only dequeue and add itself as module scope to all of its declarations,
|
||||
@ -90,45 +110,6 @@ export function compileComponent(type: Type<any>, metadata: Component): void {
|
||||
// Make the property configurable in dev mode to allow overriding in tests
|
||||
configurable: !!ngDevMode,
|
||||
});
|
||||
|
||||
// Add ngInjectableDef so components are reachable through the module injector by default
|
||||
// This is mostly to support injecting components in tests. In real application code,
|
||||
// components should be retrieved through the node injector, so this isn't a problem.
|
||||
compileInjectable(type);
|
||||
}
|
||||
|
||||
function getComponentMetadata(compiler: CompilerFacade, type: Type<any>, metadata: Component) {
|
||||
if (componentNeedsResolution(metadata)) {
|
||||
const error = [`Component '${type.name}' is not resolved:`];
|
||||
if (metadata.templateUrl) {
|
||||
error.push(` - templateUrl: ${metadata.templateUrl}`);
|
||||
}
|
||||
if (metadata.styleUrls && metadata.styleUrls.length) {
|
||||
error.push(` - styleUrls: ${JSON.stringify(metadata.styleUrls)}`);
|
||||
}
|
||||
error.push(`Did you run and wait for 'resolveComponentResources()'?`);
|
||||
throw new Error(error.join('\n'));
|
||||
}
|
||||
|
||||
const templateUrl = metadata.templateUrl || `ng:///${type.name}/template.html`;
|
||||
const meta: R3ComponentMetadataFacade = {
|
||||
...directiveMetadata(type, metadata),
|
||||
typeSourceSpan: compiler.createParseSourceSpan('Component', type.name, templateUrl),
|
||||
template: metadata.template || '',
|
||||
preserveWhitespaces: metadata.preserveWhitespaces || false,
|
||||
styles: metadata.styles || EMPTY_ARRAY,
|
||||
animations: metadata.animations,
|
||||
directives: [],
|
||||
changeDetection: metadata.changeDetection,
|
||||
pipes: new Map(),
|
||||
encapsulation: metadata.encapsulation || ViewEncapsulation.Emulated,
|
||||
interpolation: metadata.interpolation,
|
||||
viewProviders: metadata.viewProviders || null,
|
||||
};
|
||||
if (meta.usesInheritance) {
|
||||
addBaseDefToUndecoratedParents(type);
|
||||
}
|
||||
return {metadata: meta, templateUrl};
|
||||
}
|
||||
|
||||
function hasSelectorScope<T>(component: Type<T>): component is Type<T>&
|
||||
@ -145,23 +126,8 @@ function hasSelectorScope<T>(component: Type<T>): component is Type<T>&
|
||||
*/
|
||||
export function compileDirective(type: Type<any>, directive: Directive | null): void {
|
||||
let ngDirectiveDef: any = null;
|
||||
let ngFactoryDef: any = null;
|
||||
|
||||
Object.defineProperty(type, NG_FACTORY_DEF, {
|
||||
get: () => {
|
||||
if (ngFactoryDef === null) {
|
||||
// `directive` can be null in the case of abstract directives as a base class
|
||||
// that use `@Directive()` with no selector. In that case, pass empty object to the
|
||||
// `directiveMetadata` function instead of null.
|
||||
const meta = getDirectiveMetadata(type, directive || {});
|
||||
ngFactoryDef = getCompilerFacade().compileFactory(
|
||||
angularCoreEnv, `ng:///${type.name}/ngFactory.js`, meta.metadata);
|
||||
}
|
||||
return ngFactoryDef;
|
||||
},
|
||||
// Make the property configurable in dev mode to allow overriding in tests
|
||||
configurable: !!ngDevMode,
|
||||
});
|
||||
addDirectiveFactoryDef(type, directive || {});
|
||||
|
||||
Object.defineProperty(type, NG_DIRECTIVE_DEF, {
|
||||
get: () => {
|
||||
@ -178,11 +144,6 @@ export function compileDirective(type: Type<any>, directive: Directive | null):
|
||||
// Make the property configurable in dev mode to allow overriding in tests
|
||||
configurable: !!ngDevMode,
|
||||
});
|
||||
|
||||
// Add ngInjectableDef so directives are reachable through the module injector by default
|
||||
// This is mostly to support injecting directives in tests. In real application code,
|
||||
// directives should be retrieved through the node injector, so this isn't a problem.
|
||||
compileInjectable(type);
|
||||
}
|
||||
|
||||
function getDirectiveMetadata(type: Type<any>, metadata: Directive) {
|
||||
@ -197,6 +158,24 @@ function getDirectiveMetadata(type: Type<any>, metadata: Directive) {
|
||||
return {metadata: facade, sourceMapUrl};
|
||||
}
|
||||
|
||||
function addDirectiveFactoryDef(type: Type<any>, metadata: Directive | Component) {
|
||||
let ngFactoryDef: any = null;
|
||||
|
||||
Object.defineProperty(type, NG_FACTORY_DEF, {
|
||||
get: () => {
|
||||
if (ngFactoryDef === null) {
|
||||
const meta = getDirectiveMetadata(type, metadata);
|
||||
ngFactoryDef = getCompilerFacade().compileFactory(
|
||||
angularCoreEnv, `ng:///${type.name}/ngFactoryDef.js`,
|
||||
{...meta.metadata, injectFn: 'directiveInject', isPipe: false});
|
||||
}
|
||||
return ngFactoryDef;
|
||||
},
|
||||
// Make the property configurable in dev mode to allow overriding in tests
|
||||
configurable: !!ngDevMode,
|
||||
});
|
||||
}
|
||||
|
||||
export function extendsDirectlyFromObject(type: Type<any>): boolean {
|
||||
return Object.getPrototypeOf(type.prototype) === Object.prototype;
|
||||
}
|
||||
@ -225,7 +204,7 @@ export function directiveMetadata(type: Type<any>, metadata: Directive): R3Direc
|
||||
usesInheritance: !extendsDirectlyFromObject(type),
|
||||
exportAs: extractExportAs(metadata.exportAs),
|
||||
providers: metadata.providers || null,
|
||||
viewQueries: extractQueriesMetadata(type, propMetadata, isViewQuery),
|
||||
viewQueries: extractQueriesMetadata(type, propMetadata, isViewQuery)
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {getCompilerFacade} from '../../compiler/compiler_facade';
|
||||
import {R3PipeMetadataFacade, getCompilerFacade} from '../../compiler/compiler_facade';
|
||||
import {reflectDependencies} from '../../di/jit/util';
|
||||
import {Type} from '../../interface/type';
|
||||
import {Pipe} from '../../metadata/directives';
|
||||
@ -23,7 +23,8 @@ export function compilePipe(type: Type<any>, meta: Pipe): void {
|
||||
if (ngFactoryDef === null) {
|
||||
const metadata = getPipeMetadata(type, meta);
|
||||
ngFactoryDef = getCompilerFacade().compileFactory(
|
||||
angularCoreEnv, `ng:///${metadata.name}/ngFactory.js`, metadata, true);
|
||||
angularCoreEnv, `ng:///${metadata.name}/ngFactoryDef.js`,
|
||||
{...metadata, injectFn: 'directiveInject', isPipe: true});
|
||||
}
|
||||
return ngFactoryDef;
|
||||
},
|
||||
@ -45,7 +46,7 @@ export function compilePipe(type: Type<any>, meta: Pipe): void {
|
||||
});
|
||||
}
|
||||
|
||||
function getPipeMetadata(type: Type<any>, meta: Pipe) {
|
||||
function getPipeMetadata(type: Type<any>, meta: Pipe): R3PipeMetadataFacade {
|
||||
return {
|
||||
type: type,
|
||||
typeArgumentCount: 0,
|
||||
|
Reference in New Issue
Block a user