Twig update to latest Twig 1.x legacy as per vichan

This commit is contained in:
Benjamin Southall 2019-02-26 10:11:12 +10:00
parent 4ecd84f81d
commit e6c07544da
198 changed files with 6150 additions and 2506 deletions

View file

@ -3,7 +3,7 @@
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@ -27,13 +27,10 @@ class Twig_Node_AutoEscape extends Twig_Node
parent::__construct(array('body' => $body), array('value' => $value), $lineno, $tag);
}
/**
* Compiles the node to PHP.
*
* @param Twig_Compiler A Twig_Compiler instance
*/
public function compile(Twig_Compiler $compiler)
{
$compiler->subcompile($this->getNode('body'));
}
}
class_alias('Twig_Node_AutoEscape', 'Twig\Node\AutoEscapeNode', false);

View file

@ -3,8 +3,8 @@
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
* (c) 2009 Armin Ronacher
* (c) Fabien Potencier
* (c) Armin Ronacher
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@ -22,11 +22,6 @@ class Twig_Node_Block extends Twig_Node
parent::__construct(array('body' => $body), array('name' => $name), $lineno, $tag);
}
/**
* Compiles the node to PHP.
*
* @param Twig_Compiler A Twig_Compiler instance
*/
public function compile(Twig_Compiler $compiler)
{
$compiler
@ -42,3 +37,5 @@ class Twig_Node_Block extends Twig_Node
;
}
}
class_alias('Twig_Node_Block', 'Twig\Node\BlockNode', false);

View file

@ -3,8 +3,8 @@
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
* (c) 2009 Armin Ronacher
* (c) Fabien Potencier
* (c) Armin Ronacher
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@ -22,11 +22,6 @@ class Twig_Node_BlockReference extends Twig_Node implements Twig_NodeOutputInter
parent::__construct(array(), array('name' => $name), $lineno, $tag);
}
/**
* Compiles the node to PHP.
*
* @param Twig_Compiler A Twig_Compiler instance
*/
public function compile(Twig_Compiler $compiler)
{
$compiler
@ -35,3 +30,5 @@ class Twig_Node_BlockReference extends Twig_Node implements Twig_NodeOutputInter
;
}
}
class_alias('Twig_Node_BlockReference', 'Twig\Node\BlockReferenceNode', false);

View file

@ -3,7 +3,7 @@
/*
* This file is part of Twig.
*
* (c) 2011 Fabien Potencier
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@ -17,3 +17,5 @@
class Twig_Node_Body extends Twig_Node
{
}
class_alias('Twig_Node_Body', 'Twig\Node\BodyNode', false);

View file

@ -0,0 +1,80 @@
<?php
/*
* This file is part of Twig.
*
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
* @author Fabien Potencier <fabien@symfony.com>
*/
class Twig_Node_CheckSecurity extends Twig_Node
{
protected $usedFilters;
protected $usedTags;
protected $usedFunctions;
public function __construct(array $usedFilters, array $usedTags, array $usedFunctions)
{
$this->usedFilters = $usedFilters;
$this->usedTags = $usedTags;
$this->usedFunctions = $usedFunctions;
parent::__construct();
}
public function compile(Twig_Compiler $compiler)
{
$tags = $filters = $functions = array();
foreach (array('tags', 'filters', 'functions') as $type) {
foreach ($this->{'used'.ucfirst($type)} as $name => $node) {
if ($node instanceof Twig_Node) {
${$type}[$name] = $node->getTemplateLine();
} else {
${$type}[$node] = null;
}
}
}
$compiler
->write('$tags = ')->repr(array_filter($tags))->raw(";\n")
->write('$filters = ')->repr(array_filter($filters))->raw(";\n")
->write('$functions = ')->repr(array_filter($functions))->raw(";\n\n")
->write("try {\n")
->indent()
->write("\$this->env->getExtension('Twig_Extension_Sandbox')->checkSecurity(\n")
->indent()
->write(!$tags ? "array(),\n" : "array('".implode("', '", array_keys($tags))."'),\n")
->write(!$filters ? "array(),\n" : "array('".implode("', '", array_keys($filters))."'),\n")
->write(!$functions ? "array()\n" : "array('".implode("', '", array_keys($functions))."')\n")
->outdent()
->write(");\n")
->outdent()
->write("} catch (Twig_Sandbox_SecurityError \$e) {\n")
->indent()
->write("\$e->setSourceContext(\$this->getSourceContext());\n\n")
->write("if (\$e instanceof Twig_Sandbox_SecurityNotAllowedTagError && isset(\$tags[\$e->getTagName()])) {\n")
->indent()
->write("\$e->setTemplateLine(\$tags[\$e->getTagName()]);\n")
->outdent()
->write("} elseif (\$e instanceof Twig_Sandbox_SecurityNotAllowedFilterError && isset(\$filters[\$e->getFilterName()])) {\n")
->indent()
->write("\$e->setTemplateLine(\$filters[\$e->getFilterName()]);\n")
->outdent()
->write("} elseif (\$e instanceof Twig_Sandbox_SecurityNotAllowedFunctionError && isset(\$functions[\$e->getFunctionName()])) {\n")
->indent()
->write("\$e->setTemplateLine(\$functions[\$e->getFunctionName()]);\n")
->outdent()
->write("}\n\n")
->write("throw \$e;\n")
->outdent()
->write("}\n\n")
;
}
}
class_alias('Twig_Node_CheckSecurity', 'Twig\Node\CheckSecurityNode', false);

View file

@ -3,7 +3,7 @@
/*
* This file is part of Twig.
*
* (c) 2011 Fabien Potencier
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@ -21,11 +21,6 @@ class Twig_Node_Do extends Twig_Node
parent::__construct(array('expr' => $expr), array(), $lineno, $tag);
}
/**
* Compiles the node to PHP.
*
* @param Twig_Compiler A Twig_Compiler instance
*/
public function compile(Twig_Compiler $compiler)
{
$compiler
@ -36,3 +31,5 @@ class Twig_Node_Do extends Twig_Node
;
}
}
class_alias('Twig_Node_Do', 'Twig\Node\DoNode', false);

View file

@ -3,7 +3,7 @@
/*
* This file is part of Twig.
*
* (c) 2012 Fabien Potencier
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@ -17,22 +17,30 @@
class Twig_Node_Embed extends Twig_Node_Include
{
// we don't inject the module to avoid node visitors to traverse it twice (as it will be already visited in the main module)
public function __construct($filename, $index, Twig_Node_Expression $variables = null, $only = false, $ignoreMissing = false, $lineno, $tag = null)
public function __construct($name, $index, Twig_Node_Expression $variables = null, $only = false, $ignoreMissing = false, $lineno, $tag = null)
{
parent::__construct(new Twig_Node_Expression_Constant('not_used', $lineno), $variables, $only, $ignoreMissing, $lineno, $tag);
$this->setAttribute('filename', $filename);
$this->setAttribute('name', $name);
// to be removed in 2.0, used name instead
$this->setAttribute('filename', $name);
$this->setAttribute('index', $index);
}
protected function addGetTemplate(Twig_Compiler $compiler)
{
$compiler
->write("\$this->env->loadTemplate(")
->string($this->getAttribute('filename'))
->write('$this->loadTemplate(')
->string($this->getAttribute('name'))
->raw(', ')
->repr($this->getTemplateName())
->raw(', ')
->repr($this->getTemplateLine())
->raw(', ')
->string($this->getAttribute('index'))
->raw(")")
->raw(')')
;
}
}
class_alias('Twig_Node_Embed', 'Twig\Node\EmbedNode', false);

View file

@ -3,8 +3,8 @@
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
* (c) 2009 Armin Ronacher
* (c) Fabien Potencier
* (c) Armin Ronacher
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@ -18,3 +18,5 @@
abstract class Twig_Node_Expression extends Twig_Node
{
}
class_alias('Twig_Node_Expression', 'Twig\Node\Expression\AbstractExpression', false);

View file

@ -3,7 +3,7 @@
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@ -43,7 +43,7 @@ class Twig_Node_Expression_Array extends Twig_Node_Expression
foreach ($this->getKeyValuePairs() as $pair) {
// we compare the string representation of the keys
// to avoid comparing the line numbers which are not relevant here.
if ((string) $key == (string) $pair['key']) {
if ((string) $key === (string) $pair['key']) {
return true;
}
}
@ -54,17 +54,12 @@ class Twig_Node_Expression_Array extends Twig_Node_Expression
public function addElement(Twig_Node_Expression $value, Twig_Node_Expression $key = null)
{
if (null === $key) {
$key = new Twig_Node_Expression_Constant(++$this->index, $value->getLine());
$key = new Twig_Node_Expression_Constant(++$this->index, $value->getTemplateLine());
}
array_push($this->nodes, $key, $value);
}
/**
* Compiles the node to PHP.
*
* @param Twig_Compiler A Twig_Compiler instance
*/
public function compile(Twig_Compiler $compiler)
{
$compiler->raw('array(');
@ -84,3 +79,5 @@ class Twig_Node_Expression_Array extends Twig_Node_Expression
$compiler->raw(')');
}
}
class_alias('Twig_Node_Expression_Array', 'Twig\Node\Expression\ArrayExpression', false);

View file

@ -3,8 +3,8 @@
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
* (c) 2009 Armin Ronacher
* (c) Fabien Potencier
* (c) Armin Ronacher
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@ -12,11 +12,6 @@
class Twig_Node_Expression_AssignName extends Twig_Node_Expression_Name
{
/**
* Compiles the node to PHP.
*
* @param Twig_Compiler A Twig_Compiler instance
*/
public function compile(Twig_Compiler $compiler)
{
$compiler
@ -26,3 +21,5 @@ class Twig_Node_Expression_AssignName extends Twig_Node_Expression_Name
;
}
}
class_alias('Twig_Node_Expression_AssignName', 'Twig\Node\Expression\AssignNameExpression', false);

View file

@ -3,8 +3,8 @@
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
* (c) 2009 Armin Ronacher
* (c) Fabien Potencier
* (c) Armin Ronacher
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@ -16,11 +16,6 @@ abstract class Twig_Node_Expression_Binary extends Twig_Node_Expression
parent::__construct(array('left' => $left, 'right' => $right), array(), $lineno);
}
/**
* Compiles the node to PHP.
*
* @param Twig_Compiler A Twig_Compiler instance
*/
public function compile(Twig_Compiler $compiler)
{
$compiler
@ -38,3 +33,5 @@ abstract class Twig_Node_Expression_Binary extends Twig_Node_Expression
abstract public function operator(Twig_Compiler $compiler);
}
class_alias('Twig_Node_Expression_Binary', 'Twig\Node\Expression\Binary\AbstractBinary', false);

View file

@ -3,8 +3,8 @@
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
* (c) 2009 Armin Ronacher
* (c) Fabien Potencier
* (c) Armin Ronacher
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@ -16,3 +16,5 @@ class Twig_Node_Expression_Binary_Add extends Twig_Node_Expression_Binary
return $compiler->raw('+');
}
}
class_alias('Twig_Node_Expression_Binary_Add', 'Twig\Node\Expression\Binary\AddBinary', false);

View file

@ -3,8 +3,8 @@
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
* (c) 2009 Armin Ronacher
* (c) Fabien Potencier
* (c) Armin Ronacher
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@ -16,3 +16,5 @@ class Twig_Node_Expression_Binary_And extends Twig_Node_Expression_Binary
return $compiler->raw('&&');
}
}
class_alias('Twig_Node_Expression_Binary_And', 'Twig\Node\Expression\Binary\AndBinary', false);

View file

