1<?php 2 3/* 4 * This file is part of Twig. 5 * 6 * (c) Fabien Potencier 7 * 8 * For the full copyright and license information, please view the LICENSE 9 * file that was distributed with this source code. 10 */ 11 12namespace Twig\ExpressionParser\Infix; 13 14use Twig\Error\SyntaxError; 15use Twig\ExpressionParser\InfixAssociativity; 16use Twig\Node\Expression\AbstractExpression; 17use Twig\Node\Expression\ArrayExpression; 18use Twig\Node\Expression\Binary\AbstractBinary; 19use Twig\Node\Expression\Binary\ObjectDestructuringSetBinary; 20use Twig\Node\Expression\Binary\SequenceDestructuringSetBinary; 21use Twig\Node\Expression\Binary\SetBinary; 22use Twig\Node\Expression\Variable\ContextVariable; 23use Twig\Parser; 24use Twig\Token; 25 26/** 27 * @internal 28 */ 29class AssignmentExpressionParser extends BinaryOperatorExpressionParser 30{ 31 public function __construct( 32 string $name, 33 ) { 34 parent::__construct(SetBinary::class, $name, 0, InfixAssociativity::Right); 35 } 36 37 /** 38 * @return AbstractBinary 39 */ 40 public function parse(Parser $parser, AbstractExpression $left, Token $token): AbstractExpression 41 { 42 if (!$left instanceof ContextVariable && !$left instanceof ArrayExpression) { 43 throw new SyntaxError(\sprintf('Cannot assign to "%s", only variables can be assigned.', $left::class), $token->getLine(), $parser->getStream()->getSourceContext()); 44 } 45 $right = $parser->parseExpression(InfixAssociativity::Left === $this->getAssociativity() ? $this->getPrecedence() + 1 : $this->getPrecedence()); 46 $right = match ($this->getName()) { 47 '=' => $right, 48 default => throw new \LogicException(\sprintf('Unknown operator: %s.', $this->getName())), 49 }; 50 51 if ($left instanceof ArrayExpression) { 52 if ($left->isSequence()) { 53 return new SequenceDestructuringSetBinary($left, $right, $token->getLine()); 54 } 55 56 return new ObjectDestructuringSetBinary($left, $right, $token->getLine()); 57 } 58 59 return new SetBinary($left, $right, $token->getLine()); 60 } 61 62 public function getDescription(): string 63 { 64 return 'Assignment operator'; 65 } 66} 67