refactor(compiler): widen type of resolver function (#54908)

Updates the type of the resolver function to be any `Expression` since JIT may receive a function reference rather than a `ArrowFunctionExpr`.

PR Close #54908
This commit is contained in:
Kristiyan Kostadinov 2024-03-13 12:00:37 +01:00 committed by Dylan Hunn
parent 36de5c3434
commit 102688bf83
8 changed files with 18 additions and 15 deletions

View file

@ -259,7 +259,7 @@ export class PartialComponentLinkerVersion1<TStatement, TExpression> implements
private createR3ComponentDeferMetadata(boundTarget: BoundTarget<any>): R3ComponentDeferMetadata {
const deferredBlocks = boundTarget.getDeferBlocks();
const blocks = new Map<TmplAstDeferredBlock, o.ArrowFunctionExpr|null>();
const blocks = new Map<TmplAstDeferredBlock, o.Expression|null>();
for (const block of deferredBlocks) {
// TODO: leaving `deps` empty for now, to be implemented as one of the next steps.

View file

@ -1489,7 +1489,7 @@ export class ComponentDecoratorHandler implements
'Internal error: deferPerBlockDependencies must be present when compiling in PerBlock mode');
}
const blocks = new Map<TmplAstDeferredBlock, o.ArrowFunctionExpr|null>();
const blocks = new Map<TmplAstDeferredBlock, o.Expression|null>();
for (const [block, dependencies] of perBlockDeps) {
blocks.set(
block,

View file

@ -198,9 +198,8 @@ export class ConstantPool {
// TODO: useUniqueName(false) is necessary for naming compatibility with
// TemplateDefinitionBuilder, but should be removed once Template Pipeline is the default.
getSharedFunctionReference(
fn: o.FunctionExpr|o.ArrowFunctionExpr, prefix: string,
useUniqueName: boolean = true): o.Expression {
getSharedFunctionReference(fn: o.Expression, prefix: string, useUniqueName: boolean = true):
o.Expression {
const isArrow = fn instanceof o.ArrowFunctionExpr;
for (const current of this.statements) {
@ -212,14 +211,18 @@ export class ConstantPool {
// Function declarations are saved as function statements
// so we compare them directly to the passed-in function.
if (!isArrow && current instanceof o.DeclareFunctionStmt && fn.isEquivalent(current)) {
if (!isArrow && current instanceof o.DeclareFunctionStmt && fn instanceof o.FunctionExpr &&
fn.isEquivalent(current)) {
return o.variable(current.name);
}
}
// Otherwise declare the function.
const name = useUniqueName ? this.uniqueName(prefix) : prefix;
this.statements.push(fn.toDeclStmt(name, o.StmtModifier.Final));
this.statements.push(
fn instanceof o.FunctionExpr ?
fn.toDeclStmt(name, o.StmtModifier.Final) :
new o.DeclareVarStmt(name, fn, o.INFERRED_TYPE, o.StmtModifier.Final, fn.sourceSpan));
return o.variable(name);
}

View file

@ -11,7 +11,7 @@ import {ConstantPool} from './constant_pool';
import {ChangeDetectionStrategy, HostBinding, HostListener, Input, Output, ViewEncapsulation} from './core';
import {compileInjectable} from './injectable_compiler_2';
import {DEFAULT_INTERPOLATION_CONFIG, InterpolationConfig} from './ml_parser/defaults';
import {ArrowFunctionExpr, DeclareVarStmt, Expression, literal, LiteralExpr, Statement, StmtModifier, WrappedNodeExpr} from './output/output_ast';
import {DeclareVarStmt, Expression, literal, LiteralExpr, Statement, StmtModifier, WrappedNodeExpr} from './output/output_ast';
import {JitEvaluator} from './output/output_jit';
import {ParseError, ParseSourceSpan, r3JitTypeSourceSpan} from './parse_util';
import {DeferredBlock} from './render3/r3_ast';
@ -624,7 +624,7 @@ function createR3DependencyMetadata(
function createR3ComponentDeferMetadata(boundTarget: BoundTarget<any>): R3ComponentDeferMetadata {
const deferredBlocks = boundTarget.getDeferBlocks();
const blocks = new Map<DeferredBlock, ArrowFunctionExpr|null>();
const blocks = new Map<DeferredBlock, Expression|null>();
for (const block of deferredBlocks) {
// TODO: leaving dependency function empty in JIT mode for now,

View file

@ -296,10 +296,10 @@ export interface R3ComponentMetadata<DeclarationT extends R3TemplateDependency>
*/
export type R3ComponentDeferMetadata = {
mode: DeferBlockDepsEmitMode.PerBlock,
blocks: Map<t.DeferredBlock, o.ArrowFunctionExpr|null>,
blocks: Map<t.DeferredBlock, o.Expression|null>,
}|{
mode: DeferBlockDepsEmitMode.PerComponent,
dependenciesFn: o.ArrowFunctionExpr | null,
dependenciesFn: o.Expression | null,
};
/**

View file

@ -180,7 +180,7 @@ export function compileComponentFromMetadata(
meta.defer.dependenciesFn !== null) {
const fnName = `${templateTypeName}_DeferFn`;
constantPool.statements.push(
meta.defer.dependenciesFn.toDeclStmt(fnName, o.StmtModifier.Final));
new o.DeclareVarStmt(fnName, meta.defer.dependenciesFn, undefined, o.StmtModifier.Final));
allDeferrableDepsFn = o.variable(fnName);
}

View file

@ -836,7 +836,7 @@ export interface DeferOp extends Op<CreateOp>, ConsumesSlotOpTrait {
* per deferred block or one for the entire template. This field contains the function that
* belongs specifically to the current deferred block.
*/
ownResolverFn: o.ArrowFunctionExpr|null;
ownResolverFn: o.Expression|null;
/**
* After processing, the resolver function for the defer deps will be extracted to the constant
@ -848,7 +848,7 @@ export interface DeferOp extends Op<CreateOp>, ConsumesSlotOpTrait {
}
export function createDeferOp(
xref: XrefId, main: XrefId, mainSlot: SlotHandle, ownResolverFn: o.ArrowFunctionExpr|null,
xref: XrefId, main: XrefId, mainSlot: SlotHandle, ownResolverFn: o.Expression|null,
resolverFn: o.Expression|null, sourceSpan: ParseSourceSpan): DeferOp {
return {
kind: OpKind.Defer,

View file

@ -447,7 +447,7 @@ function ingestDeferView(
}
function ingestDeferBlock(unit: ViewCompilationUnit, deferBlock: t.DeferredBlock): void {
let ownResolverFn: o.ArrowFunctionExpr|null = null;
let ownResolverFn: o.Expression|null = null;
if (unit.job.deferMeta.mode === DeferBlockDepsEmitMode.PerBlock) {
if (!unit.job.deferMeta.blocks.has(deferBlock)) {