@ -3,8 +3,8 @@
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
* (c) 2009 Armin Ronacher
* (c) Fabien Potencier
* (c) Armin Ronacher
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@ -16,3 +16,5 @@ class Twig_Node_Expression_Binary_BitwiseAnd extends Twig_Node_Expression_Binary
return $compiler->raw('&');
}
}
class_alias('Twig_Node_Expression_Binary_BitwiseAnd', 'Twig\Node\Expression\Binary\BitwiseAndBinary', false);

View file

@ -3,8 +3,8 @@
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
* (c) 2009 Armin Ronacher
* (c) Fabien Potencier
* (c) Armin Ronacher
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@ -16,3 +16,5 @@ class Twig_Node_Expression_Binary_BitwiseOr extends Twig_Node_Expression_Binary
return $compiler->raw('|');
}
}
class_alias('Twig_Node_Expression_Binary_BitwiseOr', 'Twig\Node\Expression\Binary\BitwiseOrBinary', false);

View file

@ -3,8 +3,8 @@
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
* (c) 2009 Armin Ronacher
* (c) Fabien Potencier
* (c) Armin Ronacher
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@ -16,3 +16,5 @@ class Twig_Node_Expression_Binary_BitwiseXor extends Twig_Node_Expression_Binary
return $compiler->raw('^');
}
}
class_alias('Twig_Node_Expression_Binary_BitwiseXor', 'Twig\Node\Expression\Binary\BitwiseXorBinary', false);

View file

@ -3,8 +3,8 @@
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
* (c) 2009 Armin Ronacher
* (c) Fabien Potencier
* (c) Armin Ronacher
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@ -16,3 +16,5 @@ class Twig_Node_Expression_Binary_Concat extends Twig_Node_Expression_Binary
return $compiler->raw('.');
}
}
class_alias('Twig_Node_Expression_Binary_Concat', 'Twig\Node\Expression\Binary\ConcatBinary', false);

View file

@ -3,8 +3,8 @@
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
* (c) 2009 Armin Ronacher
* (c) Fabien Potencier
* (c) Armin Ronacher
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@ -16,3 +16,5 @@ class Twig_Node_Expression_Binary_Div extends Twig_Node_Expression_Binary
return $compiler->raw('/');
}
}
class_alias('Twig_Node_Expression_Binary_Div', 'Twig\Node\Expression\Binary\DivBinary', false);

View file

@ -0,0 +1,32 @@
<?php
/*
* This file is part of Twig.
*
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
class Twig_Node_Expression_Binary_EndsWith extends Twig_Node_Expression_Binary
{
public function compile(Twig_Compiler $compiler)
{
$left = $compiler->getVarName();
$right = $compiler->getVarName();
$compiler
->raw(sprintf('(is_string($%s = ', $left))
->subcompile($this->getNode('left'))
->raw(sprintf(') && is_string($%s = ', $right))
->subcompile($this->getNode('right'))
->raw(sprintf(') && (\'\' === $%2$s || $%2$s === substr($%1$s, -strlen($%2$s))))', $left, $right))
;
}
public function operator(Twig_Compiler $compiler)
{
return $compiler->raw('');
}
}
class_alias('Twig_Node_Expression_Binary_EndsWith', 'Twig\Node\Expression\Binary\EndsWithBinary', false);

View file

@ -3,7 +3,7 @@
/*
* This file is part of Twig.
*
* (c) 2010 Fabien Potencier
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@ -15,3 +15,5 @@ class Twig_Node_Expression_Binary_Equal extends Twig_Node_Expression_Binary
return $compiler->raw('==');
}
}
class_alias('Twig_Node_Expression_Binary_Equal', 'Twig\Node\Expression\Binary\EqualBinary', false);

View file

@ -3,23 +3,18 @@
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
class Twig_Node_Expression_Binary_FloorDiv extends Twig_Node_Expression_Binary
{
/**
* Compiles the node to PHP.
*
* @param Twig_Compiler A Twig_Compiler instance
*/
public function compile(Twig_Compiler $compiler)
{
$compiler->raw('intval(floor(');
$compiler->raw('(int) floor(');
parent::compile($compiler);
$compiler->raw('))');
$compiler->raw(')');
}
public function operator(Twig_Compiler $compiler)
@ -27,3 +22,5 @@ class Twig_Node_Expression_Binary_FloorDiv extends Twig_Node_Expression_Binary
return $compiler->raw('/');
}
}
class_alias('Twig_Node_Expression_Binary_FloorDiv', 'Twig\Node\Expression\Binary\FloorDivBinary', false);

View file

@ -3,7 +3,7 @@
/*
* This file is part of Twig.
*
* (c) 2010 Fabien Potencier
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@ -15,3 +15,5 @@ class Twig_Node_Expression_Binary_Greater extends Twig_Node_Expression_Binary
return $compiler->raw('>');
}
}
class_alias('Twig_Node_Expression_Binary_Greater', 'Twig\Node\Expression\Binary\GreaterBinary', false);

View file

@ -3,7 +3,7 @@
/*
* This file is part of Twig.
*
* (c) 2010 Fabien Potencier
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@ -15,3 +15,5 @@ class Twig_Node_Expression_Binary_GreaterEqual extends Twig_Node_Expression_Bina
return $compiler->raw('>=');
}
}
class_alias('Twig_Node_Expression_Binary_GreaterEqual', 'Twig\Node\Expression\Binary\GreaterEqualBinary', false);

View file

@ -3,18 +3,13 @@
/*
* This file is part of Twig.
*
* (c) 2010 Fabien Potencier
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
class Twig_Node_Expression_Binary_In extends Twig_Node_Expression_Binary
{
/**
* Compiles the node to PHP.
*
* @param Twig_Compiler A Twig_Compiler instance
*/
public function compile(Twig_Compiler $compiler)
{
$compiler
@ -31,3 +26,5 @@ class Twig_Node_Expression_Binary_In extends Twig_Node_Expression_Binary
return $compiler->raw('in');
}
}
class_alias('Twig_Node_Expression_Binary_In', 'Twig\Node\Expression\Binary\InBinary', false);

View file

@ -3,7 +3,7 @@
/*
* This file is part of Twig.
*
* (c) 2010 Fabien Potencier
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@ -15,3 +15,5 @@ class Twig_Node_Expression_Binary_Less extends Twig_Node_Expression_Binary
return $compiler->raw('<');
}
}
class_alias('Twig_Node_Expression_Binary_Less', 'Twig\Node\Expression\Binary\LessBinary', false);

View file

@ -3,7 +3,7 @@
/*
* This file is part of Twig.
*
* (c) 2010 Fabien Potencier
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@ -15,3 +15,5 @@ class Twig_Node_Expression_Binary_LessEqual extends Twig_Node_Expression_Binary
return $compiler->raw('<=');
}
}
class_alias('Twig_Node_Expression_Binary_LessEqual', 'Twig\Node\Expression\Binary\LessEqualBinary', false);

View file

@ -0,0 +1,30 @@
<?php
/*
* This file is part of Twig.
*
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
class Twig_Node_Expression_Binary_Matches extends Twig_Node_Expression_Binary
{
public function compile(Twig_Compiler $compiler)
{
$compiler
->raw('preg_match(')
->subcompile($this->getNode('right'))
->raw(', ')
->subcompile($this->getNode('left'))
->raw(')')
;
}
public function operator(Twig_Compiler $compiler)
{
return $compiler->raw('');
}
}
class_alias('Twig_Node_Expression_Binary_Matches', 'Twig\Node\Expression\Binary\MatchesBinary', false);

View file

@ -3,8 +3,8 @@
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
* (c) 2009 Armin Ronacher
* (c) Fabien Potencier
* (c) Armin Ronacher
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@ -16,3 +16,5 @@ class Twig_Node_Expression_Binary_Mod extends Twig_Node_Expression_Binary
return $compiler->raw('%');
}
}
class_alias('Twig_Node_Expression_Binary_Mod', 'Twig\Node\Expression\Binary\ModBinary', false);

View file

@ -3,8 +3,8 @@
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
* (c) 2009 Armin Ronacher
* (c) Fabien Potencier
* (c) Armin Ronacher
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@ -16,3 +16,5 @@ class Twig_Node_Expression_Binary_Mul extends Twig_Node_Expression_Binary
return $compiler->raw('*');
}
}
class_alias('Twig_Node_Expression_Binary_Mul', 'Twig\Node\Expression\Binary\MulBinary', false);

View file

@ -3,7 +3,7 @@
/*
* This file is part of Twig.
*
* (c) 2010 Fabien Potencier
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@ -15,3 +15,5 @@ class Twig_Node_Expression_Binary_NotEqual extends Twig_Node_Expression_Binary
return $compiler->raw('!=');
}
}
class_alias('Twig_Node_Expression_Binary_NotEqual', 'Twig\Node\Expression\Binary\NotEqualBinary', false);

View file

@ -3,18 +3,13 @@
/*
* This file is part of Twig.
*
* (c) 2010 Fabien Potencier
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
class Twig_Node_Expression_Binary_NotIn extends Twig_Node_Expression_Binary
{
/**
* Compiles the node to PHP.
*
* @param Twig_Compiler A Twig_Compiler instance
*/
public function compile(Twig_Compiler $compiler)
{
$compiler
@ -31,3 +26,5 @@ class Twig_Node_Expression_Binary_NotIn extends Twig_Node_Expression_Binary
return $compiler->raw('not in');
}
}
class_alias('Twig_Node_Expression_Binary_NotIn', 'Twig\Node\Expression\Binary\NotInBinary', false);

View file

@ -3,8 +3,8 @@
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
* (c) 2009 Armin Ronacher
* (c) Fabien Potencier
* (c) Armin Ronacher
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@ -16,3 +16,5 @@ class Twig_Node_Expression_Binary_Or extends Twig_Node_Expression_Binary
return $compiler->raw('||');
}
}
class_alias('Twig_Node_Expression_Binary_Or', 'Twig\Node\Expression\Binary\OrBinary', false);

View file

@ -3,20 +3,19 @@
/*
* This file is part of Twig.
*
* (c) 2010 Fabien Potencier
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
class Twig_Node_Expression_Binary_Power extends Twig_Node_Expression_Binary
{
/**
* Compiles the node to PHP.
*
* @param Twig_Compiler A Twig_Compiler instance
*/
public function compile(Twig_Compiler $compiler)
{
if (PHP_VERSION_ID >= 50600) {
return parent::compile($compiler);
}
$compiler
->raw('pow(')
->subcompile($this->getNode('left'))
@ -31,3 +30,5 @@ class Twig_Node_Expression_Binary_Power extends Twig_Node_Expression_Binary
return $compiler->raw('**');
}
}
class_alias('Twig_Node_Expression_Binary_Power', 'Twig\Node\Expression\Binary\PowerBinary', false);

View file

@ -3,18 +3,13 @@
/*
* This file is part of Twig.
*
* (c) 2010 Fabien Potencier
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
class Twig_Node_Expression_Binary_Range extends Twig_Node_Expression_Binary
{
/**
* Compiles the node to PHP.
*
* @param Twig_Compiler A Twig_Compiler instance
*/
public function compile(Twig_Compiler $compiler)
{
$compiler
@ -31,3 +26,5 @@ class Twig_Node_Expression_Binary_Range extends Twig_Node_Expression_Binary
return $compiler->raw('..');
}
}
class_alias('Twig_Node_Expression_Binary_Range', 'Twig\Node\Expression\Binary\RangeBinary', false);

View file

