mirror of
https://github.com/twigphp/Twig.git
synced 2026-09-04 06:30:57 +00:00
Remove the new yield nodes
This commit is contained in:
@@ -22,7 +22,6 @@ use Twig\Extension\CoreExtension;
|
||||
use Twig\Extension\EscaperExtension;
|
||||
use Twig\Extension\ExtensionInterface;
|
||||
use Twig\Extension\OptimizerExtension;
|
||||
use Twig\Extension\YieldingExtension;
|
||||
use Twig\Loader\ArrayLoader;
|
||||
use Twig\Loader\ChainLoader;
|
||||
use Twig\Loader\LoaderInterface;
|
||||
@@ -130,7 +129,6 @@ class Environment
|
||||
$this->addExtension(new CoreExtension());
|
||||
$this->addExtension(new EscaperExtension($options['autoescape']));
|
||||
$this->addExtension(new OptimizerExtension($options['optimizations']));
|
||||
$this->addExtension(new YieldingExtension($options['use_yield']));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
namespace Twig\Extension;
|
||||
|
||||
use Twig\NodeVisitor\YieldingNodeVisitor;
|
||||
|
||||
class YieldingExtension extends AbstractExtension
|
||||
{
|
||||
private $yielding;
|
||||
|
||||
public function __construct(bool $yielding)
|
||||
{
|
||||
$this->yielding = $yielding;
|
||||
}
|
||||
|
||||
public function getNodeVisitors(): array
|
||||
{
|
||||
return [new YieldingNodeVisitor($this->yielding)];
|
||||
}
|
||||
}
|
||||
@@ -29,9 +29,15 @@ class PrintNode extends Node implements NodeOutputInterface
|
||||
|
||||
public function compile(Compiler $compiler): void
|
||||
{
|
||||
$compiler->addDebugInfo($this);
|
||||
|
||||
if ($compiler->getEnvironment()->useYield()) {
|
||||
$compiler->write('yield ');
|
||||
} else {
|
||||
$compiler->write('echo ');
|
||||
}
|
||||
|
||||
$compiler
|
||||
->addDebugInfo($this)
|
||||
->write('echo ')
|
||||
->subcompile($this->getNode('expr'))
|
||||
->raw(";\n")
|
||||
;
|
||||
|
||||
@@ -28,9 +28,15 @@ class TextNode extends Node implements NodeOutputInterface
|
||||
|
||||
public function compile(Compiler $compiler): void
|
||||
{
|
||||
$compiler->addDebugInfo($this);
|
||||
|
||||
if ($compiler->getEnvironment()->useYield()) {
|
||||
$compiler->write('yield ');
|
||||
} else {
|
||||
$compiler->write('echo ');
|
||||
}
|
||||
|
||||
$compiler
|
||||
->addDebugInfo($this)
|
||||
->write('echo ')
|
||||
->string($this->getAttribute('data'))
|
||||
->raw(";\n")
|
||||
;
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
namespace Twig\Node;
|
||||
|
||||
use Twig\Compiler;
|
||||
|
||||
/**
|
||||
* Represents a node that outputs an expression.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class YieldExpressionNode extends PrintNode
|
||||
{
|
||||
public function compile(Compiler $compiler): void
|
||||
{
|
||||
$compiler
|
||||
->addDebugInfo($this)
|
||||
->write('yield ')
|
||||
->subcompile($this->getNode('expr'))
|
||||
->raw(";\n")
|
||||
;
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
namespace Twig\Node;
|
||||
|
||||
use Twig\Compiler;
|
||||
|
||||
/**
|
||||
* Represents a text node.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class YieldTextNode extends TextNode
|
||||
{
|
||||
public function compile(Compiler $compiler): void
|
||||
{
|
||||
$compiler
|
||||
->addDebugInfo($this)
|
||||
->write('yield ')
|
||||
->string($this->getAttribute('data'))
|
||||
->raw(";\n")
|
||||
;
|
||||
}
|
||||
}
|
||||
@@ -1,81 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
namespace Twig\NodeVisitor;
|
||||
|
||||
use Twig\Environment;
|
||||
use Twig\Node\Node;
|
||||
use Twig\Node\PrintNode;
|
||||
use Twig\Node\TextNode;
|
||||
use Twig\Node\YieldExpressionNode;
|
||||
use Twig\Node\YieldTextNode;
|
||||
|
||||
/**
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
final class YieldingNodeVisitor implements NodeVisitorInterface
|
||||
{
|
||||
private $yielding;
|
||||
|
||||
public function __construct(bool $yielding)
|
||||
{
|
||||
$this->yielding = $yielding;
|
||||
}
|
||||
|
||||
public function enterNode(Node $node, Environment $env): Node
|
||||
{
|
||||
if ($node instanceof YieldExpressionNode) {
|
||||
if ($this->yielding) {
|
||||
return $node;
|
||||
}
|
||||
|
||||
return new PrintNode($node->getNode('expr'), $node->getTemplateLine(), $node->getNodeTag());
|
||||
}
|
||||
if ($node instanceof YieldTextNode) {
|
||||
if ($this->yielding) {
|
||||
return $node;
|
||||
}
|
||||
|
||||
return new TextNode($node->getAttribute('data'), $node->getTemplateLine());
|
||||
}
|
||||
|
||||
if ($node instanceof PrintNode) {
|
||||
// FIXME: deprecation
|
||||
if (!$this->yielding) {
|
||||
return $node;
|
||||
}
|
||||
|
||||
return new YieldExpressionNode($node->getNode('expr'), $node->getTemplateLine(), $node->getNodeTag());
|
||||
}
|
||||
if ($node instanceof TextNode) {
|
||||
// FIXME: deprecation
|
||||
if (!$this->yielding) {
|
||||
return $node;
|
||||
}
|
||||
|
||||
return new YieldTextNode($node->getAttribute('data'), $node->getTemplateLine());
|
||||
}
|
||||
|
||||
return $node;
|
||||
}
|
||||
|
||||
public function leaveNode(Node $node, Environment $env): ?Node
|
||||
{
|
||||
return $node;
|
||||
}
|
||||
|
||||
public function getPriority(): int
|
||||
{
|
||||
return 255;
|
||||
}
|
||||
}
|
||||
+3
-4
@@ -22,9 +22,8 @@ use Twig\Node\ModuleNode;
|
||||
use Twig\Node\Node;
|
||||
use Twig\Node\NodeCaptureInterface;
|
||||
use Twig\Node\NodeOutputInterface;
|
||||
use Twig\Node\PrintNode;
|
||||
use Twig\Node\TextNode;
|
||||
use Twig\Node\YieldExpressionNode;
|
||||
use Twig\Node\YieldTextNode;
|
||||
use Twig\TokenParser\TokenParserInterface;
|
||||
|
||||
/**
|
||||
@@ -120,14 +119,14 @@ class Parser
|
||||
switch ($this->getCurrentToken()->getType()) {
|
||||
case /* Token::TEXT_TYPE */ 0:
|
||||
$token = $this->stream->next();
|
||||
$rv[] = new YieldTextNode($token->getValue(), $token->getLine());
|
||||
$rv[] = new TextNode($token->getValue(), $token->getLine());
|
||||
break;
|
||||
|
||||
case /* Token::VAR_START_TYPE */ 2:
|
||||
$token = $this->stream->next();
|
||||
$expr = $this->expressionParser->parseExpression();
|
||||
$this->stream->expect(/* Token::VAR_END_TYPE */ 4);
|
||||
$rv[] = new YieldExpressionNode($expr, $token->getLine());
|
||||
$rv[] = new PrintNode($expr, $token->getLine());
|
||||
break;
|
||||
|
||||
case /* Token::BLOCK_START_TYPE */ 1:
|
||||
|
||||
@@ -19,6 +19,8 @@ use Twig\Node\Node;
|
||||
|
||||
abstract class NodeTestCase extends TestCase
|
||||
{
|
||||
private Environment $currentEnv;
|
||||
|
||||
abstract public function getTests();
|
||||
|
||||
/**
|
||||
@@ -48,7 +50,7 @@ abstract class NodeTestCase extends TestCase
|
||||
|
||||
protected function getEnvironment()
|
||||
{
|
||||
return new Environment(new ArrayLoader([]));
|
||||
return $this->currentEnv = new Environment(new ArrayLoader([]));
|
||||
}
|
||||
|
||||
protected function getVariableGetter($name, $line = false)
|
||||
@@ -63,13 +65,18 @@ abstract class NodeTestCase extends TestCase
|
||||
return 'CoreExtension::getAttribute($this->env, $this->source, ';
|
||||
}
|
||||
|
||||
protected function getEchoOrYield(): string
|
||||
{
|
||||
return ($this->currentEnv ?? $this->getEnvironment())->useYield() ? 'yield' : 'echo';
|
||||
}
|
||||
|
||||
protected function getDisplayOrYield(string $expr): string
|
||||
{
|
||||
return sprintf($this->getEnvironment()->useYield() ? 'yield from %s->unwrap()->yield' : '%s->display', $expr);
|
||||
return sprintf(($this->currentEnv ?? $this->getEnvironment())->useYield() ? 'yield from %s->unwrap()->yield' : '%s->display', $expr);
|
||||
}
|
||||
|
||||
protected function getDisplayOrYieldBlock(string $expr): string
|
||||
{
|
||||
return sprintf($this->getEnvironment()->useYield() ? 'yield from %s->unwrap()->yieldBlock' : '%s->displayBlock', $expr);
|
||||
return sprintf(($this->currentEnv ?? $this->getEnvironment())->useYield() ? 'yield from %s->unwrap()->yieldBlock' : '%s->displayBlock', $expr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,8 +13,8 @@ namespace Twig\TokenParser;
|
||||
|
||||
use Twig\Node\Expression\TempNameExpression;
|
||||
use Twig\Node\Node;
|
||||
use Twig\Node\PrintNode;
|
||||
use Twig\Node\SetNode;
|
||||
use Twig\Node\YieldExpressionNode;
|
||||
use Twig\Token;
|
||||
|
||||
/**
|
||||
@@ -44,7 +44,7 @@ final class ApplyTokenParser extends AbstractTokenParser
|
||||
|
||||
return new Node([
|
||||
new SetNode(true, $ref, $body, $lineno, $this->getTag()),
|
||||
new YieldExpressionNode($filter, $lineno, $this->getTag()),
|
||||
new PrintNode($filter, $lineno, $this->getTag()),
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ use Twig\Error\SyntaxError;
|
||||
use Twig\Node\BlockNode;
|
||||
use Twig\Node\BlockReferenceNode;
|
||||
use Twig\Node\Node;
|
||||
use Twig\Node\YieldExpressionNode;
|
||||
use Twig\Node\PrintNode;
|
||||
use Twig\Token;
|
||||
|
||||
/**
|
||||
@@ -54,7 +54,7 @@ final class BlockTokenParser extends AbstractTokenParser
|
||||
}
|
||||
} else {
|
||||
$body = new Node([
|
||||
new YieldExpressionNode($this->parser->getExpressionParser()->parseExpression(), $lineno),
|
||||
new PrintNode($this->parser->getExpressionParser()->parseExpression(), $lineno),
|
||||
]);
|
||||
}
|
||||
$stream->expect(/* Token::BLOCK_END_TYPE */ 3);
|
||||
|
||||
@@ -18,7 +18,7 @@ use Twig\Extension\SandboxExtension;
|
||||
use Twig\Extension\StringLoaderExtension;
|
||||
use Twig\Node\Expression\ConstantExpression;
|
||||
use Twig\Node\Node;
|
||||
use Twig\Node\YieldExpressionNode;
|
||||
use Twig\Node\PrintNode;
|
||||
use Twig\Sandbox\SecurityPolicy;
|
||||
use Twig\Test\IntegrationTestCase;
|
||||
use Twig\Token;
|
||||
@@ -135,7 +135,7 @@ class TwigTestTokenParser_§ extends AbstractTokenParser
|
||||
{
|
||||
$this->parser->getStream()->expect(Token::BLOCK_END_TYPE);
|
||||
|
||||
return new YieldExpressionNode(new ConstantExpression('§', -1), -1);
|
||||
return new PrintNode(new ConstantExpression('§', -1), -1);
|
||||
}
|
||||
|
||||
public function getTag(): string
|
||||
|
||||
@@ -31,9 +31,10 @@ class AutoEscapeTest extends NodeTestCase
|
||||
{
|
||||
$body = new Node([new TextNode('foo', 1)]);
|
||||
$node = new AutoEscapeNode(true, $body, 1);
|
||||
$displayStmt = $this->getEchoOrYield();
|
||||
|
||||
return [
|
||||
[$node, "// line 1\necho \"foo\";"],
|
||||
[$node, "// line 1\n$displayStmt \"foo\";"],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@ use Twig\Loader\ArrayLoader;
|
||||
use Twig\Node\BlockNode;
|
||||
use Twig\Node\Node;
|
||||
use Twig\Node\TextNode;
|
||||
use Twig\Node\YieldTextNode;
|
||||
use Twig\Test\NodeTestCase;
|
||||
|
||||
class BlockTest extends NodeTestCase
|
||||
@@ -34,7 +33,7 @@ class BlockTest extends NodeTestCase
|
||||
{
|
||||
$tests = [];
|
||||
|
||||
$tests[] = [new BlockNode('foo', new YieldTextNode('foo', 1), 1), <<<EOF
|
||||
$tests[] = [new BlockNode('foo', new TextNode('foo', 1), 1), <<<EOF
|
||||
// line 1
|
||||
public function block_foo(\$context, array \$blocks = [])
|
||||
{
|
||||
|
||||
@@ -53,13 +53,14 @@ class ForTest extends NodeTestCase
|
||||
$else = null;
|
||||
$node = new ForNode($keyTarget, $valueTarget, $seq, null, $body, $else, 1);
|
||||
$node->setAttribute('with_loop', false);
|
||||
$displayStmt = $this->getEchoOrYield();
|
||||
|
||||
$tests[] = [$node, <<<EOF
|
||||
// line 1
|
||||
\$context['_parent'] = \$context;
|
||||
\$context['_seq'] = CoreExtension::ensureTraversable({$this->getVariableGetter('items')});
|
||||
foreach (\$context['_seq'] as \$context["key"] => \$context["item"]) {
|
||||
echo {$this->getVariableGetter('foo')};
|
||||
$displayStmt {$this->getVariableGetter('foo')};
|
||||
}
|
||||
\$_parent = \$context['_parent'];
|
||||
unset(\$context['_seq'], \$context['_iterated'], \$context['key'], \$context['item'], \$context['_parent'], \$context['loop']);
|
||||
@@ -93,7 +94,7 @@ if (is_array(\$context['_seq']) || (is_object(\$context['_seq']) && \$context['_
|
||||
\$context['loop']['last'] = 1 === \$length;
|
||||
}
|
||||
foreach (\$context['_seq'] as \$context["k"] => \$context["v"]) {
|
||||
echo {$this->getVariableGetter('foo')};
|
||||
$displayStmt {$this->getVariableGetter('foo')};
|
||||
++\$context['loop']['index0'];
|
||||
++\$context['loop']['index'];
|
||||
\$context['loop']['first'] = false;
|
||||
@@ -135,7 +136,7 @@ if (is_array(\$context['_seq']) || (is_object(\$context['_seq']) && \$context['_
|
||||
\$context['loop']['last'] = 1 === \$length;
|
||||
}
|
||||
foreach (\$context['_seq'] as \$context["k"] => \$context["v"]) {
|
||||
echo {$this->getVariableGetter('foo')};
|
||||
$displayStmt {$this->getVariableGetter('foo')};
|
||||
++\$context['loop']['index0'];
|
||||
++\$context['loop']['index'];
|
||||
\$context['loop']['first'] = false;
|
||||
@@ -178,7 +179,7 @@ if (is_array(\$context['_seq']) || (is_object(\$context['_seq']) && \$context['_
|
||||
\$context['loop']['last'] = 1 === \$length;
|
||||
}
|
||||
foreach (\$context['_seq'] as \$context["k"] => \$context["v"]) {
|
||||
echo {$this->getVariableGetter('foo')};
|
||||
$displayStmt {$this->getVariableGetter('foo')};
|
||||
\$context['_iterated'] = true;
|
||||
++\$context['loop']['index0'];
|
||||
++\$context['loop']['index'];
|
||||
@@ -190,7 +191,7 @@ foreach (\$context['_seq'] as \$context["k"] => \$context["v"]) {
|
||||
}
|
||||
}
|
||||
if (!\$context['_iterated']) {
|
||||
echo {$this->getVariableGetter('foo')};
|
||||
$displayStmt {$this->getVariableGetter('foo')};
|
||||
}
|
||||
\$_parent = \$context['_parent'];
|
||||
unset(\$context['_seq'], \$context['_iterated'], \$context['k'], \$context['v'], \$context['_parent'], \$context['loop']);
|
||||
|
||||
@@ -47,11 +47,12 @@ class IfTest extends NodeTestCase
|
||||
], [], 1);
|
||||
$else = null;
|
||||
$node = new IfNode($t, $else, 1);
|
||||
$displayStmt = $this->getEchoOrYield();
|
||||
|
||||
$tests[] = [$node, <<<EOF
|
||||
// line 1
|
||||
if (true) {
|
||||
echo {$this->getVariableGetter('foo')};
|
||||
$displayStmt {$this->getVariableGetter('foo')};
|
||||
}
|
||||
EOF
|
||||
];
|
||||
@@ -68,9 +69,9 @@ EOF
|
||||
$tests[] = [$node, <<<EOF
|
||||
// line 1
|
||||
if (true) {
|
||||
echo {$this->getVariableGetter('foo')};
|
||||
$displayStmt {$this->getVariableGetter('foo')};
|
||||
} elseif (false) {
|
||||
echo {$this->getVariableGetter('bar')};
|
||||
$displayStmt {$this->getVariableGetter('bar')};
|
||||
}
|
||||
EOF
|
||||
];
|
||||
@@ -85,9 +86,9 @@ EOF
|
||||
$tests[] = [$node, <<<EOF
|
||||
// line 1
|
||||
if (true) {
|
||||
echo {$this->getVariableGetter('foo')};
|
||||
$displayStmt {$this->getVariableGetter('foo')};
|
||||
} else {
|
||||
echo {$this->getVariableGetter('bar')};
|
||||
$displayStmt {$this->getVariableGetter('bar')};
|
||||
}
|
||||
EOF
|
||||
];
|
||||
|
||||
@@ -18,7 +18,6 @@ use Twig\Node\Expression\NameExpression;
|
||||
use Twig\Node\MacroNode;
|
||||
use Twig\Node\Node;
|
||||
use Twig\Node\TextNode;
|
||||
use Twig\Node\YieldTextNode;
|
||||
use Twig\Test\NodeTestCase;
|
||||
|
||||
class MacroTest extends NodeTestCase
|
||||
@@ -43,7 +42,7 @@ class MacroTest extends NodeTestCase
|
||||
'bar' => new ConstantExpression('Foo', 1),
|
||||
], [], 1);
|
||||
|
||||
$body = new YieldTextNode('foo', 1);
|
||||
$body = new TextNode('foo', 1);
|
||||
$node = new MacroNode('foo', $body, $arguments, 1);
|
||||
|
||||
$text[] = [$node, <<<EOF
|
||||
|
||||
@@ -56,6 +56,7 @@ class ModuleTest extends NodeTestCase
|
||||
$traits = new Node();
|
||||
$source = new Source('{{ foo }}', 'foo.twig');
|
||||
$parentTemplate = $this->getEnvironment()->useYield() ? 'YieldingTemplate' : 'Template';
|
||||
$displayStmt = $this->getEchoOrYield();
|
||||
|
||||
$node = new ModuleNode($body, $extends, $blocks, $macros, $traits, new Node([]), $source);
|
||||
$tests[] = [$node, <<<EOF
|
||||
@@ -96,7 +97,7 @@ class __TwigTemplate_%x extends $parentTemplate
|
||||
{
|
||||
\$macros = \$this->macros;
|
||||
// line 1
|
||||
echo "foo";
|
||||
$displayStmt "foo";
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -28,7 +28,9 @@ class PrintTest extends NodeTestCase
|
||||
public function getTests()
|
||||
{
|
||||
$tests = [];
|
||||
$tests[] = [new PrintNode(new ConstantExpression('foo', 1), 1), "// line 1\necho \"foo\";"];
|
||||
$displayStmt = $this->getEchoOrYield();
|
||||
|
||||
$tests[] = [new PrintNode(new ConstantExpression('foo', 1), 1), "// line 1\n$displayStmt \"foo\";"];
|
||||
|
||||
return $tests;
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ class SandboxTest extends NodeTestCase
|
||||
|
||||
$body = new TextNode('foo', 1);
|
||||
$node = new SandboxNode($body, 1);
|
||||
$displayStmt = $this->getEchoOrYield();
|
||||
|
||||
$tests[] = [$node, <<<EOF
|
||||
// line 1
|
||||
@@ -38,7 +39,7 @@ if (!\$alreadySandboxed = \$this->sandbox->isSandboxed()) {
|
||||
\$this->sandbox->enableSandbox();
|
||||
}
|
||||
try {
|
||||
echo "foo";
|
||||
$displayStmt "foo";
|
||||
} finally {
|
||||
if (!\$alreadySandboxed) {
|
||||
\$this->sandbox->disableSandbox();
|
||||
|
||||
@@ -55,7 +55,7 @@ EOF
|
||||
$tests[] = [$node, <<<EOF
|
||||
// line 1
|
||||
\$context["foo"] = ('' === \$tmp = implode('', iterator_to_array((function () use (&\$context, \$macros, \$blocks) {
|
||||
echo "foo";
|
||||
yield "foo";
|
||||
})() ?? new \EmptyIterator()))) ? '' : new Markup(\$tmp, \$this->env->getCharset());
|
||||
EOF
|
||||
, new Environment(new ArrayLoader(), ['use_yield' => true]),
|
||||
|
||||
@@ -26,7 +26,8 @@ class TextTest extends NodeTestCase
|
||||
public function getTests()
|
||||
{
|
||||
$tests = [];
|
||||
$tests[] = [new TextNode('foo', 1), "// line 1\necho \"foo\";"];
|
||||
$displayStmt = $this->getEchoOrYield();
|
||||
$tests[] = [new TextNode('foo', 1), "// line 1\n$displayStmt \"foo\";"];
|
||||
|
||||
return $tests;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user