Parses the `let` parameter of a `for` loop block.
( sourceSpan: ParseSourceSpan, expression: string, span: ParseSourceSpan, loopItemName: string, context: t.Variable[], errors: ParseError[], )
| 494 | |
| 495 | /** Parses the `let` parameter of a `for` loop block. */ |
| 496 | function parseLetParameter( |
| 497 | sourceSpan: ParseSourceSpan, |
| 498 | expression: string, |
| 499 | span: ParseSourceSpan, |
| 500 | loopItemName: string, |
| 501 | context: t.Variable[], |
| 502 | errors: ParseError[], |
| 503 | ): void { |
| 504 | const parts = expression.split(','); |
| 505 | let startSpan = span.start; |
| 506 | for (const part of parts) { |
| 507 | const expressionParts = part.split('='); |
| 508 | const name = expressionParts.length === 2 ? expressionParts[0].trim() : ''; |
| 509 | const variableName = expressionParts.length === 2 ? expressionParts[1].trim() : ''; |
| 510 | |
| 511 | if (name.length === 0 || variableName.length === 0) { |
| 512 | errors.push( |
| 513 | new ParseError( |
| 514 | sourceSpan, |
| 515 | `Invalid @for loop "let" parameter. Parameter should match the pattern "<name> = <variable name>"`, |
| 516 | ), |
| 517 | ); |
| 518 | } else if (!ALLOWED_FOR_LOOP_LET_VARIABLES.has(variableName)) { |
| 519 | errors.push( |
| 520 | new ParseError( |
| 521 | sourceSpan, |
| 522 | `Unknown "let" parameter variable "${variableName}". The allowed variables are: ${Array.from( |
| 523 | ALLOWED_FOR_LOOP_LET_VARIABLES, |
| 524 | ).join(', ')}`, |
| 525 | ), |
| 526 | ); |
| 527 | } else if (name === loopItemName) { |
| 528 | errors.push( |
| 529 | new ParseError( |
| 530 | sourceSpan, |
| 531 | `Invalid @for loop "let" parameter. Variable cannot be called "${loopItemName}"`, |
| 532 | ), |
| 533 | ); |
| 534 | } else if (context.some((v) => v.name === name)) { |
| 535 | errors.push( |
| 536 | new ParseError(sourceSpan, `Duplicate "let" parameter variable "${variableName}"`), |
| 537 | ); |
| 538 | } else { |
| 539 | const [, keyLeadingWhitespace, keyName] = |
| 540 | expressionParts[0].match(CHARACTERS_IN_SURROUNDING_WHITESPACE_PATTERN) ?? []; |
| 541 | const keySpan = |
| 542 | keyLeadingWhitespace !== undefined && expressionParts.length === 2 |
| 543 | ? new ParseSourceSpan( |
| 544 | /* strip leading spaces */ |
| 545 | startSpan.moveBy(keyLeadingWhitespace.length), |
| 546 | /* advance to end of the variable name */ |
| 547 | startSpan.moveBy(keyLeadingWhitespace.length + keyName.length), |
| 548 | ) |
| 549 | : span; |
| 550 | |
| 551 | let valueSpan: ParseSourceSpan | undefined = undefined; |
| 552 | if (expressionParts.length === 2) { |
| 553 | const [, valueLeadingWhitespace, implicit] = |