@ -0,0 +1,32 @@
<?php
/*
* This file is part of Twig.
*
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
class Twig_Node_Expression_Binary_StartsWith extends Twig_Node_Expression_Binary
{
public function compile(Twig_Compiler $compiler)
{
$left = $compiler->getVarName();
$right = $compiler->getVarName();
$compiler
->raw(sprintf('(is_string($%s = ', $left))
->subcompile($this->getNode('left'))
->raw(sprintf(') && is_string($%s = ', $right))
->subcompile($this->getNode('right'))
->raw(sprintf(') && (\'\' === $%2$s || 0 === strpos($%1$s, $%2$s)))', $left, $right))
;
}
public function operator(Twig_Compiler $compiler)
{
return $compiler->raw('');
}
}
class_alias('Twig_Node_Expression_Binary_StartsWith', 'Twig\Node\Expression\Binary\StartsWithBinary', false);

View file

@ -3,8 +3,8 @@
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
* (c) 2009 Armin Ronacher
* (c) Fabien Potencier
* (c) Armin Ronacher
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@ -16,3 +16,5 @@ class Twig_Node_Expression_Binary_Sub extends Twig_Node_Expression_Binary
return $compiler->raw('-');
}
}
class_alias('Twig_Node_Expression_Binary_Sub', 'Twig\Node\Expression\Binary\SubBinary', false);

View file

@ -3,8 +3,8 @@
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
* (c) 2009 Armin Ronacher
* (c) Fabien Potencier
* (c) Armin Ronacher
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@ -17,35 +17,77 @@
*/
class Twig_Node_Expression_BlockReference extends Twig_Node_Expression
{
public function __construct(Twig_NodeInterface $name, $asString = false, $lineno, $tag = null)
/**
* @param Twig_Node|null $template
*/
public function __construct(Twig_NodeInterface $name, $template = null, $lineno, $tag = null)
{
parent::__construct(array('name' => $name), array('as_string' => $asString, 'output' => false), $lineno, $tag);
if (is_bool($template)) {
@trigger_error(sprintf('The %s method "$asString" argument is deprecated since version 1.28 and will be removed in 2.0.', __METHOD__), E_USER_DEPRECATED);
$template = null;
}
$nodes = array('name' => $name);
if (null !== $template) {
$nodes['template'] = $template;
}
parent::__construct($nodes, array('is_defined_test' => false, 'output' => false), $lineno, $tag);
}
/**
* Compiles the node to PHP.
*
* @param Twig_Compiler A Twig_Compiler instance
*/
public function compile(Twig_Compiler $compiler)
{
if ($this->getAttribute('as_string')) {
$compiler->raw('(string) ');
}
if ($this->getAttribute('output')) {
$compiler
->addDebugInfo($this)
->write("\$this->displayBlock(")
->subcompile($this->getNode('name'))
->raw(", \$context, \$blocks);\n")
;
if ($this->getAttribute('is_defined_test')) {
$this->compileTemplateCall($compiler, 'hasBlock');
} else {
$compiler
->raw("\$this->renderBlock(")
->subcompile($this->getNode('name'))
->raw(", \$context, \$blocks)")
;
if ($this->getAttribute('output')) {
$compiler->addDebugInfo($this);
$this
->compileTemplateCall($compiler, 'displayBlock')
->raw(";\n");
} else {
$this->compileTemplateCall($compiler, 'renderBlock');
}
}
}
private function compileTemplateCall(Twig_Compiler $compiler, $method)
{
if (!$this->hasNode('template')) {
$compiler->write('$this');
} else {
$compiler
->write('$this->loadTemplate(')
->subcompile($this->getNode('template'))
->raw(', ')
->repr($this->getTemplateName())
->raw(', ')
->repr($this->getTemplateLine())
->raw(')')
;
}
$compiler->raw(sprintf('->%s', $method));
$this->compileBlockArguments($compiler);
return $compiler;
}
private function compileBlockArguments(Twig_Compiler $compiler)
{
$compiler
->raw('(')
->subcompile($this->getNode('name'))
->raw(', $context');
if (!$this->hasNode('template')) {
$compiler->raw(', $blocks');
}
return $compiler->raw(')');
}
}
class_alias('Twig_Node_Expression_BlockReference', 'Twig\Node\Expression\BlockReferenceExpression', false);

View file

@ -3,27 +3,36 @@
/*
* This file is part of Twig.
*
* (c) 2012 Fabien Potencier
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
abstract class Twig_Node_Expression_Call extends Twig_Node_Expression
{
private $reflector;
protected function compileCallable(Twig_Compiler $compiler)
{
$callable = $this->getAttribute('callable');
$closingParenthesis = false;
if ($callable) {
if (is_string($callable)) {
if ($this->hasAttribute('callable') && $callable = $this->getAttribute('callable')) {
if (is_string($callable) && false === strpos($callable, '::')) {
$compiler->raw($callable);
} elseif (is_array($callable) && $callable[0] instanceof Twig_ExtensionInterface) {
$compiler->raw(sprintf('$this->env->getExtension(\'%s\')->%s', $callable[0]->getName(), $callable[1]));
} else {
$type = ucfirst($this->getAttribute('type'));
$compiler->raw(sprintf('call_user_func_array($this->env->get%s(\'%s\')->getCallable(), array', $type, $this->getAttribute('name')));
$closingParenthesis = true;
list($r, $callable) = $this->reflectCallable($callable);
if ($r instanceof ReflectionMethod && is_string($callable[0])) {
if ($r->isStatic()) {
$compiler->raw(sprintf('%s::%s', $callable[0], $callable[1]));
} else {
$compiler->raw(sprintf('$this->env->getRuntime(\'%s\')->%s', $callable[0], $callable[1]));
}
} elseif ($r instanceof ReflectionMethod && $callable[0] instanceof Twig_ExtensionInterface) {
$compiler->raw(sprintf('$this->env->getExtension(\'%s\')->%s', get_class($callable[0]), $callable[1]));
} else {
$type = ucfirst($this->getAttribute('type'));
$compiler->raw(sprintf('call_user_func_array($this->env->get%s(\'%s\')->getCallable(), array', $type, $this->getAttribute('name')));
$closingParenthesis = true;
}
}
} else {
$compiler->raw($this->getAttribute('thing')->compile());
@ -73,7 +82,7 @@ abstract class Twig_Node_Expression_Call extends Twig_Node_Expression
$first = false;
}
if ($this->hasNode('arguments') && null !== $this->getNode('arguments')) {
if ($this->hasNode('arguments')) {
$callable = $this->hasAttribute('callable') ? $this->getAttribute('callable') : null;
$arguments = $this->getArguments($callable, $this->getNode('arguments'));
@ -92,6 +101,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) {
@ -99,73 +111,101 @@ 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;
}
if (!$named) {
$isVariadic = $this->hasAttribute('is_variadic') && $this->getAttribute('is_variadic');
if (!$named && !$isVariadic) {
return $parameters;
}
if (!$callable) {
throw new LogicException(sprintf('Named arguments are not supported for %s "%s".', $this->getAttribute('type'), $this->getAttribute('name')));
}
// manage named arguments
if (is_array($callable)) {
$r = new ReflectionMethod($callable[0], $callable[1]);
} elseif (is_object($callable) && !$callable instanceof Closure) {
$r = new ReflectionObject($callable);
$r = $r->getMethod('__invoke');
} else {
$r = new ReflectionFunction($callable);
}
$definition = $r->getParameters();
if ($this->hasNode('node')) {
array_shift($definition);
}
if ($this->hasAttribute('needs_environment') && $this->getAttribute('needs_environment')) {
array_shift($definition);
}
if ($this->hasAttribute('needs_context') && $this->getAttribute('needs_context')) {
array_shift($definition);
}
if ($this->hasAttribute('arguments') && null !== $this->getAttribute('arguments')) {
foreach ($this->getAttribute('arguments') as $argument) {
array_shift($definition);
if ($named) {
$message = sprintf('Named arguments are not supported for %s "%s".', $callType, $callName);
} else {
$message = sprintf('Arbitrary positional arguments are not supported for %s "%s".', $callType, $callName);
}
throw new LogicException($message);
}
$callableParameters = $this->getCallableParameters($callable, $isVariadic);
$arguments = array();
$names = array();
$missingArguments = array();
$optionalArguments = array();
$pos = 0;
foreach ($definition as $param) {
$name = $this->normalizeName($param->name);
foreach ($callableParameters as $callableParameter) {
$names[] = $name = $this->normalizeName($callableParameter->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 (count($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 = array_merge($arguments, $optionalArguments);
$arguments[] = $parameters[$name];
unset($parameters[$name]);
$optionalArguments = array();
} elseif (array_key_exists($pos, $parameters)) {
$arguments = array_merge($arguments, $optionalArguments);
$arguments[] = $parameters[$pos];
unset($parameters[$pos]);
$optionalArguments = array();
++$pos;
} elseif ($param->isDefaultValueAvailable()) {
$arguments[] = new Twig_Node_Expression_Constant($param->getDefaultValue(), -1);
} elseif ($param->isOptional()) {
break;
} elseif ($callableParameter->isDefaultValueAvailable()) {
$optionalArguments[] = new Twig_Node_Expression_Constant($callableParameter->getDefaultValue(), -1);
} elseif ($callableParameter->isOptional()) {
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 ($isVariadic) {
$arbitraryArguments = new Twig_Node_Expression_Array(array(), -1);
foreach ($parameters as $key => $value) {
if (is_int($key)) {
$arbitraryArguments->addElement($value);
} else {
$arbitraryArguments->addElement($value, new Twig_Node_Expression_Constant($key, -1));
}
unset($parameters[$key]);
}
if ($arbitraryArguments->count()) {
$arguments = array_merge($arguments, $optionalArguments);
$arguments[] = $arbitraryArguments;
}
}
if (!empty($parameters)) {
throw new Twig_Error_Syntax(sprintf('Unknown argument%s "%s" for %s "%s".', count($parameters) > 1 ? 's' : '' , implode('", "', array_keys($parameters)), $this->getAttribute('type'), $this->getAttribute('name')));
$unknownParameter = null;
foreach ($parameters as $parameter) {
if ($parameter instanceof Twig_Node) {
$unknownParameter = $parameter;
break;
}
}
throw new Twig_Error_Syntax(sprintf(
'Unknown argument%s "%s" for %s "%s(%s)".',
count($parameters) > 1 ? 's' : '', implode('", "', array_keys($parameters)), $callType, $callName, implode(', ', $names)
), $unknownParameter ? $unknownParameter->getTemplateLine() : -1);
}
return $arguments;
@ -175,4 +215,77 @@ abstract class Twig_Node_Expression_Call extends Twig_Node_Expression
{
return strtolower(preg_replace(array('/([A-Z]+)([A-Z][a-z])/', '/([a-z\d])([A-Z])/'), array('\\1_\\2', '\\1_\\2'), $name));
}
private function getCallableParameters($callable, $isVariadic)
{
list($r) = $this->reflectCallable($callable);
if (null === $r) {
return array();
}
$parameters = $r->getParameters();
if ($this->hasNode('node')) {
array_shift($parameters);
}
if ($this->hasAttribute('needs_environment') && $this->getAttribute('needs_environment')) {
array_shift($parameters);
}
if ($this->hasAttribute('needs_context') && $this->getAttribute('needs_context')) {
array_shift($parameters);
}
if ($this->hasAttribute('arguments') && null !== $this->getAttribute('arguments')) {
foreach ($this->getAttribute('arguments') as $argument) {
array_shift($parameters);
}
}
if ($isVariadic) {
$argument = end($parameters);
if ($argument && $argument->isArray() && $argument->isDefaultValueAvailable() && array() === $argument->getDefaultValue()) {
array_pop($parameters);
} else {
$callableName = $r->name;
if ($r instanceof ReflectionMethod) {
$callableName = $r->getDeclaringClass()->name.'::'.$callableName;
}
throw new LogicException(sprintf('The last parameter of "%s" for %s "%s" must be an array with default value, eg. "array $arg = array()".', $callableName, $this->getAttribute('type'), $this->getAttribute('name')));
}
}
return $parameters;
}
private function reflectCallable($callable)
{
if (null !== $this->reflector) {
return $this->reflector;
}
if (is_array($callable)) {
if (!method_exists($callable[0], $callable[1])) {
// __call()
return array(null, array());
}
$r = new ReflectionMethod($callable[0], $callable[1]);
} elseif (is_object($callable) && !$callable instanceof Closure) {
$r = new ReflectionObject($callable);
$r = $r->getMethod('__invoke');
$callable = array($callable, '__invoke');
} elseif (is_string($callable) && false !== $pos = strpos($callable, '::')) {
$class = substr($callable, 0, $pos);
$method = substr($callable, $pos + 2);
if (!method_exists($class, $method)) {
// __staticCall()
return array(null, array());
}
$r = new ReflectionMethod($callable);
$callable = array($class, $method);
} else {
$r = new ReflectionFunction($callable);
}
return $this->reflector = array($r, $callable);
}
}
class_alias('Twig_Node_Expression_Call', 'Twig\Node\Expression\CallExpression', false);

View file

@ -3,8 +3,8 @@
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
* (c) 2009 Armin Ronacher
* (c) Fabien Potencier
* (c) Armin Ronacher
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@ -29,3 +29,5 @@ class Twig_Node_Expression_Conditional extends Twig_Node_Expression
;
}
}
class_alias('Twig_Node_Expression_Conditional', 'Twig\Node\Expression\ConditionalExpression', false);

View file

@ -3,8 +3,8 @@
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
* (c) 2009 Armin Ronacher
* (c) Fabien Potencier
* (c) Armin Ronacher
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@ -21,3 +21,5 @@ class Twig_Node_Expression_Constant extends Twig_Node_Expression
$compiler->repr($this->getAttribute('value'));
}
}
class_alias('Twig_Node_Expression_Constant', 'Twig\Node\Expression\ConstantExpression', false);

View file

@ -3,16 +3,20 @@
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
@trigger_error('The Twig_Node_Expression_ExtensionReference class is deprecated since version 1.23 and will be removed in 2.0.', E_USER_DEPRECATED);
/**
* Represents an extension call node.
*
* @author Fabien Potencier <fabien@symfony.com>
*
* @deprecated since 1.23 and will be removed in 2.0.
*/
class Twig_Node_Expression_ExtensionReference extends Twig_Node_Expression
{
@ -21,11 +25,6 @@ class Twig_Node_Expression_ExtensionReference extends Twig_Node_Expression
parent::__construct(array(), array('name' => $name), $lineno, $tag);
}
/**
* Compiles the node to PHP.
*
* @param Twig_Compiler A Twig_Compiler instance
*/
public function compile(Twig_Compiler $compiler)
{
$compiler->raw(sprintf("\$this->env->getExtension('%s')", $this->getAttribute('name')));

View file

@ -3,8 +3,8 @@
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
* (c) 2009 Armin Ronacher
* (c) Fabien Potencier
* (c) Armin Ronacher
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@ -30,7 +30,12 @@ class Twig_Node_Expression_Filter extends Twig_Node_Expression_Call
if ($filter instanceof Twig_FilterCallableInterface || $filter instanceof Twig_SimpleFilter) {
$this->setAttribute('callable', $filter->getCallable());
}
if ($filter instanceof Twig_SimpleFilter) {
$this->setAttribute('is_variadic', $filter->isVariadic());
}
$this->compileCallable($compiler);
}
}
class_alias('Twig_Node_Expression_Filter', 'Twig\Node\Expression\FilterExpression', false);

