From 91dbcb5eab3c60638a3a41ea6dc667f2c19c7ab3 Mon Sep 17 00:00:00 2001 From: Miles Malerba Date: Fri, 3 Nov 2023 13:47:06 -0700 Subject: [PATCH] refactor(compiler): Add more comments for i18n template pipeline phases (#52503) Adds some additional comments about the i18n termplate pipeline phases to more clearly document how they work. PR Close #52503 --- .../pipeline/src/phases/create_i18n_contexts.ts | 12 +++++++++++- .../src/phases/create_i18n_icu_expressions.ts | 1 + .../pipeline/src/phases/i18n_text_extraction.ts | 2 ++ .../pipeline/src/phases/merge_i18n_contexts.ts | 2 +- .../pipeline/src/phases/propagate_i18n_blocks.ts | 4 +++- 5 files changed, 18 insertions(+), 3 deletions(-) diff --git a/packages/compiler/src/template/pipeline/src/phases/create_i18n_contexts.ts b/packages/compiler/src/template/pipeline/src/phases/create_i18n_contexts.ts index 798e40c137f..15b6bcf130d 100644 --- a/packages/compiler/src/template/pipeline/src/phases/create_i18n_contexts.ts +++ b/packages/compiler/src/template/pipeline/src/phases/create_i18n_contexts.ts @@ -10,7 +10,14 @@ import * as ir from '../../ir'; import {CompilationJob} from '../compilation'; /** - * Create i18n context ops that will be used to generate the final i18n messages. + * Create one helper context op per i18n block (including generate descending blocks). + * + * Also, if an ICU exists inside an i18n block that also contains other localizable content (such as + * string), create an additional helper context op for the ICU. + * + * These context ops are later used for generating i18n messages. (Although we generate at least one + * context op per nested view, we will collect them up the tree later, to generate a top-level + * message.) */ export function createI18nContexts(job: CompilationJob) { let currentI18nOp: ir.I18nStartOp|null = null; @@ -35,10 +42,13 @@ export function createI18nContexts(job: CompilationJob) { throw Error('Unexpected ICU outside of an i18n block.'); } if (op.message.id !== currentI18nOp.message.id) { + // There was an enclosing i18n block around this ICU somewhere. xref = job.allocateXrefId(); unit.create.push(ir.createI18nContextOp(xref, currentI18nOp.xref, op.message, null!)); op.context = xref; } else { + // The i18n block was generated because of this ICU, OR it was explicit, but the ICU is + // the only localizable content inside of it. op.context = currentI18nOp.context; } break; diff --git a/packages/compiler/src/template/pipeline/src/phases/create_i18n_icu_expressions.ts b/packages/compiler/src/template/pipeline/src/phases/create_i18n_icu_expressions.ts index 0888ea32978..cc62b17ab0b 100644 --- a/packages/compiler/src/template/pipeline/src/phases/create_i18n_icu_expressions.ts +++ b/packages/compiler/src/template/pipeline/src/phases/create_i18n_icu_expressions.ts @@ -51,6 +51,7 @@ export function createI18nIcuExpressions(job: CompilationJob) { ir.createI18nExpressionOp( i18nContext.xref, i18nBlock.xref, i18nBlock.handle, new ir.LexicalReadExpr(icuOp.icu.expression), icuOp.icu.expressionPlaceholder, + // ICU-based i18n Expressions are resolved during post-processing. ir.I18nParamResolutionTime.Postproccessing, null!)); break; } diff --git a/packages/compiler/src/template/pipeline/src/phases/i18n_text_extraction.ts b/packages/compiler/src/template/pipeline/src/phases/i18n_text_extraction.ts index a472d59efce..439b8df35b3 100644 --- a/packages/compiler/src/template/pipeline/src/phases/i18n_text_extraction.ts +++ b/packages/compiler/src/template/pipeline/src/phases/i18n_text_extraction.ts @@ -52,6 +52,8 @@ export function extractI18nText(job: CompilationJob): void { for (let i = 0; i < op.interpolation.expressions.length; i++) { const expr = op.interpolation.expressions[i]; const placeholder = op.i18nPlaceholders[i]; + // For now, this i18nExpression depends on the slot context of the enclosing i18n block. + // Later, we will modify this, and advance to a different point. ops.push(ir.createI18nExpressionOp( i18nOp.context!, i18nOp.xref, i18nOp.handle, expr, placeholder.name, ir.I18nParamResolutionTime.Creation, expr.sourceSpan ?? op.sourceSpan)); diff --git a/packages/compiler/src/template/pipeline/src/phases/merge_i18n_contexts.ts b/packages/compiler/src/template/pipeline/src/phases/merge_i18n_contexts.ts index 66b3976498f..63684080f2d 100644 --- a/packages/compiler/src/template/pipeline/src/phases/merge_i18n_contexts.ts +++ b/packages/compiler/src/template/pipeline/src/phases/merge_i18n_contexts.ts @@ -10,7 +10,7 @@ import * as ir from '../../ir'; import {ComponentCompilationJob} from '../compilation'; /** - * Merge i18n contexts for child i18n blocks into their parent context. + * Merge i18n contexts for child i18n blocks into their ancestor root contexts. */ export function mergeI18nContexts(job: ComponentCompilationJob) { // Record all of the i18n and extracted message ops for use later. diff --git a/packages/compiler/src/template/pipeline/src/phases/propagate_i18n_blocks.ts b/packages/compiler/src/template/pipeline/src/phases/propagate_i18n_blocks.ts index 71d75ccff5f..90f24b8397f 100644 --- a/packages/compiler/src/template/pipeline/src/phases/propagate_i18n_blocks.ts +++ b/packages/compiler/src/template/pipeline/src/phases/propagate_i18n_blocks.ts @@ -12,7 +12,9 @@ import {ComponentCompilationJob, ViewCompilationUnit} from '../compilation'; /** * Propagate i18n blocks down through child templates that act as placeholders in the root i18n - * message. + * message. Specifically, perform an in-order traversal of all the views, and add i18nStart/i18nEnd + * op pairs into descending views. Also, assign an increasing sub-template index to each + * descending view. */ export function propagateI18nBlocks(job: ComponentCompilationJob): void { propagateI18nBlocksToTemplates(job.root, 0);