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