Submit
Path:
~
/
/
proc
/
self
/
root
/
proc
/
self
/
root
/
opt
/
cpguard
/
app
/
vendor
/
twig
/
twig
/
src
/
ExpressionParser
/
Prefix
/
File Content:
LiteralExpressionParser.php
<?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\ExpressionParser\Prefix; use Twig\Error\SyntaxError; use Twig\ExpressionParser\AbstractExpressionParser; use Twig\ExpressionParser\ExpressionParserDescriptionInterface; use Twig\ExpressionParser\PrefixExpressionParserInterface; use Twig\Lexer; use Twig\Node\Expression\AbstractExpression; use Twig\Node\Expression\ArrayExpression; use Twig\Node\Expression\Binary\ConcatBinary; use Twig\Node\Expression\ConstantExpression; use Twig\Node\Expression\Variable\ContextVariable; use Twig\Parser; use Twig\Token; /** * @internal */ final class LiteralExpressionParser extends AbstractExpressionParser implements PrefixExpressionParserInterface, ExpressionParserDescriptionInterface { private string $type = 'literal'; public function parse(Parser $parser, Token $token): AbstractExpression { $stream = $parser->getStream(); switch (true) { case $token->test(Token::NAME_TYPE): $stream->next(); switch ($token->getValue()) { case 'true': case 'TRUE': $this->type = 'constant'; return new ConstantExpression(true, $token->getLine()); case 'false': case 'FALSE': $this->type = 'constant'; return new ConstantExpression(false, $token->getLine()); case 'none': case 'NONE': case 'null': case 'NULL': $this->type = 'constant'; return new ConstantExpression(null, $token->getLine()); default: $this->type = 'variable'; return new ContextVariable($token->getValue(), $token->getLine()); } // no break case $token->test(Token::NUMBER_TYPE): $stream->next(); $this->type = 'constant'; return new ConstantExpression($token->getValue(), $token->getLine()); case $token->test(Token::STRING_TYPE): case $token->test(Token::INTERPOLATION_START_TYPE): $this->type = 'string'; return $this->parseStringExpression($parser); case $token->test(Token::PUNCTUATION_TYPE): // In 4.0, we should always return the node or throw an error for default if ($node = match ($token->getValue()) { '{' => $this->parseMappingExpression($parser), default => null, }) { return $node; } // no break case $token->test(Token::OPERATOR_TYPE): if ('[' === $token->getValue()) { return $this->parseSequenceExpression($parser); } if (preg_match(Lexer::REGEX_NAME, $token->getValue(), $matches) && $matches[0] == $token->getValue()) { // in this context, string operators are variable names $stream->next(); $this->type = 'variable'; return new ContextVariable($token->getValue(), $token->getLine()); } if ('=' === $token->getValue() && ('==' === $stream->look(-1)->getValue() || '!=' === $stream->look(-1)->getValue())) { throw new SyntaxError(\sprintf('Unexpected operator of value "%s". Did you try to use "===" or "!==" for strict comparison? Use "is same as(value)" instead.', $token->getValue()), $token->getLine(), $stream->getSourceContext()); } // no break default: throw new SyntaxError(\sprintf('Unexpected token "%s" of value "%s".', $token->toEnglish(), $token->getValue()), $token->getLine(), $stream->getSourceContext()); } } public function getName(): string { return $this->type; } public function getDescription(): string { return 'A literal value (boolean, string, number, sequence, mapping, ...)'; } public function getPrecedence(): int { // not used return 0; } private function parseStringExpression(Parser $parser) { $stream = $parser->getStream(); $nodes = []; // a string cannot be followed by another string in a single expression $nextCanBeString = true; while (true) { if ($nextCanBeString && $token = $stream->nextIf(Token::STRING_TYPE)) { $nodes[] = new ConstantExpression($token->getValue(), $token->getLine()); $nextCanBeString = false; } elseif ($stream->nextIf(Token::INTERPOLATION_START_TYPE)) { $nodes[] = $parser->parseExpression(); $stream->expect(Token::INTERPOLATION_END_TYPE); $nextCanBeString = true; } else { break; } } $expr = array_shift($nodes); foreach ($nodes as $node) { $expr = new ConcatBinary($expr, $node, $node->getTemplateLine()); } return $expr; } private function parseSequenceExpression(Parser $parser) { $this->type = 'sequence'; $stream = $parser->getStream(); $stream->expect(Token::OPERATOR_TYPE, '[', 'A sequence element was expected'); $node = new ArrayExpression([], $stream->getCurrent()->getLine()); $first = true; while (!$stream->test(Token::PUNCTUATION_TYPE, ']')) { if (!$first) { $stream->expect(Token::PUNCTUATION_TYPE, ',', 'A sequence element must be followed by a comma'); // trailing ,? if ($stream->test(Token::PUNCTUATION_TYPE, ']')) { break; } } $first = false; $node->addElement($parser->parseExpression()); } $stream->expect(Token::PUNCTUATION_TYPE, ']', 'An opened sequence is not properly closed'); return $node; } private function parseMappingExpression(Parser $parser) { $this->type = 'mapping'; $stream = $parser->getStream(); $stream->expect(Token::PUNCTUATION_TYPE, '{', 'A mapping element was expected'); $node = new ArrayExpression([], $stream->getCurrent()->getLine()); $first = true; while (!$stream->test(Token::PUNCTUATION_TYPE, '}')) { if (!$first) { $stream->expect(Token::PUNCTUATION_TYPE, ',', 'A mapping value must be followed by a comma'); // trailing ,? if ($stream->test(Token::PUNCTUATION_TYPE, '}')) { break; } } $first = false; if ($stream->test(Token::OPERATOR_TYPE, '...')) { $node->addElement($parser->parseExpression()); continue; } // a mapping key can be: // // * a number -- 12 // * a string -- 'a' // * a name, which is equivalent to a string -- a // * an expression, which must be enclosed in parentheses -- (1 + 2) if ($token = $stream->nextIf(Token::NAME_TYPE)) { $key = new ConstantExpression($token->getValue(), $token->getLine()); // {a} is a shortcut for {a:a} if ($stream->test(Token::PUNCTUATION_TYPE, [',', '}'])) { $value = new ContextVariable($key->getAttribute('value'), $key->getTemplateLine()); $node->addElement($value, $key); continue; } } elseif (($token = $stream->nextIf(Token::STRING_TYPE)) || $token = $stream->nextIf(Token::NUMBER_TYPE)) { $key = new ConstantExpression($token->getValue(), $token->getLine()); } elseif ($stream->test(Token::OPERATOR_TYPE, '(')) { $key = $parser->parseExpression(); } else { $current = $stream->getCurrent(); throw new SyntaxError(\sprintf('A mapping key must be a quoted string, a number, a name, or an expression enclosed in parentheses (unexpected token "%s" of value "%s".', $current->toEnglish(), $current->getValue()), $current->getLine(), $stream->getSourceContext()); } $stream->expect(Token::PUNCTUATION_TYPE, ':', 'A mapping key must be followed by a colon (:)'); $value = $parser->parseExpression(); $node->addElement($value, $key); } $stream->expect(Token::PUNCTUATION_TYPE, '}', 'An opened mapping is not properly closed'); return $node; } }
Edit
Rename
Chmod
Delete
FILE
FOLDER
Name
Size
Permission
Action
GroupingExpressionParser.php
2396 bytes
0644
LiteralExpressionParser.php
9018 bytes
0644
UnaryOperatorExpressionParser.php
1804 bytes
0644
N4ST4R_ID | Naxtarrr