mirror of
https://github.com/twigphp/Twig.git
synced 2026-08-31 20:47:28 +00:00
Fix repeated object destructuring evaluation
This commit is contained in:
@@ -4,6 +4,8 @@
|
||||
* Fix `html_attr` JSON encoding a `Stringable` value in a `data-*` attribute instead of using its string representation
|
||||
* Add documentation comments to attach metadata to nodes (experimental)
|
||||
* Fix destructuring patterns with no variables, including sequences containing only empty slots, triggering a PHP fatal error instead of a `SyntaxError`
|
||||
* Fix an empty destructuring pattern triggering a PHP fatal error instead of a `SyntaxError`
|
||||
* Fix object and mapping destructuring evaluating the right-hand expression more than once
|
||||
* Fix sequence destructuring of iterators throwing a `TypeError`
|
||||
* Add `TempestMarkdown` to use `tempest/markdown` as the `markdown_to_html` converter
|
||||
* Fix imported macros not resolving their own template-level macro imports
|
||||
|
||||
@@ -53,6 +53,7 @@ class ObjectDestructuringSetBinary extends AbstractBinary
|
||||
public function compile(Compiler $compiler): void
|
||||
{
|
||||
$compiler->addDebugInfo($this);
|
||||
$var = '$'.$compiler->getVarName();
|
||||
$compiler->raw('[');
|
||||
foreach ($this->mappings as $i => $mapping) {
|
||||
if ($i) {
|
||||
@@ -65,7 +66,13 @@ class ObjectDestructuringSetBinary extends AbstractBinary
|
||||
if ($i) {
|
||||
$compiler->raw(', ');
|
||||
}
|
||||
$compiler->raw('CoreExtension::getAttribute($this->env, $this->source, ')->subcompile($this->getNode('right'))->raw(', ')->repr($mapping['property'])->raw(', [], \\Twig\\Template::ANY_CALL, false, false, ')->repr($compiler->getEnvironment()->hasExtension(SandboxExtension::class))->raw(', ')->repr($this->getNode('right')->getTemplateLine())->raw(')');
|
||||
$compiler->raw('CoreExtension::getAttribute($this->env, $this->source, ');
|
||||
if (0 === $i) {
|
||||
$compiler->raw('('.$var.' = ')->subcompile($this->getNode('right'))->raw(')');
|
||||
} else {
|
||||
$compiler->raw($var);
|
||||
}
|
||||
$compiler->raw(', ')->repr($mapping['property'])->raw(', [], \\Twig\\Template::ANY_CALL, false, false, ')->repr($compiler->getEnvironment()->hasExtension(SandboxExtension::class))->raw(', ')->repr($this->getNode('right')->getTemplateLine())->raw(')');
|
||||
}
|
||||
$compiler->raw(']');
|
||||
}
|
||||
|
||||
@@ -303,6 +303,20 @@ class ExpressionParserTest extends TestCase
|
||||
$this->assertSame('user_name', $pair['value']->getAttribute('name'));
|
||||
}
|
||||
|
||||
public function testObjectDestructuringEvaluatesRightHandExpressionOnce(): void
|
||||
{
|
||||
$calls = 0;
|
||||
$env = new Environment(new ArrayLoader(['template' => '{% do [result_first, result_second] = ({first, second} = next_value()) %}{{ first }} {{ second }} {{ result_first }} {{ result_second }}']));
|
||||
$env->addFunction(new TwigFunction('next_value', static function () use (&$calls): object {
|
||||
++$calls;
|
||||
|
||||
return (object) ['first' => $calls, 'second' => $calls];
|
||||
}));
|
||||
|
||||
$this->assertSame('1 1 1 1', $env->render('template'));
|
||||
$this->assertSame(1, $calls);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getTestsForString
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user