Файловый менеджер - Редактировать - /home/pimjdymy/public_html/safrandsi/twig.zip
Назад
PK �xE\ �W�� � twig/README.rstnu �[��� Twig, the flexible, fast, and secure template language for PHP ============================================================== Twig is a template language for PHP. Twig uses a syntax similar to the Django and Jinja template languages which inspired the Twig runtime environment. Sponsors -------- .. raw:: html <a href="https://docs.blackfire.io/introduction?utm_source=twig&utm_medium=github_readme&utm_campaign=logo"> <img src="https://static.blackfire.io/assets/intemporals/logo/png/blackfire-io_secondary_horizontal_transparent.png?1" width="255px" alt="Blackfire.io"> </a> More Information ---------------- Read the `documentation`_ for more information. .. _documentation: https://twig.symfony.com/documentation PK �xE\�'��@ �@ twig/CHANGELOGnu �[��� # 3.15.0 (2024-XX-XX) * Add Spanish inflector support for the `plural` and `singular` filters in the String extension * Deprecate `TempNameExpression` in favor of `LocalVariable` * Deprecate `NameExpression` in favor of `ContextVariable` * Deprecate `AssignNameExpression` in favor of `AssignContextVariable` * Remove `MacroAutoImportNodeVisitor` * Deprecate `MethodCallExpression` in favor of `MacroReferenceExpression` * Fix support for the "is defined" test on `_self.xxx` (auto-imported) macros * Fix support for the "is defined" test on inherited macros * Add named arguments support for the dot operator arguments (`foo.bar(some: arg)`) * Add named arguments support for macros * Add a new `guard` tag that allows to test if some Twig callables are available at compilation time * Allow arrow functions everywhere * Deprecate passing a string or an array to Twig callable arguments accepting arrow functions (pass a `\Closure`) * Add support for triggering deprecations for future operator precedence changes * Deprecate using the `not` unary operator in an expression with ``*``, ``/``, ``//``, or ``%`` without using explicit parentheses to clarify precedence * Deprecate using the `??` binary operator without explicit parentheses * Deprecate using the `~` binary operator in an expression with `+` or `-` without using parentheses to clarify precedence * Deprecate not passing `AbstractExpression` args to most constructor arguments for classes extending `AbstractExpression` * Fix `power` expressions with a negative number in parenthesis (`(-1) ** 2`) * Deprecate instantiating `Node` directly. Use `EmptyNode` or `Nodes` instead. * Add support for inline comments * Add support for accessing class constants with the dot operator * Add `Profile::getStartTime()` and `Profile::getEndTime()` * Fix "ignore missing" when used on an "embed" tag * Fix the possibility to override an aliased block (via use) * Add template cache hot reload * Allow Twig callable argument names to be free-form (snake-case or camelCase) independently of the PHP callable signature They were automatically converted to snake-cased before * Deprecate the `attribute` function; use the `.` notation and wrap the name with parenthesis instead * Add support for argument unpackaging * Add JSON support for the file extension escaping strategy * Support Markup instances (and any other \Stringable) as dynamic mapping keys * Deprecate the `sandbox` tag * Improve the way one can deprecate a Twig callable (use `deprecation_info` instead of the other callable options) * Add the `enum` function * Add support for logical `xor` operator # 3.14.2 (2024-11-07) * Fix an infinite recursion in the sandbox code # 3.14.1 (2024-11-06) * [BC BREAK] Fix a security issue in the sandbox mode allowing an attacker to call attributes on Array-like objects They are now checked via the property policy * Fix a security issue in the sandbox mode allowing an attacker to be able to call `toString()` under some circumstances on an object even if the `__toString()` method is not allowed by the security policy # 3.14.0 (2024-09-09) * Fix a security issue when an included sandboxed template has been loaded before without the sandbox context * Add the possibility to reset globals via `Environment::resetGlobals()` * Deprecate `Environment::mergeGlobals()` # 3.13.0 (2024-09-07) * Add the `types` tag (experimental) * Deprecate the `Twig\Test\NodeTestCase::getTests()` data provider, override `provideTests()` instead. * Mark `Twig\Test\NodeTestCase::getEnvironment()` as final, override `createEnvironment()` instead. * Deprecate `Twig\Test\NodeTestCase::getVariableGetter()`, call `createVariableGetter()` instead. * Deprecate `Twig\Test\NodeTestCase::getAttributeGetter()`, call `createAttributeGetter()` instead. * Deprecate not overriding `Twig\Test\IntegrationTestCase::getFixturesDirectory()`, this method will be abstract in 4.0 * Marked `Twig\Test\IntegrationTestCase::getTests()` and `getLegacyTests()` as final # 3.12.0 (2024-08-29) * Deprecate the fact that the `extends` and `use` tags are always allowed in a sandboxed template. This behavior will change in 4.0 where these tags will need to be explicitly allowed like any other tag. * Deprecate the "tag" constructor argument of the "Twig\Node\Node" class as the tag is now automatically set by the Parser when needed * Fix precedence of two-word tests when the first word is a valid test * Deprecate the `spaceless` filter * Deprecate some internal methods from `Parser`: `getBlockStack()`, `hasBlock()`, `getBlock()`, `hasMacro()`, `hasTraits()`, `getParent()` * Deprecate passing `null` to `Twig\Parser::setParent()` * Update `Node::__toString()` to include the node tag if set * Add support for integers in methods of `Twig\Node\Node` that take a Node name * Deprecate not passing a `BodyNode` instance as the body of a `ModuleNode` or `MacroNode` constructor * Deprecate returning "null" from "TokenParserInterface::parse()". * Deprecate `OptimizerNodeVisitor::OPTIMIZE_TEXT_NODES` * Fix performance regression when `use_yield` is `false` (which is the default) * Improve compatibility when `use_yield` is `false` (as extensions still using `echo` will work as is) * Accept colons (`:`) in addition to equals (`=`) to separate argument names and values in named arguments * Add the `html_cva` function (in the HTML extra package) * Add support for named arguments to the `block` and `attribute` functions * Throw a SyntaxError exception at compile time when a Twig callable has not the minimum number of required arguments * Add a `CallableArgumentsExtractor` class * Deprecate passing a name to `FunctionExpression`, `FilterExpression`, and `TestExpression`; pass a `TwigFunction`, `TwigFilter`, or `TestFilter` instead * Deprecate all Twig callable attributes on `FunctionExpression`, `FilterExpression`, and `TestExpression` * Deprecate the `filter` node of `FilterExpression` * Add the notion of Twig callables (functions, filters, and tests) * Bump minimum PHP version to 8.0 * Fix integration tests when a test has more than one data/expect section and deprecations * Add the `enum_cases` function # 3.11.2 (2024-11-06) * [BC BREAK] Fix a security issue in the sandbox mode allowing an attacker to call attributes on Array-like objects They are now checked via the property policy * Fix a security issue in the sandbox mode allowing an attacker to be able to call `toString()` under some circumstances on an object even if the `__toString()` method is not allowed by the security policy # 3.11.1 (2024-09-10) * Fix a security issue when an included sandboxed template has been loaded before without the sandbox context # 3.11.0 (2024-08-08) * Deprecate `OptimizerNodeVisitor::OPTIMIZE_RAW_FILTER` * Add `Twig\Cache\ChainCache` and `Twig\Cache\ReadOnlyFilesystemCache` * Add the possibility to deprecate attributes and nodes on `Node` * Add the possibility to add a package and a version to the `deprecated` tag * Add the possibility to add a package for filter/function/test deprecations * Mark `ConstantExpression` as being `@final` * Add the `find` filter * Fix optimizer mode validation in `OptimizerNodeVisitor` * Add the possibility to yield from a generator in `PrintNode` * Add the `shuffle` filter * Add the `singular` and `plural` filters in `StringExtension` * Deprecate the second argument of `Twig\Node\Expression\CallExpression::compileArguments()` * Deprecate `Twig\ExpressionParser\parseHashExpression()` in favor of `Twig\ExpressionParser::parseMappingExpression()` * Deprecate `Twig\ExpressionParser\parseArrayExpression()` in favor of `Twig\ExpressionParser::parseSequenceExpression()` * Add `sequence` and `mapping` tests * Deprecate `Twig\Node\Expression\NameExpression::isSimple()` and `Twig\Node\Expression\NameExpression::isSpecial()` # 3.10.3 (2024-05-16) * Fix missing ; in generated code # 3.10.2 (2024-05-14) * Fix support for the deprecated escaper signature # 3.10.1 (2024-05-12) * Fix BC break on escaper extension * Fix constant return type # 3.10.0 (2024-05-11) * Make `CoreExtension::formatDate`, `CoreExtension::convertDate`, and `CoreExtension::formatNumber` part of the public API * Add `needs_charset` option for filters and functions * Extract the escaping logic from the `EscaperExtension` class to a new `EscaperRuntime` class. The following methods from ``Twig\\Extension\\EscaperExtension`` are deprecated: ``setEscaper()``, ``getEscapers()``, ``setSafeClasses``, ``addSafeClasses()``. Use the same methods on the ``Twig\\Runtime\\EscaperRuntime`` class instead. * Fix capturing output from extensions that still use echo * Fix a PHP warning in the Lexer on malformed templates * Fix blocks not available under some circumstances * Synchronize source context in templates when setting a Node on a Node # 3.9.3 (2024-04-18) * Add missing `twig_escape_filter_is_safe` deprecated function * Fix yield usage with CaptureNode * Add missing unwrap call when using a TemplateWrapper instance internally * Ensure Lexer is initialized early on # 3.9.2 (2024-04-17) * Fix usage of display_end hook # 3.9.1 (2024-04-17) * Fix missing `$blocks` variable in `CaptureNode` # 3.9.0 (2024-04-16) * Add support for PHP 8.4 * Deprecate AbstractNodeVisitor * Deprecate passing Template to Environment::resolveTemplate(), Environment::load(), and Template::loadTemplate() * Add a new "yield" mode for output generation; Node implementations that use "echo" or "print" should use "yield" instead; all Node implementations should be flagged with `#[YieldReady]` once they've been made ready for "yield"; the "use_yield" Environment option can be turned on when all nodes have been made `#[YieldReady]`; "yield" will be the only strategy supported in the next major version * Add return type for Symfony 7 compatibility * Fix premature loop exit in Security Policy lookup of allowed methods/properties * Deprecate all internal extension functions in favor of methods on the extension classes * Mark all extension functions as @internal * Add SourcePolicyInterface to selectively enable the Sandbox based on a template's Source * Throw a proper Twig exception when using cycle on an empty array # 3.8.0 (2023-11-21) * Catch errors thrown during template rendering * Fix IntlExtension::formatDateTime use of date formatter prototype * Fix premature loop exit in Security Policy lookup of allowed methods/properties * Remove NumberFormatter::TYPE_CURRENCY (deprecated in PHP 8.3) * Restore return type annotations * Allow Symfony 7 packages to be installed * Deprecate `twig_test_iterable` function. Use the native `is_iterable` instead. # 3.7.1 (2023-08-28) * Fix some phpdocs # 3.7.0 (2023-07-26) * Add support for the ...spread operator on arrays and hashes # 3.6.1 (2023-06-08) * Suppress some native return type deprecation messages # 3.6.0 (2023-05-03) * Allow psr/container 2.0 * Add the new PHP 8.0 IntlDateFormatter::RELATIVE_* constants for date formatting * Make the Lexer initialize itself lazily # 3.5.1 (2023-02-08) * Arrow functions passed to the "reduce" filter now accept the current key as a third argument * Restores the leniency of the matches twig comparison * Fix error messages in sandboxed mode for "has some" and "has every" # 3.5.0 (2022-12-27) * Make Twig\ExpressionParser non-internal * Add "has some" and "has every" operators * Add Compile::reset() * Throw a better runtime error when the "matches" regexp is not valid * Add "twig *_names" intl functions * Fix optimizing closures callbacks * Add a better exception when getting an undefined constant via `constant` * Fix `if` nodes when outside of a block and with an empty body # 3.4.3 (2022-09-28) * Fix a security issue on filesystem loader (possibility to load a template outside a configured directory) # 3.4.2 (2022-08-12) * Allow inherited magic method to still run with calling class * Fix CallExpression::reflectCallable() throwing TypeError * Fix typo in naming (currency_code) # 3.4.1 (2022-05-17) * Fix optimizing non-public named closures # 3.4.0 (2022-05-22) * Add support for named closures # 3.3.10 (2022-04-06) * Enable bytecode invalidation when auto_reload is enabled # 3.3.9 (2022-03-25) * Fix custom escapers when using multiple Twig environments * Add support for "constant('class', object)" * Do not reuse internally generated variable names during parsing # 3.3.8 (2022-02-04) * Fix a security issue when in a sandbox: the `sort` filter must require a Closure for the `arrow` parameter * Fix deprecation notice on `round` * Fix call to deprecated `convertToHtml` method # 3.3.7 (2022-01-03) * Allow more null support when Twig expects a string (for better 8.1 support) * Only use Commonmark extensions if markdown enabled # 3.3.6 (2022-01-03) * Only use Commonmark extensions if markdown enabled # 3.3.5 (2022-01-03) * Allow CommonMark extensions to easily be added * Allow null when Twig expects a string (for better 8.1 support) * Make some performance optimizations * Allow Symfony translation contract v3+ # 3.3.4 (2021-11-25) * Bump minimum supported Symfony component versions * Fix a deprecated message # 3.3.3 (2021-09-17) * Allow Symfony 6 * Improve compatibility with PHP 8.1 * Explicitly specify the encoding for mb_ord in JS escaper # 3.3.2 (2021-05-16) * Revert "Throw a proper exception when a template name is an absolute path (as it has never been supported)" # 3.3.1 (2021-05-12) * Fix PHP 8.1 compatibility * Throw a proper exception when a template name is an absolute path (as it has never been supported) # 3.3.0 (2021-02-08) * Fix macro calls in a "cache" tag * Add the slug filter * Allow extra bundle to be compatible with Twig 2 # 3.2.1 (2021-01-05) * Fix extra bundle compat with older versions of Symfony # 3.2.0 (2021-01-05) * Add the Cache extension in the "extra" repositories: "cache" tag * Add "registerUndefinedTokenParserCallback" * Mark built-in node visitors as @internal * Fix "odd" not working for negative numbers # 3.1.1 (2020-10-27) * Fix "include(template_from_string())" # 3.1.0 (2020-10-21) * Fix sandbox support when using "include(template_from_string())" * Make round brackets optional for one argument tests like "same as" or "divisible by" * Add support for ES2015 style object initialisation shortcut { a } is the same as { 'a': a } # 3.0.5 (2020-08-05) * Fix twig_compare w.r.t. whitespace trimming * Fix sandbox not disabled if syntax error occurs within {% sandbox %} tag * Fix a regression when not using a space before an operator * Restrict callables to closures in filters * Allow trailing commas in argument lists (in calls as well as definitions) # 3.0.4 (2020-07-05) * Fix comparison operators * Fix options not taken into account when using "Michelf\MarkdownExtra" * Fix "Twig\Extra\Intl\IntlExtension::getCountryName()" to accept "null" as a first argument * Throw exception in case non-Traversable data is passed to "filter" * Fix context optimization on PHP 7.4 * Fix PHP 8 compatibility * Fix ambiguous syntax parsing # 3.0.3 (2020-02-11) * Add a check to ensure that iconv() is defined # 3.0.2 (2020-02-11) * Avoid exceptions when an intl resource is not found * Fix implementation of case-insensitivity for method names # 3.0.1 (2019-12-28) * fixed Symfony 5.0 support for the HTML extra extension # 3.0.0 (2019-11-15) * fixed number formatter in Intl extra extension when using a formatter prototype # 3.0.0-BETA1 (2019-11-11) * removed the "if" condition support on the "for" tag * made the in, <, >, <=, >=, ==, and != operators more strict when comparing strings and integers/floats * removed the "filter" tag * added type hints everywhere * changed Environment::resolveTemplate() to always return a TemplateWrapper instance * removed Template::__toString() * removed Parser::isReservedMacroName() * removed SanboxedPrintNode * removed Node::setTemplateName() * made classes marked as "@final" final * removed InitRuntimeInterface, ExistsLoaderInterface, and SourceContextLoaderInterface * removed the "spaceless" tag * removed Twig\Environment::getBaseTemplateClass() and Twig\Environment::setBaseTemplateClass() * removed the "base_template_class" option on Twig\Environment * bumped minimum PHP version to 7.2 * removed PSR-0 classes PK �xE\��Z� � twig/LICENSEnu �[��� Copyright (c) 2009-present by the Twig Team. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Twig nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. PK �xE\G�3;= = , twig/src/TokenParser/AbstractTokenParser.phpnu �[��� <?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\TokenParser; use Twig\Parser; /** * Base class for all token parsers. * * @author Fabien Potencier <fabien@symfony.com> */ abstract class AbstractTokenParser implements TokenParserInterface { /** * @var Parser */ protected $parser; public function setParser(Parser $parser): void { $this->parser = $parser; } } PK �xE\i+`)� � ) twig/src/TokenParser/GuardTokenParser.phpnu �[��� <?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\TokenParser; use Twig\Error\SyntaxError; use Twig\Node\EmptyNode; use Twig\Node\Node; use Twig\Node\Nodes; use Twig\Token; /** * @internal */ final class GuardTokenParser extends AbstractTokenParser { public function parse(Token $token): Node { $stream = $this->parser->getStream(); $typeToken = $stream->expect(Token::NAME_TYPE); if (!in_array($typeToken->getValue(), ['function', 'filter', 'test'])) { throw new SyntaxError(\sprintf('Supported guard types are function, filter and test, "%s" given.', $typeToken->getValue()), $typeToken->getLine(), $stream->getSourceContext()); } $method = 'get'.$typeToken->getValue(); $nameToken = $stream->expect(Token::NAME_TYPE); $exists = null !== $this->parser->getEnvironment()->$method($nameToken->getValue()); $stream->expect(Token::BLOCK_END_TYPE); if ($exists) { $body = $this->parser->subparse([$this, 'decideGuardFork']); } else { $body = new EmptyNode(); $this->parser->subparseIgnoreUnknownTwigCallables([$this, 'decideGuardFork']); } $else = new EmptyNode(); if ('else' === $stream->next()->getValue()) { $stream->expect(Token::BLOCK_END_TYPE); $else = $this->parser->subparse([$this, 'decideGuardEnd'], true); } $stream->expect(Token::BLOCK_END_TYPE); return new Nodes([$exists ? $body : $else]); } public function decideGuardFork(Token $token): bool { return $token->test(['else', 'endguard']); } public function decideGuardEnd(Token $token): bool { return $token->test(['endguard']); } public function getTag(): string { return 'guard'; } } PK �xE\&�U�� � ) twig/src/TokenParser/MacroTokenParser.phpnu �[��� <?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\TokenParser; use Twig\Error\SyntaxError; use Twig\Node\BodyNode; use Twig\Node\EmptyNode; use Twig\Node\Expression\ArrayExpression; use Twig\Node\Expression\ConstantExpression; use Twig\Node\Expression\Unary\NegUnary; use Twig\Node\Expression\Unary\PosUnary; use Twig\Node\Expression\Variable\LocalVariable; use Twig\Node\MacroNode; use Twig\Node\Node; use Twig\Token; /** * Defines a macro. * * {% macro input(name, value, type, size) %} * <input type="{{ type|default('text') }}" name="{{ name }}" value="{{ value|e }}" size="{{ size|default(20) }}" /> * {% endmacro %} * * @internal */ final class MacroTokenParser extends AbstractTokenParser { public function parse(Token $token): Node { $lineno = $token->getLine(); $stream = $this->parser->getStream(); $name = $stream->expect(Token::NAME_TYPE)->getValue(); $arguments = $this->parseDefinition(); $stream->expect(Token::BLOCK_END_TYPE); $this->parser->pushLocalScope(); $body = $this->parser->subparse([$this, 'decideBlockEnd'], true); if ($token = $stream->nextIf(Token::NAME_TYPE)) { $value = $token->getValue(); if ($value != $name) { throw new SyntaxError(\sprintf('Expected endmacro for macro "%s" (but "%s" given).', $name, $value), $stream->getCurrent()->getLine(), $stream->getSourceContext()); } } $this->parser->popLocalScope(); $stream->expect(Token::BLOCK_END_TYPE); $this->parser->setMacro($name, new MacroNode($name, new BodyNode([$body]), $arguments, $lineno)); return new EmptyNode($lineno); } public function decideBlockEnd(Token $token): bool { return $token->test('endmacro'); } public function getTag(): string { return 'macro'; } private function parseDefinition(): ArrayExpression { $arguments = new ArrayExpression([], $this->parser->getCurrentToken()->getLine()); $stream = $this->parser->getStream(); $stream->expect(Token::PUNCTUATION_TYPE, '(', 'A list of arguments must begin with an opening parenthesis'); while (!$stream->test(Token::PUNCTUATION_TYPE, ')')) { if (count($arguments)) { $stream->expect(Token::PUNCTUATION_TYPE, ',', 'Arguments must be separated by a comma'); // if the comma above was a trailing comma, early exit the argument parse loop if ($stream->test(Token::PUNCTUATION_TYPE, ')')) { break; } } $token = $stream->expect(Token::NAME_TYPE, null, 'An argument must be a name'); $name = new LocalVariable($token->getValue(), $this->parser->getCurrentToken()->getLine()); if ($token = $stream->nextIf(Token::OPERATOR_TYPE, '=')) { $default = $this->parser->getExpressionParser()->parseExpression(); } else { $default = new ConstantExpression(null, $this->parser->getCurrentToken()->getLine()); $default->setAttribute('is_implicit', true); } if (!$this->checkConstantExpression($default)) { throw new SyntaxError('A default value for an argument must be a constant (a boolean, a string, a number, a sequence, or a mapping).', $token->getLine(), $stream->getSourceContext()); } $arguments->addElement($default, $name); } $stream->expect(Token::PUNCTUATION_TYPE, ')', 'A list of arguments must be closed by a parenthesis'); return $arguments; } // checks that the node only contains "constant" elements private function checkConstantExpression(Node $node): bool { if (!($node instanceof ConstantExpression || $node instanceof ArrayExpression || $node instanceof NegUnary || $node instanceof PosUnary )) { return false; } foreach ($node as $n) { if (!$this->checkConstantExpression($n)) { return false; } } return true; } } PK �xE\y}�� � ) twig/src/TokenParser/TypesTokenParser.phpnu �[��� <?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\TokenParser; use Twig\Error\SyntaxError; use Twig\Node\Node; use Twig\Node\TypesNode; use Twig\Token; use Twig\TokenStream; /** * Declare variable types. * * {% types {foo: 'number', bar?: 'string'} %} * * @author Jeroen Versteeg <jeroen@alisqi.com> * * @internal */ final class TypesTokenParser extends AbstractTokenParser { public function parse(Token $token): Node { $stream = $this->parser->getStream(); $types = $this->parseSimpleMappingExpression($stream); $stream->expect(Token::BLOCK_END_TYPE); return new TypesNode($types, $token->getLine()); } /** * @return array<string, array{type: string, optional: bool}> * * @throws SyntaxError */ private function parseSimpleMappingExpression(TokenStream $stream): array { $stream->expect(Token::PUNCTUATION_TYPE, '{', 'A mapping element was expected'); $types = []; $first = true; while (!$stream->test(Token::PUNCTUATION_TYPE, '}')) { if (!$first) { $stream->expect(Token::PUNCTUATION_TYPE, ',', 'A type string must be followed by a comma'); // trailing ,? if ($stream->test(Token::PUNCTUATION_TYPE, '}')) { break; } } $first = false; $nameToken = $stream->expect(Token::NAME_TYPE); $isOptional = null !== $stream->nextIf(Token::PUNCTUATION_TYPE, '?'); $stream->expect(Token::PUNCTUATION_TYPE, ':', 'A type name must be followed by a colon (:)'); $valueToken = $stream->expect(Token::STRING_TYPE); $types[$nameToken->getValue()] = [ 'type' => $valueToken->getValue(), 'optional' => $isOptional, ]; } $stream->expect(Token::PUNCTUATION_TYPE, '}', 'An opened mapping is not properly closed'); return $types; } public function getTag(): string { return 'types'; } } PK �xE\�1��� � &