View file

@ -3,7 +3,7 @@
/*
* This file is part of Twig.
*
* (c) 2011 Fabien Potencier
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@ -22,13 +22,13 @@ class Twig_Node_Expression_Filter_Default extends Twig_Node_Expression_Filter
{
public function __construct(Twig_NodeInterface $node, Twig_Node_Expression_Constant $filterName, Twig_NodeInterface $arguments, $lineno, $tag = null)
{
$default = new Twig_Node_Expression_Filter($node, new Twig_Node_Expression_Constant('default', $node->getLine()), $arguments, $node->getLine());
$default = new Twig_Node_Expression_Filter($node, new Twig_Node_Expression_Constant('default', $node->getTemplateLine()), $arguments, $node->getTemplateLine());
if ('default' === $filterName->getAttribute('value') && ($node instanceof Twig_Node_Expression_Name || $node instanceof Twig_Node_Expression_GetAttr)) {
$test = new Twig_Node_Expression_Test_Defined(clone $node, 'defined', new Twig_Node(), $node->getLine());
$false = count($arguments) ? $arguments->getNode(0) : new Twig_Node_Expression_Constant('', $node->getLine());
$test = new Twig_Node_Expression_Test_Defined(clone $node, 'defined', new Twig_Node(), $node->getTemplateLine());
$false = count($arguments) ? $arguments->getNode(0) : new Twig_Node_Expression_Constant('', $node->getTemplateLine());
$node = new Twig_Node_Expression_Conditional($test, $default, $false, $node->getLine());
$node = new Twig_Node_Expression_Conditional($test, $default, $false, $node->getTemplateLine());
} else {
$node = $default;
}
@ -41,3 +41,5 @@ class Twig_Node_Expression_Filter_Default extends Twig_Node_Expression_Filter
$compiler->subcompile($this->getNode('node'));
}
}
class_alias('Twig_Node_Expression_Filter_Default', 'Twig\Node\Expression\Filter\DefaultFilter', false);

View file

@ -3,7 +3,7 @@
/*
* This file is part of Twig.
*
* (c) 2010 Fabien Potencier
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@ -12,7 +12,7 @@ class Twig_Node_Expression_Function extends Twig_Node_Expression_Call
{
public function __construct($name, Twig_NodeInterface $arguments, $lineno)
{
parent::__construct(array('arguments' => $arguments), array('name' => $name), $lineno);
parent::__construct(array('arguments' => $arguments), array('name' => $name, 'is_defined_test' => false), $lineno);
}
public function compile(Twig_Compiler $compiler)
@ -27,9 +27,19 @@ class Twig_Node_Expression_Function extends Twig_Node_Expression_Call
$this->setAttribute('needs_context', $function->needsContext());
$this->setAttribute('arguments', $function->getArguments());
if ($function instanceof Twig_FunctionCallableInterface || $function instanceof Twig_SimpleFunction) {
$this->setAttribute('callable', $function->getCallable());
$callable = $function->getCallable();
if ('constant' === $name && $this->getAttribute('is_defined_test')) {
$callable = 'twig_constant_is_defined';
}
$this->setAttribute('callable', $callable);
}
if ($function instanceof Twig_SimpleFunction) {
$this->setAttribute('is_variadic', $function->isVariadic());
}
$this->compileCallable($compiler);
}
}
class_alias('Twig_Node_Expression_Function', 'Twig\Node\Expression\FunctionExpression', false);

View file

@ -3,21 +3,30 @@
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
* (c) 2009 Armin Ronacher
* (c) Fabien Potencier
* (c) Armin Ronacher
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
class Twig_Node_Expression_GetAttr extends Twig_Node_Expression
{
public function __construct(Twig_Node_Expression $node, Twig_Node_Expression $attribute, Twig_Node_Expression_Array $arguments, $type, $lineno)
public function __construct(Twig_Node_Expression $node, Twig_Node_Expression $attribute, Twig_Node_Expression $arguments = null, $type, $lineno)
{
parent::__construct(array('node' => $node, 'attribute' => $attribute, 'arguments' => $arguments), array('type' => $type, 'is_defined_test' => false, 'ignore_strict_check' => false, 'disable_c_ext' => false), $lineno);
$nodes = array('node' => $node, 'attribute' => $attribute);
if (null !== $arguments) {
$nodes['arguments'] = $arguments;
}
parent::__construct($nodes, array('type' => $type, 'is_defined_test' => false, 'ignore_strict_check' => false, 'disable_c_ext' => false), $lineno);
}
public function compile(Twig_Compiler $compiler)
{
if ($this->getAttribute('disable_c_ext')) {
@trigger_error(sprintf('Using the "disable_c_ext" attribute on %s is deprecated since version 1.30 and will be removed in 2.0.', __CLASS__), E_USER_DEPRECATED);
}
if (function_exists('twig_template_get_attributes') && !$this->getAttribute('disable_c_ext')) {
$compiler->raw('twig_template_get_attributes($this, ');
} else {
@ -32,22 +41,34 @@ class Twig_Node_Expression_GetAttr extends Twig_Node_Expression
$compiler->raw(', ')->subcompile($this->getNode('attribute'));
if (count($this->getNode('arguments')) || Twig_Template::ANY_CALL !== $this->getAttribute('type') || $this->getAttribute('is_defined_test') || $this->getAttribute('ignore_strict_check')) {
$compiler->raw(', ')->subcompile($this->getNode('arguments'));
// only generate optional arguments when needed (to make generated code more readable)
$needFourth = $this->getAttribute('ignore_strict_check');
$needThird = $needFourth || $this->getAttribute('is_defined_test');
$needSecond = $needThird || Twig_Template::ANY_CALL !== $this->getAttribute('type');
$needFirst = $needSecond || $this->hasNode('arguments');
if (Twig_Template::ANY_CALL !== $this->getAttribute('type') || $this->getAttribute('is_defined_test') || $this->getAttribute('ignore_strict_check')) {
$compiler->raw(', ')->repr($this->getAttribute('type'));
if ($needFirst) {
if ($this->hasNode('arguments')) {
$compiler->raw(', ')->subcompile($this->getNode('arguments'));
} else {
$compiler->raw(', array()');
}
}
if ($this->getAttribute('is_defined_test') || $this->getAttribute('ignore_strict_check')) {
$compiler->raw(', '.($this->getAttribute('is_defined_test') ? 'true' : 'false'));
}
if ($needSecond) {
$compiler->raw(', ')->repr($this->getAttribute('type'));
}
if ($this->getAttribute('ignore_strict_check')) {
$compiler->raw(', '.($this->getAttribute('ignore_strict_check') ? 'true' : 'false'));
}
if ($needThird) {
$compiler->raw(', ')->repr($this->getAttribute('is_defined_test'));
}
if ($needFourth) {
$compiler->raw(', ')->repr($this->getAttribute('ignore_strict_check'));
}
$compiler->raw(')');
}
}
class_alias('Twig_Node_Expression_GetAttr', 'Twig\Node\Expression\GetAttrExpression', false);

View file

@ -3,7 +3,7 @@
/*
* This file is part of Twig.
*
* (c) 2012 Fabien Potencier
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@ -39,3 +39,5 @@ class Twig_Node_Expression_MethodCall extends Twig_Node_Expression
$compiler->raw(')');
}
}
class_alias('Twig_Node_Expression_MethodCall', 'Twig\Node\Expression\MethodCallExpression', false);

View file

@ -3,8 +3,8 @@
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
* (c) 2009 Armin Ronacher
* (c) Fabien Potencier
* (c) Armin Ronacher
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@ -12,7 +12,7 @@
class Twig_Node_Expression_Name extends Twig_Node_Expression
{
protected $specialVars = array(
'_self' => '$this',
'_self' => '$this',
'_context' => '$context',
'_charset' => '$this->env->getCharset()',
);
@ -26,6 +26,8 @@ class Twig_Node_Expression_Name extends Twig_Node_Expression
{
$name = $this->getAttribute('name');
$compiler->addDebugInfo($this);
if ($this->getAttribute('is_defined_test')) {
if ($this->isSpecial()) {
$compiler->repr(true);
@ -41,10 +43,20 @@ class Twig_Node_Expression_Name extends Twig_Node_Expression
->raw(']')
;
} else {
// remove the non-PHP 5.4 version when PHP 5.3 support is dropped
// as the non-optimized version is just a workaround for slow ternary operator
// when the context has a lot of variables
if (version_compare(phpversion(), '5.4.0RC1', '>=')) {
if (PHP_VERSION_ID >= 70000) {
// use PHP 7 null coalescing operator
$compiler
->raw('($context[')
->string($name)
->raw('] ?? ')
;
if ($this->getAttribute('ignore_strict_check') || !$compiler->getEnvironment()->isStrictVariables()) {
$compiler->raw('null)');
} else {
$compiler->raw('$this->getContext($context, ')->string($name)->raw('))');
}
} elseif (PHP_VERSION_ID >= 50400) {
// PHP 5.4 ternary operator performance was optimized
$compiler
->raw('(isset($context[')
@ -86,3 +98,5 @@ class Twig_Node_Expression_Name extends Twig_Node_Expression
return !$this->isSpecial() && !$this->getAttribute('is_defined_test');
}
}
class_alias('Twig_Node_Expression_Name', 'Twig\Node\Expression\NameExpression', false);

View file

@ -0,0 +1,48 @@
<?php
/*
* This file is part of Twig.
*
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
class Twig_Node_Expression_NullCoalesce extends Twig_Node_Expression_Conditional
{
public function __construct(Twig_NodeInterface $left, Twig_NodeInterface $right, $lineno)
{
$test = new Twig_Node_Expression_Binary_And(
new Twig_Node_Expression_Test_Defined(clone $left, 'defined', new Twig_Node(), $left->getTemplateLine()),
new Twig_Node_Expression_Unary_Not(new Twig_Node_Expression_Test_Null($left, 'null', new Twig_Node(), $left->getTemplateLine()), $left->getTemplateLine()),
$left->getTemplateLine()
);
parent::__construct($test, $left, $right, $lineno);
}
public function compile(Twig_Compiler $compiler)
{
/*
* This optimizes only one case. PHP 7 also supports more complex expressions
* that can return null. So, for instance, if log is defined, log("foo") ?? "..." works,
* but log($a["foo"]) ?? "..." does not if $a["foo"] is not defined. More advanced
* cases might be implemented as an optimizer node visitor, but has not been done
* as benefits are probably not worth the added complexity.
*/
if (PHP_VERSION_ID >= 70000 && $this->getNode('expr2') instanceof Twig_Node_Expression_Name) {
$this->getNode('expr2')->setAttribute('always_defined', true);
$compiler
->raw('((')
->subcompile($this->getNode('expr2'))
->raw(') ?? (')
->subcompile($this->getNode('expr3'))
->raw('))')
;
} else {
parent::compile($compiler);
}
}
}
class_alias('Twig_Node_Expression_NullCoalesce', 'Twig\Node\Expression\NullCoalesceExpression', false);

