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

Function ingestForBlock

packages/compiler/src/template/pipeline/src/ingest.ts:906–1007  ·  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

904 * Ingest an `@for` block into the given `ViewCompilation`.
905 */
906function ingestForBlock(unit: ViewCompilationUnit, forBlock: t.ForLoopBlock): void {
907 const repeaterView = unit.job.allocateView(unit.xref);
908
909 // We copy TemplateDefinitionBuilder's scheme of creating names for `$count` and `$index`
910 // that are suffixed with special information, to disambiguate which level of nested loop
911 // the below aliases refer to.
912 // TODO: We should refactor Template Pipeline's variable phases to gracefully handle
913 // shadowing, and arbitrarily many levels of variables depending on each other.
914 const indexName = `ɵ$index_${repeaterView.xref}`;
915 const countName = `ɵ$count_${repeaterView.xref}`;
916 const indexVarNames = new Set<string>();
917
918 // Set all the context variables and aliases available in the repeater.
919 repeaterView.contextVariables.set(forBlock.item.name, forBlock.item.value);
920
921 for (const variable of forBlock.contextVariables) {
922 if (variable.value === '$index') {
923 indexVarNames.add(variable.name);
924 }
925 if (variable.name === '$index') {
926 repeaterView.contextVariables.set('$index', variable.value).set(indexName, variable.value);
927 } else if (variable.name === '$count') {
928 repeaterView.contextVariables.set('$count', variable.value).set(countName, variable.value);
929 } else {
930 repeaterView.aliases.add({
931 kind: ir.SemanticVariableKind.Alias,
932 name: null,
933 identifier: variable.name,
934 expression: getComputedForLoopVariableExpression(variable, indexName, countName),
935 });
936 }
937 }
938
939 let track: o.Expression;
940
941 if (forBlock.trackBy === null) {
942 // `@for` without a `track` is invalid and it produces a parser error.
943 // Put a placeholder here so we don't need to account for it throughout the pipeline.
944 track = o.variable('$index');
945 } else {
946 track = convertAst(
947 forBlock.trackBy,
948 unit.job,
949 convertSourceSpan(forBlock.trackBy.span, forBlock.sourceSpan),
950 );
951 }
952
953 ingestNodes(repeaterView, forBlock.children);
954
955 let emptyView: ViewCompilationUnit | null = null;
956 let emptyTagName: string | null = null;
957 if (forBlock.empty !== null) {
958 emptyView = unit.job.allocateView(unit.xref);
959 ingestNodes(emptyView, forBlock.empty.children);
960 emptyTagName = ingestControlFlowInsertionPoint(unit, emptyView.xref, forBlock.empty);
961 }
962
963 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