Skip to content

Commit

Permalink
Replace "use_yield" by #[YieldReady] on nodes
Browse files Browse the repository at this point in the history
  • Loading branch information
nicolas-grekas committed Feb 12, 2024
1 parent 7f5958c commit 047ec50
Show file tree
Hide file tree
Showing 50 changed files with 391 additions and 657 deletions.
28 changes: 0 additions & 28 deletions src/Compiler.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,10 @@ class Compiler
private $sourceOffset;
private $sourceLine;
private $varNameSalt = 0;
private $checkForOutput;

public function __construct(Environment $env)
{
$this->env = $env;
$this->checkForOutput = $env->isDebug();
}

public function getEnvironment(): Environment
Expand Down Expand Up @@ -87,26 +85,13 @@ public function subcompile(Node $node, bool $raw = true)
return $this;
}

/**
* @return $this
*/
public function checkForOutput(bool $checkForOutput)
{
$this->checkForOutput = $checkForOutput ? $this->env->isDebug() : false;

return $this;
}

/**
* Adds a raw string to the compiled code.
*
* @return $this
*/
public function raw(string $string)
{
if ($this->checkForOutput) {
$this->checkStringForOutput(trim($string));
}
$this->source .= $string;

return $this;
Expand All @@ -120,10 +105,6 @@ public function raw(string $string)
public function write(...$strings)
{
foreach ($strings as $string) {
if ($this->checkForOutput) {
$this->checkStringForOutput(trim($string));
}

$this->source .= str_repeat(' ', $this->indentation * 4).$string;
}

Expand Down Expand Up @@ -239,13 +220,4 @@ public function getVarName(): string
{
return sprintf('__internal_compile_%d', $this->varNameSalt++);
}

private function checkStringForOutput(string $string): void
{
if (str_starts_with($string, 'echo')) {
trigger_deprecation('twig/twig', '3.9.0', 'Using "echo" in a "Node::compile()" method is deprecated; use a "TextNode" or "PrintNode" instead or use "yield" when "use_yield" is "true" on the environment (triggered by "%s").', $string);
} elseif (str_starts_with($string, 'print')) {
trigger_deprecation('twig/twig', '3.9.0', 'Using "print" in a "Node::compile()" method is deprecated; use a "TextNode" or "PrintNode" instead or use "yield" when "use_yield" is "true" on the environment (triggered by "%s").', $string);
}
}
}
25 changes: 4 additions & 21 deletions src/Environment.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
use Twig\Extension\EscaperExtension;
use Twig\Extension\ExtensionInterface;
use Twig\Extension\OptimizerExtension;
use Twig\Extension\YieldNotReadyExtension;
use Twig\Loader\ArrayLoader;
use Twig\Loader\ChainLoader;
use Twig\Loader\LoaderInterface;
Expand Down Expand Up @@ -66,8 +67,6 @@ class Environment
private $runtimeLoaders = [];
private $runtimes = [];
private $optionsHash;
/** @var bool */
private $useYield;

/**
* Constructor.
Expand Down Expand Up @@ -99,10 +98,6 @@ class Environment
* * optimizations: A flag that indicates which optimizations to apply
* (default to -1 which means that all optimizations are enabled;
* set it to 0 to disable).
*
* * use_yield: Enable a new mode where template are using "yield" instead of "echo"
* (default to "false", but switch it to "true" when possible
* as this will be the only supported mode in Twig 4.0)
*/
public function __construct(LoaderInterface $loader, $options = [])
{
Expand All @@ -116,14 +111,8 @@ public function __construct(LoaderInterface $loader, $options = [])
'cache' => false,
'auto_reload' => null,
'optimizations' => -1,
'use_yield' => false,
], $options);

$this->useYield = (bool) $options['use_yield'];
if (!$this->useYield) {
trigger_deprecation('twig/twig', '3.9.0', 'Not setting "use_yield" to "true" is deprecated.');
}

$this->debug = (bool) $options['debug'];
$this->setCharset($options['charset'] ?? 'UTF-8');
$this->autoReload = null === $options['auto_reload'] ? $this->debug : (bool) $options['auto_reload'];
Expand All @@ -133,17 +122,12 @@ public function __construct(LoaderInterface $loader, $options = [])

