ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
Twig_ExpressionParser Class Reference

Parses expressions. More...

+ Collaboration diagram for Twig_ExpressionParser:

Public Member Functions

 __construct (Twig_Parser $parser, $env=null)
 
 parseExpression ($precedence=0)
 
 parsePrimaryExpression ()
 
 parseStringExpression ()
 
 parseArrayExpression ()
 
 parseHashExpression ()
 
 parsePostfixExpression ($node)
 
 getFunctionNode ($name, $line)
 
 parseSubscriptExpression ($node)
 
 parseFilterExpression ($node)
 
 parseFilterExpressionRaw ($node, $tag=null)
 
 parseArguments ($namedArguments=false, $definition=false)
 Parses arguments. More...
 
 parseAssignmentExpression ()
 
 parseMultitargetExpression ()
 

Data Fields

const OPERATOR_LEFT = 1
 
const OPERATOR_RIGHT = 2
 

Protected Member Functions

 getPrimary ()
 
 parseConditionalExpression ($expr)
 
 isUnary (Twig_Token $token)
 
 isBinary (Twig_Token $token)
 
 getFunctionNodeClass ($name, $line)
 
 getFilterNodeClass ($name, $line)
 
 checkConstantExpression (Twig_NodeInterface $node)
 

Protected Attributes

 $parser
 
 $unaryOperators
 
 $binaryOperators
 

Private Member Functions

 parseNotTestExpression (Twig_NodeInterface $node)
 
 parseTestExpression (Twig_NodeInterface $node)
 
 getTest ($line)
 
 getTestNodeClass ($test)
 

Private Attributes

 $env
 

Detailed Description

Parses expressions.

This parser implements a "Precedence climbing" algorithm.

See also
http://www.engr.mun.ca/~theo/Misc/exp_parsing.htm
http://en.wikipedia.org/wiki/Operator-precedence_parser
Author
Fabien Potencier fabie.nosp@m.n@sy.nosp@m.mfony.nosp@m..com

Definition at line 25 of file ExpressionParser.php.

Constructor & Destructor Documentation

◆ __construct()

Twig_ExpressionParser::__construct ( Twig_Parser  $parser,
  $env = null 
)

Definition at line 36 of file ExpressionParser.php.

References $env, $parser, and Twig_Parser\getEnvironment().

37  {
38  $this->parser = $parser;
39 
40  if ($env instanceof Twig_Environment) {
41  $this->env = $env;
42  $this->unaryOperators = $env->getUnaryOperators();
43  $this->binaryOperators = $env->getBinaryOperators();
44  } else {
45  @trigger_error('Passing the operators as constructor arguments to '.__METHOD__.' is deprecated since version 1.27. Pass the environment instead.', E_USER_DEPRECATED);
46 
47  $this->env = $parser->getEnvironment();
48  $this->unaryOperators = func_get_arg(1);
49  $this->binaryOperators = func_get_arg(2);
50  }
51  }
getEnvironment()
Definition: Parser.php:44
Stores the Twig configuration.
Definition: Environment.php:17
+ Here is the call graph for this function:

Member Function Documentation

◆ checkConstantExpression()

Twig_ExpressionParser::checkConstantExpression ( Twig_NodeInterface  $node)
protected

Definition at line 726 of file ExpressionParser.php.

References $n.

Referenced by parseArguments().

727  {
728  if (!($node instanceof Twig_Node_Expression_Constant || $node instanceof Twig_Node_Expression_Array
729  || $node instanceof Twig_Node_Expression_Unary_Neg || $node instanceof Twig_Node_Expression_Unary_Pos
730  )) {
731  return false;
732  }
733 
734  foreach ($node as $n) {
735  if (!$this->checkConstantExpression($n)) {
736  return false;
737  }
738  }
739 
740  return true;
741  }
checkConstantExpression(Twig_NodeInterface $node)
$n
Definition: RandomTest.php:85
+ Here is the caller graph for this function:

◆ getFilterNodeClass()

Twig_ExpressionParser::getFilterNodeClass (   $name,
  $line 
)
protected

Definition at line 695 of file ExpressionParser.php.

References $message, $name, Twig_Error_Syntax\addSuggestions(), Twig_Filter_Node\getClass(), and Twig_SimpleFilter\isDeprecated().

Referenced by parseFilterExpressionRaw(), and parseSubscriptExpression().

696  {
697  if (false === $filter = $this->env->getFilter($name)) {
698  $e = new Twig_Error_Syntax(sprintf('Unknown "%s" filter.', $name), $line, $this->parser->getStream()->getSourceContext());
699  $e->addSuggestions($name, array_keys($this->env->getFilters()));
700 
701  throw $e;
702  }
703 
704  if ($filter instanceof Twig_SimpleFilter && $filter->isDeprecated()) {
705  $message = sprintf('Twig Filter "%s" is deprecated', $filter->getName());
706  if (!is_bool($filter->getDeprecatedVersion())) {
707  $message .= sprintf(' since version %s', $filter->getDeprecatedVersion());
708  }
709  if ($filter->getAlternative()) {
710  $message .= sprintf('. Use "%s" instead', $filter->getAlternative());
711  }
712  $src = $this->parser->getStream()->getSourceContext();
713  $message .= sprintf(' in %s at line %d.', $src->getPath() ? $src->getPath() : $src->getName(), $line);
714 
715  @trigger_error($message, E_USER_DEPRECATED);
716  }
717 
718  if ($filter instanceof Twig_SimpleFilter) {
719  return $filter->getNodeClass();
720  }
721 
722  return $filter instanceof Twig_Filter_Node ? $filter->getClass() : 'Twig_Node_Expression_Filter';
723  }
addSuggestions($name, array $items)
Tweaks the error message to include suggestions.
Definition: Syntax.php:26
Represents a template filter.
Exception thrown when a syntax error occurs during lexing or parsing of a template.
Definition: Syntax.php:18
catch(Exception $e) $message
Represents a template filter as a node.
Definition: Node.php:23
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getFunctionNode()