View file

@ -3,8 +3,8 @@
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
* (c) 2009 Armin Ronacher
* (c) Fabien Potencier
* (c) Armin Ronacher
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@ -22,26 +22,23 @@ class Twig_Node_Expression_Parent extends Twig_Node_Expression
parent::__construct(array(), array('output' => false, 'name' => $name), $lineno, $tag);
}
/**
* Compiles the node to PHP.
*
* @param Twig_Compiler A Twig_Compiler instance
*/
public function compile(Twig_Compiler $compiler)
{
if ($this->getAttribute('output')) {
$compiler
->addDebugInfo($this)
->write("\$this->displayParentBlock(")
->write('$this->displayParentBlock(')
->string($this->getAttribute('name'))
->raw(", \$context, \$blocks);\n")
;
} else {
$compiler
->raw("\$this->renderParentBlock(")
->raw('$this->renderParentBlock(')
->string($this->getAttribute('name'))
->raw(", \$context, \$blocks)")
->raw(', $context, $blocks)')
;
}
}
}
class_alias('Twig_Node_Expression_Parent', 'Twig\Node\Expression\ParentExpression', false);

View file

@ -3,7 +3,7 @@
/*
* This file is part of Twig.
*
* (c) 2011 Fabien Potencier
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@ -24,3 +24,5 @@ class Twig_Node_Expression_TempName extends Twig_Node_Expression
;
}
}
class_alias('Twig_Node_Expression_TempName', 'Twig\Node\Expression\TempNameExpression', false);

View file

@ -3,7 +3,7 @@
/*
* This file is part of Twig.
*
* (c) 2010 Fabien Potencier
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@ -12,7 +12,12 @@ class Twig_Node_Expression_Test extends Twig_Node_Expression_Call
{
public function __construct(Twig_NodeInterface $node, $name, Twig_NodeInterface $arguments = null, $lineno)
{
parent::__construct(array('node' => $node, 'arguments' => $arguments), array('name' => $name), $lineno);
$nodes = array('node' => $node);
if (null !== $arguments) {
$nodes['arguments'] = $arguments;
}
parent::__construct($nodes, array('name' => $name), $lineno);
}
public function compile(Twig_Compiler $compiler)
@ -26,7 +31,12 @@ class Twig_Node_Expression_Test extends Twig_Node_Expression_Call
if ($test instanceof Twig_TestCallableInterface || $test instanceof Twig_SimpleTest) {
$this->setAttribute('callable', $test->getCallable());
}
if ($test instanceof Twig_SimpleTest) {
$this->setAttribute('is_variadic', $test->isVariadic());
}
$this->compileCallable($compiler);
}
}
class_alias('Twig_Node_Expression_Test', 'Twig\Node\Expression\TestExpression', false);

View file

@ -3,7 +3,7 @@
/*
* This file is part of Twig.
*
* (c) 2011 Fabien Potencier
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@ -44,3 +44,5 @@ class Twig_Node_Expression_Test_Constant extends Twig_Node_Expression_Test
;
}
}
class_alias('Twig_Node_Expression_Test_Constant', 'Twig\Node\Expression\Test\ConstantTest', false);

View file

@ -3,7 +3,7 @@
/*
* This file is part of Twig.
*
* (c) 2011 Fabien Potencier
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@ -25,17 +25,22 @@ class Twig_Node_Expression_Test_Defined extends Twig_Node_Expression_Test
{
public function __construct(Twig_NodeInterface $node, $name, Twig_NodeInterface $arguments = null, $lineno)
{
parent::__construct($node, $name, $arguments, $lineno);
if ($node instanceof Twig_Node_Expression_Name) {
$node->setAttribute('is_defined_test', true);
} elseif ($node instanceof Twig_Node_Expression_GetAttr) {
$node->setAttribute('is_defined_test', true);
$this->changeIgnoreStrictCheck($node);
} elseif ($node instanceof Twig_Node_Expression_BlockReference) {
$node->setAttribute('is_defined_test', true);
} elseif ($node instanceof Twig_Node_Expression_Function && 'constant' === $node->getAttribute('name')) {
$node->setAttribute('is_defined_test', true);
} elseif ($node instanceof Twig_Node_Expression_Constant || $node instanceof Twig_Node_Expression_Array) {
$node = new Twig_Node_Expression_Constant(true, $node->getTemplateLine());
} else {
throw new Twig_Error_Syntax('The "defined" test only works with simple variables', $this->getLine());
throw new Twig_Error_Syntax('The "defined" test only works with simple variables.', $this->getTemplateLine());
}
parent::__construct($node, $name, $arguments, $lineno);
}
protected function changeIgnoreStrictCheck(Twig_Node_Expression_GetAttr $node)
@ -52,3 +57,5 @@ class Twig_Node_Expression_Test_Defined extends Twig_Node_Expression_Test
$compiler->subcompile($this->getNode('node'));
}
}
class_alias('Twig_Node_Expression_Test_Defined', 'Twig\Node\Expression\Test\DefinedTest', false);

View file

@ -3,7 +3,7 @@
/*
* This file is part of Twig.
*
* (c) 2011 Fabien Potencier
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@ -13,7 +13,7 @@
* Checks if a variable is divisible by a number.
*
* <pre>
* {% if loop.index is divisibleby(3) %}
* {% if loop.index is divisible by(3) %}
* </pre>
*
* @author Fabien Potencier <fabien@symfony.com>
@ -31,3 +31,5 @@ class Twig_Node_Expression_Test_Divisibleby extends Twig_Node_Expression_Test
;
}
}
class_alias('Twig_Node_Expression_Test_Divisibleby', 'Twig\Node\Expression\Test\DivisiblebyTest', false);

View file

@ -3,7 +3,7 @@
/*
* This file is part of Twig.
*
* (c) 2011 Fabien Potencier
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@ -30,3 +30,5 @@ class Twig_Node_Expression_Test_Even extends Twig_Node_Expression_Test
;
}
}
class_alias('Twig_Node_Expression_Test_Even', 'Twig\Node\Expression\Test\EvenTest', false);

View file

@ -3,7 +3,7 @@
/*
* This file is part of Twig.
*
* (c) 2011 Fabien Potencier
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@ -29,3 +29,5 @@ class Twig_Node_Expression_Test_Null extends Twig_Node_Expression_Test
;
}
}
class_alias('Twig_Node_Expression_Test_Null', 'Twig\Node\Expression\Test\NullTest', false);

View file

@ -3,7 +3,7 @@
/*
* This file is part of Twig.
*
* (c) 2011 Fabien Potencier
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@ -30,3 +30,5 @@ class Twig_Node_Expression_Test_Odd extends Twig_Node_Expression_Test
;
}
}
class_alias('Twig_Node_Expression_Test_Odd', 'Twig\Node\Expression\Test\OddTest', false);

View file

@ -3,7 +3,7 @@
/*
* This file is part of Twig.
*
* (c) 2011 Fabien Potencier
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@ -27,3 +27,5 @@ class Twig_Node_Expression_Test_Sameas extends Twig_Node_Expression_Test
;
}
}
class_alias('Twig_Node_Expression_Test_Sameas', 'Twig\Node\Expression\Test\SameasTest', false);

View file

@ -3,8 +3,8 @@
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
* (c) 2009 Armin Ronacher
* (c) Fabien Potencier
* (c) Armin Ronacher
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@ -18,13 +18,12 @@ abstract class Twig_Node_Expression_Unary extends Twig_Node_Expression
public function compile(Twig_Compiler $compiler)
{
$compiler->raw('(');
$compiler->raw(' ');
$this->operator($compiler);
$compiler
->subcompile($this->getNode('node'))
->raw(')')
;
$compiler->subcompile($this->getNode('node'));
}
abstract public function operator(Twig_Compiler $compiler);
}
class_alias('Twig_Node_Expression_Unary', 'Twig\Node\Expression\Unary\AbstractUnary', false);

View file

@ -3,8 +3,8 @@
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
* (c) 2009 Armin Ronacher
* (c) Fabien Potencier
* (c) Armin Ronacher
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@ -16,3 +16,5 @@ class Twig_Node_Expression_Unary_Neg extends Twig_Node_Expression_Unary
$compiler->raw('-');
}
}
class_alias('Twig_Node_Expression_Unary_Neg', 'Twig\Node\Expression\Unary\NegUnary', false);

View file

@ -3,8 +3,8 @@
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
* (c) 2009 Armin Ronacher
* (c) Fabien Potencier
* (c) Armin Ronacher
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@ -16,3 +16,5 @@ class Twig_Node_Expression_Unary_Not extends Twig_Node_Expression_Unary
$compiler->raw('!');
}
}
class_alias('Twig_Node_Expression_Unary_Not', 'Twig\Node\Expression\Unary\NotUnary', false);

View file

@ -3,8 +3,8 @@
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
* (c) 2009 Armin Ronacher
* (c) Fabien Potencier
* (c) Armin Ronacher
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@ -16,3 +16,5 @@ class Twig_Node_Expression_Unary_Pos extends Twig_Node_Expression_Unary
$compiler->raw('+');
}
}
class_alias('Twig_Node_Expression_Unary_Pos', 'Twig\Node\Expression\Unary\PosUnary', false);

View file

@ -3,7 +3,7 @@
/*
* This file is part of Twig.
*
* (c) 2011 Fabien Potencier
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@ -21,11 +21,6 @@ class Twig_Node_Flush extends Twig_Node
parent::__construct(array(), array(), $lineno, $tag);
}
/**
* Compiles the node to PHP.
*
* @param Twig_Compiler A Twig_Compiler instance
*/
public function compile(Twig_Compiler $compiler)
{
$compiler
@ -34,3 +29,5 @@ class Twig_Node_Flush extends Twig_Node
;
}
}
class_alias('Twig_Node_Flush', 'Twig\Node\FlushNode', false);

