Skip to content

Commit

Permalink
moved filters/functions/tests syntax errors to the parser
Browse files Browse the repository at this point in the history
  • Loading branch information
fabpot committed Nov 14, 2012
1 parent 2243a14 commit e1ad2bd
Show file tree
Hide file tree
Showing 10 changed files with 75 additions and 92 deletions.
1 change: 1 addition & 0 deletions CHANGELOG
@@ -1,5 +1,6 @@
* 1.12.0 (2012-XX-XX)

* moved filters/functions/tests syntax errors to the parser
* added support for extended ternary operator syntaxes

* 1.11.1 (2012-11-11)
Expand Down
38 changes: 25 additions & 13 deletions lib/Twig/ExpressionParser.php
Expand Up @@ -330,7 +330,7 @@ public function getFunctionNode($name, $line)
return $node;
}

$class = $this->getFunctionNodeClass($name);
$class = $this->getFunctionNodeClass($name, $line);

return new $class($name, $args, $line);
}
Expand Down Expand Up @@ -378,7 +378,7 @@ public function parseSubscriptExpression($node)
$length = $this->parseExpression();
}

$class = $this->getFilterNodeClass('slice');
$class = $this->getFilterNodeClass('slice', $token->getLine());
$arguments = new Twig_Node(array($arg, $length));
$filter = new $class($node, new Twig_Node_Expression_Constant('slice', $token->getLine()), $arguments, $token->getLine());

Expand Down Expand Up @@ -419,7 +419,7 @@ public function parseFilterExpressionRaw($node, $tag = null)
$arguments = $this->parseArguments();
}

$class = $this->getFilterNodeClass($name->getAttribute('value'));
$class = $this->getFilterNodeClass($name->getAttribute('value'), $token->getLine());

$node = new $class($node, $name, $arguments, $token->getLine(), $tag);

Expand Down Expand Up @@ -483,23 +483,35 @@ public function parseMultitargetExpression()
return new Twig_Node($targets);
}

protected function getFunctionNodeClass($name)
protected function getFunctionNodeClass($name, $line)
{
$functionMap = $this->parser->getEnvironment()->getFunctions();
if (isset($functionMap[$name]) && $functionMap[$name] instanceof Twig_Function_Node) {
return $functionMap[$name]->getClass();
$env = $this->parser->getEnvironment();

if (false === $function = $env->getFunction($name)) {
$message = sprintf('The function "%s" does not exist', $name);
if ($alternatives = $env->computeAlternatives($name, array_keys($env->getFunctions()))) {
$message = sprintf('%s. Did you mean "%s"', $message, implode('", "', $alternatives));
}

throw new Twig_Error_Syntax($message, $line, $this->parser->getFilename());
}

return 'Twig_Node_Expression_Function';
return $function instanceof Twig_Function_Node ? $function->getClass() : 'Twig_Node_Expression_Function';
}

protected function getFilterNodeClass($name)
protected function getFilterNodeClass($name, $line)
{
$filterMap = $this->parser->getEnvironment()->getFilters();
if (isset($filterMap[$name]) && $filterMap[$name] instanceof Twig_Filter_Node) {
return $filterMap[$name]->getClass();
$env = $this->parser->getEnvironment();

if (false === $filter = $env->getFilter($name)) {
$message = sprintf('The filter "%s" does not exist', $name);
if ($alternatives = $env->computeAlternatives($name, array_keys($env->getFilters()))) {
$message = sprintf('%s. Did you mean "%s"', $message, implode('", "', $alternatives));
}

throw new Twig_Error_Syntax($message, $line, $this->parser->getFilename());
}

return 'Twig_Node_Expression_Filter';
return $filter instanceof Twig_Filter_Node ? $filter->getClass() : 'Twig_Node_Expression_Filter';
}
}
16 changes: 11 additions & 5 deletions lib/Twig/Extension/Core.php
Expand Up @@ -270,19 +270,25 @@ public function parseTestExpression(Twig_Parser $parser, $node)
$arguments = $parser->getExpressionParser()->parseArguments();
}