Twig_ExpressionParser::getFunctionNode (   $name,
  $line 
)

Definition at line 335 of file ExpressionParser.php.

References $n, $name, Twig_TemplateInterface\ANY_CALL, getFunctionNodeClass(), and parseArguments().

Referenced by parsePrimaryExpression().

336  {
337  switch ($name) {
338  case 'parent':
339  $this->parseArguments();
340  if (!count($this->parser->getBlockStack())) {
341  throw new Twig_Error_Syntax('Calling "parent" outside a block is forbidden.', $line, $this->parser->getStream()->getSourceContext());
342  }
343 
344  if (!$this->parser->getParent() && !$this->parser->hasTraits()) {
345  throw new Twig_Error_Syntax('Calling "parent" on a template that does not extend nor "use" another template is forbidden.', $line, $this->parser->getStream()->getSourceContext());
346  }
347 
348  return new Twig_Node_Expression_Parent($this->parser->peekBlockStack(), $line);
349  case 'block':
350  $args = $this->parseArguments();
351  if (count($args) < 1) {
352  throw new Twig_Error_Syntax('The "block" function takes one argument (the block name).', $line, $this->parser->getStream()->getSourceContext());
353  }
354 
355  return new Twig_Node_Expression_BlockReference($args->getNode(0), count($args) > 1 ? $args->getNode(1) : null, $line);
356  case 'attribute':
357  $args = $this->parseArguments();
358  if (count($args) < 2) {
359  throw new Twig_Error_Syntax('The "attribute" function takes at least two arguments (the variable and the attributes).', $line, $this->parser->getStream()->getSourceContext());
360  }
361 
362  return new Twig_Node_Expression_GetAttr($args->getNode(0), $args->getNode(1), count($args) > 2 ? $args->getNode(2) : null, Twig_Template::ANY_CALL, $line);
363  default:
364  if (null !== $alias = $this->parser->getImportedSymbol('function', $name)) {
365  $arguments = new Twig_Node_Expression_Array(array(), $line);
366  foreach ($this->parseArguments() as $n) {
367  $arguments->addElement($n);
368  }
369 
370  $node = new Twig_Node_Expression_MethodCall($alias['node'], $alias['name'], $arguments, $line);
371  $node->setAttribute('safe', true);
372 
373  return $node;
374  }
375 
376  $args = $this->parseArguments(true);
377  $class = $this->getFunctionNodeClass($name, $line);
378 
379  return new $class($name, $args, $line);
380  }
381  }
parseArguments($namedArguments=false, $definition=false)
Parses arguments.
Exception thrown when a syntax error occurs during lexing or parsing of a template.
Definition: Syntax.php:18
getFunctionNodeClass($name, $line)
Represents a parent node.
Definition: Parent.php:18
$n
Definition: RandomTest.php:85
Represents a block call node.
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getFunctionNodeClass()

Twig_ExpressionParser::getFunctionNodeClass (   $name,
  $line 
)
protected

Definition at line 665 of file ExpressionParser.php.

References $message, $name, Twig_Error_Syntax\addSuggestions(), Twig_Function_Node\getClass(), and Twig_SimpleFunction\isDeprecated().

Referenced by getFunctionNode().

666  {
667  if (false === $function = $this->env->getFunction($name)) {
668  $e = new Twig_Error_Syntax(sprintf('Unknown "%s" function.', $name), $line, $this->parser->getStream()->getSourceContext());
669  $e->addSuggestions($name, array_keys($this->env->getFunctions()));
670 
671  throw $e;
672  }
673 
674  if ($function instanceof Twig_SimpleFunction && $function->isDeprecated()) {
675  $message = sprintf('Twig Function "%s" is deprecated', $function->getName());
676  if (!is_bool($function->getDeprecatedVersion())) {
677  $message .= sprintf(' since version %s', $function->getDeprecatedVersion());
678  }
679  if ($function->getAlternative()) {
680  $message .= sprintf('. Use "%s" instead', $function->getAlternative());
681  }
682  $src = $this->parser->getStream()->getSourceContext();
683  $message .= sprintf(' in %s at line %d.', $src->getPath() ? $src->getPath() : $src->getName(), $line);
684 
685  @trigger_error($message, E_USER_DEPRECATED);
686  }
687 
688  if ($function instanceof Twig_SimpleFunction) {
689  return $function->getNodeClass();
690  }
691 
692  return $function instanceof Twig_Function_Node ? $function->getClass() : 'Twig_Node_Expression_Function';
693  }
Represents a template function.
addSuggestions($name, array $items)
Tweaks the error message to include suggestions.
Definition: Syntax.php:26
Represents a template function as a node.
Definition: Node.php:23
Exception thrown when a syntax error occurs during lexing or parsing of a template.
Definition: Syntax.php:18
catch(Exception $e) $message
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getPrimary()

Twig_ExpressionParser::getPrimary ( )
protected

Definition at line 83 of file ExpressionParser.php.

References PHPMailer\PHPMailer\$token, isUnary(), parseExpression(), parsePostfixExpression(), parsePrimaryExpression(), and Twig_Token\PUNCTUATION_TYPE.

Referenced by parseExpression().

