mirror of
https://github.com/slawkens/myaac.git
synced 2025-10-14 17:54:55 +02:00
Update Twig to v2.15.4
This commit is contained in:
@@ -15,9 +15,9 @@ use Twig\Compiler;
|
||||
|
||||
class ArrayExpression extends AbstractExpression
|
||||
{
|
||||
protected $index;
|
||||
private $index;
|
||||
|
||||
public function __construct(array $elements, $lineno)
|
||||
public function __construct(array $elements, int $lineno)
|
||||
{
|
||||
parent::__construct($elements, [], $lineno);
|
||||
|
||||
|
@@ -44,7 +44,7 @@ class ArrowFunctionExpression extends AbstractExpression
|
||||
;
|
||||
}
|
||||
$compiler
|
||||
->raw(') use ($context) { ')
|
||||
->raw(') use ($context, $macros) { ')
|
||||
;
|
||||
foreach ($this->getNode('names') as $name) {
|
||||
$compiler
|
||||
|
@@ -14,10 +14,11 @@ namespace Twig\Node\Expression\Binary;
|
||||
|
||||
use Twig\Compiler;
|
||||
use Twig\Node\Expression\AbstractExpression;
|
||||
use Twig\Node\Node;
|
||||
|
||||
abstract class AbstractBinary extends AbstractExpression
|
||||
{
|
||||
public function __construct(\Twig_NodeInterface $left, \Twig_NodeInterface $right, $lineno)
|
||||
public function __construct(Node $left, Node $right, int $lineno)
|
||||
{
|
||||
parent::__construct(['left' => $left, 'right' => $right], [], $lineno);
|
||||
}
|
||||
|
@@ -15,21 +15,6 @@ use Twig\Compiler;
|
||||
|
||||
class PowerBinary extends AbstractBinary
|
||||
{
|
||||
public function compile(Compiler $compiler)
|
||||
{
|
||||
if (\PHP_VERSION_ID >= 50600) {
|
||||
return parent::compile($compiler);
|
||||
}
|
||||
|
||||
$compiler
|
||||
->raw('pow(')
|
||||
->subcompile($this->getNode('left'))
|
||||
->raw(', ')
|
||||
->subcompile($this->getNode('right'))
|
||||
->raw(')')
|
||||
;
|
||||
}
|
||||
|
||||
public function operator(Compiler $compiler)
|
||||
{
|
||||
return $compiler->raw('**');
|
||||
|
22
system/libs/Twig/Node/Expression/Binary/SpaceshipBinary.php
Normal file
22
system/libs/Twig/Node/Expression/Binary/SpaceshipBinary.php
Normal file
@@ -0,0 +1,22 @@
|
||||
<?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\Expression\Binary;
|
||||
|
||||
use Twig\Compiler;
|
||||
|
||||
class SpaceshipBinary extends AbstractBinary
|
||||
{
|
||||
public function operator(Compiler $compiler)
|
||||
{
|
||||
return $compiler->raw('<=>');
|
||||
}
|
||||
}
|
@@ -22,17 +22,8 @@ use Twig\Node\Node;
|
||||
*/
|
||||
class BlockReferenceExpression extends AbstractExpression
|
||||
{
|
||||
/**
|
||||
* @param Node|null $template
|
||||
*/
|
||||
public function __construct(\Twig_NodeInterface $name, $template = null, $lineno, $tag = null)
|
||||
public function __construct(Node $name, ?Node $template, int $lineno, string $tag = null)
|
||||
{
|
||||
if (\is_bool($template)) {
|
||||
@trigger_error(sprintf('The %s method "$asString" argument is deprecated since version 1.28 and will be removed in 2.0.', __METHOD__), E_USER_DEPRECATED);
|
||||
|
||||
$template = null;
|
||||
}
|
||||
|
||||
$nodes = ['name' => $name];
|
||||
if (null !== $template) {
|
||||
$nodes['template'] = $template;
|
||||
@@ -58,7 +49,7 @@ class BlockReferenceExpression extends AbstractExpression
|
||||
}
|
||||
}
|
||||
|
||||
private function compileTemplateCall(Compiler $compiler, $method)
|
||||
private function compileTemplateCall(Compiler $compiler, string $method): Compiler
|
||||
{
|
||||
if (!$this->hasNode('template')) {
|
||||
$compiler->write('$this');
|
||||
@@ -75,12 +66,11 @@ class BlockReferenceExpression extends AbstractExpression
|
||||
}
|
||||
|
||||
$compiler->raw(sprintf('->%s', $method));
|
||||
$this->compileBlockArguments($compiler);
|
||||
|
||||
return $compiler;
|
||||
return $this->compileBlockArguments($compiler);
|
||||
}
|
||||
|
||||
private function compileBlockArguments(Compiler $compiler)
|
||||
private function compileBlockArguments(Compiler $compiler): Compiler
|
||||
{
|
||||
$compiler
|
||||
->raw('(')
|
||||
|
@@ -22,37 +22,37 @@ abstract class CallExpression extends AbstractExpression
|
||||
|
||||
protected function compileCallable(Compiler $compiler)
|
||||
{
|
||||
$closingParenthesis = false;
|
||||
$isArray = false;
|
||||
if ($this->hasAttribute('callable') && $callable = $this->getAttribute('callable')) {
|
||||
if (\is_string($callable) && false === strpos($callable, '::')) {
|
||||
$compiler->raw($callable);
|
||||
} else {
|
||||
list($r, $callable) = $this->reflectCallable($callable);
|
||||
if ($r instanceof \ReflectionMethod && \is_string($callable[0])) {
|
||||
if ($r->isStatic()) {
|
||||
$compiler->raw(sprintf('%s::%s', $callable[0], $callable[1]));
|
||||
} else {
|
||||
$compiler->raw(sprintf('$this->env->getRuntime(\'%s\')->%s', $callable[0], $callable[1]));
|
||||
}
|
||||
} elseif ($r instanceof \ReflectionMethod && $callable[0] instanceof ExtensionInterface) {
|
||||
$compiler->raw(sprintf('$this->env->getExtension(\'%s\')->%s', \get_class($callable[0]), $callable[1]));
|
||||
} else {
|
||||
$type = ucfirst($this->getAttribute('type'));
|
||||
$compiler->raw(sprintf('call_user_func_array($this->env->get%s(\'%s\')->getCallable(), ', $type, $this->getAttribute('name')));
|
||||
$closingParenthesis = true;
|
||||
$isArray = true;
|
||||
}
|
||||
}
|
||||
$callable = $this->getAttribute('callable');
|
||||
|
||||
if (\is_string($callable) && false === strpos($callable, '::')) {
|
||||
$compiler->raw($callable);
|
||||
} else {
|
||||
$compiler->raw($this->getAttribute('thing')->compile());
|
||||
[$r, $callable] = $this->reflectCallable($callable);
|
||||
|
||||
if (\is_string($callable)) {
|
||||
$compiler->raw($callable);
|
||||
} elseif (\is_array($callable) && \is_string($callable[0])) {
|
||||
if (!$r instanceof \ReflectionMethod || $r->isStatic()) {
|
||||
$compiler->raw(sprintf('%s::%s', $callable[0], $callable[1]));
|
||||
} else {
|
||||
$compiler->raw(sprintf('$this->env->getRuntime(\'%s\')->%s', $callable[0], $callable[1]));
|
||||
}
|
||||
} elseif (\is_array($callable) && $callable[0] instanceof ExtensionInterface) {
|
||||
$class = \get_class($callable[0]);
|
||||
if (!$compiler->getEnvironment()->hasExtension($class)) {
|
||||
// Compile a non-optimized call to trigger a \Twig\Error\RuntimeError, which cannot be a compile-time error
|
||||
$compiler->raw(sprintf('$this->env->getExtension(\'%s\')', $class));
|
||||
} else {
|
||||
$compiler->raw(sprintf('$this->extensions[\'%s\']', ltrim($class, '\\')));
|
||||
}
|
||||
|
||||
$compiler->raw(sprintf('->%s', $callable[1]));
|
||||
} else {
|
||||
$compiler->raw(sprintf('$this->env->get%s(\'%s\')->getCallable()', ucfirst($this->getAttribute('type')), $this->getAttribute('name')));
|
||||
}
|
||||
}
|
||||
|
||||
$this->compileArguments($compiler, $isArray);
|
||||
|
||||
if ($closingParenthesis) {
|
||||
$compiler->raw(')');
|
||||
}
|
||||
$this->compileArguments($compiler);
|
||||
}
|
||||
|
||||
protected function compileArguments(Compiler $compiler, $isArray = false)
|
||||
@@ -93,10 +93,8 @@ abstract class CallExpression extends AbstractExpression
|
||||
}
|
||||
|
||||
if ($this->hasNode('arguments')) {
|
||||
$callable = $this->hasAttribute('callable') ? $this->getAttribute('callable') : null;
|
||||
|
||||
$callable = $this->getAttribute('callable');
|
||||
$arguments = $this->getArguments($callable, $this->getNode('arguments'));
|
||||
|
||||
foreach ($arguments as $node) {
|
||||
if (!$first) {
|
||||
$compiler->raw(', ');
|
||||
@@ -142,14 +140,23 @@ abstract class CallExpression extends AbstractExpression
|
||||
throw new \LogicException($message);
|
||||
}
|
||||
|
||||
$callableParameters = $this->getCallableParameters($callable, $isVariadic);
|
||||
list($callableParameters, $isPhpVariadic) = $this->getCallableParameters($callable, $isVariadic);
|
||||
$arguments = [];
|
||||
$names = [];
|
||||
$missingArguments = [];
|
||||
$optionalArguments = [];
|
||||
$pos = 0;
|
||||
foreach ($callableParameters as $callableParameter) {
|
||||
$names[] = $name = $this->normalizeName($callableParameter->name);
|
||||
$name = $this->normalizeName($callableParameter->name);
|
||||
if (\PHP_VERSION_ID >= 80000 && 'range' === $callable) {
|
||||
if ('start' === $name) {
|
||||
$name = 'low';
|
||||
} elseif ('end' === $name) {
|
||||
$name = 'high';
|
||||
}
|
||||
}
|
||||
|
||||
$names[] = $name;
|
||||
|
||||
if (\array_key_exists($name, $parameters)) {
|
||||
if (\array_key_exists($pos, $parameters)) {
|
||||
@@ -187,7 +194,7 @@ abstract class CallExpression extends AbstractExpression
|
||||
}
|
||||
|
||||
if ($isVariadic) {
|
||||
$arbitraryArguments = new ArrayExpression([], -1);
|
||||
$arbitraryArguments = $isPhpVariadic ? new VariadicExpression([], -1) : new ArrayExpression([], -1);
|
||||
foreach ($parameters as $key => $value) {
|
||||
if (\is_int($key)) {
|
||||
$arbitraryArguments->addElement($value);
|
||||
@@ -230,12 +237,9 @@ abstract class CallExpression extends AbstractExpression
|
||||
return strtolower(preg_replace(['/([A-Z]+)([A-Z][a-z])/', '/([a-z\d])([A-Z])/'], ['\\1_\\2', '\\1_\\2'], $name));
|
||||
}
|
||||
|
||||
private function getCallableParameters($callable, $isVariadic)
|
||||
private function getCallableParameters($callable, bool $isVariadic): array
|
||||
{
|
||||
list($r) = $this->reflectCallable($callable);
|
||||
if (null === $r) {
|
||||
return [];
|
||||
}
|
||||
[$r, , $callableName] = $this->reflectCallable($callable);
|
||||
|
||||
$parameters = $r->getParameters();
|
||||
if ($this->hasNode('node')) {
|
||||
@@ -252,21 +256,21 @@ abstract class CallExpression extends AbstractExpression
|
||||
array_shift($parameters);
|
||||
}
|
||||
}
|
||||
$isPhpVariadic = false;
|
||||
if ($isVariadic) {
|
||||
$argument = end($parameters);
|
||||
if ($argument && $argument->isArray() && $argument->isDefaultValueAvailable() && [] === $argument->getDefaultValue()) {
|
||||
$isArray = $argument && $argument->hasType() && 'array' === $argument->getType()->getName();
|
||||
if ($isArray && $argument->isDefaultValueAvailable() && [] === $argument->getDefaultValue()) {
|
||||
array_pop($parameters);
|
||||
} elseif ($argument && $argument->isVariadic()) {
|
||||
array_pop($parameters);
|
||||
$isPhpVariadic = true;
|
||||
} else {
|
||||
$callableName = $r->name;
|
||||
if ($r instanceof \ReflectionMethod) {
|
||||
$callableName = $r->getDeclaringClass()->name.'::'.$callableName;
|
||||
}
|
||||
|
||||
throw new \LogicException(sprintf('The last parameter of "%s" for %s "%s" must be an array with default value, eg. "array $arg = []".', $callableName, $this->getAttribute('type'), $this->getAttribute('name')));
|
||||
}
|
||||
}
|
||||
|
||||
return $parameters;
|
||||
return [$parameters, $isPhpVariadic];
|
||||
}
|
||||
|
||||
private function reflectCallable($callable)
|
||||
@@ -275,30 +279,44 @@ abstract class CallExpression extends AbstractExpression
|
||||
return $this->reflector;
|
||||
}
|
||||
|
||||
if (\is_array($callable)) {
|
||||
if (!method_exists($callable[0], $callable[1])) {
|
||||
// __call()
|
||||
return [null, []];
|
||||
}
|
||||
$r = new \ReflectionMethod($callable[0], $callable[1]);
|
||||
} elseif (\is_object($callable) && !$callable instanceof \Closure) {
|
||||
$r = new \ReflectionObject($callable);
|
||||
$r = $r->getMethod('__invoke');
|
||||
$callable = [$callable, '__invoke'];
|
||||
} elseif (\is_string($callable) && false !== $pos = strpos($callable, '::')) {
|
||||
$class = substr($callable, 0, $pos);
|
||||
$method = substr($callable, $pos + 2);
|
||||
if (!method_exists($class, $method)) {
|
||||
// __staticCall()
|
||||
return [null, []];
|
||||
}
|
||||
$r = new \ReflectionMethod($callable);
|
||||
$callable = [$class, $method];
|
||||
} else {
|
||||
$r = new \ReflectionFunction($callable);
|
||||
if (\is_string($callable) && false !== $pos = strpos($callable, '::')) {
|
||||
$callable = [substr($callable, 0, $pos), substr($callable, 2 + $pos)];
|
||||
}
|
||||
|
||||
return $this->reflector = [$r, $callable];
|
||||
if (\is_array($callable) && method_exists($callable[0], $callable[1])) {
|
||||
$r = new \ReflectionMethod($callable[0], $callable[1]);
|
||||
|
||||
return $this->reflector = [$r, $callable, $r->class.'::'.$r->name];
|
||||
}
|
||||
|
||||
$checkVisibility = $callable instanceof \Closure;
|
||||
try {
|
||||
$closure = \Closure::fromCallable($callable);
|
||||
} catch (\TypeError $e) {
|
||||
throw new \LogicException(sprintf('Callback for %s "%s" is not callable in the current scope.', $this->getAttribute('type'), $this->getAttribute('name')), 0, $e);
|
||||
}
|
||||
$r = new \ReflectionFunction($closure);
|
||||
|
||||
if (false !== strpos($r->name, '{closure}')) {
|
||||
return $this->reflector = [$r, $callable, 'Closure'];
|
||||
}
|
||||
|
||||
if ($object = $r->getClosureThis()) {
|
||||
$callable = [$object, $r->name];
|
||||
$callableName = (\function_exists('get_debug_type') ? get_debug_type($object) : \get_class($object)).'::'.$r->name;
|
||||
} elseif (\PHP_VERSION_ID >= 80111 && $class = $r->getClosureCalledClass()) {
|
||||
$callableName = $class->name.'::'.$r->name;
|
||||
} elseif (\PHP_VERSION_ID < 80111 && $class = $r->getClosureScopeClass()) {
|
||||
$callableName = (\is_array($callable) ? $callable[0] : $class->name).'::'.$r->name;
|
||||
} else {
|
||||
$callable = $callableName = $r->name;
|
||||
}
|
||||
|
||||
if ($checkVisibility && \is_array($callable) && method_exists(...$callable) && !(new \ReflectionMethod(...$callable))->isPublic()) {
|
||||
$callable = $r->getClosure();
|
||||
}
|
||||
|
||||
return $this->reflector = [$r, $callable, $callableName];
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -16,7 +16,7 @@ use Twig\Compiler;
|
||||
|
||||
class ConditionalExpression extends AbstractExpression
|
||||
{
|
||||
public function __construct(AbstractExpression $expr1, AbstractExpression $expr2, AbstractExpression $expr3, $lineno)
|
||||
public function __construct(AbstractExpression $expr1, AbstractExpression $expr2, AbstractExpression $expr3, int $lineno)
|
||||
{
|
||||
parent::__construct(['expr1' => $expr1, 'expr2' => $expr2, 'expr3' => $expr3], [], $lineno);
|
||||
}
|
||||
|
@@ -16,7 +16,7 @@ use Twig\Compiler;
|
||||
|
||||
class ConstantExpression extends AbstractExpression
|
||||
{
|
||||
public function __construct($value, $lineno)
|
||||
public function __construct($value, int $lineno)
|
||||
{
|
||||
parent::__construct([], ['value' => $value], $lineno);
|
||||
}
|
||||
|
@@ -29,7 +29,7 @@ use Twig\Node\Node;
|
||||
*/
|
||||
class DefaultFilter extends FilterExpression
|
||||
{
|
||||
public function __construct(\Twig_NodeInterface $node, ConstantExpression $filterName, \Twig_NodeInterface $arguments, $lineno, $tag = null)
|
||||
public function __construct(Node $node, ConstantExpression $filterName, Node $arguments, int $lineno, string $tag = null)
|
||||
{
|
||||
$default = new FilterExpression($node, new ConstantExpression('default', $node->getTemplateLine()), $arguments, $node->getTemplateLine());
|
||||
|
||||
|
@@ -13,11 +13,11 @@
|
||||
namespace Twig\Node\Expression;
|
||||
|
||||
use Twig\Compiler;
|
||||
use Twig\TwigFilter;
|
||||
use Twig\Node\Node;
|
||||
|
||||
class FilterExpression extends CallExpression
|
||||
{
|
||||
public function __construct(\Twig_NodeInterface $node, ConstantExpression $filterName, \Twig_NodeInterface $arguments, $lineno, $tag = null)
|
||||
public function __construct(Node $node, ConstantExpression $filterName, Node $arguments, int $lineno, string $tag = null)
|
||||
{
|
||||
parent::__construct(['node' => $node, 'filter' => $filterName, 'arguments' => $arguments], [], $lineno, $tag);
|
||||
}
|
||||
@@ -29,16 +29,11 @@ class FilterExpression extends CallExpression
|
||||
|
||||
$this->setAttribute('name', $name);
|
||||
$this->setAttribute('type', 'filter');
|
||||
$this->setAttribute('thing', $filter);
|
||||
$this->setAttribute('needs_environment', $filter->needsEnvironment());
|
||||
$this->setAttribute('needs_context', $filter->needsContext());
|
||||
$this->setAttribute('arguments', $filter->getArguments());
|
||||
if ($filter instanceof \Twig_FilterCallableInterface || $filter instanceof TwigFilter) {
|
||||
$this->setAttribute('callable', $filter->getCallable());
|
||||
}
|
||||
if ($filter instanceof TwigFilter) {
|
||||
$this->setAttribute('is_variadic', $filter->isVariadic());
|
||||
}
|
||||
$this->setAttribute('callable', $filter->getCallable());
|
||||
$this->setAttribute('is_variadic', $filter->isVariadic());
|
||||
|
||||
$this->compileCallable($compiler);
|
||||
}
|
||||
|
@@ -12,11 +12,11 @@
|
||||
namespace Twig\Node\Expression;
|
||||
|
||||
use Twig\Compiler;
|
||||
use Twig\TwigFunction;
|
||||
use Twig\Node\Node;
|
||||
|
||||
class FunctionExpression extends CallExpression
|
||||
{
|
||||
public function __construct($name, \Twig_NodeInterface $arguments, $lineno)
|
||||
public function __construct(string $name, Node $arguments, int $lineno)
|
||||
{
|
||||
parent::__construct(['arguments' => $arguments], ['name' => $name, 'is_defined_test' => false], $lineno);
|
||||
}
|
||||
@@ -28,21 +28,15 @@ class FunctionExpression extends CallExpression
|
||||
|
||||
$this->setAttribute('name', $name);
|
||||
$this->setAttribute('type', 'function');
|
||||
$this->setAttribute('thing', $function);
|
||||
$this->setAttribute('needs_environment', $function->needsEnvironment());
|
||||
$this->setAttribute('needs_context', $function->needsContext());
|
||||
$this->setAttribute('arguments', $function->getArguments());
|
||||
if ($function instanceof \Twig_FunctionCallableInterface || $function instanceof TwigFunction) {
|
||||
$callable = $function->getCallable();
|
||||
if ('constant' === $name && $this->getAttribute('is_defined_test')) {
|
||||
$callable = 'twig_constant_is_defined';
|
||||
}
|
||||
|
||||
$this->setAttribute('callable', $callable);
|
||||
}
|
||||
if ($function instanceof TwigFunction) {
|
||||
$this->setAttribute('is_variadic', $function->isVariadic());
|
||||
$callable = $function->getCallable();
|
||||
if ('constant' === $name && $this->getAttribute('is_defined_test')) {
|
||||
$callable = 'twig_constant_is_defined';
|
||||
}
|
||||
$this->setAttribute('callable', $callable);
|
||||
$this->setAttribute('is_variadic', $function->isVariadic());
|
||||
|
||||
$this->compileCallable($compiler);
|
||||
}
|
||||
|
@@ -13,67 +13,76 @@
|
||||
namespace Twig\Node\Expression;
|
||||
|
||||
use Twig\Compiler;
|
||||
use Twig\Extension\SandboxExtension;
|
||||
use Twig\Template;
|
||||
|
||||
class GetAttrExpression extends AbstractExpression
|
||||
{
|
||||
public function __construct(AbstractExpression $node, AbstractExpression $attribute, AbstractExpression $arguments = null, $type, $lineno)
|
||||
public function __construct(AbstractExpression $node, AbstractExpression $attribute, ?AbstractExpression $arguments, string $type, int $lineno)
|
||||
{
|
||||
$nodes = ['node' => $node, 'attribute' => $attribute];
|
||||
if (null !== $arguments) {
|
||||
$nodes['arguments'] = $arguments;
|
||||
}
|
||||
|
||||
parent::__construct($nodes, ['type' => $type, 'is_defined_test' => false, 'ignore_strict_check' => false, 'disable_c_ext' => false], $lineno);
|
||||
parent::__construct($nodes, ['type' => $type, 'is_defined_test' => false, 'ignore_strict_check' => false, 'optimizable' => true], $lineno);
|
||||
}
|
||||
|
||||
public function compile(Compiler $compiler)
|
||||
{
|
||||
if ($this->getAttribute('disable_c_ext')) {
|
||||
@trigger_error(sprintf('Using the "disable_c_ext" attribute on %s is deprecated since version 1.30 and will be removed in 2.0.', __CLASS__), E_USER_DEPRECATED);
|
||||
$env = $compiler->getEnvironment();
|
||||
|
||||
// optimize array calls
|
||||
if (
|
||||
$this->getAttribute('optimizable')
|
||||
&& (!$env->isStrictVariables() || $this->getAttribute('ignore_strict_check'))
|
||||
&& !$this->getAttribute('is_defined_test')
|
||||
&& Template::ARRAY_CALL === $this->getAttribute('type')
|
||||
) {
|
||||
$var = '$'.$compiler->getVarName();
|
||||
$compiler
|
||||
->raw('(('.$var.' = ')
|
||||
->subcompile($this->getNode('node'))
|
||||
->raw(') && is_array(')
|
||||
->raw($var)
|
||||
->raw(') || ')
|
||||
->raw($var)
|
||||
->raw(' instanceof ArrayAccess ? (')
|
||||
->raw($var)
|
||||
->raw('[')
|
||||
->subcompile($this->getNode('attribute'))
|
||||
->raw('] ?? null) : null)')
|
||||
;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (\function_exists('twig_template_get_attributes') && !$this->getAttribute('disable_c_ext')) {
|
||||
$compiler->raw('twig_template_get_attributes($this, ');
|
||||
} else {
|
||||
$compiler->raw('$this->getAttribute(');
|
||||
}
|
||||
$compiler->raw('twig_get_attribute($this->env, $this->source, ');
|
||||
|
||||
if ($this->getAttribute('ignore_strict_check')) {
|
||||
$this->getNode('node')->setAttribute('ignore_strict_check', true);
|
||||
}
|
||||
|
||||
$compiler->subcompile($this->getNode('node'));
|
||||
$compiler
|
||||
->subcompile($this->getNode('node'))
|
||||
->raw(', ')
|
||||
->subcompile($this->getNode('attribute'))
|
||||
;
|
||||
|
||||
$compiler->raw(', ')->subcompile($this->getNode('attribute'));
|
||||
|
||||
// only generate optional arguments when needed (to make generated code more readable)
|
||||
$needFourth = $this->getAttribute('ignore_strict_check');
|
||||
$needThird = $needFourth || $this->getAttribute('is_defined_test');
|
||||
$needSecond = $needThird || Template::ANY_CALL !== $this->getAttribute('type');
|
||||
$needFirst = $needSecond || $this->hasNode('arguments');
|
||||
|
||||
if ($needFirst) {
|
||||
if ($this->hasNode('arguments')) {
|
||||
$compiler->raw(', ')->subcompile($this->getNode('arguments'));
|
||||
} else {
|
||||
$compiler->raw(', []');
|
||||
}
|
||||
if ($this->hasNode('arguments')) {
|
||||
$compiler->raw(', ')->subcompile($this->getNode('arguments'));
|
||||
} else {
|
||||
$compiler->raw(', []');
|
||||
}
|
||||
|
||||
if ($needSecond) {
|
||||
$compiler->raw(', ')->repr($this->getAttribute('type'));
|
||||
}
|
||||
|
||||
if ($needThird) {
|
||||
$compiler->raw(', ')->repr($this->getAttribute('is_defined_test'));
|
||||
}
|
||||
|
||||
if ($needFourth) {
|
||||
$compiler->raw(', ')->repr($this->getAttribute('ignore_strict_check'));
|
||||
}
|
||||
|
||||
$compiler->raw(')');
|
||||
$compiler->raw(', ')
|
||||
->repr($this->getAttribute('type'))
|
||||
->raw(', ')->repr($this->getAttribute('is_defined_test'))
|
||||
->raw(', ')->repr($this->getAttribute('ignore_strict_check'))
|
||||
->raw(', ')->repr($env->hasExtension(SandboxExtension::class))
|
||||
->raw(', ')->repr($this->getNode('node')->getTemplateLine())
|
||||
->raw(')')
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -15,9 +15,9 @@ use Twig\Compiler;
|
||||
|
||||
class MethodCallExpression extends AbstractExpression
|
||||
{
|
||||
public function __construct(AbstractExpression $node, $method, ArrayExpression $arguments, $lineno)
|
||||
public function __construct(AbstractExpression $node, string $method, ArrayExpression $arguments, int $lineno)
|
||||
{
|
||||
parent::__construct(['node' => $node, 'arguments' => $arguments], ['method' => $method, 'safe' => false], $lineno);
|
||||
parent::__construct(['node' => $node, 'arguments' => $arguments], ['method' => $method, 'safe' => false, 'is_defined_test' => false], $lineno);
|
||||
|
||||
if ($node instanceof NameExpression) {
|
||||
$node->setAttribute('always_defined', true);
|
||||
@@ -26,11 +26,24 @@ class MethodCallExpression extends AbstractExpression
|
||||
|
||||
public function compile(Compiler $compiler)
|
||||
{
|
||||
if ($this->getAttribute('is_defined_test')) {
|
||||
$compiler
|
||||
->raw('method_exists($macros[')
|
||||
->repr($this->getNode('node')->getAttribute('name'))
|
||||
->raw('], ')
|
||||
->repr($this->getAttribute('method'))
|
||||
->raw(')')
|
||||
;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$compiler
|
||||
->subcompile($this->getNode('node'))
|
||||
->raw('->')
|
||||
->raw($this->getAttribute('method'))
|
||||
->raw('(')
|
||||
->raw('twig_call_macro($macros[')
|
||||
->repr($this->getNode('node')->getAttribute('name'))
|
||||
->raw('], ')
|
||||
->repr($this->getAttribute('method'))
|
||||
->raw(', [')
|
||||
;
|
||||
$first = true;
|
||||
foreach ($this->getNode('arguments')->getKeyValuePairs() as $pair) {
|
||||
@@ -41,7 +54,10 @@ class MethodCallExpression extends AbstractExpression
|
||||
|
||||
$compiler->subcompile($pair['value']);
|
||||
}
|
||||
$compiler->raw(')');
|
||||
$compiler
|
||||
->raw('], ')
|
||||
->repr($this->getTemplateLine())
|
||||
->raw(', $context, $this->getSourceContext())');
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -16,13 +16,13 @@ use Twig\Compiler;
|
||||
|
||||
class NameExpression extends AbstractExpression
|
||||
{
|
||||
protected $specialVars = [
|
||||
'_self' => '$this',
|
||||
private $specialVars = [
|
||||
'_self' => '$this->getTemplateName()',
|
||||
'_context' => '$context',
|
||||
'_charset' => '$this->env->getCharset()',
|
||||
];
|
||||
|
||||
public function __construct($name, $lineno)
|
||||
public function __construct(string $name, int $lineno)
|
||||
{
|
||||
parent::__construct([], ['name' => $name, 'is_defined_test' => false, 'ignore_strict_check' => false, 'always_defined' => false], $lineno);
|
||||
}
|
||||
@@ -36,7 +36,7 @@ class NameExpression extends AbstractExpression
|
||||
if ($this->getAttribute('is_defined_test')) {
|
||||
if ($this->isSpecial()) {
|
||||
$compiler->repr(true);
|
||||
} elseif (\PHP_VERSION_ID >= 700400) {
|
||||
} elseif (\PHP_VERSION_ID >= 70400) {
|
||||
$compiler
|
||||
->raw('array_key_exists(')
|
||||
->string($name)
|
||||
@@ -60,45 +60,25 @@ class NameExpression extends AbstractExpression
|
||||
->raw(']')
|
||||
;
|
||||
} else {
|
||||
if (\PHP_VERSION_ID >= 70000) {
|
||||
// use PHP 7 null coalescing operator
|
||||
if ($this->getAttribute('ignore_strict_check') || !$compiler->getEnvironment()->isStrictVariables()) {
|
||||
$compiler
|
||||
->raw('($context[')
|
||||
->string($name)
|
||||
->raw('] ?? ')
|
||||
->raw('] ?? null)')
|
||||
;
|
||||
|
||||
if ($this->getAttribute('ignore_strict_check') || !$compiler->getEnvironment()->isStrictVariables()) {
|
||||
$compiler->raw('null)');
|
||||
} else {
|
||||
$compiler->raw('$this->getContext($context, ')->string($name)->raw('))');
|
||||
}
|
||||
} elseif (\PHP_VERSION_ID >= 50400) {
|
||||
// PHP 5.4 ternary operator performance was optimized
|
||||
} else {
|
||||
$compiler
|
||||
->raw('(isset($context[')
|
||||
->string($name)
|
||||
->raw(']) ? $context[')
|
||||
->raw(']) || array_key_exists(')
|
||||
->string($name)
|
||||
->raw('] : ')
|
||||
;
|
||||
|
||||
if ($this->getAttribute('ignore_strict_check') || !$compiler->getEnvironment()->isStrictVariables()) {
|
||||
$compiler->raw('null)');
|
||||
} else {
|
||||
$compiler->raw('$this->getContext($context, ')->string($name)->raw('))');
|
||||
}
|
||||
} else {
|
||||
$compiler
|
||||
->raw('$this->getContext($context, ')
|
||||
->raw(', $context) ? $context[')
|
||||
->string($name)
|
||||
;
|
||||
|
||||
if ($this->getAttribute('ignore_strict_check')) {
|
||||
$compiler->raw(', true');
|
||||
}
|
||||
|
||||
$compiler
|
||||
->raw('] : (function () { throw new RuntimeError(\'Variable ')
|
||||
->string($name)
|
||||
->raw(' does not exist.\', ')
|
||||
->repr($this->lineno)
|
||||
->raw(', $this->source); })()')
|
||||
->raw(')')
|
||||
;
|
||||
}
|
||||
|
@@ -20,7 +20,7 @@ use Twig\Node\Node;
|
||||
|
||||
class NullCoalesceExpression extends ConditionalExpression
|
||||
{
|
||||
public function __construct(\Twig_NodeInterface $left, \Twig_NodeInterface $right, $lineno)
|
||||
public function __construct(Node $left, Node $right, int $lineno)
|
||||
{
|
||||
$test = new DefinedTest(clone $left, 'defined', new Node(), $left->getTemplateLine());
|
||||
// for "block()", we don't need the null test as the return value is always a string
|
||||
@@ -44,7 +44,7 @@ class NullCoalesceExpression extends ConditionalExpression
|
||||
* cases might be implemented as an optimizer node visitor, but has not been done
|
||||
* as benefits are probably not worth the added complexity.
|
||||
*/
|
||||
if (\PHP_VERSION_ID >= 70000 && $this->getNode('expr2') instanceof NameExpression) {
|
||||
if ($this->getNode('expr2') instanceof NameExpression) {
|
||||
$this->getNode('expr2')->setAttribute('always_defined', true);
|
||||
$compiler
|
||||
->raw('((')
|
||||
|
@@ -21,7 +21,7 @@ use Twig\Compiler;
|
||||
*/
|
||||
class ParentExpression extends AbstractExpression
|
||||
{
|
||||
public function __construct($name, $lineno, $tag = null)
|
||||
public function __construct(string $name, int $lineno, string $tag = null)
|
||||
{
|
||||
parent::__construct([], ['output' => false, 'name' => $name], $lineno, $tag);
|
||||
}
|
||||
|
@@ -15,7 +15,7 @@ use Twig\Compiler;
|
||||
|
||||
class TempNameExpression extends AbstractExpression
|
||||
{
|
||||
public function __construct($name, $lineno)
|
||||
public function __construct(string $name, int $lineno)
|
||||
{
|
||||
parent::__construct([], ['name' => $name], $lineno);
|
||||
}
|
||||
|
@@ -18,8 +18,10 @@ use Twig\Node\Expression\BlockReferenceExpression;
|
||||
use Twig\Node\Expression\ConstantExpression;
|
||||
use Twig\Node\Expression\FunctionExpression;
|
||||
use Twig\Node\Expression\GetAttrExpression;
|
||||
use Twig\Node\Expression\MethodCallExpression;
|
||||
use Twig\Node\Expression\NameExpression;
|
||||
use Twig\Node\Expression\TestExpression;
|
||||
use Twig\Node\Node;
|
||||
|
||||
/**
|
||||
* Checks if a variable is defined in the current context.
|
||||
@@ -33,7 +35,7 @@ use Twig\Node\Expression\TestExpression;
|
||||
*/
|
||||
class DefinedTest extends TestExpression
|
||||
{
|
||||
public function __construct(\Twig_NodeInterface $node, $name, \Twig_NodeInterface $arguments = null, $lineno)
|
||||
public function __construct(Node $node, string $name, ?Node $arguments, int $lineno)
|
||||
{
|
||||
if ($node instanceof NameExpression) {
|
||||
$node->setAttribute('is_defined_test', true);
|
||||
@@ -46,6 +48,8 @@ class DefinedTest extends TestExpression
|
||||
$node->setAttribute('is_defined_test', true);
|
||||
} elseif ($node instanceof ConstantExpression || $node instanceof ArrayExpression) {
|
||||
$node = new ConstantExpression(true, $node->getTemplateLine());
|
||||
} elseif ($node instanceof MethodCallExpression) {
|
||||
$node->setAttribute('is_defined_test', true);
|
||||
} else {
|
||||
throw new SyntaxError('The "defined" test only works with simple variables.', $lineno);
|
||||
}
|
||||
@@ -53,8 +57,9 @@ class DefinedTest extends TestExpression
|
||||
parent::__construct($node, $name, $arguments, $lineno);
|
||||
}
|
||||
|
||||
protected function changeIgnoreStrictCheck(GetAttrExpression $node)
|
||||
private function changeIgnoreStrictCheck(GetAttrExpression $node)
|
||||
{
|
||||
$node->setAttribute('optimizable', false);
|
||||
$node->setAttribute('ignore_strict_check', true);
|
||||
|
||||
if ($node->getNode('node') instanceof GetAttrExpression) {
|
||||
|
@@ -28,7 +28,7 @@ class OddTest extends TestExpression
|
||||
$compiler
|
||||
->raw('(')
|
||||
->subcompile($this->getNode('node'))
|
||||
->raw(' % 2 == 1')
|
||||
->raw(' % 2 != 0')
|
||||
->raw(')')
|
||||
;
|
||||
}
|
||||
|
@@ -12,11 +12,11 @@
|
||||
namespace Twig\Node\Expression;
|
||||
|
||||
use Twig\Compiler;
|
||||
use Twig\TwigTest;
|
||||
use Twig\Node\Node;
|
||||
|
||||
class TestExpression extends CallExpression
|
||||
{
|
||||
public function __construct(\Twig_NodeInterface $node, $name, \Twig_NodeInterface $arguments = null, $lineno)
|
||||
public function __construct(Node $node, string $name, ?Node $arguments, int $lineno)
|
||||
{
|
||||
$nodes = ['node' => $node];
|
||||
if (null !== $arguments) {
|
||||
@@ -33,16 +33,9 @@ class TestExpression extends CallExpression
|
||||
|
||||
$this->setAttribute('name', $name);
|
||||
$this->setAttribute('type', 'test');
|
||||
$this->setAttribute('thing', $test);
|
||||
if ($test instanceof TwigTest) {
|
||||
$this->setAttribute('arguments', $test->getArguments());
|
||||
}
|
||||
if ($test instanceof \Twig_TestCallableInterface || $test instanceof TwigTest) {
|
||||
$this->setAttribute('callable', $test->getCallable());
|
||||
}
|
||||
if ($test instanceof TwigTest) {
|
||||
$this->setAttribute('is_variadic', $test->isVariadic());
|
||||
}
|
||||
$this->setAttribute('arguments', $test->getArguments());
|
||||
$this->setAttribute('callable', $test->getCallable());
|
||||
$this->setAttribute('is_variadic', $test->isVariadic());
|
||||
|
||||
$this->compileCallable($compiler);
|
||||
}
|
||||
|
@@ -14,10 +14,11 @@ namespace Twig\Node\Expression\Unary;
|
||||
|
||||
use Twig\Compiler;
|
||||
use Twig\Node\Expression\AbstractExpression;
|
||||
use Twig\Node\Node;
|
||||
|
||||
abstract class AbstractUnary extends AbstractExpression
|
||||
{
|
||||
public function __construct(\Twig_NodeInterface $node, $lineno)
|
||||
public function __construct(Node $node, int $lineno)
|
||||
{
|
||||
parent::__construct(['node' => $node], [], $lineno);
|
||||
}
|
||||
|
24
system/libs/Twig/Node/Expression/VariadicExpression.php
Normal file
24
system/libs/Twig/Node/Expression/VariadicExpression.php
Normal file
@@ -0,0 +1,24 @@
|
||||
<?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\Expression;
|
||||
|
||||
use Twig\Compiler;
|
||||
|
||||
class VariadicExpression extends ArrayExpression
|
||||
{
|
||||
public function compile(Compiler $compiler)
|
||||
{
|
||||
$compiler->raw('...');
|
||||
|
||||
parent::compile($compiler);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user