added support for method calls with arguments

git-svn-id: http://svn.twig-project.org/trunk@35 93ef8e89-cb99-4229-a87c-7fa0fa45744b
This commit is contained in:
fabien
2009-10-12 17:05:12 +00:00
parent 3468042663
commit 7fa1167b2d
6 changed files with 100 additions and 23 deletions
+28 -16
View File
@@ -313,12 +313,15 @@ class Twig_ExpressionParser
{
$token = $this->parser->getStream()->next();
$lineno = $token->getLine();
$arguments = array();
if ($token->getValue() == '.')
{
$token = $this->parser->getStream()->next();
if ($token->getType() == Twig_Token::NAME_TYPE || $token->getType() == Twig_Token::NUMBER_TYPE)
{
$arg = new Twig_Node_Expression_Constant($token->getValue(), $lineno);
$arguments = $this->parseArguments();
}
else
{
@@ -331,7 +334,7 @@ class Twig_ExpressionParser
$this->parser->getStream()->expect(Twig_Token::OPERATOR_TYPE, ']');
}
return new Twig_Node_Expression_GetAttr($node, $arg, $lineno, $token->getValue());
return new Twig_Node_Expression_GetAttr($node, $arg, $arguments, $lineno, $token->getValue());
}
public function parseFilterExpression($node)
@@ -342,26 +345,35 @@ class Twig_ExpressionParser
{
$this->parser->getStream()->next();
$token = $this->parser->getStream()->expect(Twig_Token::NAME_TYPE);
$args = array();
if ($this->parser->getStream()->test(Twig_Token::OPERATOR_TYPE, '('))
{
$this->parser->getStream()->next();
while (!$this->parser->getStream()->test(Twig_Token::OPERATOR_TYPE, ')'))
{
if (!empty($args))
{
$this->parser->getStream()->expect(Twig_Token::OPERATOR_TYPE, ',');
}
$args[] = $this->parseExpression();
}
$this->parser->getStream()->expect(Twig_Token::OPERATOR_TYPE, ')');
}
$filters[] = array($token->getValue(), $args);
$filters[] = array($token->getValue(), $this->parseArguments());
}
return new Twig_Node_Expression_Filter($node, $filters, $lineno);
}
public function parseArguments()
{
if (!$this->parser->getStream()->test(Twig_Token::OPERATOR_TYPE, '('))
{
return array();
}
$args = array();
$this->parser->getStream()->next();
while (!$this->parser->getStream()->test(Twig_Token::OPERATOR_TYPE, ')'))
{
if (!empty($args))
{
$this->parser->getStream()->expect(Twig_Token::OPERATOR_TYPE, ',');
}
$args[] = $this->parseExpression();
}
$this->parser->getStream()->expect(Twig_Token::OPERATOR_TYPE, ')');
return $args;
}
public function parseAssignmentExpression()
{
$lineno = $this->parser->getCurrentToken()->getLine();
+16 -3
View File
@@ -13,12 +13,14 @@ class Twig_Node_Expression_GetAttr extends Twig_Node_Expression implements Twig_
{
protected $node;
protected $attr;
protected $arguments;
public function __construct(Twig_Node $node, $attr, $lineno, $token_value)
public function __construct(Twig_Node $node, $attr, $arguments, $lineno, $token_value)
{
parent::__construct($lineno);
$this->node = $node;
$this->attr = $attr;
$this->arguments = $arguments;
$this->token_value = $token_value;
}
@@ -44,11 +46,22 @@ class Twig_Node_Expression_GetAttr extends Twig_Node_Expression implements Twig_
->subcompile($this->node)
->raw(', ')
->subcompile($this->attr)
->raw(', array(')
;
if ('[' == $this->token_value) # Don't look for functions if they're using foo[bar]
foreach ($this->arguments as $node)
{
$compiler->raw(', false');
$compiler
->subcompile($node)
->raw(', ')
;
}
$compiler->raw(')');
if ('[' == $this->token_value) // Don't look for functions if they're using foo[bar]
{
$compiler->raw(', true');
}
$compiler->raw(')');
+12 -3
View File
@@ -43,15 +43,24 @@ abstract class Twig_Template implements Twig_TemplateInterface
throw new Twig_RuntimeError(sprintf('The filter "%s" does not exist', $name));
}
protected function getAttribute($object, $item)
protected function getAttribute($object, $item, array $arguments = array(), $arrayOnly = false)
{
$item = (string) $item;
if (is_array($object) && isset($object[$item]))
if (
is_array($object) && isset($object[$item])
||
is_object($object) && $object instanceof ArrayAccess && isset($object[$item])
)
{
return $object[$item];
}
if ($arrayOnly)
{
return null;
}
if (
!is_object($object) ||
(
@@ -68,6 +77,6 @@ abstract class Twig_Template implements Twig_TemplateInterface
$this->env->getExtension('sandbox')->checkMethodAllowed($object, $method);
}
return $object->$method();
return call_user_func_array(array($object, $method), $arguments);
}
}
+14
View File
@@ -0,0 +1,14 @@
--TEST--
Twig supports method calls
--TEMPLATE--
{{ items.foo }}
{{ items['foo'] }}
{{ items[foo] }}
{{ items[items[foo]] }}
--DATA--
return array('foo' => 'bar', 'items' => array('foo' => 'bar', 'bar' => 'foo'))
--EXPECT--
bar
bar
foo
bar
+16
View File
@@ -0,0 +1,16 @@
--TEST--
Twig supports method calls
--TEMPLATE--
{{ items.foo.foo }}
{{ items.foo.bar }}
{{ items.foo['bar'] }}
{{ items.foo.bar('a', 43) }}
{{ items.foo.bar(foo) }}
--DATA--
return array('foo' => 'bar', 'items' => array('foo' => new Foo(), 'bar' => 'foo'))
--EXPECT--
foo
bar
bar_a-43
bar_bar
+14 -1
View File
@@ -17,7 +17,20 @@ Twig_Autoloader::register();
require_once dirname(__FILE__).'/../lib/Twig_Loader_Var.php';
$t = new LimeTest(42);
class Foo
{
public function bar($param1 = null, $param2 = null)
{
return 'bar'.($param1 ? '_'.$param1 : '').($param2 ? '-'.$param2 : '');
}
public function getFoo()
{
return 'foo';
}
}
$t = new LimeTest(44);
$fixturesDir = realpath(dirname(__FILE__).'/../fixtures/');
foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($fixturesDir), RecursiveIteratorIterator::LEAVES_ONLY) as $file)