added optimized versions of expressions

This commit is contained in:
Fabien Potencier 2013-09-06 08:52:21 +02:00
parent 984bd38568
commit 1bcfb40eb5
5 changed files with 135 additions and 14 deletions

View File

@ -24,6 +24,7 @@ use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\Parameter;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\ExpressionLanguage\Expression;
use Symfony\Component\Security\Core\Authorization\ExpressionLanguage;
/**
* SecurityExtension.
@ -39,6 +40,7 @@ class SecurityExtension extends Extension
private $listenerPositions = array('pre_auth', 'form', 'http', 'remember_me');
private $factories = array();
private $userProviderFactories = array();
private $expressionLanguage;
public function __construct()
{
@ -610,9 +612,10 @@ class SecurityExtension extends Extension
}
$container
->register($id, 'Symfony\Component\ExpressionLanguage\Expression')
->register($id, 'Symfony\Component\ExpressionLanguage\SerializedParsedExpression')
->setPublic(false)
->addArgument($expression)
->addArgument(serialize($this->getExpressionLanguage()->parse($expression, array('token', 'user', 'object', 'roles', 'request'))))
;
return $this->expressions[$id] = new Reference($id);
@ -676,4 +679,16 @@ class SecurityExtension extends Extension
// first assemble the factories
return new MainConfiguration($this->factories, $this->userProviderFactories);
}
private function getExpressionLanguage()
{
if (null === $this->expressionLanguage) {
if (!class_exists('Symfony\Component\ExpressionLanguage\ExpressionLanguage')) {
throw new RuntimeException('Unable to use expressions as the Symfony ExpressionLanguage component is not installed.');
}
$this->expressionLanguage = new ExpressionLanguage();
}
return $this->expressionLanguage;
}
}

View File

@ -18,7 +18,7 @@ namespace Symfony\Component\ExpressionLanguage;
*/
class Expression
{
private $expression;
protected $expression;
/**
* Constructor.

View File

@ -11,6 +11,8 @@
namespace Symfony\Component\ExpressionLanguage;
use Symfony\Component\ExpressionLanguage\Node\Node;
/**
* Allows to compile and evaluate expressions written in your own DSL.
*
@ -44,9 +46,41 @@ class ExpressionLanguage
return $this->getCompiler()->compile($this->parse($expression, $names))->getSource();
}
/**
* Evaluate an expression.
*
* @param Expression|string $expression The expression to compile
* @param array $values An array of values
*
* @return string The result of the evaluation of the expression
*/
public function evaluate($expression, $values = array())
{
return $this->parse($expression, array_keys($values))->evaluate($this->functions, $values);
if ($expression instanceof ParsedExpression) {
$expression = $expression->getNodes();
} else {
$expression = $this->parse($expression, array_keys($values));
}
return $expression->evaluate($this->functions, $values);
}
/**
* Parses an expression.
*
* @param Expression|string $expression The expression to parse
*
* @return Node A Node tree
*/
public function parse($expression, $names)
{
$key = $expression.'//'.implode('-', $names);
if (!isset($this->cache[$key])) {
$this->cache[$key] = $this->getParser()->parse($this->getLexer()->tokenize((string) $expression), $names);
}
return $this->cache[$key];
}
public function addFunction($name, $compiler, $evaluator)
@ -89,15 +123,4 @@ class ExpressionLanguage
return $this->compiler->reset();
}
private function parse($expression, $names)
{
$key = $expression.'//'.implode('-', $names);
if (!isset($this->cache[$key])) {
$this->cache[$key] = $this->getParser()->parse($this->getLexer()->tokenize((string) $expression), $names);
}
return $this->cache[$key];
}
}

View File

@ -0,0 +1,42 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\ExpressionLanguage;
use Symfony\Component\ExpressionLanguage\Node\Node;
/**
* Represents an already parsed expression.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
class ParsedExpression extends Expression
{
private $nodes;
/**
* Constructor.
*
* @param string $expression An expression
* @param Node $nodes A Node representing the expression
*/
public function __construct($expression, Node $nodes)
{
parent::__construct($expression);
$this->nodes = $nodes;
}
public function getNodes()
{
return $this->nodes;
}
}

View File

@ -0,0 +1,41 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\ExpressionLanguage;
use Symfony\Component\ExpressionLanguage\Node\Node;
/**
* Represents an already parsed expression.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
class SerializedParsedExpression extends ParsedExpression
{
private $nodes;
/**
* Constructor.
*
* @param string $expression An expression
* @param string $nodes The serialized nodes for the expression
*/
public function __construct($expression, $nodes)
{
$this->expression = (string) $expression;
$this->nodes = $nodes;
}
public function getNodes()
{
return unserialize($this->nodes);
}
}