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

Function ingestForBlock

packages/compiler/src/template/pipeline/src/ingest.ts:1022–1123  ·  view source on GitHub ↗

* Ingest an `@for` block into the given `ViewCompilation`.

(unit: ViewCompilationUnit, forBlock: t.ForLoopBlock)

Source from the content-addressed store, hash-verified

1020 * Ingest an `@for` block into the given `ViewCompilation`.
1021 */
1022function ingestForBlock(unit: ViewCompilationUnit, forBlock: t.ForLoopBlock): void {
1023 const repeaterView = unit.job.allocateView(unit.xref);
1024
1025 // We copy TemplateDefinitionBuilder's scheme of creating names for `$count` and `$index`
1026 // that are suffixed with special information, to disambiguate which level of nested loop
1027 // the below aliases refer to.
1028 // TODO: We should refactor Template Pipeline's variable phases to gracefully handle
1029 // shadowing, and arbitrarily many levels of variables depending on each other.
1030 const indexName = `ɵ$index_${repeaterView.xref}`;
1031 const countName = `ɵ$count_${repeaterView.xref}`;
1032 const indexVarNames = new Set<string>();
1033
1034 // Set all the context variables and aliases available in the repeater.
1035 repeaterView.contextVariables.set(forBlock.item.name, forBlock.item.value);
1036
1037 for (const variable of forBlock.contextVariables) {
1038 if (variable.value === '$index') {
1039 indexVarNames.add(variable.name);
1040 }
1041 if (variable.name === '$index') {
1042 repeaterView.contextVariables.set('$index', variable.value).set(indexName, variable.value);
1043 } else if (variable.name === '$count') {
1044 repeaterView.contextVariables.set('$count', variable.value).set(countName, variable.value);
1045 } else {
1046 repeaterView.aliases.add({
1047 kind: ir.SemanticVariableKind.Alias,
1048 name: null,
1049 identifier: variable.name,
1050 expression: getComputedForLoopVariableExpression(variable, indexName, countName),
1051 });
1052 }
1053 }
1054
1055 let track: o.Expression;
1056
1057 if (forBlock.trackBy === null) {
1058 // `@for` without a `track` is invalid and it produces a parser error.
1059 // Put a placeholder here so we don't need to account for it throughout the pipeline.
1060 track = o.variable('$index');
1061 } else {
1062 track = convertAst(
1063 forBlock.trackBy,
1064 unit.job,
1065 convertSourceSpan(forBlock.trackBy.span, forBlock.sourceSpan),
1066 );
1067 }
1068
1069 ingestNodes(repeaterView, forBlock.children);
1070
1071 let emptyView: ViewCompilationUnit | null = null;
1072 let emptyTagName: string | null = null;
1073 if (forBlock.empty !== null) {
1074 emptyView = unit.job.allocateView(unit.xref);
1075 ingestNodes(emptyView, forBlock.empty.children);
1076 emptyTagName = ingestControlFlowInsertionPoint(unit, emptyView.xref, forBlock.empty);
1077 }
1078
1079 const varNames: ir.RepeaterVarNames = {

Callers 1

ingestNodesFunction · 0.85

Calls 10

convertAstFunction · 0.85
convertSourceSpanFunction · 0.85
ingestNodesFunction · 0.85
ErrorInterface · 0.85
allocateViewMethod · 0.80
setMethod · 0.65
addMethod · 0.65
pushMethod · 0.45

Tested by

no test coverage detected