From e1ad2bde9c2cf12e65a89ef5eadcccd048f1af0c Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Wed, 14 Nov 2012 14:31:49 +0100 Subject: [PATCH] moved filters/functions/tests syntax errors to the parser --- CHANGELOG | 1 + lib/Twig/ExpressionParser.php | 38 ++++++++++++------- lib/Twig/Extension/Core.php | 16 +++++--- lib/Twig/Node/Expression/Filter.php | 11 +----- lib/Twig/Node/Expression/Function.php | 11 +----- lib/Twig/Node/Expression/Test.php | 8 ---- test/Twig/Tests/ExpressionParserTest.php | 36 ++++++++++++++++++ .../Twig/Tests/Node/Expression/FilterTest.php | 24 ------------ .../Tests/Node/Expression/FunctionTest.php | 11 ------ test/Twig/Tests/Node/Expression/TestTest.php | 11 ------ 10 files changed, 75 insertions(+), 92 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index c5716be7b6..ce2854d9d6 100644 --- a/CHANGELOG +++ b/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) diff --git a/lib/Twig/ExpressionParser.php b/lib/Twig/ExpressionParser.php index 62b90ea9b8..aa483030b4 100644 --- a/lib/Twig/ExpressionParser.php +++ b/lib/Twig/ExpressionParser.php @@ -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); } @@ -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()); @@ -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); @@ -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'; } } diff --git a/lib/Twig/Extension/Core.php b/lib/Twig/Extension/Core.php index 3db899f750..d2781b6d51 100644 --- a/lib/Twig/Extension/Core.php +++ b/lib/Twig/Extension/Core.php @@ -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'; } /** diff --git a/lib/Twig/Node/Expression/Filter.php b/lib/Twig/Node/Expression/Filter.php index eb9cd310f8..b7c62cc402 100644 --- a/lib/Twig/Node/Expression/Filter.php +++ b/lib/Twig/Node/Expression/Filter.php @@ -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); } diff --git a/lib/Twig/Node/Expression/Function.php b/lib/Twig/Node/Expression/Function.php index 56403775a6..9e0b3052eb 100644 --- a/lib/Twig/Node/Expression/Function.php +++ b/lib/Twig/Node/Expression/Function.php @@ -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().'('); diff --git a/lib/Twig/Node/Expression/Test.php b/lib/Twig/Node/Expression/Test.php index 076e39dae2..507d5d0454 100644 --- a/lib/Twig/Node/Expression/Test.php +++ b/lib/Twig/Node/Expression/Test.php @@ -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'); diff --git a/test/Twig/Tests/ExpressionParserTest.php b/test/Twig/Tests/ExpressionParserTest.php index b3f300fae6..88d6d59177 100644 --- a/test/Twig/Tests/ExpressionParserTest.php +++ b/test/Twig/Tests/ExpressionParserTest.php @@ -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')); + } } diff --git a/test/Twig/Tests/Node/Expression/FilterTest.php b/test/Twig/Tests/Node/Expression/FilterTest.php index d37dd220fa..48241d4be2 100644 --- a/test/Twig/Tests/Node/Expression/FilterTest.php +++ b/test/Twig/Tests/Node/Expression/FilterTest.php @@ -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(); @@ -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); diff --git a/test/Twig/Tests/Node/Expression/FunctionTest.php b/test/Twig/Tests/Node/Expression/FunctionTest.php index 13f4823264..b5ddf336e8 100644 --- a/test/Twig/Tests/Node/Expression/FunctionTest.php +++ b/test/Twig/Tests/Node/Expression/FunctionTest.php @@ -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(); diff --git a/test/Twig/Tests/Node/Expression/TestTest.php b/test/Twig/Tests/Node/Expression/TestTest.php index 4d0cf41c88..01a188b41f 100644 --- a/test/Twig/Tests/Node/Expression/TestTest.php +++ b/test/Twig/Tests/Node/Expression/TestTest.php @@ -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);