MCPcopy Index your code
hub / github.com/angular/angular / compileFactoryFunction

Function compileFactoryFunction

packages/compiler/src/render3/r3_factory.ts:106–220  ·  view source on GitHub ↗
(meta: R3FactoryMetadata)

Source from the content-addressed store, hash-verified

104 * Construct a factory function expression for the given `R3FactoryMetadata`.
105 */
106export function compileFactoryFunction(meta: R3FactoryMetadata): R3CompiledExpression {
107 const t = o.variable('__ngFactoryType__');
108 let baseFactoryVar: o.ReadVarExpr | null = null;
109
110 // The type to instantiate via constructor invocation. If there is no delegated factory, meaning
111 // this type is always created by constructor invocation, then this is the type-to-create
112 // parameter provided by the user (t) if specified, or the current type if not. If there is a
113 // delegated factory (which is used to create the current type) then this is only the type-to-
114 // create parameter (t).
115 const typeForCtor = !isDelegatedFactoryMetadata(meta)
116 ? new o.BinaryOperatorExpr(o.BinaryOperator.Or, t, meta.type.value)
117 : t;
118
119 let ctorExpr: o.Expression | null = null;
120
121 // If the factory has invalid dependencies (e.g. trying to inject an interface), we normally mark
122 // the `deps` as invalid so we can emit an invalid factory. In some environments we may not
123 // be able to determine if the dependency is invalid, because that depends on information in
124 // other files. To ensure that cases like that still compile, we need to add a `@ts-ignore`
125 // comment which allows the code to compile and then error at runtime. Note that it's important
126 // to put the comment on a statement, because it includes a new line which may break `return`
127 // statements if the comment is set on the expression.
128 const factoryComments =
129 meta.deps !== null && meta.deps !== 'invalid' && meta.deps.length > 0
130 ? [tsIgnoreComment()]
131 : undefined;
132
133 if (meta.deps !== null) {
134 // There is a constructor (either explicitly or implicitly defined).
135 if (meta.deps !== 'invalid') {
136 ctorExpr = new o.InstantiateExpr(typeForCtor, injectDependencies(meta.deps, meta.target));
137 }
138 } else {
139 // There is no constructor, use the base class' factory to construct typeForCtor.
140 baseFactoryVar = o.variable(`ɵ${meta.name}_BaseFactory`);
141 ctorExpr = baseFactoryVar.callFn([typeForCtor]);
142 }
143
144 const body: o.Statement[] = [];
145 let retExpr: o.Expression | null = null;
146
147 function makeConditionalFactory(nonCtorExpr: o.Expression): o.ReadVarExpr {
148 const r = o.variable('__ngConditionalFactory__');
149 body.push(new o.DeclareVarStmt(r.name, o.NULL_EXPR, o.DYNAMIC_TYPE));
150 const ctorStmt =
151 ctorExpr !== null
152 ? r.set(ctorExpr).toStmt(factoryComments)
153 : o.importExpr(R3.invalidFactory).callFn([]).toStmt();
154 // Always add a `ts-ignore` on the alternate factory.
155 body.push(o.ifStmt(t, [ctorStmt], [r.set(nonCtorExpr).toStmt([tsIgnoreComment()])]));
156 return r;
157 }
158
159 if (isDelegatedFactoryMetadata(meta)) {
160 // This type is created with a delegated factory. If a type parameter is not specified, call
161 // the factory instead.
162 const delegateArgs = injectDependencies(meta.delegateDeps, meta.target);
163 // Either call `new delegate(...)` or `delegate(...)` depending on meta.delegateType.

Callers 5

compileFactoryMethod · 0.90
compileInjectableFunction · 0.90
compileNgFactoryDefFieldFunction · 0.90

Calls 9

tsIgnoreCommentFunction · 0.90
injectDependenciesFunction · 0.85
makeConditionalFactoryFunction · 0.85
createFactoryTypeFunction · 0.85
setMethod · 0.65
pushMethod · 0.45
fnMethod · 0.45

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…