Skip to content

Commit a56726c

Browse files
alxhubdylhunn
authored andcommitted
refactor(compiler): transform all expressions in the template pipeline (#50118)
Previously the helper operations for transforming expressions in the template pipeline would only operate against `ir.Expression`s. This commit changes them to process `o.Expression`s instead, paving the way to use them for transformations of native expressions in addition to IR expressions. PR Close #50118
1 parent 1b37dcd commit a56726c

6 files changed

Lines changed: 38 additions & 7 deletions

File tree

packages/compiler/src/template/pipeline/ir/src/expression.ts

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,15 @@ export type Expression =
2424
ResetViewExpr|ReadVariableExpr|PureFunctionExpr|PureFunctionParameterExpr;
2525

2626
/**
27-
* Transformer type which converts IR expressions into general `o.Expression`s (which may be an
27+
* Transformer type which converts expressions into general `o.Expression`s (which may be an
2828
* identity transformation).
2929
*/
30-
export type ExpressionTransform = (expr: Expression, flags: VisitorContextFlag) => o.Expression;
30+
export type ExpressionTransform = (expr: o.Expression, flags: VisitorContextFlag) => o.Expression;
3131

3232
/**
3333
* Check whether a given `o.Expression` is a logical IR expression type.
3434
*/
35-
export function isIrExpression(expr: o.Expression): boolean {
35+
export function isIrExpression(expr: o.Expression): expr is Expression {
3636
return expr instanceof ExpressionBase;
3737
}
3838

@@ -363,7 +363,7 @@ export class PureFunctionParameterExpr extends ExpressionBase {
363363
* Visits all `Expression`s in the AST of `op` with the `visitor` function.
364364
*/
365365
export function visitExpressionsInOp(
366-
op: CreateOp|UpdateOp, visitor: (expr: Expression, flags: VisitorContextFlag) => void): void {
366+
op: CreateOp|UpdateOp, visitor: (expr: o.Expression, flags: VisitorContextFlag) => void): void {
367367
transformExpressionsInOp(op, (expr, flags) => {
368368
visitor(expr, flags);
369369
return expr;
@@ -429,7 +429,6 @@ export function transformExpressionsInExpression(
429429
expr: o.Expression, transform: ExpressionTransform, flags: VisitorContextFlag): o.Expression {
430430
if (expr instanceof ExpressionBase) {
431431
expr.transformInternalExpressions(transform, flags);
432-
return transform(expr as Expression, flags);
433432
} else if (expr instanceof o.BinaryOperatorExpr) {
434433
expr.lhs = transformExpressionsInExpression(expr.lhs, transform, flags);
435434
expr.rhs = transformExpressionsInExpression(expr.rhs, transform, flags);
@@ -459,7 +458,7 @@ export function transformExpressionsInExpression(
459458
} else {
460459
throw new Error(`Unhandled expression kind: ${expr.constructor.name}`);
461460
}
462-
return expr;
461+
return transform(expr, flags);
463462
}
464463

465464
/**

packages/compiler/src/template/pipeline/src/phases/next_context_merging.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@ function mergeNextContextsInOps(ops: ir.OpList<ir.UpdateOp>): void {
4949
for (let candidate = op.next!; candidate.kind !== ir.OpKind.ListEnd && tryToMerge;
5050
candidate = candidate.next!) {
5151
ir.visitExpressionsInOp(candidate, (expr, flags) => {
52+
if (!ir.isIrExpression(expr)) {
53+
return expr;
54+
}
55+
5256
if (!tryToMerge) {
5357
// Either we've already merged, or failed to merge.
5458
return;

packages/compiler/src/template/pipeline/src/phases/reify.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,11 @@ function reifyUpdateOperations(_view: ViewCompilation, ops: ir.OpList<ir.UpdateO
140140
}
141141
}
142142

143-
function reifyIrExpression(expr: ir.Expression): o.Expression {
143+
function reifyIrExpression(expr: o.Expression): o.Expression {
144+
if (!ir.isIrExpression(expr)) {
145+
return expr;
146+
}
147+
144148
switch (expr.kind) {
145149
case ir.ExpressionKind.NextContext:
146150
return ng.nextContext(expr.steps);

packages/compiler/src/template/pipeline/src/phases/slot_allocation.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,10 @@ export function phaseSlotAllocation(cpl: ComponentCompilation): void {
7777

7878
// Process all `ir.Expression`s within this view, and look for `usesSlotIndexExprTrait`.
7979
ir.visitExpressionsInOp(op, expr => {
80+
if (!ir.isIrExpression(expr)) {
81+
return;
82+
}
83+
8084
if (!ir.hasUsesSlotIndexTrait(expr) || expr.slot !== null) {
8185
return;
8286
}

packages/compiler/src/template/pipeline/src/phases/var_counting.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ export function phaseVarCounting(cpl: ComponentCompilation): void {
2323
}
2424

2525
ir.visitExpressionsInOp(op, expr => {
26+
if (!ir.isIrExpression(expr)) {
27+
return;
28+
}
29+
2630
// Some expressions require knowledge of the number of variable slots consumed.
2731
if (ir.hasUsesVarOffsetTrait(expr)) {
2832
expr.varOffset = varCount;

packages/compiler/src/template/pipeline/src/phases/variable_optimization.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,10 @@ function collectOpInfo(op: ir.CreateOp|ir.UpdateOp): OpInfo {
281281
let fences = Fence.None;
282282
const variablesUsed = new Set<ir.XrefId>();
283283
ir.visitExpressionsInOp(op, expr => {
284+
if (!ir.isIrExpression(expr)) {
285+
return;
286+
}
287+
284288
switch (expr.kind) {
285289
case ir.ExpressionKind.ReadVariable:
286290
variablesUsed.add(expr.xref);
@@ -300,6 +304,10 @@ function countVariableUsages(
300304
op: ir.CreateOp|ir.UpdateOp, varUsages: Map<ir.XrefId, number>,
301305
varRemoteUsage: Set<ir.XrefId>): void {
302306
ir.visitExpressionsInOp(op, (expr, flags) => {
307+
if (!ir.isIrExpression(expr)) {
308+
return;
309+
}
310+
303311
if (expr.kind !== ir.ExpressionKind.ReadVariable) {
304312
return;
305313
}
@@ -323,6 +331,10 @@ function countVariableUsages(
323331
function uncountVariableUsages(
324332
op: ir.CreateOp|ir.UpdateOp, varUsages: Map<ir.XrefId, number>): void {
325333
ir.visitExpressionsInOp(op, expr => {
334+
if (!ir.isIrExpression(expr)) {
335+
return;
336+
}
337+
326338
if (expr.kind !== ir.ExpressionKind.ReadVariable) {
327339
return;
328340
}
@@ -377,6 +389,10 @@ function tryInlineVariableInitializer(
377389
let inliningAllowed = true;
378390

379391
ir.transformExpressionsInOp(target, (expr, flags) => {
392+
if (!ir.isIrExpression(expr)) {
393+
return expr;
394+
}
395+
380396
if (inlined || !inliningAllowed) {
381397
// Either the inlining has already succeeded, or we've passed a fence that disallows inlining
382398
// at this point, so don't try.

0 commit comments

Comments
 (0)