View file

@ -3,8 +3,8 @@
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
* (c) 2009 Armin Ronacher
* (c) Fabien Potencier
* (c) Armin Ronacher
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@ -27,26 +27,25 @@ class Twig_Node_For extends Twig_Node
$body = new Twig_Node_If(new Twig_Node(array($ifexpr, $body)), null, $lineno, $tag);
}
parent::__construct(array('key_target' => $keyTarget, 'value_target' => $valueTarget, 'seq' => $seq, 'body' => $body, 'else' => $else), array('with_loop' => true, 'ifexpr' => null !== $ifexpr), $lineno, $tag);
$nodes = array('key_target' => $keyTarget, 'value_target' => $valueTarget, 'seq' => $seq, 'body' => $body);
if (null !== $else) {
$nodes['else'] = $else;
}
parent::__construct($nodes, array('with_loop' => true, 'ifexpr' => null !== $ifexpr), $lineno, $tag);
}
/**
* Compiles the node to PHP.
*
* @param Twig_Compiler A Twig_Compiler instance
*/
public function compile(Twig_Compiler $compiler)
{
$compiler
->addDebugInfo($this)
// the (array) cast bypasses a PHP 5.2.6 bug
->write("\$context['_parent'] = (array) \$context;\n")
->write("\$context['_parent'] = \$context;\n")
->write("\$context['_seq'] = twig_ensure_traversable(")
->subcompile($this->getNode('seq'))
->raw(");\n")
;
if (null !== $this->getNode('else')) {
if ($this->hasNode('else')) {
$compiler->write("\$context['_iterated'] = false;\n");
}
@ -75,14 +74,14 @@ class Twig_Node_For extends Twig_Node
}
}
$this->loop->setAttribute('else', null !== $this->getNode('else'));
$this->loop->setAttribute('else', $this->hasNode('else'));
$this->loop->setAttribute('with_loop', $this->getAttribute('with_loop'));
$this->loop->setAttribute('ifexpr', $this->getAttribute('ifexpr'));
$compiler
->write("foreach (\$context['_seq'] as ")
->subcompile($this->getNode('key_target'))
->raw(" => ")
->raw(' => ')
->subcompile($this->getNode('value_target'))
->raw(") {\n")
->indent()
@ -91,7 +90,7 @@ class Twig_Node_For extends Twig_Node
->write("}\n")
;
if (null !== $this->getNode('else')) {
if ($this->hasNode('else')) {
$compiler
->write("if (!\$context['_iterated']) {\n")
->indent()
@ -110,3 +109,5 @@ class Twig_Node_For extends Twig_Node
$compiler->write("\$context = array_intersect_key(\$context, \$_parent) + \$_parent;\n");
}
}
class_alias('Twig_Node_For', 'Twig\Node\ForNode', false);

View file

@ -3,7 +3,7 @@
/*
* This file is part of Twig.
*
* (c) 2011 Fabien Potencier
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@ -21,11 +21,6 @@ class Twig_Node_ForLoop extends Twig_Node
parent::__construct(array(), array('with_loop' => false, 'ifexpr' => false, 'else' => false), $lineno, $tag);
}
/**
* Compiles the node to PHP.
*
* @param Twig_Compiler A Twig_Compiler instance
*/
public function compile(Twig_Compiler $compiler)
{
if ($this->getAttribute('else')) {
@ -53,3 +48,5 @@ class Twig_Node_ForLoop extends Twig_Node
}
}
}
class_alias('Twig_Node_ForLoop', 'Twig\Node\ForLoopNode', false);

View file

