From 135b618ff900bb453f1ae203fff6ea54ece49f7e Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Wed, 1 May 2013 08:13:09 +0200 Subject: [PATCH] enforced usage of named arguments after positional ones --- CHANGELOG | 4 +- composer.json | 2 +- doc/templates.rst | 6 +-- ext/twig/php_twig.h | 2 +- lib/Twig/Environment.php | 2 +- lib/Twig/Node/Expression/Call.php | 7 +++ .../Tests/Fixtures/filters/date_namedargs.test | 2 - test/Twig/Tests/Node/Expression/CallTest.php | 47 ++++++++++++++++++++ 8 files changed, 61 insertions(+), 11 deletions(-) create mode 100644 test/Twig/Tests/Node/Expression/CallTest.php diff --git a/CHANGELOG b/CHANGELOG index c1ac6d9..da7ac75 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,6 @@ -* 1.12.4 (2013-XX-XX) +* 1.13.0 (2013-XX-XX) - * n/a + * enforced usage of named arguments after positional ones * 1.12.3 (2013-04-08) diff --git a/composer.json b/composer.json index 5530d28..3c5d079 100644 --- a/composer.json +++ b/composer.json @@ -25,7 +25,7 @@ }, "extra": { "branch-alias": { - "dev-master": "1.12-dev" + "dev-master": "1.13-dev" } } } diff --git a/doc/templates.rst b/doc/templates.rst index a329c92..c2047d9 100644 --- a/doc/templates.rst +++ b/doc/templates.rst @@ -227,14 +227,12 @@ to change the default value: {# or skip the format value by using a named argument for the timezone #} {{ "now"|date(timezone="Europe/Paris") }} -You can also use both positional and named arguments in one call, which is not -recommended as it can be confusing: +You can also use both positional and named arguments in one call, in which +case positional arguments must always come before named arguments: .. code-block:: jinja - {# both work #} {{ "now"|date('d/m/Y H:i', timezone="Europe/Paris") }} - {{ "now"|date(timezone="Europe/Paris", 'd/m/Y H:i') }} .. tip:: diff --git a/ext/twig/php_twig.h b/ext/twig/php_twig.h index 1bae647..ce0caf5 100644 --- a/ext/twig/php_twig.h +++ b/ext/twig/php_twig.h @@ -15,7 +15,7 @@ #ifndef PHP_TWIG_H #define PHP_TWIG_H -#define PHP_TWIG_VERSION "1.12.4-DEV" +#define PHP_TWIG_VERSION "1.13.0-DEV" #include "php.h" diff --git a/lib/Twig/Environment.php b/lib/Twig/Environment.php index 32b026a..54df5be 100644 --- a/lib/Twig/Environment.php +++ b/lib/Twig/Environment.php @@ -16,7 +16,7 @@ */ class Twig_Environment { - const VERSION = '1.12.4-DEV'; + const VERSION = '1.13.0-DEV'; protected $charset; protected $loader; diff --git a/lib/Twig/Node/Expression/Call.php b/lib/Twig/Node/Expression/Call.php index a97b3b5..87b62de 100644 --- a/lib/Twig/Node/Expression/Call.php +++ b/lib/Twig/Node/Expression/Call.php @@ -98,7 +98,10 @@ abstract class Twig_Node_Expression_Call extends Twig_Node_Expression if (!is_int($name)) { $named = true; $name = $this->normalizeName($name); + } elseif ($named) { + throw new Twig_Error_Syntax(sprintf('Positional arguments cannot be used after named arguments for %s "%s".', $this->getAttribute('type'), $this->getAttribute('name'))); } + $parameters[$name] = $node; } @@ -142,6 +145,10 @@ abstract class Twig_Node_Expression_Call extends Twig_Node_Expression $name = $this->normalizeName($param->name); if (array_key_exists($name, $parameters)) { + if (array_key_exists($pos, $parameters)) { + throw new Twig_Error_Syntax(sprintf('Arguments "%s" is defined twice for %s "%s".', $name, $this->getAttribute('type'), $this->getAttribute('name'))); + } + $arguments[] = $parameters[$name]; unset($parameters[$name]); } elseif (array_key_exists($pos, $parameters)) { diff --git a/test/Twig/Tests/Fixtures/filters/date_namedargs.test b/test/Twig/Tests/Fixtures/filters/date_namedargs.test index 6ca2049..4ecde8a 100644 --- a/test/Twig/Tests/Fixtures/filters/date_namedargs.test +++ b/test/Twig/Tests/Fixtures/filters/date_namedargs.test @@ -3,7 +3,6 @@ --TEMPLATE-- {{ date|date(format='d/m/Y H:i:s P', timezone='America/Chicago') }} {{ date|date(timezone='America/Chicago', format='d/m/Y H:i:s P') }} -{{ date|date(timezone='America/Chicago', 'd/m/Y H:i:s P') }} {{ date|date('d/m/Y H:i:s P', timezone='America/Chicago') }} --DATA-- date_default_timezone_set('UTC'); @@ -12,4 +11,3 @@ return array('date' => mktime(13, 45, 0, 10, 4, 2010)) 04/10/2010 08:45:00 -05:00 04/10/2010 08:45:00 -05:00 04/10/2010 08:45:00 -05:00 -04/10/2010 08:45:00 -05:00 diff --git a/test/Twig/Tests/Node/Expression/CallTest.php b/test/Twig/Tests/Node/Expression/CallTest.php new file mode 100644 index 0000000..b465549 --- /dev/null +++ b/test/Twig/Tests/Node/Expression/CallTest.php @@ -0,0 +1,47 @@ + 'function', 'name' => 'date')); + $this->assertEquals(array('U'), $node->getArguments('date', array('format' => 'U'))); + } + + /** + * @expectedException Twig_Error_Syntax + * @expectedExceptionMessage Positional arguments cannot be used after named arguments for function "date". + */ + public function testGetArgumentsWhenPositionalArgumentsAfterNamedArguments() + { + $node = new Twig_Tests_Node_Expression_Call(array(), array('type' => 'function', 'name' => 'date')); + $node->getArguments('date', array('timestamp' => 123456, 'Y-m-d')); + } + + /** + * @expectedException Twig_Error_Syntax + * @expectedExceptionMessage Arguments "format" is defined twice for function "date". + */ + public function testGetArgumentsWhenArgumentIsDefinedTwice() + { + $node = new Twig_Tests_Node_Expression_Call(array(), array('type' => 'function', 'name' => 'date')); + $node->getArguments('date', array('Y-m-d', 'format' => 'U')); + } +} + +class Twig_Tests_Node_Expression_Call extends Twig_Node_Expression_Call +{ + public function getArguments($callable, $arguments) + { + return parent::getArguments($callable, $arguments); + } +} -- 1.7.2.5