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

Function createForLoop

packages/compiler/src/render3/r3_control_flow.ts:145–215  ·  view source on GitHub ↗
(
  ast: html.Block,
  connectedBlocks: html.Block[],
  visitor: html.Visitor,
  bindingParser: BindingParser,
)

Source from the content-addressed store, hash-verified

143
144/** Creates a `for` loop block from an HTML AST node. */
145export function createForLoop(
146 ast: html.Block,
147 connectedBlocks: html.Block[],
148 visitor: html.Visitor,
149 bindingParser: BindingParser,
150): {node: t.ForLoopBlock | null; errors: ParseError[]} {
151 const errors: ParseError[] = [];
152 const params = parseForLoopParameters(ast, errors, bindingParser);
153 let node: t.ForLoopBlock | null = null;
154 let empty: t.ForLoopBlockEmpty | null = null;
155
156 for (const block of connectedBlocks) {
157 if (block.name === 'empty') {
158 if (empty !== null) {
159 errors.push(new ParseError(block.sourceSpan, '@for loop can only have one @empty block'));
160 } else if (block.parameters.length > 0) {
161 errors.push(new ParseError(block.sourceSpan, '@empty block cannot have parameters'));
162 } else {
163 empty = new t.ForLoopBlockEmpty(
164 html.visitAll(visitor, block.children, block.children),
165 block.sourceSpan,
166 block.startSourceSpan,
167 block.endSourceSpan,
168 block.nameSpan,
169 block.i18n,
170 );
171 }
172 } else {
173 errors.push(new ParseError(block.sourceSpan, `Unrecognized @for loop block "${block.name}"`));
174 }
175 }
176
177 if (params !== null) {
178 // The `for` block has a main span that includes the `empty` branch. For only the span of the
179 // main `for` body, use `mainSourceSpan`.
180 const endSpan = empty?.endSourceSpan ?? ast.endSourceSpan;
181 const sourceSpan = new ParseSourceSpan(
182 ast.sourceSpan.start,
183 endSpan?.end ?? ast.sourceSpan.end,
184 );
185 let trackExpression: ASTWithSource | null;
186 let trackKeywordSpan: ParseSourceSpan | null;
187
188 if (params.trackBy === null) {
189 trackExpression = trackKeywordSpan = null;
190 errors.push(new ParseError(ast.startSourceSpan, '@for loop must have a "track" expression'));
191 } else {
192 trackExpression = params.trackBy.expression;
193 trackKeywordSpan = params.trackBy.keywordSpan;
194 validateTrackByExpression(params.trackBy.expression, params.trackBy.keywordSpan, errors);
195 }
196
197 node = new t.ForLoopBlock(
198 params.itemName,
199 params.expression,
200 trackExpression,
201 trackKeywordSpan,
202 params.context,

Callers 1

visitBlockMethod · 0.90

Calls 4

parseForLoopParametersFunction · 0.85
pushMethod · 0.45
visitAllMethod · 0.45

Tested by

no test coverage detected