@ -3,8 +3,8 @@
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
* (c) 2009 Armin Ronacher
* (c) Fabien Potencier
* (c) Armin Ronacher
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@ -19,22 +19,22 @@ class Twig_Node_If extends Twig_Node
{
public function __construct(Twig_NodeInterface $tests, Twig_NodeInterface $else = null, $lineno, $tag = null)
{
parent::__construct(array('tests' => $tests, 'else' => $else), array(), $lineno, $tag);
$nodes = array('tests' => $tests);
if (null !== $else) {
$nodes['else'] = $else;
}
parent::__construct($nodes, array(), $lineno, $tag);
}
/**
* Compiles the node to PHP.
*
* @param Twig_Compiler A Twig_Compiler instance
*/
public function compile(Twig_Compiler $compiler)
{
$compiler->addDebugInfo($this);
for ($i = 0; $i < count($this->getNode('tests')); $i += 2) {
for ($i = 0, $count = count($this->getNode('tests')); $i < $count; $i += 2) {
if ($i > 0) {
$compiler
->outdent()
->write("} elseif (")
->write('} elseif (')
;
} else {
$compiler
@ -50,7 +50,7 @@ class Twig_Node_If extends Twig_Node
;
}
if ($this->hasNode('else') && null !== $this->getNode('else')) {
if ($this->hasNode('else')) {
$compiler
->outdent()
->write("} else {\n")
@ -64,3 +64,5 @@ class Twig_Node_If extends Twig_Node
->write("}\n");
}
}
class_alias('Twig_Node_If', 'Twig\Node\IfNode', false);

View file

@ -3,7 +3,7 @@
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@ -21,11 +21,6 @@ class Twig_Node_Import extends Twig_Node
parent::__construct(array('expr' => $expr, 'var' => $var), array(), $lineno, $tag);
}
/**
* Compiles the node to PHP.
*
* @param Twig_Compiler A Twig_Compiler instance
*/
public function compile(Twig_Compiler $compiler)
{
$compiler
@ -36,15 +31,21 @@ class Twig_Node_Import extends Twig_Node
;
if ($this->getNode('expr') instanceof Twig_Node_Expression_Name && '_self' === $this->getNode('expr')->getAttribute('name')) {
$compiler->raw("\$this");
$compiler->raw('$this');
} else {
$compiler
->raw('$this->env->loadTemplate(')
->raw('$this->loadTemplate(')
->subcompile($this->getNode('expr'))
->raw(")")
->raw(', ')
->repr($this->getTemplateName())
->raw(', ')
->repr($this->getTemplateLine())
->raw(')')
;
}
$compiler->raw(";\n");
}
}
class_alias('Twig_Node_Import', 'Twig\Node\ImportNode', false);

View file

@ -3,8 +3,8 @@
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
* (c) 2009 Armin Ronacher
* (c) Fabien Potencier
* (c) Armin Ronacher
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@ -19,14 +19,14 @@ class Twig_Node_Include extends Twig_Node implements Twig_NodeOutputInterface
{
public function __construct(Twig_Node_Expression $expr, Twig_Node_Expression $variables = null, $only = false, $ignoreMissing = false, $lineno, $tag = null)
{
parent::__construct(array('expr' => $expr, 'variables' => $variables), array('only' => (Boolean) $only, 'ignore_missing' => (Boolean) $ignoreMissing), $lineno, $tag);
$nodes = array('expr' => $expr);
if (null !== $variables) {
$nodes['variables'] = $variables;
}
parent::__construct($nodes, array('only' => (bool) $only, 'ignore_missing' => (bool) $ignoreMissing), $lineno, $tag);
}
/**
* Compiles the node to PHP.
*
* @param Twig_Compiler A Twig_Compiler instance
*/
public function compile(Twig_Compiler $compiler)
{
$compiler->addDebugInfo($this);
@ -60,40 +60,31 @@ class Twig_Node_Include extends Twig_Node implements Twig_NodeOutputInterface
protected function addGetTemplate(Twig_Compiler $compiler)
{
if ($this->getNode('expr') instanceof Twig_Node_Expression_Constant) {
$compiler
->write("\$this->env->loadTemplate(")
->subcompile($this->getNode('expr'))
->raw(")")
;
} else {
$compiler
->write("\$template = \$this->env->resolveTemplate(")
->subcompile($this->getNode('expr'))
->raw(");\n")
->write('$template')
;
}
$compiler
->write('$this->loadTemplate(')
->subcompile($this->getNode('expr'))
->raw(', ')
->repr($this->getTemplateName())
->raw(', ')
->repr($this->getTemplateLine())
->raw(')')
;
}
protected function addTemplateArguments(Twig_Compiler $compiler)
{
if (false === $this->getAttribute('only')) {
if (null === $this->getNode('variables')) {
$compiler->raw('$context');
} else {
$compiler
->raw('array_merge($context, ')
->subcompile($this->getNode('variables'))
->raw(')')
;
}
if (!$this->hasNode('variables')) {
$compiler->raw(false === $this->getAttribute('only') ? '$context' : 'array()');
} elseif (false === $this->getAttribute('only')) {
$compiler
->raw('array_merge($context, ')
->subcompile($this->getNode('variables'))
->raw(')')
;
} else {
if (null === $this->getNode('variables')) {
$compiler->raw('array()');
} else {
$compiler->subcompile($this->getNode('variables'));
}
$compiler->subcompile($this->getNode('variables'));
}
}
}
class_alias('Twig_Node_Include', 'Twig\Node\IncludeNode', false);

View file

@ -3,7 +3,7 @@
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@ -16,28 +16,31 @@
*/
class Twig_Node_Macro extends Twig_Node
{
const VARARGS_NAME = 'varargs';
public function __construct($name, Twig_NodeInterface $body, Twig_NodeInterface $arguments, $lineno, $tag = null)
{
parent::__construct(array('body' => $body, 'arguments' => $arguments), array('name' => $name, 'method' => 'get'.ucfirst($name)), $lineno, $tag);
foreach ($arguments as $argumentName => $argument) {
if (self::VARARGS_NAME === $argumentName) {
throw new Twig_Error_Syntax(sprintf('The argument "%s" in macro "%s" cannot be defined because the variable "%s" is reserved for arbitrary arguments.', self::VARARGS_NAME, $name, self::VARARGS_NAME), $argument->getTemplateLine());
}
}
parent::__construct(array('body' => $body, 'arguments' => $arguments), array('name' => $name), $lineno, $tag);
}
/**
* Compiles the node to PHP.
*
* @param Twig_Compiler A Twig_Compiler instance
*/
public function compile(Twig_Compiler $compiler)
{
$compiler
->addDebugInfo($this)
->write(sprintf("public function %s(", $this->getAttribute('method')))
->write(sprintf('public function get%s(', $this->getAttribute('name')))
;
$count = count($this->getNode('arguments'));
$pos = 0;
foreach ($this->getNode('arguments') as $name => $default) {
$compiler
->raw('$_'.$name.' = ')
->raw('$__'.$name.'__ = ')
->subcompile($default)
;
@ -46,36 +49,55 @@ class Twig_Node_Macro extends Twig_Node
}
}
if (PHP_VERSION_ID >= 50600) {
if ($count) {
$compiler->raw(', ');
}
$compiler->raw('...$__varargs__');
}
$compiler
->raw(")\n")
->write("{\n")
->indent()
;
if (!count($this->getNode('arguments'))) {
$compiler->write("\$context = \$this->env->getGlobals();\n\n");
} else {
$compiler
->write("\$context = \$this->env->mergeGlobals(array(\n")
->indent()
;
foreach ($this->getNode('arguments') as $name => $default) {
$compiler
->write('')
->string($name)
->raw(' => $_'.$name)
->raw(",\n")
;
}
$compiler
->write("\$context = \$this->env->mergeGlobals(array(\n")
->indent()
;
foreach ($this->getNode('arguments') as $name => $default) {
$compiler
->outdent()
->write("));\n\n")
->write('')
->string($name)
->raw(' => $__'.$name.'__')
->raw(",\n")
;
}
$compiler
->write('')
->string(self::VARARGS_NAME)
->raw(' => ')
;
if (PHP_VERSION_ID >= 50600) {
$compiler->raw("\$__varargs__,\n");
} else {
$compiler
->raw('func_num_args() > ')
->repr($count)
->raw(' ? array_slice(func_get_args(), ')
->repr($count)
->raw(") : array(),\n")
;
}
$compiler
->outdent()
->write("));\n\n")
->write("\$blocks = array();\n\n")
->write("ob_start();\n")
->write("try {\n")
@ -87,6 +109,11 @@ class Twig_Node_Macro extends Twig_Node
->write("ob_end_clean();\n\n")
->write("throw \$e;\n")
->outdent()
->write("} catch (Throwable \$e) {\n")
->indent()
->write("ob_end_clean();\n\n")
->write("throw \$e;\n")
->outdent()
->write("}\n\n")
->write("return ('' === \$tmp = ob_get_clean()) ? '' : new Twig_Markup(\$tmp, \$this->env->getCharset());\n")
->outdent()
@ -94,3 +121,5 @@ class Twig_Node_Macro extends Twig_Node
;
}
}
class_alias('Twig_Node_Macro', 'Twig\Node\MacroNode', false);

View file

@ -3,8 +3,8 @@
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
* (c) 2009 Armin Ronacher
* (c) Fabien Potencier
* (c) Armin Ronacher
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@ -13,14 +13,52 @@
/**
* Represents a module node.
*
* Consider this class as being final. If you need to customize the behavior of
* the generated class, consider adding nodes to the following nodes: display_start,
* display_end, constructor_start, constructor_end, and class_end.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
class Twig_Node_Module extends Twig_Node
{
public function __construct(Twig_NodeInterface $body, Twig_Node_Expression $parent = null, Twig_NodeInterface $blocks, Twig_NodeInterface $macros, Twig_NodeInterface $traits, $embeddedTemplates, $filename)
private $source;
public function __construct(Twig_NodeInterface $body, Twig_Node_Expression $parent = null, Twig_NodeInterface $blocks, Twig_NodeInterface $macros, Twig_NodeInterface $traits, $embeddedTemplates, $name, $source = '')
{
if (!$name instanceof Twig_Source) {
@trigger_error(sprintf('Passing a string as the $name argument of %s() is deprecated since version 1.27. Pass a Twig_Source instance instead.', __METHOD__), E_USER_DEPRECATED);
$this->source = new Twig_Source($source, $name);
} else {
$this->source = $name;
}
$nodes = array(
'body' => $body,
'blocks' => $blocks,
'macros' => $macros,
'traits' => $traits,
'display_start' => new Twig_Node(),
'display_end' => new Twig_Node(),
'constructor_start' => new Twig_Node(),
'constructor_end' => new Twig_Node(),
'class_end' => new Twig_Node(),
);
if (null !== $parent) {
$nodes['parent'] = $parent;
}
// embedded templates are set as attributes so that they are only visited once by the visitors
parent::__construct(array('parent' => $parent, 'body' => $body, 'blocks' => $blocks, 'macros' => $macros, 'traits' => $traits), array('filename' => $filename, 'index' => null, 'embedded_templates' => $embeddedTemplates), 1);
parent::__construct($nodes, array(
// source to be remove in 2.0
'source' => $this->source->getCode(),
// filename to be remove in 2.0 (use getTemplateName() instead)
'filename' => $this->source->getName(),
'index' => null,
'embedded_templates' => $embeddedTemplates,
), 1);
// populate the template name of all node children
$this->setTemplateName($this->source->getName());
}
public function setIndex($index)
@ -28,11 +66,6 @@ class Twig_Node_Module extends Twig_Node
$this->setAttribute('index', $index);
}
/**
* Compiles the node to PHP.
*
* @param Twig_Compiler A Twig_Compiler instance
*/
public function compile(Twig_Compiler $compiler)
{
$this->compileTemplate($compiler);
@ -50,17 +83,20 @@ class Twig_Node_Module extends Twig_Node
$this->compileClassHeader($compiler);
if (count($this->getNode('blocks')) || count($this->getNode('traits')) || null === $this->getNode('parent') || $this->getNode('parent') instanceof Twig_Node_Expression_Constant) {
if (
count($this->getNode('blocks'))
|| count($this->getNode('traits'))
|| !$this->hasNode('parent')
|| $this->getNode('parent') instanceof Twig_Node_Expression_Constant
|| count($this->getNode('constructor_start'))
|| count($this->getNode('constructor_end'))
) {
$this->compileConstructor($compiler);
}
$this->compileGetParent($compiler);
$this->compileDisplayHeader($compiler);
$this->compileDisplayBody($compiler);
$this->compileDisplayFooter($compiler);
$this->compileDisplay($compiler);
$compiler->subcompile($this->getNode('blocks'));
@ -72,28 +108,38 @@ class Twig_Node_Module extends Twig_Node
$this->compileDebugInfo($compiler);
$this->compileGetSource($compiler);
$this->compileGetSourceContext($compiler);
$this->compileClassFooter($compiler);
}
protected function compileGetParent(Twig_Compiler $compiler)
{
if (null === $this->getNode('parent')) {
if (!$this->hasNode('parent')) {
return;
}
$parent = $this->getNode('parent');
$compiler
->write("protected function doGetParent(array \$context)\n", "{\n")
->indent()
->write("return ")
->addDebugInfo($parent)
->write('return ')
;
if ($this->getNode('parent') instanceof Twig_Node_Expression_Constant) {
$compiler->subcompile($this->getNode('parent'));
if ($parent instanceof Twig_Node_Expression_Constant) {
$compiler->subcompile($parent);
} else {
$compiler
->raw("\$this->env->resolveTemplate(")
->subcompile($this->getNode('parent'))
->raw(")")
->raw('$this->loadTemplate(')
->subcompile($parent)
->raw(', ')
->repr($this->source->getName())
->raw(', ')
->repr($parent->getTemplateLine())
->raw(')')
;
}
@ -104,27 +150,13 @@ class Twig_Node_Module extends Twig_Node
;
}
protected function compileDisplayBody(Twig_Compiler $compiler)
{
$compiler->subcompile($this->getNode('body'));
if (null !== $this->getNode('parent')) {
if ($this->getNode('parent') instanceof Twig_Node_Expression_Constant) {
$compiler->write("\$this->parent");
} else {
$compiler->write("\$this->getParent(\$context)");
}
$compiler->raw("->display(\$context, array_merge(\$this->blocks, \$blocks));\n");
}
}
protected function compileClassHeader(Twig_Compiler $compiler)
{
$compiler
->write("\n\n")
// if the filename contains */, add a blank to avoid a PHP parse error
->write("/* ".str_replace('*/', '* /', $this->getAttribute('filename'))." */\n")
->write('class '.$compiler->getEnvironment()->getTemplateClass($this->getAttribute('filename'), $this->getAttribute('index')))
// if the template name contains */, add a blank to avoid a PHP parse error
->write('/* '.str_replace('*/', '* /', $this->source->getName())." */\n")
->write('class '.$compiler->getEnvironment()->getTemplateClass($this->source->getName(), $this->getAttribute('index')))
->raw(sprintf(" extends %s\n", $compiler->getEnvironment()->getBaseTemplateClass()))
->write("{\n")
->indent()
@ -136,17 +168,23 @@ class Twig_Node_Module extends Twig_Node
$compiler
->write("public function __construct(Twig_Environment \$env)\n", "{\n")
->indent()
->subcompile($this->getNode('constructor_start'))
->write("parent::__construct(\$env);\n\n")
;
// parent
if (null === $this->getNode('parent')) {
if (!$this->hasNode('parent')) {
$compiler->write("\$this->parent = false;\n\n");
} elseif ($this->getNode('parent') instanceof Twig_Node_Expression_Constant) {
} elseif (($parent = $this->getNode('parent')) && $parent instanceof Twig_Node_Expression_Constant) {
$compiler
->write("\$this->parent = \$this->env->loadTemplate(")
->subcompile($this->getNode('parent'))
->raw(");\n\n")
->addDebugInfo($parent)
->write('$this->parent = $this->loadTemplate(')
->subcompile($parent)
->raw(', ')
->repr($this->source->getName())
->raw(', ')
->repr($parent->getTemplateLine())
->raw(");\n")
;
}
@ -170,11 +208,23 @@ class Twig_Node_Module extends Twig_Node
foreach ($trait->getNode('targets') as $key => $value) {
$compiler
->write(sprintf("\$_trait_%s_blocks[", $i))
->subcompile($value)
->raw(sprintf("] = \$_trait_%s_blocks[", $i))
->write(sprintf('if (!isset($_trait_%s_blocks[', $i))
->string($key)
->raw(sprintf("]; unset(\$_trait_%s_blocks[", $i))
->raw("])) {\n")
->indent()
->write("throw new Twig_Error_Runtime(sprintf('Block ")
->string($key)
->raw(' is not defined in trait ')
->subcompile($trait->getNode('template'))
->raw(".'));\n")
->outdent()
->write("}\n\n")
->write(sprintf('$_trait_%s_blocks[', $i))
->subcompile($value)
->raw(sprintf('] = $_trait_%s_blocks[', $i))
->string($key)
->raw(sprintf(']; unset($_trait_%s_blocks[', $i))
->string($key)
->raw("]);\n\n")
;
@ -187,9 +237,9 @@ class Twig_Node_Module extends Twig_Node
->indent()
;
for ($i = 0; $i < $countTraits; $i++) {
for ($i = 0; $i < $countTraits; ++$i) {
$compiler
->write(sprintf("\$_trait_%s_blocks".($i == $countTraits - 1 ? '' : ',')."\n", $i))
->write(sprintf('$_trait_%s_blocks'.($i == $countTraits - 1 ? '' : ',')."\n", $i))
;
}
@ -233,57 +283,37 @@ class Twig_Node_Module extends Twig_Node
;
}
$compiler
->outdent()
->write(");\n\n")
;
// macro information
$compiler
->write("\$this->macros = array(\n")
->indent()
;
foreach ($this->getNode('macros') as $name => $node) {
$compiler
->addIndentation()->repr($name)->raw(" => array(\n")
->indent()
->write("'method' => ")->repr($node->getAttribute('method'))->raw(",\n")
->write("'arguments' => array(\n")
->indent()
;
foreach ($node->getNode('arguments') as $argument => $value) {
$compiler->addIndentation()->repr($argument)->raw (' => ')->subcompile($value)->raw(",\n");
}
$compiler
->outdent()
->write("),\n")
->outdent()
->write("),\n")
;
}
$compiler
->outdent()
->write(");\n")
;
$compiler
->outdent()
->subcompile($this->getNode('constructor_end'))
->write("}\n\n")
;
}
protected function compileDisplayHeader(Twig_Compiler $compiler)
protected function compileDisplay(Twig_Compiler $compiler)
{
$compiler
->write("protected function doDisplay(array \$context, array \$blocks = array())\n", "{\n")
->indent()
->subcompile($this->getNode('display_start'))
->subcompile($this->getNode('body'))
;
}
protected function compileDisplayFooter(Twig_Compiler $compiler)
{
if ($this->hasNode('parent')) {
$parent = $this->getNode('parent');
$compiler->addDebugInfo($parent);
if ($parent instanceof Twig_Node_Expression_Constant) {
$compiler->write('$this->parent');
} else {
$compiler->write('$this->getParent($context)');
}
$compiler->raw("->display(\$context, array_merge(\$this->blocks, \$blocks));\n");
}
$compiler
->subcompile($this->getNode('display_end'))
->outdent()
->write("}\n\n")
;
@ -292,6 +322,7 @@ class Twig_Node_Module extends Twig_Node
protected function compileClassFooter(Twig_Compiler $compiler)
{
$compiler
->subcompile($this->getNode('class_end'))
->outdent()
->write("}\n")
;
@ -308,7 +339,7 @@ class Twig_Node_Module extends Twig_Node
->write("public function getTemplateName()\n", "{\n")
->indent()
->write('return ')
->repr($this->getAttribute('filename'))
->repr($this->source->getName())
->raw(";\n")
->outdent()
->write("}\n\n")
@ -324,7 +355,7 @@ class Twig_Node_Module extends Twig_Node
//
// Put another way, a template can be used as a trait if it
// only contains blocks and use statements.
$traitable = null === $this->getNode('parent') && 0 === count($this->getNode('macros'));
$traitable = !$this->hasNode('parent') && 0 === count($this->getNode('macros'));
if ($traitable) {
if ($this->getNode('body') instanceof Twig_Node_Body) {
$nodes = $this->getNode('body')->getNode(0);
@ -374,6 +405,37 @@ class Twig_Node_Module extends Twig_Node
->indent()
->write(sprintf("return %s;\n", str_replace("\n", '', var_export(array_reverse($compiler->getDebugInfo(), true), true))))
->outdent()
->write("}\n\n")
;
}
protected function compileGetSource(Twig_Compiler $compiler)
{
$compiler
->write("/** @deprecated since 1.27 (to be removed in 2.0). Use getSourceContext() instead */\n")
->write("public function getSource()\n", "{\n")
->indent()
->write("@trigger_error('The '.__METHOD__.' method is deprecated since version 1.27 and will be removed in 2.0. Use getSourceContext() instead.', E_USER_DEPRECATED);\n\n")
->write('return $this->getSourceContext()->getCode();')
->raw("\n")
->outdent()
->write("}\n\n")
;
}
protected function compileGetSourceContext(Twig_Compiler $compiler)
{
$compiler
->write("public function getSourceContext()\n", "{\n")
->indent()
->write('return new Twig_Source(')
->string($compiler->getEnvironment()->isDebug() ? $this->source->getCode() : '')
->raw(', ')
->string($this->source->getName())
->raw(', ')
->string($this->source->getPath())
->raw(");\n")
->outdent()
->write("}\n")
;
}
@ -382,22 +444,18 @@ class Twig_Node_Module extends Twig_Node
{
if ($node instanceof Twig_Node_Expression_Constant) {
$compiler
->write(sprintf("%s = \$this->env->loadTemplate(", $var))
->write(sprintf('%s = $this->loadTemplate(', $var))
->subcompile($node)
->raw(', ')
->repr($node->getTemplateName())
->raw(', ')
->repr($node->getTemplateLine())
->raw(");\n")
;
} else {
$compiler
->write(sprintf("%s = ", $var))
->subcompile($node)
->raw(";\n")
->write(sprintf("if (!%s", $var))
->raw(" instanceof Twig_Template) {\n")
->indent()
->write(sprintf("%s = \$this->env->loadTemplate(%s);\n", $var, $var))
->outdent()
->write("}\n")
;
throw new LogicException('Trait templates can only be constant nodes.');
}
}
}
class_alias('Twig_Node_Module', 'Twig\Node\ModuleNode', false);

View file

@ -3,8 +3,8 @@
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
* (c) 2009 Armin Ronacher
* (c) Fabien Potencier
* (c) Armin Ronacher
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@ -22,11 +22,6 @@ class Twig_Node_Print extends Twig_Node implements Twig_NodeOutputInterface
parent::__construct(array('expr' => $expr), array(), $lineno, $tag);
}
/**
* Compiles the node to PHP.
*
* @param Twig_Compiler A Twig_Compiler instance
*/
public function compile(Twig_Compiler $compiler)
{
$compiler
@ -37,3 +32,5 @@ class Twig_Node_Print extends Twig_Node implements Twig_NodeOutputInterface
;
}
}
class_alias('Twig_Node_Print', 'Twig\Node\PrintNode', false);

View file

@ -3,7 +3,7 @@
/*
* This file is part of Twig.
*
* (c) 2010 Fabien Potencier
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@ -21,16 +21,11 @@ class Twig_Node_Sandbox extends Twig_Node
parent::__construct(array('body' => $body), array(), $lineno, $tag);
}
/**
* Compiles the node to PHP.
*
* @param Twig_Compiler A Twig_Compiler instance
*/
public function compile(Twig_Compiler $compiler)
{
$compiler
->addDebugInfo($this)
->write("\$sandbox = \$this->env->getExtension('sandbox');\n")
->write("\$sandbox = \$this->env->getExtension('Twig_Extension_Sandbox');\n")
->write("if (!\$alreadySandboxed = \$sandbox->isSandboxed()) {\n")
->indent()
->write("\$sandbox->enableSandbox();\n")
@ -45,3 +40,5 @@ class Twig_Node_Sandbox extends Twig_Node
;
}
}
class_alias('Twig_Node_Sandbox', 'Twig\Node\SandboxNode', false);

View file

@ -3,7 +3,7 @@
/*
* This file is part of Twig.
*
* (c) 2010 Fabien Potencier
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@ -21,21 +21,11 @@
*/
class Twig_Node_SandboxedPrint extends Twig_Node_Print
{
public function __construct(Twig_Node_Expression $expr, $lineno, $tag = null)
{
parent::__construct($expr, $lineno, $tag);
}
/**
* Compiles the node to PHP.
*
* @param Twig_Compiler A Twig_Compiler instance
*/
public function compile(Twig_Compiler $compiler)
{
$compiler
->addDebugInfo($this)
->write('echo $this->env->getExtension(\'sandbox\')->ensureToStringAllowed(')
->write('echo $this->env->getExtension(\'Twig_Extension_Sandbox\')->ensureToStringAllowed(')
->subcompile($this->getNode('expr'))
->raw(");\n")
;
@ -46,9 +36,9 @@ class Twig_Node_SandboxedPrint extends Twig_Node_Print
*
* This is mostly needed when another visitor adds filters (like the escaper one).
*
* @param Twig_Node $node A Node
* @return Twig_Node
*/
protected function removeNodeFilter($node)
protected function removeNodeFilter(Twig_Node $node)
{
if ($node instanceof Twig_Node_Expression_Filter) {
return $this->removeNodeFilter($node->getNode('node'));
@ -57,3 +47,5 @@ class Twig_Node_SandboxedPrint extends Twig_Node_Print
return $node;
}
}
class_alias('Twig_Node_SandboxedPrint', 'Twig\Node\SandboxedPrintNode', false);

View file

@ -3,7 +3,7 @@
/*
* This file is part of Twig.
*
* (c) 2010 Fabien Potencier
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@ -14,7 +14,7 @@
*
* @author Fabien Potencier <fabien@symfony.com>
*/
class Twig_Node_Set extends Twig_Node
class Twig_Node_Set extends Twig_Node implements Twig_NodeCaptureInterface
{
public function __construct($capture, Twig_NodeInterface $names, Twig_NodeInterface $values, $lineno, $tag = null)
{
@ -30,17 +30,12 @@ class Twig_Node_Set extends Twig_Node
$values = $this->getNode('values');
if ($values instanceof Twig_Node_Text) {
$this->setNode('values', new Twig_Node_Expression_Constant($values->getAttribute('data'), $values->getLine()));
$this->setNode('values', new Twig_Node_Expression_Constant($values->getAttribute('data'), $values->getTemplateLine()));
$this->setAttribute('capture', false);
}
}
}
/**
* Compiles the node to PHP.
*
* @param Twig_Compiler A Twig_Compiler instance
*/
public function compile(Twig_Compiler $compiler)
{
$compiler->addDebugInfo($this);
@ -99,3 +94,5 @@ class Twig_Node_Set extends Twig_Node
$compiler->raw(";\n");
}
}
class_alias('Twig_Node_Set', 'Twig\Node\SetNode', false);

View file

@ -3,12 +3,15 @@
/*
* This file is part of Twig.
*
* (c) 2011 Fabien Potencier
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
* @internal
*/
class Twig_Node_SetTemp extends Twig_Node
{
public function __construct($name, $lineno)
@ -33,3 +36,5 @@ class Twig_Node_SetTemp extends Twig_Node
;
}
}
class_alias('Twig_Node_SetTemp', 'Twig\Node\SetTempNode', false);

View file

@ -3,7 +3,7 @@
/*
* This file is part of Twig.
*
* (c) 2010 Fabien Potencier
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@ -23,11 +23,6 @@ class Twig_Node_Spaceless extends Twig_Node
parent::__construct(array('body' => $body), array(), $lineno, $tag);
}
/**
* Compiles the node to PHP.
*
* @param Twig_Compiler A Twig_Compiler instance
*/
public function compile(Twig_Compiler $compiler)
{
$compiler
@ -38,3 +33,5 @@ class Twig_Node_Spaceless extends Twig_Node
;
}
}
class_alias('Twig_Node_Spaceless', 'Twig\Node\SpacelessNode', false);

View file

@ -3,8 +3,8 @@
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
* (c) 2009 Armin Ronacher
* (c) Fabien Potencier
* (c) Armin Ronacher
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@ -22,11 +22,6 @@ class Twig_Node_Text extends Twig_Node implements Twig_NodeOutputInterface
parent::__construct(array(), array('data' => $data), $lineno);
}
/**
* Compiles the node to PHP.
*
* @param Twig_Compiler A Twig_Compiler instance
*/
public function compile(Twig_Compiler $compiler)
{
$compiler
@ -37,3 +32,5 @@ class Twig_Node_Text extends Twig_Node implements Twig_NodeOutputInterface
;
}
}
class_alias('Twig_Node_Text', 'Twig\Node\TextNode', false);

View file

@ -0,0 +1,64 @@
<?php
/*
* This file is part of Twig.
*
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
* Represents a nested "with" scope.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
class Twig_Node_With extends Twig_Node
{
public function __construct(Twig_Node $body, Twig_Node $variables = null, $only = false, $lineno, $tag = null)
{
$nodes = array('body' => $body);
if (null !== $variables) {
$nodes['variables'] = $variables;
}
parent::__construct($nodes, array('only' => (bool) $only), $lineno, $tag);
}
public function compile(Twig_Compiler $compiler)
{
$compiler->addDebugInfo($this);
if ($this->hasNode('variables')) {
$varsName = $compiler->getVarName();
$compiler
->write(sprintf('$%s = ', $varsName))
->subcompile($this->getNode('variables'))
->raw(";\n")
->write(sprintf("if (!is_array(\$%s)) {\n", $varsName))
->indent()
->write("throw new Twig_Error_Runtime('Variables passed to the \"with\" tag must be a hash.');\n")
->outdent()
->write("}\n")
;
if ($this->getAttribute('only')) {
$compiler->write("\$context = array('_parent' => \$context);\n");
} else {
$compiler->write("\$context['_parent'] = \$context;\n");
}
$compiler->write(sprintf("\$context = array_merge(\$context, \$%s);\n", $varsName));
} else {
$compiler->write("\$context['_parent'] = \$context;\n");
}
$compiler
->subcompile($this->getNode('body'))
->write("\$context = \$context['_parent'];\n")
;
}
}
class_alias('Twig_Node_With', 'Twig\Node\WithNode', false);