$class = $this->getTestNodeClass($parser->getEnvironment(), $name);
$class = $this->getTestNodeClass($parser, $name, $node->getLine());

return new $class($node, $name, $arguments, $parser->getCurrentToken()->getLine());
}

protected function getTestNodeClass(Twig_Environment $env, $name)
protected function getTestNodeClass(Twig_Parser $parser, $name, $line)
{
$env = $parser->getEnvironment();
$testMap = $env->getTests();
if (isset($testMap[$name]) && $testMap[$name] instanceof Twig_Test_Node) {
return $testMap[$name]->getClass();
if (!isset($testMap[$name])) {
$message = sprintf('The test "%s" does not exist', $name);
if ($alternatives = $env->computeAlternatives($name, array_keys($env->getTests()))) {
$message = sprintf('%s. Did you mean "%s"', $message, implode('", "', $alternatives));
}

throw new Twig_Error_Syntax($message, $line, $parser->getFilename());
}

return 'Twig_Node_Expression_Test';
return $testMap[$name] instanceof Twig_Test_Node ? $testMap[$name]->getClass() : 'Twig_Node_Expression_Test';
}

/**
Expand Down
11 changes: 1 addition & 10 deletions lib/Twig/Node/Expression/Filter.php
Expand Up @@ -18,16 +18,7 @@ public function __construct(Twig_NodeInterface $node, Twig_Node_Expression_Const

public function compile(Twig_Compiler $compiler)
{
$name = $this->getNode('filter')->getAttribute('value');

if (false === $filter = $compiler->getEnvironment()->getFilter($name)) {
$message = sprintf('The filter "%s" does not exist', $name);
if ($alternatives = $compiler->getEnvironment()->computeAlternatives($name, array_keys($compiler->getEnvironment()->getFilters()))) {
$message = sprintf('%s. Did you mean "%s"', $message, implode('", "', $alternatives));
}

throw new Twig_Error_Syntax($message, $this->getLine(), $compiler->getFilename());
}
$filter = $compiler->getEnvironment()->getFilter($this->getNode('filter')->getAttribute('value'));

$this->compileFilter($compiler, $filter);
}
Expand Down
11 changes: 1 addition & 10 deletions lib/Twig/Node/Expression/Function.php
Expand Up @@ -17,16 +17,7 @@ public function __construct($name, Twig_NodeInterface $arguments, $lineno)

public function compile(Twig_Compiler $compiler)
{
$name = $this->getAttribute('name');

if (false === $function = $compiler->getEnvironment()->getFunction($name)) {
$message = sprintf('The function "%s" does not exist', $name);
if ($alternatives = $compiler->getEnvironment()->computeAlternatives($name, array_keys($compiler->getEnvironment()->getFunctions()))) {
$message = sprintf('%s. Did you mean "%s"', $message, implode('", "', $alternatives));
}

throw new Twig_Error_Syntax($message, $this->getLine(), $compiler->getFilename());
}
$function = $compiler->getEnvironment()->getFunction($this->getAttribute('name'));

$compiler->raw($function->compile().'(');

Expand Down
8 changes: 0 additions & 8 deletions lib/Twig/Node/Expression/Test.php
Expand Up @@ -19,14 +19,6 @@ public function compile(Twig_Compiler $compiler)
{
$name = $this->getAttribute('name');
$testMap = $compiler->getEnvironment()->getTests();
if (!isset($testMap[$name])) {
$message = sprintf('The test "%s" does not exist', $name);
if ($alternatives = $compiler->getEnvironment()->computeAlternatives($name, array_keys($compiler->getEnvironment()->getTests()))) {
$message = sprintf('%s. Did you mean "%s"', $message, implode('", "', $alternatives));
}

throw new Twig_Error_Syntax($message, $this->getLine(), $compiler->getFilename());
}

$name = $this->getAttribute('name');
$node = $this->getNode('node');
Expand Down
36 changes: 36 additions & 0 deletions test/Twig/Tests/ExpressionParserTest.php
Expand Up @@ -214,4 +214,40 @@ public function getTestsForString()
),
);
}

/**
* @expectedException Twig_Error_Syntax
* @expectedExceptionMessage The function "cycl" does not exist. Did you mean "cycle" in "index" at line 1
*/
public function testUnknownFunction()
{
$env = new Twig_Environment(new Twig_Loader_String(), array('cache' => false, 'autoescape' => false));
$parser = new Twig_Parser($env);

$parser->parse($env->tokenize('{{ cycl() }}', 'index'));
}

/**
* @expectedException Twig_Error_Syntax
* @expectedExceptionMessage The filter "lowe" does not exist. Did you mean "lower" in "index" at line 1
*/
public function testUnknownFilter()
{
$env = new Twig_Environment(new Twig_Loader_String(), array('cache' => false, 'autoescape' => false));
$parser = new Twig_Parser($env);

$parser->parse($env->tokenize('{{ 1|lowe }}', 'index'));
}

/**
* @expectedException Twig_Error_Syntax
* @expectedExceptionMessage The test "nul" does not exist. Did you mean "null" in "index" at line 1
*/
public function testUnknownTest()
{
$env = new Twig_Environment(new Twig_Loader_String(), array('cache' => false, 'autoescape' => false));
$parser = new Twig_Parser($env);

$parser->parse($env->tokenize('{{ 1 is nul }}', 'index'));
}
}
24 changes: 0 additions & 24 deletions test/Twig/Tests/Node/Expression/FilterTest.php
Expand Up @@ -35,19 +35,6 @@ public function testCompile($node, $source, $environment = null)
parent::testCompile($node, $source, $environment);
}