84  {
85  $token = $this->parser->getCurrentToken();
86 
87  if ($this->isUnary($token)) {
88  $operator = $this->unaryOperators[$token->getValue()];
89  $this->parser->getStream()->next();
90  $expr = $this->parseExpression($operator['precedence']);
91  $class = $operator['class'];
92 
93  return $this->parsePostfixExpression(new $class($expr, $token->getLine()));
94  } elseif ($token->test(Twig_Token::PUNCTUATION_TYPE, '(')) {
95  $this->parser->getStream()->next();
96  $expr = $this->parseExpression();
97  $this->parser->getStream()->expect(Twig_Token::PUNCTUATION_TYPE, ')', 'An opened parenthesis is not properly closed');
98 
99  return $this->parsePostfixExpression($expr);
100  }
101 
102  return $this->parsePrimaryExpression();
103  }
isUnary(Twig_Token $token)
parseExpression($precedence=0)
const PUNCTUATION_TYPE
Definition: Token.php:36
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getTest()

Twig_ExpressionParser::getTest (   $line)
private

Definition at line 615 of file ExpressionParser.php.

References $name, GuzzleHttp\Psr7\$stream, $test, Twig_Error_Syntax\addSuggestions(), and Twig_Token\NAME_TYPE.

Referenced by parseTestExpression().

616  {
617  $stream = $this->parser->getStream();
618  $name = $stream->expect(Twig_Token::NAME_TYPE)->getValue();
619 
620  if ($test = $this->env->getTest($name)) {
621  return array($name, $test);
622  }
623 
624  if ($stream->test(Twig_Token::NAME_TYPE)) {
625  // try 2-words tests
626  $name = $name.' '.$this->parser->getCurrentToken()->getValue();
627 
628  if ($test = $this->env->getTest($name)) {
629  $stream->next();
630 
631  return array($name, $test);
632  }
633  }
634 
635  $e = new Twig_Error_Syntax(sprintf('Unknown "%s" test.', $name), $line, $stream->getSourceContext());
636  $e->addSuggestions($name, array_keys($this->env->getTests()));
637 
638  throw $e;
639  }
addSuggestions($name, array $items)
Tweaks the error message to include suggestions.
Definition: Syntax.php:26
$stream
PHP stream implementation.
Exception thrown when a syntax error occurs during lexing or parsing of a template.
Definition: Syntax.php:18
const NAME_TYPE
Definition: Token.php:32
$test
Definition: Utf8Test.php:84
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getTestNodeClass()

Twig_ExpressionParser::getTestNodeClass (   $test)
private

Definition at line 641 of file ExpressionParser.php.

References $message, GuzzleHttp\Psr7\$stream, and $test.

Referenced by parseTestExpression().

642  {
643  if ($test instanceof Twig_SimpleTest && $test->isDeprecated()) {
644  $stream = $this->parser->getStream();
645  $message = sprintf('Twig Test "%s" is deprecated', $test->getName());
646  if (!is_bool($test->getDeprecatedVersion())) {
647  $message .= sprintf(' since version %s', $test->getDeprecatedVersion());
648  }
649  if ($test->getAlternative()) {
650  $message .= sprintf('. Use "%s" instead', $test->getAlternative());
651  }
652  $src = $stream->getSourceContext();
653  $message .= sprintf(' in %s at line %d.', $src->getPath() ? $src->getPath() : $src->getName(), $stream->getCurrent()->getLine());
654 
655  @trigger_error($message, E_USER_DEPRECATED);
656  }
657 
658  if ($test instanceof Twig_SimpleTest) {
659  return $test->getNodeClass();
660  }
661 
662  return $test instanceof Twig_Test_Node ? $test->getClass() : 'Twig_Node_Expression_Test';
663  }
Represents a template test as a Node.
Definition: Node.php:21
$stream
PHP stream implementation.
catch(Exception $e) $message
Represents a template test.
Definition: SimpleTest.php:19
$test
Definition: Utf8Test.php:84
+ Here is the caller graph for this function:

◆ isBinary()

Twig_ExpressionParser::isBinary ( Twig_Token  $token)
protected

Definition at line 131 of file ExpressionParser.php.

References Twig_Token\getValue(), Twig_Token\OPERATOR_TYPE, and Twig_Token\test().

Referenced by parseExpression().

132  {
133  return $token->test(Twig_Token::OPERATOR_TYPE) && isset($this->binaryOperators[$token->getValue()]);
134  }
test($type, $values=null)
Tests the current token for a type and/or a value.
Definition: Token.php:70
getValue()
Definition: Token.php:103
const OPERATOR_TYPE
Definition: Token.php:35
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ isUnary()

Twig_ExpressionParser::isUnary ( Twig_Token  $token)
protected

Definition at line 126 of file ExpressionParser.php.

References Twig_Token\getValue(), Twig_Token\OPERATOR_TYPE, and Twig_Token\test().

Referenced by getPrimary().

127  {
128  return $token->test(Twig_Token::OPERATOR_TYPE) && isset($this->unaryOperators[$token->getValue()]);
129  }
test($type, $values=null)
Tests the current token for a type and/or a value.
Definition: Token.php:70
getValue()
Definition: Token.php:103
const OPERATOR_TYPE
Definition: Token.php:35
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ parseArguments()

Twig_ExpressionParser::parseArguments (   $namedArguments = false,
  $definition = false 
)

Parses arguments.

Parameters
bool$namedArgumentsWhether to allow named arguments or not
bool$definitionWhether we are parsing arguments for a function definition
Returns
Twig_Node
Exceptions
Twig_Error_Syntax

Definition at line 508 of file ExpressionParser.php.

References $name, GuzzleHttp\Psr7\$stream, PHPMailer\PHPMailer\$token, checkConstantExpression(), Twig_Token\NAME_TYPE, Twig_Token\OPERATOR_TYPE, parseExpression(), parsePrimaryExpression(), and Twig_Token\PUNCTUATION_TYPE.

Referenced by getFunctionNode(), parseFilterExpressionRaw(), and parseSubscriptExpression().

