mirror of
https://github.com/twigphp/Twig.git
synced 2026-09-06 07:27:17 +00:00
Add support for yielding from a generator in PrintNode
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
# 3.11.0 (2024-XX-XX)
|
||||
|
||||
* Add the possibility to yield from a generator in `PrintNode`
|
||||
* Add the `shuffle` filter
|
||||
* Add the `singular` and `plural` filters in `StringExtension`
|
||||
* Deprecate the second argument of `Twig\Node\Expression\CallExpression::compileArguments()`
|
||||
|
||||
@@ -21,4 +21,8 @@ use Twig\Node\Node;
|
||||
*/
|
||||
abstract class AbstractExpression extends Node
|
||||
{
|
||||
public function isGenerator(): bool
|
||||
{
|
||||
return $this->hasAttribute('is_generator') && $this->getAttribute('is_generator');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,10 +31,9 @@ class PrintNode extends Node implements NodeOutputInterface
|
||||
|
||||
public function compile(Compiler $compiler): void
|
||||
{
|
||||
$compiler->addDebugInfo($this);
|
||||
|
||||
$compiler
|
||||
->write('yield ')
|
||||
->addDebugInfo($this)
|
||||
->write($this->getNode('expr')->isGenerator() ? 'yield from ' : 'yield ')
|
||||
->subcompile($this->getNode('expr'))
|
||||
->raw(";\n")
|
||||
;
|
||||
|
||||
@@ -119,7 +119,7 @@ final class SandboxNodeVisitor implements NodeVisitorInterface
|
||||
private function wrapNode(Node $node, string $name): void
|
||||
{
|
||||
$expr = $node->getNode($name);
|
||||
if ($expr instanceof NameExpression || $expr instanceof GetAttrExpression) {
|
||||
if (($expr instanceof NameExpression || $expr instanceof GetAttrExpression) && !$expr->isGenerator()) {
|
||||
$node->setNode($name, new CheckToStringNode($expr));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,10 @@ namespace Twig\Tests\Node;
|
||||
*/
|
||||
|
||||
use Twig\Node\Expression\ConstantExpression;
|
||||
use Twig\Node\Expression\GetAttrExpression;
|
||||
use Twig\Node\Expression\NameExpression;
|
||||
use Twig\Node\PrintNode;
|
||||
use Twig\Template;
|
||||
use Twig\Test\NodeTestCase;
|
||||
|
||||
class PrintTest extends NodeTestCase
|
||||
@@ -30,6 +33,12 @@ class PrintTest extends NodeTestCase
|
||||
$tests = [];
|
||||
$tests[] = [new PrintNode(new ConstantExpression('foo', 1), 1), "// line 1\nyield \"foo\";"];
|
||||
|
||||
$expr = new NameExpression('foo', 1);
|
||||
$attr = new ConstantExpression('bar', 1);
|
||||
$node = new GetAttrExpression($expr, $attr, null, Template::METHOD_CALL, 1);
|
||||
$node->setAttribute('is_generator', true);
|
||||
$tests[] = [new PrintNode($node, 1), "// line 1\nyield from CoreExtension::getAttribute(\$this->env, \$this->source, (\$context[\"foo\"] ?? null), \"bar\", [], \"method\", false, false, false, 1);"];
|
||||
|
||||
return $tests;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace Twig\Tests\NodeVisitor;
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Twig\Environment;
|
||||
use Twig\Loader\ArrayLoader;
|
||||
use Twig\Node\CheckToStringNode;
|
||||
use Twig\Node\Expression\NameExpression;
|
||||
use Twig\Node\ModuleNode;
|
||||
use Twig\Node\Node;
|
||||
use Twig\Node\PrintNode;
|
||||
use Twig\NodeTraverser;
|
||||
use Twig\NodeVisitor\SandboxNodeVisitor;
|
||||
use Twig\Source;
|
||||
|
||||
class SandboxTest extends TestCase
|
||||
{
|
||||
public function testGeneratorExpression()
|
||||
{
|
||||
$env = new Environment(new ArrayLoader());
|
||||
$expr = new NameExpression('foo', 1);
|
||||
$expr->setAttribute('is_generator', true);
|
||||
$node = new ModuleNode(new PrintNode($expr, 1), null, new Node(), new Node(), new Node(), new Node([]), new Source('foo', 'foo'));
|
||||
$traverser = new NodeTraverser($env, [new SandboxNodeVisitor($env)]);
|
||||
$node = $traverser->traverse($node);
|
||||
|
||||
$this->assertNotInstanceOf(CheckToStringNode::class, $node->getNode('body')->getNode('expr'));
|
||||
$this->assertSame("// line 1\nyield from (\$context[\"foo\"] ?? null);\n", $env->compile($node->getNode('body')));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user