Move some code to LoopContext

This commit is contained in:
Fabien Potencier
2024-07-11 09:30:12 +02:00
parent 0c2a69ceb3
commit 437ad31dfa
5 changed files with 18 additions and 38 deletions
+2 -2
View File
@@ -44,11 +44,11 @@ class ForNode extends Node
->write("\$context['_parent'] = \$context;\n")
->write("\$$loopName = new \Twig\Runtime\Loop(")
->subcompile($this->getNode('seq'))
->raw(", \$context['_parent']);\n")
->raw(");\n")
;
if ($this->getAttribute('with_loop')) {
$compiler->write("\$context['loop'] = new \Twig\Runtime\LoopContext(\${$loopName});\n");
$compiler->write("\$context['loop'] = new \Twig\Runtime\LoopContext(\${$loopName}, \$context['_parent']);\n");
}
$compiler
+1 -21
View File
@@ -26,7 +26,7 @@ final class Loop implements \Iterator
private int $index0;
private int $length;
public function __construct($seq, private $parent)
public function __construct($seq)
{
$this->seq = is_iterable($seq) ? (is_array($seq) ? new \ArrayIterator($seq) : $seq) : new \ArrayIterator([]);
$this->rewind();
@@ -64,16 +64,6 @@ final class Loop implements \Iterator
return 0 !== $this->index0;
}
public function getParent(): mixed
{
return $this->parent;
}
public function getRevindex0(): int
{
return $this->getLength('revindex0') - $this->index0 - 1;
}
public function getIndex0(): int
{
return $this->index0;
@@ -91,14 +81,4 @@ final class Loop implements \Iterator
return $this->length = count($this->seq);
}
public function isFirst(): bool
{
return 0 === $this->index0;
}
public function isLast(): bool
{
return 0 === $this->getLength('last') - $this->index0 - 1;
}
}
+6 -6
View File
@@ -20,23 +20,23 @@ namespace Twig\Runtime;
*/
final class LoopContext
{
public function __construct(private Loop $loop)
public function __construct(private Loop $loop, private $parent)
{
}
public function getParent(): mixed
{
return $this->loop->getParent();
return $this->parent;
}
public function getRevindex0(): int
{
return $this->loop->getRevindex0();
return $this->loop->getLength('revindex0') - $this->getIndex();
}
public function getRevindex(): int
{
return $this->loop->getRevindex0() + 1;
return $this->loop->getLength('revindex') - $this->getIndex0();
}
public function getIndex0(): int
@@ -56,11 +56,11 @@ final class LoopContext
public function isFirst(): bool
{
return $this->loop->isFirst();
return 0 === $this->getIndex0();
}
public function isLast(): bool
{
return $this->loop->isLast();
return 0 === $this->loop->getLength('last') - $this->getIndex();
}
}
+2 -2
View File
@@ -2,7 +2,7 @@
"for" tag loop variable throws when last is used on a non-countable
--TEMPLATE--
{% for item in items %}
* {{ loop.last }}
* {{ loop.revindex }}
{% endfor %}
--DATA--
class ItemsIteratorNotCountable implements \Iterator
@@ -16,4 +16,4 @@ class ItemsIteratorNotCountable implements \Iterator
}
return ['items' => new ItemsIteratorNotCountable()]
--EXCEPTION--
Twig\Error\RuntimeError: The "loop.last" variable is not defined as the loop iterates on a non-countable iterator in "index.twig" at line 3.
Twig\Error\RuntimeError: The "loop.revindex" variable is not defined as the loop iterates on a non-countable iterator in "index.twig" at line 3.
+7 -7
View File
@@ -57,7 +57,7 @@ class ForTest extends NodeTestCase
$tests[] = [$node, <<<EOF
// line 1
\$context['_parent'] = \$context;
\$__internal_compile_0 = new \Twig\Runtime\Loop({$this->getVariableGetter('items')}, \$context['_parent']);
\$__internal_compile_0 = new \Twig\Runtime\Loop({$this->getVariableGetter('items')});
foreach (\$__internal_compile_0 as \$context["key"] => \$context["item"]) {
yield {$this->getVariableGetter('foo')};
}
@@ -78,8 +78,8 @@ EOF
$tests[] = [$node, <<<EOF
// line 1
\$context['_parent'] = \$context;
\$__internal_compile_0 = new \Twig\Runtime\Loop({$this->getVariableGetter('values')}, \$context['_parent']);
\$context['loop'] = new \Twig\Runtime\LoopContext(\$__internal_compile_0);
\$__internal_compile_0 = new \Twig\Runtime\Loop({$this->getVariableGetter('values')});
\$context['loop'] = new \Twig\Runtime\LoopContext(\$__internal_compile_0, \$context['_parent']);
foreach (\$__internal_compile_0 as \$context["k"] => \$context["v"]) {
yield {$this->getVariableGetter('foo')};
}
@@ -100,8 +100,8 @@ EOF
$tests[] = [$node, <<<EOF
// line 1
\$context['_parent'] = \$context;
\$__internal_compile_0 = new \Twig\Runtime\Loop({$this->getVariableGetter('values')}, \$context['_parent']);
\$context['loop'] = new \Twig\Runtime\LoopContext(\$__internal_compile_0);
\$__internal_compile_0 = new \Twig\Runtime\Loop({$this->getVariableGetter('values')});
\$context['loop'] = new \Twig\Runtime\LoopContext(\$__internal_compile_0, \$context['_parent']);
foreach (\$__internal_compile_0 as \$context["k"] => \$context["v"]) {
yield {$this->getVariableGetter('foo')};
}
@@ -122,8 +122,8 @@ EOF
$tests[] = [$node, <<<EOF
// line 1
\$context['_parent'] = \$context;
\$__internal_compile_0 = new \Twig\Runtime\Loop({$this->getVariableGetter('values')}, \$context['_parent']);
\$context['loop'] = new \Twig\Runtime\LoopContext(\$__internal_compile_0);
\$__internal_compile_0 = new \Twig\Runtime\Loop({$this->getVariableGetter('values')});
\$context['loop'] = new \Twig\Runtime\LoopContext(\$__internal_compile_0, \$context['_parent']);
foreach (\$__internal_compile_0 as \$context["k"] => \$context["v"]) {
yield {$this->getVariableGetter('foo')};
}