509  {
510  $args = array();
511  $stream = $this->parser->getStream();
512 
513  $stream->expect(Twig_Token::PUNCTUATION_TYPE, '(', 'A list of arguments must begin with an opening parenthesis');
514  while (!$stream->test(Twig_Token::PUNCTUATION_TYPE, ')')) {
515  if (!empty($args)) {
516  $stream->expect(Twig_Token::PUNCTUATION_TYPE, ',', 'Arguments must be separated by a comma');
517  }
518 
519  if ($definition) {
520  $token = $stream->expect(Twig_Token::NAME_TYPE, null, 'An argument must be a name');
521  $value = new Twig_Node_Expression_Name($token->getValue(), $this->parser->getCurrentToken()->getLine());
522  } else {
523  $value = $this->parseExpression();
524  }
525 
526  $name = null;
527  if ($namedArguments && $token = $stream->nextIf(Twig_Token::OPERATOR_TYPE, '=')) {
528  if (!$value instanceof Twig_Node_Expression_Name) {
529  throw new Twig_Error_Syntax(sprintf('A parameter name must be a string, "%s" given.', get_class($value)), $token->getLine(), $stream->getSourceContext());
530  }
531  $name = $value->getAttribute('name');
532 
533  if ($definition) {
534  $value = $this->parsePrimaryExpression();
535 
536  if (!$this->checkConstantExpression($value)) {
537  throw new Twig_Error_Syntax(sprintf('A default value for an argument must be a constant (a boolean, a string, a number, or an array).'), $token->getLine(), $stream->getSourceContext());
538  }
539  } else {
540  $value = $this->parseExpression();
541  }
542  }
543 
544  if ($definition) {
545  if (null === $name) {
546  $name = $value->getAttribute('name');
547  $value = new Twig_Node_Expression_Constant(null, $this->parser->getCurrentToken()->getLine());
548  }
549  $args[$name] = $value;
550  } else {
551  if (null === $name) {
552  $args[] = $value;
553  } else {
554  $args[$name] = $value;
555  }
556  }
557  }
558  $stream->expect(Twig_Token::PUNCTUATION_TYPE, ')', 'A list of arguments must be closed by a parenthesis');
559 
560  return new Twig_Node($args);
561  }
parseExpression($precedence=0)
const PUNCTUATION_TYPE
Definition: Token.php:36
Represents a node in the AST.
Definition: Node.php:18
$stream
PHP stream implementation.
Exception thrown when a syntax error occurs during lexing or parsing of a template.
Definition: Syntax.php:18
checkConstantExpression(Twig_NodeInterface $node)
const OPERATOR_TYPE
Definition: Token.php:35
const NAME_TYPE
Definition: Token.php:32
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ parseArrayExpression()

Twig_ExpressionParser::parseArrayExpression ( )

Definition at line 246 of file ExpressionParser.php.

References GuzzleHttp\Psr7\$stream, Twig_Node_Expression_Array\addElement(), parseExpression(), and Twig_Token\PUNCTUATION_TYPE.

Referenced by parsePrimaryExpression().

247  {
248  $stream = $this->parser->getStream();
249  $stream->expect(Twig_Token::PUNCTUATION_TYPE, '[', 'An array element was expected');
250 
251  $node = new Twig_Node_Expression_Array(array(), $stream->getCurrent()->getLine());
252  $first = true;
253  while (!$stream->test(Twig_Token::PUNCTUATION_TYPE, ']')) {
254  if (!$first) {
255  $stream->expect(Twig_Token::PUNCTUATION_TYPE, ',', 'An array element must be followed by a comma');
256 
257  // trailing ,?
258  if ($stream->test(Twig_Token::PUNCTUATION_TYPE, ']')) {
259  break;
260  }
261  }
262  $first = false;
263 
264  $node->addElement($this->parseExpression());
265  }
266  $stream->expect(Twig_Token::PUNCTUATION_TYPE, ']', 'An opened array is not properly closed');
267 
268  return $node;
269  }
addElement(Twig_Node_Expression $value, Twig_Node_Expression $key=null)
Definition: Array.php:54
parseExpression($precedence=0)
const PUNCTUATION_TYPE
Definition: Token.php:36
$stream
PHP stream implementation.
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ parseAssignmentExpression()

Twig_ExpressionParser::parseAssignmentExpression ( )

Definition at line 563 of file ExpressionParser.php.

References GuzzleHttp\Psr7\$stream, PHPMailer\PHPMailer\$token, Twig_Token\NAME_TYPE, and Twig_Token\PUNCTUATION_TYPE.

564  {
565  $stream = $this->parser->getStream();
566  $targets = array();
567  while (true) {
568  $token = $stream->expect(Twig_Token::NAME_TYPE, null, 'Only variables can be assigned to');
569  $value = $token->getValue();
570  if (in_array(strtolower($value), array('true', 'false', 'none', 'null'))) {
571  throw new Twig_Error_Syntax(sprintf('You cannot assign a value to "%s".', $value), $token->getLine(), $stream->getSourceContext());
572  }
573  $targets[] = new Twig_Node_Expression_AssignName($value, $token->getLine());
574 
575  if (!$stream->nextIf(Twig_Token::PUNCTUATION_TYPE, ',')) {
576  break;
577  }
578  }
579 
580  return new Twig_Node($targets);
581  }
const PUNCTUATION_TYPE
Definition: Token.php:36
Represents a node in the AST.
Definition: Node.php:18
$stream
PHP stream implementation.
Exception thrown when a syntax error occurs during lexing or parsing of a template.
Definition: Syntax.php:18
const NAME_TYPE
Definition: Token.php:32

◆ parseConditionalExpression()

Twig_ExpressionParser::parseConditionalExpression (   $expr)
protected

Definition at line 105 of file ExpressionParser.php.

References parseExpression(), and Twig_Token\PUNCTUATION_TYPE.

Referenced by parseExpression().

