MCPcopy Create free account
hub / github.com/angular/angular / compileFactoryFunction

Function compileFactoryFunction

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

Source from the content-addressed store, hash-verified

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