/**
* @covers Twig_Node_Expression_Filter::compile
* @expectedException Twig_Error_Syntax
* @expectedExceptionMessage The filter "lowe" does not exist. Did you mean "lower" at line 1
*/
public function testCompileUnknownFilter()
{
$expr = new Twig_Node_Expression_Constant('foo', 1);
$node = $this->createFilter($expr, 'lowe', array(new Twig_Node_Expression_Constant('bar', 1), new Twig_Node_Expression_Constant('foobar', 1)));

$node->compile($this->getCompiler());
}

public function getTests()
{
$tests = array();
Expand All @@ -65,17 +52,6 @@ public function getTests()
return $tests;
}

/**
* @covers Twig_Node_Expression_Filter::compile
* @expectedException Twig_Error_Syntax
* @expectedExceptionMessage The filter "uppe" does not exist. Did you mean "upper" at line 1
*/
public function testUnknownFilter()
{
$node = $this->createFilter(new Twig_Node_Expression_Constant('foo', 1), 'uppe');
$node->compile($this->getCompiler());
}

protected function createFilter($node, $name, array $arguments = array())
{
$name = new Twig_Node_Expression_Constant($name, 1);
Expand Down
11 changes: 0 additions & 11 deletions test/Twig/Tests/Node/Expression/FunctionTest.php
Expand Up @@ -33,17 +33,6 @@ public function testCompile($node, $source, $environment = null)
parent::testCompile($node, $source, $environment);
}

/**
* @covers Twig_Node_Expression_Filter::compile
* @expectedException Twig_Error_Syntax
* @expectedExceptionMessage The function "cycl" does not exist. Did you mean "cycle" at line 1
*/
public function testUnknownFunction()
{
$node = $this->createFunction('cycl', array());
$node->compile($this->getCompiler());
}

public function getTests()
{
$environment = new Twig_Environment();
Expand Down
11 changes: 0 additions & 11 deletions test/Twig/Tests/Node/Expression/TestTest.php
Expand Up @@ -47,17 +47,6 @@ public function getTests()
return $tests;
}

/**
* @covers Twig_Node_Expression_Filter::compile
* @expectedException Twig_Error_Syntax
* @expectedExceptionMessage The test "nul" does not exist. Did you mean "null" at line 1
*/
public function testUnknownTest()
{
$node = $this->createTest(new Twig_Node_Expression_Constant('foo', 1), 'nul');
$node->compile($this->getCompiler());
}

protected function createTest($node, $name, array $arguments = array())
{
return new Twig_Node_Expression_Test($node, $name, new Twig_Node($arguments), 1);
Expand Down

0 comments on commit e1ad2bd

Please sign in to comment.