protected $runtimeInitialized;
protected $loadedTemplates;
protected $strictVariables;
+ protected $unaryOperators;
+ protected $binaryOperators;
/**
* Constructor.
return $this->tests;
}
+ public function getUnaryOperators()
+ {
+ if (null === $this->unaryOperators) {
+ $this->initOperators();
+ }
+
+ return $this->unaryOperators;
+ }
+
+ public function getBinaryOperators()
+ {
+ if (null === $this->binaryOperators) {
+ $this->initOperators();
+ }
+
+ return $this->binaryOperators;
+ }
+
+ protected function initOperators()
+ {
+ $this->unaryOperators = array();
+ $this->binaryOperators = array();
+ foreach ($this->getExtensions() as $extension) {
+ $operators = $extension->getOperators();
+
+ if (!$operators) {
+ continue;
+ }
+
+ if (2 !== count($operators)) {
+ throw new InvalidArgumentException(sprintf('"%s::getOperators()" does not return a valid operators array.', get_class($extension)));
+ }
+
+ $this->unaryOperators = array_merge($this->unaryOperators, $operators[0]);
+ $this->binaryOperators = array_merge($this->binaryOperators, $operators[1]);
+ }
+ }
+
protected function writeCacheFile($file, $content)
{
$tmpFile = tempnam(dirname($file), basename($file));
protected $unaryOperators;
protected $binaryOperators;
- public function __construct(Twig_Parser $parser)
+ public function __construct(Twig_Parser $parser, array $unaryOperators, array $binaryOperators)
{
$this->parser = $parser;
- $this->unaryOperators = $this->getUnaryOperators();
- $this->binaryOperators = $this->getBinaryOperators();
- }
-
- public function getUnaryOperators()
- {
- return array(
- 'not' => array('precedence' => 50, 'class' => 'Twig_Node_Expression_Unary_Not'),
- '-' => array('precedence' => 50, 'class' => 'Twig_Node_Expression_Unary_Neg'),
- '+' => array('precedence' => 50, 'class' => 'Twig_Node_Expression_Unary_Pos'),
- );
- }
-
- public function getBinaryOperators()
- {
- return array(
- 'or' => array('precedence' => 10, 'class' => 'Twig_Node_Expression_Binary_Or', 'associativity' => self::OPERATOR_LEFT),
- 'and' => array('precedence' => 15, 'class' => 'Twig_Node_Expression_Binary_And', 'associativity' => self::OPERATOR_LEFT),
- '==' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_Equal', 'associativity' => self::OPERATOR_LEFT),
- '!=' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_NotEqual', 'associativity' => self::OPERATOR_LEFT),
- '<' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_Less', 'associativity' => self::OPERATOR_LEFT),
- '>' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_Greater', 'associativity' => self::OPERATOR_LEFT),
- '>=' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_GreaterEqual', 'associativity' => self::OPERATOR_LEFT),
- '<=' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_LessEqual', 'associativity' => self::OPERATOR_LEFT),
- 'not in' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_NotIn', 'associativity' => self::OPERATOR_LEFT),
- 'in' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_In', 'associativity' => self::OPERATOR_LEFT),
- '+' => array('precedence' => 30, 'class' => 'Twig_Node_Expression_Binary_Add', 'associativity' => self::OPERATOR_LEFT),
- '-' => array('precedence' => 30, 'class' => 'Twig_Node_Expression_Binary_Sub', 'associativity' => self::OPERATOR_LEFT),
- '~' => array('precedence' => 40, 'class' => 'Twig_Node_Expression_Binary_Concat', 'associativity' => self::OPERATOR_LEFT),
- '*' => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_Mul', 'associativity' => self::OPERATOR_LEFT),
- '/' => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_Div', 'associativity' => self::OPERATOR_LEFT),
- '//' => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_FloorDiv', 'associativity' => self::OPERATOR_LEFT),
- '%' => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_Mod', 'associativity' => self::OPERATOR_LEFT),
- 'is' => array('precedence' => 100, 'callable' => array($this, 'parseTestExpression'), 'associativity' => self::OPERATOR_LEFT),
- 'is not' => array('precedence' => 100, 'callable' => array($this, 'parseNotTestExpression'), 'associativity' => self::OPERATOR_LEFT),
- '..' => array('precedence' => 110, 'class' => 'Twig_Node_Expression_Binary_Range', 'associativity' => self::OPERATOR_LEFT),
- '**' => array('precedence' => 200, 'class' => 'Twig_Node_Expression_Binary_Power', 'associativity' => self::OPERATOR_RIGHT),
- );
+ $this->unaryOperators = $unaryOperators;
+ $this->binaryOperators = $binaryOperators;
}
public function parseExpression($precedence = 0)
$this->parser->getStream()->next();
if (isset($op['callable'])) {
- $expr = call_user_func($op['callable'], $expr);
+ $expr = call_user_func($op['callable'], $this->parser, $expr);
} else {
$expr1 = $this->parseExpression(self::OPERATOR_LEFT === $op['associativity'] ? $op['precedence'] + 1 : $op['precedence']);
$class = $op['class'];
return $node;
}
- public function parseNotTestExpression($node)
- {
- return new Twig_Node_Expression_Unary_Not($this->parseTestExpression($node), $this->parser->getCurrentToken()->getLine());
- }
-
- public function parseTestExpression($node)
- {
- $stream = $this->parser->getStream();
- $name = $stream->expect(Twig_Token::NAME_TYPE);
- $arguments = null;
- if ($stream->test(Twig_Token::PUNCTUATION_TYPE, '(')) {
- $arguments = $this->parseArguments($node);
- }
-
- return new Twig_Node_Expression_Test($node, $name->getValue(), $arguments, $this->parser->getCurrentToken()->getLine());
- }
-
public function parseSubscriptExpression($node)
{
$token = $this->parser->getStream()->next();
{
return array();
}
+
+ /**
+ * Returns a list of operators to add to the existing list.
+ *
+ * @return array An array of operators
+ */
+ public function getOperators()
+ {
+ return array();
+ }
}
}
/**
+ * Returns a list of operators to add to the existing list.
+ *
+ * @return array An array of operators
+ */
+ public function getOperators()
+ {
+ return array(
+ array(
+ 'not' => array('precedence' => 50, 'class' => 'Twig_Node_Expression_Unary_Not'),
+ '-' => array('precedence' => 50, 'class' => 'Twig_Node_Expression_Unary_Neg'),
+ '+' => array('precedence' => 50, 'class' => 'Twig_Node_Expression_Unary_Pos'),
+ ),
+ array(
+ 'or' => array('precedence' => 10, 'class' => 'Twig_Node_Expression_Binary_Or', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
+ 'and' => array('precedence' => 15, 'class' => 'Twig_Node_Expression_Binary_And', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
+ '==' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_Equal', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
+ '!=' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_NotEqual', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
+ '<' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_Less', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
+ '>' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_Greater', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
+ '>=' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_GreaterEqual', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
+ '<=' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_LessEqual', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
+ 'not in' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_NotIn', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
+ 'in' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_In', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
+ '+' => array('precedence' => 30, 'class' => 'Twig_Node_Expression_Binary_Add', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
+ '-' => array('precedence' => 30, 'class' => 'Twig_Node_Expression_Binary_Sub', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
+ '~' => array('precedence' => 40, 'class' => 'Twig_Node_Expression_Binary_Concat', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
+ '*' => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_Mul', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
+ '/' => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_Div', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
+ '//' => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_FloorDiv', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
+ '%' => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_Mod', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
+ 'is' => array('precedence' => 100, 'callable' => array($this, 'parseTestExpression'), 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
+ 'is not' => array('precedence' => 100, 'callable' => array($this, 'parseNotTestExpression'), 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
+ '..' => array('precedence' => 110, 'class' => 'Twig_Node_Expression_Binary_Range', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
+ '**' => array('precedence' => 200, 'class' => 'Twig_Node_Expression_Binary_Power', 'associativity' => Twig_ExpressionParser::OPERATOR_RIGHT),
+ ),
+ );
+ }
+
+ public function parseNotTestExpression($parser, $node)
+ {
+ return new Twig_Node_Expression_Unary_Not($this->parseTestExpression($parser, $node), $parser->getCurrentToken()->getLine());
+ }
+
+ public function parseTestExpression($parser, $node)
+ {
+ $stream = $parser->getStream();
+ $name = $stream->expect(Twig_Token::NAME_TYPE);
+ $arguments = null;
+ if ($stream->test(Twig_Token::PUNCTUATION_TYPE, '(')) {
+ $arguments = $parser->getExpressionParser()->parseArguments($node);
+ }
+
+ return new Twig_Node_Expression_Test($node, $name->getValue(), $arguments, $parser->getCurrentToken()->getLine());
+ }
+
+ /**
* Returns the name of the extension.
*
* @return string The extension name
public function getTests();
/**
+ * Returns a list of operators to add to the existing list.
+ *
+ * @return array An array of operators
+ */
+ public function getOperators();
+
+ /**
* Returns the name of the extension.
*
* @return string The extension name
$this->visitors = $this->env->getNodeVisitors();
if (null === $this->expressionParser) {
- $this->expressionParser = new Twig_ExpressionParser($this);
+ $this->expressionParser = new Twig_ExpressionParser($this, $this->env->getUnaryOperators(), $this->env->getBinaryOperators());
}
$this->stream = $stream;