mirror of
https://github.com/twigphp/Twig.git
synced 2026-09-14 11:27:00 +00:00
Merge branch '3.x' into 4.x
* 3.x: Add return type annotations on Twig 3 to prepare Twig 4
This commit is contained in:
@@ -67,6 +67,9 @@ abstract class AbstractTwigCallable implements TwigCallableInterface
|
||||
return $this->dynamicName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return callable|array{class-string, string}|null
|
||||
*/
|
||||
public function getCallable()
|
||||
{
|
||||
return $this->callable;
|
||||
|
||||
@@ -145,6 +145,8 @@ class Environment
|
||||
|
||||
/**
|
||||
* Enables debugging mode.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function enableDebug()
|
||||
{
|
||||
@@ -154,6 +156,8 @@ class Environment
|
||||
|
||||
/**
|
||||
* Disables debugging mode.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function disableDebug()
|
||||
{
|
||||
@@ -173,6 +177,8 @@ class Environment
|
||||
|
||||
/**
|
||||
* Enables the auto_reload option.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function enableAutoReload()
|
||||
{
|
||||
@@ -181,6 +187,8 @@ class Environment
|
||||
|
||||
/**
|
||||
* Disables the auto_reload option.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function disableAutoReload()
|
||||
{
|
||||
@@ -199,6 +207,8 @@ class Environment
|
||||
|
||||
/**
|
||||
* Enables the strict_variables option.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function enableStrictVariables()
|
||||
{
|
||||
@@ -208,6 +218,8 @@ class Environment
|
||||
|
||||
/**
|
||||
* Disables the strict_variables option.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function disableStrictVariables()
|
||||
{
|
||||
@@ -257,6 +269,8 @@ class Environment
|
||||
* @param CacheInterface|string|false $cache A Twig\Cache\CacheInterface implementation,
|
||||
* an absolute path to the compiled templates,
|
||||
* or false to disable cache
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setCache($cache)
|
||||
{
|
||||
@@ -483,6 +497,9 @@ class Environment
|
||||
throw new LoaderError(\sprintf('Unable to find one of the following templates: "%s".', implode('", "', $names)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function setLexer(Lexer $lexer)
|
||||
{
|
||||
$this->lexer = $lexer;
|
||||
@@ -500,6 +517,9 @@ class Environment
|
||||
return $this->lexer->tokenize($source);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function setParser(Parser $parser)
|
||||
{
|
||||
$this->parser = $parser;
|
||||
@@ -519,6 +539,9 @@ class Environment
|
||||
return $this->parser->parse($stream);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function setCompiler(Compiler $compiler)
|
||||
{
|
||||
$this->compiler = $compiler;
|
||||
@@ -553,6 +576,9 @@ class Environment
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function setLoader(LoaderInterface $loader)
|
||||
{
|
||||
$this->loader = $loader;
|
||||
@@ -563,6 +589,9 @@ class Environment
|
||||
return $this->loader;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function setCharset(string $charset)
|
||||
{
|
||||
if ('UTF8' === $charset = strtoupper($charset ?: '')) {
|
||||
@@ -583,6 +612,9 @@ class Environment
|
||||
return $this->extensionSet->hasExtension($class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function addRuntimeLoader(RuntimeLoaderInterface $loader)
|
||||
{
|
||||
$this->runtimeLoaders[] = $loader;
|
||||
@@ -630,6 +662,9 @@ class Environment
|
||||
throw new RuntimeError(\sprintf('Unable to load the "%s" runtime.', $class));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function addExtension(ExtensionInterface $extension)
|
||||
{
|
||||
$this->extensionSet->addExtension($extension);
|
||||
@@ -638,6 +673,8 @@ class Environment
|
||||
|
||||
/**
|
||||
* @param ExtensionInterface[] $extensions An array of extensions
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setExtensions(array $extensions)
|
||||
{
|
||||
@@ -653,6 +690,9 @@ class Environment
|
||||
return $this->extensionSet->getExtensions();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function addTokenParser(TokenParserInterface $parser)
|
||||
{
|
||||
$this->extensionSet->addTokenParser($parser);
|
||||
@@ -681,6 +721,9 @@ class Environment
|
||||
$this->extensionSet->registerUndefinedTokenParserCallback($callable);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function addNodeVisitor(NodeVisitorInterface $visitor)
|
||||
{
|
||||
$this->extensionSet->addNodeVisitor($visitor);
|
||||
@@ -696,6 +739,9 @@ class Environment
|
||||
return $this->extensionSet->getNodeVisitors();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function addFilter(TwigFilter $filter)
|
||||
{
|
||||
$this->extensionSet->addFilter($filter);
|
||||
@@ -730,6 +776,9 @@ class Environment
|
||||
return $this->extensionSet->getFilters();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function addTest(TwigTest $test)
|
||||
{
|
||||
$this->extensionSet->addTest($test);
|
||||
@@ -753,6 +802,9 @@ class Environment
|
||||
return $this->extensionSet->getTest($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function addFunction(TwigFunction $function)
|
||||
{
|
||||
$this->extensionSet->addFunction($function);
|
||||
@@ -794,6 +846,8 @@ class Environment
|
||||
* but after, you can only update existing globals.
|
||||
*
|
||||
* @param mixed $value The global value
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function addGlobal(string $name, $value)
|
||||
{
|
||||
|
||||
@@ -97,6 +97,8 @@ final class EscaperExtension extends AbstractExtension
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @return array<string>
|
||||
*/
|
||||
public static function escapeFilterIsSafe(Node $filterArgs)
|
||||
{
|
||||
|
||||
@@ -66,7 +66,7 @@ final class SandboxExtension extends AbstractExtension
|
||||
return $this->sourcePolicy->enableSandbox($source);
|
||||
}
|
||||
|
||||
public function setSecurityPolicy(SecurityPolicyInterface $policy)
|
||||
public function setSecurityPolicy(SecurityPolicyInterface $policy): void
|
||||
{
|
||||
$this->policy = $policy;
|
||||
}
|
||||
@@ -111,6 +111,13 @@ final class SandboxExtension extends AbstractExtension
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $obj
|
||||
*
|
||||
* @return mixed
|
||||
*
|
||||
* @throws SecurityNotAllowedMethodError
|
||||
*/
|
||||
public function ensureToStringAllowed($obj, int $lineno = -1, ?Source $source = null)
|
||||
{
|
||||
if (\is_array($obj)) {
|
||||
|
||||
@@ -66,6 +66,9 @@ final class ExtensionSet
|
||||
$this->staging = new StagingExtension();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function initRuntime()
|
||||
{
|
||||
$this->runtimeInitialized = true;
|
||||
|
||||
@@ -78,6 +78,9 @@ class IncludeNode extends Node implements NodeOutputInterface
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
protected function addGetTemplate(Compiler $compiler/* , string $template = '' */)
|
||||
{
|
||||
$compiler
|
||||
@@ -91,6 +94,9 @@ class IncludeNode extends Node implements NodeOutputInterface
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
protected function addTemplateArguments(Compiler $compiler)
|
||||
{
|
||||
if (!$this->hasNode('variables')) {
|
||||
|
||||
@@ -139,6 +139,9 @@ abstract class Node implements \Countable, \IteratorAggregate
|
||||
return \array_key_exists($name, $this->attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getAttribute(string $name)
|
||||
{
|
||||
if (!\array_key_exists($name, $this->attributes)) {
|
||||
|
||||
@@ -230,6 +230,9 @@ class Parser
|
||||
return new Nodes($rv, $lineno);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
public function peekBlockStack()
|
||||
{
|
||||
return $this->blockStack[\count($this->blockStack) - 1] ?? null;
|
||||
@@ -279,6 +282,9 @@ class Parser
|
||||
$this->importedSymbols[0][$type][$alias] = ['name' => $name, 'node' => $internalRef];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array{name: string, node: AssignTemplateVariable|null}|null
|
||||
*/
|
||||
public function getImportedSymbol(string $type, string $alias)
|
||||
{
|
||||
// if the symbol does not exist in the current scope (0), try in the main/global scope (last index)
|
||||
@@ -305,6 +311,9 @@ class Parser
|
||||
return $this->expressionParser;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function hasInheritance()
|
||||
{
|
||||
return $this->parent || 0 < \count($this->traits);
|
||||
|
||||
@@ -36,6 +36,8 @@ final class EscaperRuntime implements RuntimeExtensionInterface
|
||||
*
|
||||
* @param string $strategy The strategy name that should be used as a strategy in the escape call
|
||||
* @param callable(string $string, string $charset): string $callable A valid PHP callable
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setEscaper($strategy, callable $callable)
|
||||
{
|
||||
@@ -54,6 +56,8 @@ final class EscaperRuntime implements RuntimeExtensionInterface
|
||||
|
||||
/**
|
||||
* @param array<class-string<\Stringable>, string[]> $safeClasses
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setSafeClasses(array $safeClasses = [])
|
||||
{
|
||||
@@ -67,6 +71,8 @@ final class EscaperRuntime implements RuntimeExtensionInterface
|
||||
/**
|
||||
* @param class-string<\Stringable> $class
|
||||
* @param string[] $strategies
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function addSafeClass(string $class, array $strategies)
|
||||
{
|
||||
|
||||
@@ -33,7 +33,7 @@ final class SecurityNotAllowedMethodError extends SecurityError
|
||||
return $this->className;
|
||||
}
|
||||
|
||||
public function getMethodName()
|
||||
public function getMethodName(): string
|
||||
{
|
||||
return $this->methodName;
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ final class SecurityNotAllowedPropertyError extends SecurityError
|
||||
return $this->className;
|
||||
}
|
||||
|
||||
public function getPropertyName()
|
||||
public function getPropertyName(): string
|
||||
{
|
||||
return $this->propertyName;
|
||||
}
|
||||
|
||||
@@ -51,6 +51,9 @@ final class TemplateWrapper
|
||||
return $this->template->render($context);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function display(array $context = [])
|
||||
{
|
||||
// using func_get_args() allows to not expose the blocks argument
|
||||
@@ -76,6 +79,9 @@ final class TemplateWrapper
|
||||
return $this->template->renderBlock($name, $context + $this->env->getGlobals());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function displayBlock(string $name, array $context = [])
|
||||
{
|
||||
$context += $this->env->getGlobals();
|
||||
|
||||
@@ -76,6 +76,8 @@ abstract class IntegrationTestCase extends TestCase
|
||||
|
||||
/**
|
||||
* @dataProvider getTests
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
#[DataProvider('getTests')]
|
||||
public function testIntegration($file, $message, $condition, $templates, $exception, $outputs, $deprecation = '')
|
||||
@@ -87,6 +89,8 @@ abstract class IntegrationTestCase extends TestCase
|
||||
* @dataProvider getLegacyTests
|
||||
*
|
||||
* @group legacy
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
#[DataProvider('getLegacyTests'), IgnoreDeprecations]
|
||||
public function testLegacyIntegration($file, $message, $condition, $templates, $exception, $outputs, $deprecation = '')
|
||||
@@ -150,6 +154,9 @@ abstract class IntegrationTestCase extends TestCase
|
||||
return self::assembleTests(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
protected function doIntegrationTest($file, $message, $condition, $templates, $exception, $outputs, $deprecation = '')
|
||||
{
|
||||
if (!$outputs) {
|
||||
@@ -259,6 +266,9 @@ abstract class IntegrationTestCase extends TestCase
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, string>
|
||||
*/
|
||||
protected static function parseTemplates($test)
|
||||
{
|
||||
$templates = [];
|
||||
|
||||
@@ -22,6 +22,14 @@ abstract class NodeTestCase extends TestCase
|
||||
{
|
||||
private Environment $currentEnv;
|
||||
|
||||
/**
|
||||
* @return iterable<array{0: Node, 1: string, 2?: Environment|null, 3?: bool}>
|
||||
*/
|
||||
public function getTests()
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return iterable<array{0: Node, 1: string, 2?: Environment|null, 3?: bool}>
|
||||
*/
|
||||
@@ -29,6 +37,8 @@ abstract class NodeTestCase extends TestCase
|
||||
|
||||
/**
|
||||
* @dataProvider provideTests
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
#[DataProvider('provideTests')]
|
||||
public function testCompile($node, $source, $environment = null, $isPattern = false)
|
||||
@@ -36,6 +46,9 @@ abstract class NodeTestCase extends TestCase
|
||||
$this->assertNodeCompilation($source, $node, $environment, $isPattern);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function assertNodeCompilation($source, Node $node, ?Environment $environment = null, $isPattern = false)
|
||||
{
|
||||
$compiler = $this->getCompiler($environment);
|
||||
@@ -48,6 +61,9 @@ abstract class NodeTestCase extends TestCase
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Compiler
|
||||
*/
|
||||
protected function getCompiler(?Environment $environment = null)
|
||||
{
|
||||
return new Compiler($environment ?? $this->getEnvironment());
|
||||
|
||||
@@ -80,6 +80,9 @@ final class Token
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getValue()
|
||||
{
|
||||
return $this->value;
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
namespace Twig\TokenParser;
|
||||
|
||||
use Twig\Node\Expression\AbstractExpression;
|
||||
use Twig\Node\IncludeNode;
|
||||
use Twig\Node\Node;
|
||||
use Twig\Token;
|
||||
@@ -36,6 +37,9 @@ class IncludeTokenParser extends AbstractTokenParser
|
||||
return new IncludeNode($expr, $variables, $only, $ignoreMissing, $token->getLine());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array{0: ?AbstractExpression, 1: bool, 2: bool}
|
||||
*/
|
||||
protected function parseArguments()
|
||||
{
|
||||
$stream = $this->parser->getStream();
|
||||
|
||||
Reference in New Issue
Block a user