Improved an exception message for missing value of optional arguments

This commit is contained in:
Martin Hasoň
2014-07-11 00:33:39 +02:00
parent b9e3e6c51a
commit 5f4377b863
2 changed files with 35 additions and 6 deletions
+21 -6
View File
@@ -90,6 +90,9 @@ abstract class Twig_Node_Expression_Call extends Twig_Node_Expression
protected function getArguments($callable, $arguments)
{
$callType = $this->getAttribute('type');
$callName = $this->getAttribute('name');
$parameters = array();
$named = false;
foreach ($arguments as $name => $node) {
@@ -97,7 +100,7 @@ abstract class Twig_Node_Expression_Call extends Twig_Node_Expression
$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')));
throw new Twig_Error_Syntax(sprintf('Positional arguments cannot be used after named arguments for %s "%s".', $callType, $callName));
}
$parameters[$name] = $node;
@@ -108,7 +111,7 @@ abstract class Twig_Node_Expression_Call extends Twig_Node_Expression
}
if (!$callable) {
throw new LogicException(sprintf('Named arguments are not supported for %s "%s".', $this->getAttribute('type'), $this->getAttribute('name')));
throw new LogicException(sprintf('Named arguments are not supported for %s "%s".', $callType, $callName));
}
// manage named arguments
@@ -139,13 +142,21 @@ abstract class Twig_Node_Expression_Call extends Twig_Node_Expression
$arguments = array();
$names = array();
$missingArguments = array();
$pos = 0;
foreach ($definition as $param) {
$names[] = $name = $this->normalizeName($param->name);
if (array_key_exists($name, $parameters)) {
if (array_key_exists($pos, $parameters)) {
throw new Twig_Error_Syntax(sprintf('Argument "%s" is defined twice for %s "%s".', $name, $this->getAttribute('type'), $this->getAttribute('name')));
throw new Twig_Error_Syntax(sprintf('Argument "%s" is defined twice for %s "%s".', $name, $callType, $callName));
}
if (!empty($missingArguments)) {
throw new Twig_Error_Syntax(sprintf(
'Argument "%s" could not be assigned for %s "%s(%s)" because it is mapped to an internal PHP function which cannot determine default value for optional argument%s "%s".',
$name, $callType, $callName, implode(', ', $names), count($missingArguments) > 1 ? 's' : '', implode('", "', $missingArguments))
);
}
$arguments[] = $parameters[$name];
@@ -157,16 +168,20 @@ abstract class Twig_Node_Expression_Call extends Twig_Node_Expression
} elseif ($param->isDefaultValueAvailable()) {
$arguments[] = new Twig_Node_Expression_Constant($param->getDefaultValue(), -1);
} elseif ($param->isOptional()) {
break;
if (empty($parameters)) {
break;
} else {
$missingArguments[] = $name;
}
} else {
throw new Twig_Error_Syntax(sprintf('Value for argument "%s" is required for %s "%s".', $name, $this->getAttribute('type'), $this->getAttribute('name')));
throw new Twig_Error_Syntax(sprintf('Value for argument "%s" is required for %s "%s".', $name, $callType, $callName));
}
}
if (!empty($parameters)) {
throw new Twig_Error_Syntax(sprintf(
'Unknown argument%s "%s" for %s "%s(%s)".',
count($parameters) > 1 ? 's' : '', implode('", "', array_keys($parameters)), $this->getAttribute('type'), $this->getAttribute('name'), implode(', ', $names)
count($parameters) > 1 ? 's' : '', implode('", "', array_keys($parameters)), $callType, $callName, implode(', ', $names)
));
}
@@ -56,6 +56,20 @@ class Twig_Tests_Node_Expression_CallTest extends PHPUnit_Framework_TestCase
$node = new Twig_Tests_Node_Expression_Call(array(), array('type' => 'function', 'name' => 'date'));
$node->getArguments('date', array('Y-m-d', 'timestamp' => null, 'unknown1' => '', 'unknown2' => ''));
}
/**
* @expectedException Twig_Error_Syntax
* @expectedExceptionMessage Argument "case_sensitivity" could not be assigned for function "substr_compare(main_str, str, offset, length, case_sensitivity)" because it is mapped to an internal PHP function which cannot determine default value for optional argument "length".
*/
public function testResolveArgumentsWithMissingValueForOptionalArgument()
{
if (defined('HHVM_VERSION')) {
$this->markTestSkipped('Skip under HHVM as the behavior is not the same as plain PHP (which is an edge case anyway)');
}
$node = new Twig_Tests_Node_Expression_Call(array(), array('type' => 'function', 'name' => 'substr_compare'));
$node->getArguments('substr_compare', array('abcd', 'bc', 'offset' => 1, 'case_sensitivity' => true));
}
}
class Twig_Tests_Node_Expression_Call extends Twig_Node_Expression_Call