Enforce more precise type on ListExpression

This commit is contained in:
Fabien Potencier
2026-02-23 13:31:04 +01:00
parent f8fb235f47
commit dcfc419a25
3 changed files with 18 additions and 8 deletions
@@ -17,6 +17,7 @@ use Twig\ExpressionParser\ExpressionParserDescriptionInterface;
use Twig\ExpressionParser\PrefixExpressionParserInterface;
use Twig\Node\Expression\AbstractExpression;
use Twig\Node\Expression\ListExpression;
use Twig\Node\Expression\Variable\AssignContextVariable;
use Twig\Node\Expression\Variable\ContextVariable;
use Twig\Parser;
use Twig\Token;
@@ -36,7 +37,7 @@ final class GroupingExpressionParser extends AbstractExpressionParser implements
return $expr->setExplicitParentheses();
}
return new ListExpression([$expr], $token->getLine());
return new ListExpression([self::toAssignContextVariable($expr)], $token->getLine());
}
// determine if we are parsing an arrow function arguments
@@ -58,7 +59,16 @@ final class GroupingExpressionParser extends AbstractExpressionParser implements
throw new SyntaxError('A list of variables must be followed by an arrow.', $stream->getCurrent()->getLine(), $stream->getSourceContext());
}
return new ListExpression($names, $token->getLine());
return new ListExpression(array_map(self::toAssignContextVariable(...), $names), $token->getLine());
}
private static function toAssignContextVariable(AbstractExpression $expr): AssignContextVariable
{
if (!$expr instanceof ContextVariable) {
throw new SyntaxError('A list must only contain variables.', $expr->getTemplateLine(), $expr->getSourceContext());
}
return $expr instanceof AssignContextVariable ? $expr : new AssignContextVariable($expr->getAttribute('name'), $expr->getTemplateLine());
}
public function getName(): string
@@ -26,14 +26,14 @@ class ArrowFunctionExpression extends AbstractExpression
{
public function __construct(AbstractExpression $expr, Node $names, $lineno)
{
if (!$names instanceof ListExpression && !$names instanceof ContextVariable) {
throw new SyntaxError('The arrow function argument must be a list of variables or a single variable.', $names->getTemplateLine(), $names->getSourceContext());
}
if ($names instanceof ContextVariable) {
$names = new ListExpression([new AssignContextVariable($names->getAttribute('name'), $names->getTemplateLine())], $lineno);
}
if (!$names instanceof ListExpression) {
throw new SyntaxError('The arrow function argument must be a list of variables or a single variable.', $names->getTemplateLine(), $names->getSourceContext());
}
parent::__construct(['expr' => $expr, 'names' => $names], [], $lineno);
}
+2 -2
View File
@@ -12,12 +12,12 @@
namespace Twig\Node\Expression;
use Twig\Compiler;
use Twig\Node\Expression\Variable\ContextVariable;
use Twig\Node\Expression\Variable\AssignContextVariable;
class ListExpression extends AbstractExpression
{
/**
* @param array<ContextVariable> $items
* @param array<AssignContextVariable> $items
*/
public function __construct(array $items, int $lineno)
{