106  {
107  while ($this->parser->getStream()->nextIf(Twig_Token::PUNCTUATION_TYPE, '?')) {
108  if (!$this->parser->getStream()->nextIf(Twig_Token::PUNCTUATION_TYPE, ':')) {
109  $expr2 = $this->parseExpression();
110  if ($this->parser->getStream()->nextIf(Twig_Token::PUNCTUATION_TYPE, ':')) {
111  $expr3 = $this->parseExpression();
112  } else {
113  $expr3 = new Twig_Node_Expression_Constant('', $this->parser->getCurrentToken()->getLine());
114  }
115  } else {
116  $expr2 = $expr;
117  $expr3 = $this->parseExpression();
118  }
119 
120  $expr = new Twig_Node_Expression_Conditional($expr, $expr2, $expr3, $this->parser->getCurrentToken()->getLine());
121  }
122 
123  return $expr;
124  }
parseExpression($precedence=0)
const PUNCTUATION_TYPE
Definition: Token.php:36
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ parseExpression()

Twig_ExpressionParser::parseExpression (   $precedence = 0)

Definition at line 53 of file ExpressionParser.php.

References PHPMailer\PHPMailer\$token, getPrimary(), isBinary(), parseConditionalExpression(), parseNotTestExpression(), and parseTestExpression().

Referenced by getPrimary(), parseArguments(), parseArrayExpression(), parseConditionalExpression(), parseHashExpression(), parseMultitargetExpression(), parseStringExpression(), and parseSubscriptExpression().

54  {
55  $expr = $this->getPrimary();
56  $token = $this->parser->getCurrentToken();
57  while ($this->isBinary($token) && $this->binaryOperators[$token->getValue()]['precedence'] >= $precedence) {
58  $op = $this->binaryOperators[$token->getValue()];
59  $this->parser->getStream()->next();
60 
61  if ('is not' === $token->getValue()) {
62  $expr = $this->parseNotTestExpression($expr);
63  } elseif ('is' === $token->getValue()) {
64  $expr = $this->parseTestExpression($expr);
65  } elseif (isset($op['callable'])) {
66  $expr = call_user_func($op['callable'], $this->parser, $expr);
67  } else {
68  $expr1 = $this->parseExpression(self::OPERATOR_LEFT === $op['associativity'] ? $op['precedence'] + 1 : $op['precedence']);
69  $class = $op['class'];
70  $expr = new $class($expr, $expr1, $token->getLine());
71  }
72 
73  $token = $this->parser->getCurrentToken();
74  }
75 
76  if (0 === $precedence) {
77  return $this->parseConditionalExpression($expr);
78  }
79 
80  return $expr;
81  }
parseExpression($precedence=0)
isBinary(Twig_Token $token)
parseTestExpression(Twig_NodeInterface $node)
parseNotTestExpression(Twig_NodeInterface $node)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ parseFilterExpression()

Twig_ExpressionParser::parseFilterExpression (   $node)

Definition at line 465 of file ExpressionParser.php.

References parseFilterExpressionRaw().

Referenced by parsePostfixExpression().

466  {
467  $this->parser->getStream()->next();
468 
469  return $this->parseFilterExpressionRaw($node);
470  }
parseFilterExpressionRaw($node, $tag=null)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ parseFilterExpressionRaw()

Twig_ExpressionParser::parseFilterExpressionRaw (   $node,
  $tag = null 
)

Definition at line 472 of file ExpressionParser.php.

References $name, $tag, PHPMailer\PHPMailer\$token, getFilterNodeClass(), Twig_Token\NAME_TYPE, parseArguments(), and Twig_Token\PUNCTUATION_TYPE.

Referenced by parseFilterExpression().

473  {
474  while (true) {
475  $token = $this->parser->getStream()->expect(Twig_Token::NAME_TYPE);
476 
477  $name = new Twig_Node_Expression_Constant($token->getValue(), $token->getLine());
478  if (!$this->parser->getStream()->test(Twig_Token::PUNCTUATION_TYPE, '(')) {
479  $arguments = new Twig_Node();
480  } else {
481  $arguments = $this->parseArguments(true);
482  }
483 
484  $class = $this->getFilterNodeClass($name->getAttribute('value'), $token->getLine());
485 
486  $node = new $class($node, $name, $arguments, $token->getLine(), $tag);
487 
488  if (!$this->parser->getStream()->test(Twig_Token::PUNCTUATION_TYPE, '|')) {
489  break;
490  }
491 
492  $this->parser->getStream()->next();
493  }
494 
495  return $node;
496  }
const PUNCTUATION_TYPE
Definition: Token.php:36
Represents a node in the AST.
Definition: Node.php:18
parseArguments($namedArguments=false, $definition=false)
Parses arguments.
getFilterNodeClass($name, $line)
const NAME_TYPE
Definition: Token.php:32
if(function_exists('posix_getuid') &&posix_getuid()===0) if(!array_key_exists('t', $options)) $tag
Definition: cron.php:35
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ parseHashExpression()

Twig_ExpressionParser::parseHashExpression ( )

Definition at line 271 of file ExpressionParser.php.

References $current, $key, GuzzleHttp\Psr7\$stream, PHPMailer\PHPMailer\$token, Twig_Token\NAME_TYPE, Twig_Token\NUMBER_TYPE, parseExpression(), Twig_Token\PUNCTUATION_TYPE, Twig_Token\STRING_TYPE, and Twig_Token\typeToEnglish().

Referenced by parsePrimaryExpression().