$this->addExtension(new CoreExtension());
$this->addExtension(new EscaperExtension($options['autoescape']));
if (\PHP_VERSION_ID >= 80000) {
$this->addExtension(new YieldNotReadyExtension());
}
$this->addExtension(new OptimizerExtension($options['optimizations']));
}

/**
* @internal
*/
public function useYield(): bool
{
return $this->useYield;
}

/**
* Enables debugging mode.
*/
Expand Down Expand Up @@ -854,7 +838,6 @@ private function updateOptionsHash(): void
self::VERSION,
(int) $this->debug,
(int) $this->strictVariables,
$this->useYield ? '1' : '0',
]);
}
}
25 changes: 25 additions & 0 deletions src/Extension/YieldNotReadyExtension.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?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\YieldNotReadyNodeVisitor;

/**
* @internal to be removed in Twig 4
*/
final class YieldNotReadyExtension extends AbstractExtension
{
public function getNodeVisitors(): array
{
return [new YieldNotReadyNodeVisitor()];
}
}
1 change: 1 addition & 0 deletions src/Node/AutoEscapeNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
*
* @author Fabien Potencier <fabien@symfony.com>
*/
#[YieldReady]
class AutoEscapeNode extends Node
{
public function __construct($value, Node $body, int $lineno, string $tag = 'autoescape')
Expand Down
3 changes: 2 additions & 1 deletion src/Node/BlockNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
*
* @author Fabien Potencier <fabien@symfony.com>
*/
#[YieldReady]
class BlockNode extends Node
{
public function __construct(string $name, Node $body, int $lineno, ?string $tag = null)
Expand All @@ -39,7 +40,7 @@ public function compile(Compiler $compiler): void
->subcompile($this->getNode('body'))
;

if (!$this->getNode('body') instanceof NodeOutputInterface && $compiler->getEnvironment()->useYield()) {
if (!$this->getNode('body') instanceof NodeOutputInterface) {
// needed when body doesn't yield anything
$compiler->write("yield '';\n");
}
Expand Down
16 changes: 5 additions & 11 deletions src/Node/BlockReferenceNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
*
* @author Fabien Potencier <fabien@symfony.com>
*/
#[YieldReady]
class BlockReferenceNode extends Node implements NodeOutputInterface
{
public function __construct(string $name, int $lineno, ?string $tag = null)
Expand All @@ -28,16 +29,9 @@ public function __construct(string $name, int $lineno, ?string $tag = null)

public function compile(Compiler $compiler): void
{
if ($compiler->getEnvironment()->useYield()) {
$compiler
->addDebugInfo($this)
->write(sprintf("yield from \$this->unwrap()->yieldBlock('%s', \$context, \$blocks);\n", $this->getAttribute('name')))
;
} else {
$compiler
->addDebugInfo($this)
->write(sprintf("\$this->displayBlock('%s', \$context, \$blocks);\n", $this->getAttribute('name')))
;
}
$compiler
->addDebugInfo($this)
->write(sprintf("yield from \$this->unwrap()->yieldBlock('%s', \$context, \$blocks);\n", $this->getAttribute('name')))
;
}
}
1 change: 1 addition & 0 deletions src/Node/BodyNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
*
* @author Fabien Potencier <fabien@symfony.com>
*/
#[YieldReady]
class BodyNode extends Node
{
}
56 changes: 10 additions & 46 deletions src/Node/CaptureNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
*
* @author Fabien Potencier <fabien@symfony.com>
*/
#[YieldReady]
class CaptureNode extends Node
{
public function __construct(Node $body, int $lineno, ?string $tag = null)
Expand All @@ -27,62 +28,25 @@ public function __construct(Node $body, int $lineno, ?string $tag = null)

public function compile(Compiler $compiler): void
{
if ($compiler->getEnvironment()->useYield()) {
if ($this->getAttribute('raw')) {
$compiler->raw("implode('', iterator_to_array(");
} else {
$compiler->raw("('' === \$tmp = implode('', iterator_to_array(");
}
if ($this->getAttribute('with_blocks')) {
$compiler->raw("(function () use (&\$context, \$macros, \$blocks) {\n");
} else {
$compiler->raw("(function () use (&\$context, \$macros) {\n");
}
$compiler
->indent()
->subcompile($this->getNode('body'))
->outdent()
->write("})() ?? new \EmptyIterator()))")
;
if (!$this->getAttribute('raw')) {
$compiler->raw(") ? '' : new Markup(\$tmp, \$this->env->getCharset())");
}
$compiler->raw(';');

return;
if ($this->getAttribute('raw')) {
$compiler->raw("implode('', iterator_to_array(");
} else {
$compiler->raw("('' === \$tmp = implode('', iterator_to_array(");
}

if ($this->getAttribute('with_blocks')) {
$compiler->raw("(function () use (&\$context, \$macros, \$blocks) {\n");
} else {
$compiler->raw("(function () use (&\$context, \$macros) {\n");
}
$compiler->indent();
if ($compiler->getEnvironment()->isDebug()) {
$compiler->write("ob_start();\n");
} else {
$compiler->write("ob_start(function () { return ''; });\n");
}
$compiler
->write("try {\n")
->indent()
->subcompile($this->getNode('body'))
->raw("\n")
;
if ($this->getAttribute('raw')) {
$compiler->write("return ob_get_contents();\n");
} else {
$compiler->write("return ('' === \$tmp = ob_get_contents()) ? '' : new Markup(\$tmp, \$this->env->getCharset());\n");
}
$compiler
->outdent()
->write("} finally {\n")
->indent()
->write("ob_end_clean();\n")
->outdent()
->write("}\n")
->outdent()
->write('})();')
->write("})() ?? new \EmptyIterator()))")
;
if (!$this->getAttribute('raw')) {
$compiler->raw(") ? '' : new Markup(\$tmp, \$this->env->getCharset())");
}
$compiler->raw(';');
}
}
1 change: 1 addition & 0 deletions src/Node/CheckSecurityCallNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
/**
* @author Fabien Potencier <fabien@symfony.com>
*/
#[YieldReady]
class CheckSecurityCallNode extends Node
{
public function compile(Compiler $compiler)
Expand Down
1 change: 1 addition & 0 deletions src/Node/CheckSecurityNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
/**
* @author Fabien Potencier <fabien@symfony.com>
*/
#[YieldReady]
class CheckSecurityNode extends Node
{
private $usedFilters;
Expand Down
1 change: 1 addition & 0 deletions src/Node/CheckToStringNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
*
* @author Fabien Potencier <fabien@symfony.com>
*/
#[YieldReady]
class CheckToStringNode extends AbstractExpression
{
public function __construct(AbstractExpression $expr)
Expand Down
1 change: 1 addition & 0 deletions src/Node/DeprecatedNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
*
* @author Yonel Ceruto <yonelceruto@gmail.com>
*/
#[YieldReady]
class DeprecatedNode extends Node
{
public function __construct(AbstractExpression $expr, int $lineno, ?string $tag = null)
Expand Down
1 change: 1 addition & 0 deletions src/Node/DoNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
*
* @author Fabien Potencier <fabien@symfony.com>
*/
#[YieldReady]
class DoNode extends Node
{
public function __construct(AbstractExpression $expr, int $lineno, ?string $tag = null)
Expand Down
1 change: 1 addition & 0 deletions src/Node/EmbedNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
*
* @author Fabien Potencier <fabien@symfony.com>
*/
#[YieldReady]
class EmbedNode extends IncludeNode
{
// we don't inject the module to avoid node visitors to traverse it twice (as it will be already visited in the main module)
Expand Down
20 changes: 5 additions & 15 deletions src/Node/Expression/BlockReferenceExpression.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,16 +40,10 @@ public function compile(Compiler $compiler): void
if ($this->getAttribute('output')) {
$compiler->addDebugInfo($this);

if ($compiler->getEnvironment()->useYield()) {
$compiler->write('yield from ');
$this
->compileTemplateCall($compiler, 'yieldBlock')
->raw(";\n");
} else {
$this
->compileTemplateCall($compiler, 'displayBlock')
->raw(";\n");
}
$compiler->write('yield from ');
$this
->compileTemplateCall($compiler, 'yieldBlock')
->raw(";\n");
} else {
$this->compileTemplateCall($compiler, 'renderBlock');
}
Expand All @@ -72,11 +66,7 @@ private function compileTemplateCall(Compiler $compiler, string $method): Compil
;
}

if ($compiler->getEnvironment()->useYield()) {
$compiler->raw('->unwrap()');
}

$compiler->raw(sprintf('->%s', $method));
$compiler->raw(sprintf('->unwrap()->%s', $method));

return $this->compileBlockArguments($compiler);
}
Expand Down
Loading

0 comments on commit 047ec50

Please sign in to comment.