272  {
273  $stream = $this->parser->getStream();
274  $stream->expect(Twig_Token::PUNCTUATION_TYPE, '{', 'A hash element was expected');
275 
276  $node = new Twig_Node_Expression_Array(array(), $stream->getCurrent()->getLine());
277  $first = true;
278  while (!$stream->test(Twig_Token::PUNCTUATION_TYPE, '}')) {
279  if (!$first) {
280  $stream->expect(Twig_Token::PUNCTUATION_TYPE, ',', 'A hash value must be followed by a comma');
281 
282  // trailing ,?
283  if ($stream->test(Twig_Token::PUNCTUATION_TYPE, '}')) {
284  break;
285  }
286  }
287  $first = false;
288 
289  // a hash key can be:
290  //
291  // * a number -- 12
292  // * a string -- 'a'
293  // * a name, which is equivalent to a string -- a
294  // * an expression, which must be enclosed in parentheses -- (1 + 2)
296  $key = new Twig_Node_Expression_Constant($token->getValue(), $token->getLine());
297  } elseif ($stream->test(Twig_Token::PUNCTUATION_TYPE, '(')) {
298  $key = $this->parseExpression();
299  } else {
300  $current = $stream->getCurrent();
301 
302  throw new Twig_Error_Syntax(sprintf('A hash key must be a quoted string, a number, a name, or an expression enclosed in parentheses (unexpected token "%s" of value "%s".', Twig_Token::typeToEnglish($current->getType()), $current->getValue()), $current->getLine(), $stream->getSourceContext());
303  }
304 
305  $stream->expect(Twig_Token::PUNCTUATION_TYPE, ':', 'A hash key must be followed by a colon (:)');
306  $value = $this->parseExpression();
307 
308  $node->addElement($value, $key);
309  }
310  $stream->expect(Twig_Token::PUNCTUATION_TYPE, '}', 'An opened hash is not properly closed');
311 
312  return $node;
313  }
parseExpression($precedence=0)
const PUNCTUATION_TYPE
Definition: Token.php:36
$stream
PHP stream implementation.
Exception thrown when a syntax error occurs during lexing or parsing of a template.
Definition: Syntax.php:18
const STRING_TYPE
Definition: Token.php:34
const NUMBER_TYPE
Definition: Token.php:33
static typeToEnglish($type)
Returns the English representation of a given type.
Definition: Token.php:172
$key
Definition: croninfo.php:18
const NAME_TYPE
Definition: Token.php:32
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ parseMultitargetExpression()

Twig_ExpressionParser::parseMultitargetExpression ( )

Definition at line 583 of file ExpressionParser.php.

References parseExpression(), and Twig_Token\PUNCTUATION_TYPE.

584  {
585  $targets = array();
586  while (true) {
587  $targets[] = $this->parseExpression();
588  if (!$this->parser->getStream()->nextIf(Twig_Token::PUNCTUATION_TYPE, ',')) {
589  break;
590  }
591  }
592 
593  return new Twig_Node($targets);
594  }
parseExpression($precedence=0)
const PUNCTUATION_TYPE
Definition: Token.php:36
Represents a node in the AST.
Definition: Node.php:18
+ Here is the call graph for this function:

◆ parseNotTestExpression()

Twig_ExpressionParser::parseNotTestExpression ( Twig_NodeInterface  $node)
private

Definition at line 596 of file ExpressionParser.php.

References parseTestExpression().

Referenced by parseExpression().

597  {
598  return new Twig_Node_Expression_Unary_Not($this->parseTestExpression($node), $this->parser->getCurrentToken()->getLine());
599  }
parseTestExpression(Twig_NodeInterface $node)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ parsePostfixExpression()

Twig_ExpressionParser::parsePostfixExpression (   $node)

Definition at line 315 of file ExpressionParser.php.

References PHPMailer\PHPMailer\$token, parseFilterExpression(), parseSubscriptExpression(), and Twig_Token\PUNCTUATION_TYPE.

Referenced by getPrimary(), and parsePrimaryExpression().

316  {
317  while (true) {
318  $token = $this->parser->getCurrentToken();
319  if (Twig_Token::PUNCTUATION_TYPE == $token->getType()) {
320  if ('.' == $token->getValue() || '[' == $token->getValue()) {
321  $node = $this->parseSubscriptExpression($node);
322  } elseif ('|' == $token->getValue()) {
323  $node = $this->parseFilterExpression($node);
324  } else {
325  break;
326  }
327  } else {
328  break;
329  }
330  }
331 
332  return $node;
333  }
const PUNCTUATION_TYPE
Definition: Token.php:36
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ parsePrimaryExpression()

Twig_ExpressionParser::parsePrimaryExpression ( )

Definition at line 136 of file ExpressionParser.php.

References PHPMailer\PHPMailer\$token, getFunctionNode(), Twig_Token\INTERPOLATION_START_TYPE, Twig_Token\NAME_TYPE, Twig_Token\NUMBER_TYPE, Twig_Token\OPERATOR_TYPE, parseArrayExpression(), parseHashExpression(), parsePostfixExpression(), parseStringExpression(), Twig_Token\PUNCTUATION_TYPE, Twig_Lexer\REGEX_NAME, Twig_Token\STRING_TYPE, and Twig_Token\typeToEnglish().

Referenced by getPrimary(), and parseArguments().

137  {
138  $token = $this->parser->getCurrentToken();
139  switch ($token->getType()) {
141  $this->parser->getStream()->next();
142  switch ($token->getValue()) {
143  case 'true':
144  case 'TRUE':
145  $node = new Twig_Node_Expression_Constant(true, $token->getLine());
146  break;
147 
148  case 'false':
149  case 'FALSE':
150  $node = new Twig_Node_Expression_Constant(false, $token->getLine());
151  break;
152 
153  case 'none':
154  case 'NONE':
155  case 'null':
156  case 'NULL':
157  $node = new Twig_Node_Expression_Constant(null, $token->getLine());
158  break;
159 
160  default:
161  if ('(' === $this->parser->getCurrentToken()->getValue()) {
162  $node = $this->getFunctionNode($token->getValue(), $token->getLine());
163  } else {
164  $node = new Twig_Node_Expression_Name($token->getValue(), $token->getLine());
165  }
166  }
167  break;
168 
170  $this->parser->getStream()->next();
171  $node = new Twig_Node_Expression_Constant($token->getValue(), $token->getLine());
172  break;
173 
176  $node = $this->parseStringExpression();
177  break;
178 
180  if (preg_match(Twig_Lexer::REGEX_NAME, $token->getValue(), $matches) && $matches[0] == $token->getValue()) {
181  // in this context, string operators are variable names
182  $this->parser->getStream()->next();
183  $node = new Twig_Node_Expression_Name($token->getValue(), $token->getLine());
184  break;
185  } elseif (isset($this->unaryOperators[$token->getValue()])) {
186  $class = $this->unaryOperators[$token->getValue()]['class'];
187 
188  $ref = new ReflectionClass($class);
189  $negClass = 'Twig_Node_Expression_Unary_Neg';
190  $posClass = 'Twig_Node_Expression_Unary_Pos';
191  if (!(in_array($ref->getName(), array($negClass, $posClass)) || $ref->isSubclassOf($negClass) || $ref->isSubclassOf($posClass))) {
192  throw new Twig_Error_Syntax(sprintf('Unexpected unary operator "%s".', $token->getValue()), $token->getLine(), $this->parser->getStream()->getSourceContext());
193  }
194 
195  $this->parser->getStream()->next();
196  $expr = $this->parsePrimaryExpression();
197 
198  $node = new $class($expr, $token->getLine());
199  break;
200  }
201 
202  // no break
203  default:
204  if ($token->test(Twig_Token::PUNCTUATION_TYPE, '[')) {
205  $node = $this->parseArrayExpression();
206  } elseif ($token->test(Twig_Token::PUNCTUATION_TYPE, '{')) {
207  $node = $this->parseHashExpression();
208  } elseif ($token->test(Twig_Token::OPERATOR_TYPE, '=') && ('==' === $this->parser->getStream()->look(-1)->getValue() || '!=' === $this->parser->getStream()->look(-1)->getValue())) {
209  throw new Twig_Error_Syntax(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(), $this->parser->getStream()->getSourceContext());
210  } else {
211  throw new Twig_Error_Syntax(sprintf('Unexpected token "%s" of value "%s".', Twig_Token::typeToEnglish($token->getType()), $token->getValue()), $token->getLine(), $this->parser->getStream()->getSourceContext());
212  }
213  }
214 
215  return $this->parsePostfixExpression($node);
216  }
const PUNCTUATION_TYPE
Definition: Token.php:36
Exception thrown when a syntax error occurs during lexing or parsing of a template.
Definition: Syntax.php:18
const STRING_TYPE
Definition: Token.php:34
getFunctionNode($name, $line)
const NUMBER_TYPE
Definition: Token.php:33
static typeToEnglish($type)
Returns the English representation of a given type.
Definition: Token.php:172
const REGEX_NAME
Definition: Lexer.php:45
const OPERATOR_TYPE
Definition: Token.php:35
const NAME_TYPE
Definition: Token.php:32
const INTERPOLATION_START_TYPE
Definition: Token.php:37
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ parseStringExpression()

Twig_ExpressionParser::parseStringExpression ( )

Definition at line 218 of file ExpressionParser.php.

References $nodes, GuzzleHttp\Psr7\$stream, PHPMailer\PHPMailer\$token, Twig_Token\INTERPOLATION_END_TYPE, Twig_Token\INTERPOLATION_START_TYPE, parseExpression(), and Twig_Token\STRING_TYPE.

Referenced by parsePrimaryExpression().

219  {
220  $stream = $this->parser->getStream();
221 
222  $nodes = array();
223  // a string cannot be followed by another string in a single expression
224  $nextCanBeString = true;
225  while (true) {
226  if ($nextCanBeString && $token = $stream->nextIf(Twig_Token::STRING_TYPE)) {
227  $nodes[] = new Twig_Node_Expression_Constant($token->getValue(), $token->getLine());
228  $nextCanBeString = false;
229  } elseif ($stream->nextIf(Twig_Token::INTERPOLATION_START_TYPE)) {
230  $nodes[] = $this->parseExpression();
232  $nextCanBeString = true;
233  } else {
234  break;
235  }
236  }
237 
238  $expr = array_shift($nodes);
239  foreach ($nodes as $node) {
240  $expr = new Twig_Node_Expression_Binary_Concat($expr, $node, $node->getTemplateLine());
241  }
242 
243  return $expr;
244  }
parseExpression($precedence=0)
$stream
PHP stream implementation.
const STRING_TYPE
Definition: Token.php:34
const INTERPOLATION_END_TYPE
Definition: Token.php:38
const INTERPOLATION_START_TYPE
Definition: Token.php:37
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ parseSubscriptExpression()

Twig_ExpressionParser::parseSubscriptExpression (   $node)

Definition at line 383 of file ExpressionParser.php.

References $n, $name, GuzzleHttp\Psr7\$stream, PHPMailer\PHPMailer\$token, $type, Twig_TemplateInterface\ANY_CALL, Twig_TemplateInterface\ARRAY_CALL, getFilterNodeClass(), Twig_TemplateInterface\METHOD_CALL, Twig_Token\NAME_TYPE, Twig_Token\NUMBER_TYPE, Twig_Token\OPERATOR_TYPE, parseArguments(), parseExpression(), Twig_Token\PUNCTUATION_TYPE, and Twig_Lexer\REGEX_NAME.

Referenced by parsePostfixExpression().

384  {
385  $stream = $this->parser->getStream();
386  $token = $stream->next();
387  $lineno = $token->getLine();
388  $arguments = new Twig_Node_Expression_Array(array(), $lineno);
390  if ('.' == $token->getValue()) {
391  $token = $stream->next();
392  if (
393  Twig_Token::NAME_TYPE == $token->getType()
394  ||
395  Twig_Token::NUMBER_TYPE == $token->getType()
396  ||
397  (Twig_Token::OPERATOR_TYPE == $token->getType() && preg_match(Twig_Lexer::REGEX_NAME, $token->getValue()))
398  ) {
399  $arg = new Twig_Node_Expression_Constant($token->getValue(), $lineno);
400 
401  if ($stream->test(Twig_Token::PUNCTUATION_TYPE, '(')) {
403  foreach ($this->parseArguments() as $n) {
404  $arguments->addElement($n);
405  }
406  }
407  } else {
408  throw new Twig_Error_Syntax('Expected name or number.', $lineno, $stream->getSourceContext());
409  }
410 
411  if ($node instanceof Twig_Node_Expression_Name && null !== $this->parser->getImportedSymbol('template', $node->getAttribute('name'))) {
412  if (!$arg instanceof Twig_Node_Expression_Constant) {
413  throw new Twig_Error_Syntax(sprintf('Dynamic macro names are not supported (called on "%s").', $node->getAttribute('name')), $token->getLine(), $stream->getSourceContext());
414  }
415 
416  $name = $arg->getAttribute('value');
417 
418  if ($this->parser->isReservedMacroName($name)) {
419  throw new Twig_Error_Syntax(sprintf('"%s" cannot be called as macro as it is a reserved keyword.', $name), $token->getLine(), $stream->getSourceContext());
420  }
421 
422  $node = new Twig_Node_Expression_MethodCall($node, 'get'.$name, $arguments, $lineno);
423  $node->setAttribute('safe', true);
424 
425  return $node;
426  }
427  } else {
429 
430  // slice?
431  $slice = false;
432  if ($stream->test(Twig_Token::PUNCTUATION_TYPE, ':')) {
433  $slice = true;
434  $arg = new Twig_Node_Expression_Constant(0, $token->getLine());
435  } else {
436  $arg = $this->parseExpression();
437  }
438 
439  if ($stream->nextIf(Twig_Token::PUNCTUATION_TYPE, ':')) {
440  $slice = true;
441  }
442 
443  if ($slice) {
444  if ($stream->test(Twig_Token::PUNCTUATION_TYPE, ']')) {
445  $length = new Twig_Node_Expression_Constant(null, $token->getLine());
446  } else {
447  $length = $this->parseExpression();
448  }
449 
450  $class = $this->getFilterNodeClass('slice', $token->getLine());
451  $arguments = new Twig_Node(array($arg, $length));
452  $filter = new $class($node, new Twig_Node_Expression_Constant('slice', $token->getLine()), $arguments, $token->getLine());
453 
455 
456  return $filter;
457  }
458 
460  }
461 
462  return new Twig_Node_Expression_GetAttr($node, $arg, $arguments, $type, $lineno);
463  }
parseExpression($precedence=0)
const PUNCTUATION_TYPE
Definition: Token.php:36
Represents a node in the AST.
Definition: Node.php:18
$type
parseArguments($namedArguments=false, $definition=false)
Parses arguments.
getFilterNodeClass($name, $line)
$stream
PHP stream implementation.
Exception thrown when a syntax error occurs during lexing or parsing of a template.
Definition: Syntax.php:18
$n
Definition: RandomTest.php:85
const NUMBER_TYPE
Definition: Token.php:33
const REGEX_NAME
Definition: Lexer.php:45
const OPERATOR_TYPE
Definition: Token.php:35
const NAME_TYPE
Definition: Token.php:32
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ parseTestExpression()

Twig_ExpressionParser::parseTestExpression ( Twig_NodeInterface  $node)
private

Definition at line 601 of file ExpressionParser.php.

References $name, GuzzleHttp\Psr7\$stream, $test, getTest(), getTestNodeClass(), and Twig_Token\PUNCTUATION_TYPE.

Referenced by parseExpression(), and parseNotTestExpression().

602  {
603  $stream = $this->parser->getStream();
604  list($name, $test) = $this->getTest($node->getTemplateLine());
605 
606  $class = $this->getTestNodeClass($test);
607  $arguments = null;
608  if ($stream->test(Twig_Token::PUNCTUATION_TYPE, '(')) {
609  $arguments = $this->parser->getExpressionParser()->parseArguments(true);
610  }
611 
612  return new $class($node, $name, $arguments, $this->parser->getCurrentToken()->getLine());
613  }
const PUNCTUATION_TYPE
Definition: Token.php:36
$stream
PHP stream implementation.
$test
Definition: Utf8Test.php:84
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Field Documentation

◆ $binaryOperators

Twig_ExpressionParser::$binaryOperators
protected

Definition at line 32 of file ExpressionParser.php.

◆ $env

Twig_ExpressionParser::$env
private

Definition at line 34 of file ExpressionParser.php.

Referenced by __construct().

◆ $parser

Twig_ExpressionParser::$parser
protected

Definition at line 30 of file ExpressionParser.php.

Referenced by __construct().

◆ $unaryOperators

Twig_ExpressionParser::$unaryOperators
protected

Definition at line 31 of file ExpressionParser.php.

◆ OPERATOR_LEFT

const Twig_ExpressionParser::OPERATOR_LEFT = 1

Definition at line 27 of file ExpressionParser.php.

Referenced by Twig_Extension_Core\getOperators().

◆ OPERATOR_RIGHT

const Twig_ExpressionParser::OPERATOR_RIGHT = 2

Definition at line 28 of file ExpressionParser.php.

Referenced by Twig_Extension_Core\getOperators().


The documentation for this class was generated from the following file: