/**
  * Loads assets from the supplied node.
  *
  * @param \Twig_Node $node
  *
  * @return array An array of asset formulae indexed by name
  */
 private function loadNode(\Twig_Node $node)
 {
     $formulae = array();
     if ($node instanceof AsseticNode) {
         $formulae[$node->getAttribute('name')] = array($node->getAttribute('inputs'), $node->getAttribute('filters'), array('output' => $node->getAttribute('asset')->getTargetPath(), 'name' => $node->getAttribute('name'), 'debug' => $node->getAttribute('debug'), 'combine' => $node->getAttribute('combine'), 'vars' => $node->getAttribute('vars')));
     } elseif ($node instanceof \Twig_Node_Expression_Function) {
         $name = version_compare(\Twig_Environment::VERSION, '1.2.0-DEV', '<') ? $node->getNode('name')->getAttribute('name') : $node->getAttribute('name');
         if ($this->twig->getFunction($name) instanceof AsseticFilterFunction) {
             $arguments = array();
             foreach ($node->getNode('arguments') as $argument) {
                 $arguments[] = eval('return ' . $this->twig->compile($argument) . ';');
             }
             $invoker = $this->twig->getExtension('assetic')->getFilterInvoker($name);
             $inputs = isset($arguments[0]) ? (array) $arguments[0] : array();
             $filters = $invoker->getFilters();
             $options = array_replace($invoker->getOptions(), isset($arguments[1]) ? $arguments[1] : array());
             if (!isset($options['name'])) {
                 $options['name'] = $invoker->getFactory()->generateAssetName($inputs, $filters, $options);
             }
             $formulae[$options['name']] = array($inputs, $filters, $options);
         }
     }
     foreach ($node as $child) {
         if ($child instanceof \Twig_Node) {
             $formulae += $this->loadNode($child);
         }
     }
     if ($node->hasAttribute('embedded_templates')) {
         foreach ($node->getAttribute('embedded_templates') as $child) {
             $formulae += $this->loadNode($child);
         }
     }
     return $formulae;
 }
Esempio n. 2
0
 public static function process(\Twig_Node $node, Translations $translations, $file)
 {
     $fileReference = str_replace(realpath(self::$rootDir . '/../') . '/', "", $file);
     if ($node instanceof TransNode) {
         //Process nodes that {% trans %} blocks
         $body = new \Twig_Node_Expression_Constant($node->getNode('body')->getAttribute('data'), $node->getLine());
         $compiledTranslation = eval('return ' . self::$twig->compile($body) . ';');
         $translations->insert('', $compiledTranslation)->addReference($fileReference, $node->getLine());
     }
     if ($node instanceof \Twig_Node_Expression_Function) {
         //Process nodes that are function expressions
         if ($node->getAttribute('name') == '__') {
             //Check the function name for __()
             foreach ($node->getNode('arguments') as $argument) {
                 //Grab the argument
                 $key = eval('return ' . self::$twig->compile($argument) . ';');
                 $translations->insert('', $key)->addReference($fileReference, $node->getLine());
                 break;
                 //I only needed the first argument in my implementation
             }
         }
     }
     //Recursively loop through the AST
     foreach ($node as $child) {
         if ($child instanceof \Twig_Node) {
             self::process($child, $translations, $file);
         }
     }
 }
Esempio n. 3
0
 /**
  * Determines at compile time whether the generated URL will be safe and thus
  * saving the unneeded automatic escaping for performance reasons.
  *
  * The URL generation process percent encodes non-alphanumeric characters. So there is no risk
  * that malicious/invalid characters are part of the URL. The only character within an URL that
  * must be escaped in html is the ampersand ("&") which separates query params. So we cannot mark
  * the URL generation as always safe, but only when we are sure there won't be multiple query
  * params. This is the case when there are none or only one constant parameter given.
  * E.g. we know beforehand this will be safe:
  * - path('route')
  * - path('route', {'param': 'value'})
  * But the following may not:
  * - path('route', var)
  * - path('route', {'param': ['val1', 'val2'] }) // a sub-array
  * - path('route', {'param1': 'value1', 'param2': 'value2'})
  * If param1 and param2 reference placeholder in the route, it would still be safe. But we don't know.
  *
  * @param \Twig_Node $argsNode The arguments of the path/url function
  *
  * @return array An array with the contexts the URL is safe
  */
 public function isUrlGenerationSafe(\Twig_Node $argsNode)
 {
     // support named arguments
     $paramsNode = $argsNode->hasNode('parameters') ? $argsNode->getNode('parameters') : ($argsNode->hasNode(1) ? $argsNode->getNode(1) : null);
     if (null === $paramsNode || $paramsNode instanceof \Twig_Node_Expression_Array && count($paramsNode) <= 2 && (!$paramsNode->hasNode(1) || $paramsNode->getNode(1) instanceof \Twig_Node_Expression_Constant)) {
         return array('html');
     }
     return array();
 }
 /**
  * Loads assets from the supplied node.
  *
  * @param \Twig_Node $node
  *
  * @return array An array of asset formulae indexed by name
  */
 private function loadNode(\Twig_Node $node)
 {
     $formulae = array();
     if ($node instanceof AsseticNode) {
         $formulae[$node->getAttribute('name')] = array($node->getAttribute('inputs'), $node->getAttribute('filters'), array('output' => $node->getAttribute('asset')->getTargetPath(), 'name' => $node->getAttribute('name'), 'debug' => $node->getAttribute('debug'), 'combine' => $node->getAttribute('combine'), 'vars' => $node->getAttribute('vars')));
     } elseif ($node instanceof \Twig_Node_Expression_Function) {
         $name = version_compare(\Twig_Environment::VERSION, '1.2.0-DEV', '<') ? $node->getNode('name')->getAttribute('name') : $node->getAttribute('name');
         if ($this->twig->getFunction($name) instanceof AsseticFilterFunction) {
             $arguments = array();
             foreach ($node->getNode('arguments') as $argument) {
                 $arguments[] = eval('return ' . $this->twig->compile($argument) . ';');
             }
             $invoker = $this->twig->getExtension('assetic')->getFilterInvoker($name);
             $inputs = isset($arguments[0]) ? (array) $arguments[0] : array();
             $filters = $invoker->getFilters();
             $options = array_replace($invoker->getOptions(), isset($arguments[1]) ? $arguments[1] : array());
             if (!isset($options['name'])) {
                 $options['name'] = $invoker->getFactory()->generateAssetName($inputs, $filters, $options);
             }
             $formulae[$options['name']] = array($inputs, $filters, $options);
         }
     }
     foreach ($node as $child) {
         if ($child instanceof \Twig_Node) {
             $formulae += $this->loadNode($child);
         }
     }
     if ($node->hasAttribute('embedded_templates')) {
         foreach ($node->getAttribute('embedded_templates') as $child) {
             $formulae += $this->loadNode($child);
         }
     }
     $formulaes = array();
     foreach ($formulae as $n => $f) {
         list($inputs, $filters, $options) = $f;
         // 當沒有資源或此資源已被解開過的時候
         if (count($inputs) > 0 && strlen($n) <= 7 && ($this->debug === true || $options['debug'] === true || $options['combine'] === false)) {
             $path = pathinfo($options['output']);
             $counter = 1;
             foreach ($inputs as $input) {
                 $inputPath = pathinfo($input);
                 $_name = $n . '_' . md5($input);
                 $_inputs = array($input);
                 $_filters = $filters;
                 $_options = array('output' => "{$path['dirname']}/{$path['filename']}_{$inputPath['filename']}_{$counter}.{$path['extension']}", 'name' => "{$path['filename']}_{$inputPath['filename']}_{$counter}") + $options;
                 $formulaes[$_name] = array($_inputs, $_filters, $_options);
                 $counter++;
             }
         } else {
             $formulaes[$n] = $f;
         }
     }
     $formulae = $formulaes;
     return $formulae;
 }
 /**
  * @param \Twig_Node $arguments
  * @param int        $index
  *
  * @return string|null
  */
 private function getReadDomainFromArguments(\Twig_Node $arguments, $index)
 {
     if ($arguments->hasNode('domain')) {
         $argument = $arguments->getNode('domain');
     } elseif ($arguments->hasNode($index)) {
         $argument = $arguments->getNode($index);
     } else {
         return null;
     }
     return $this->getReadDomainFromNode($argument);
 }
 protected function doLeaveNode(\Twig_Node $node, \Twig_Environment $env)
 {
     if ($node instanceof \Twig_Node_Include) {
         if ($node->hasNode('expr') && $node->getNode('expr')->hasAttribute('value')) {
             $patternStoreKey = $node->getNode('expr')->getAttribute('value');
             $data = Data::getPatternSpecificData($patternStoreKey);
             $dataNode = new PatternDataIncludeNode($node, $data);
             return $dataNode;
         }
     }
     return $node;
 }
Esempio n. 7
0
 /**
  * {@inheritdoc}
  */
 public function leaveNode(Twig_Node $node, Twig_Environment $env)
 {
     if ($node instanceof Twig_Node_Module) {
         $varName = $this->getVarName();
         $node->setNode('display_start', new Twig_Node(array(new Twig_Profiler_Node_EnterProfile($this->extensionName, Twig_Profiler_Profile::TEMPLATE, $node->getAttribute('filename'), $varName), $node->getNode('display_start'))));
         $node->setNode('display_end', new Twig_Node(array(new Twig_Profiler_Node_LeaveProfile($varName), $node->getNode('display_end'))));
     } elseif ($node instanceof Twig_Node_Block) {
         $varName = $this->getVarName();
         $node->setNode('body', new Twig_Node_Body(array(new Twig_Profiler_Node_EnterProfile($this->extensionName, Twig_Profiler_Profile::BLOCK, $node->getAttribute('name'), $varName), $node->getNode('body'), new Twig_Profiler_Node_LeaveProfile($varName))));
     } elseif ($node instanceof Twig_Node_Macro) {
         $varName = $this->getVarName();
         $node->setNode('body', new Twig_Node_Body(array(new Twig_Profiler_Node_EnterProfile($this->extensionName, Twig_Profiler_Profile::MACRO, $node->getAttribute('name'), $varName), $node->getNode('body'), new Twig_Profiler_Node_LeaveProfile($varName))));
     }
     return $node;
 }
 private function loadNode(Node $node, $resource)
 {
     $assets = array();
     if ($node instanceof ExpressionFunction) {
         $name = $node->getAttribute('name');
         if ($name === $this->functionName) {
             $arguments = iterator_to_array($node->getNode('arguments'));
             if (!is_array($arguments)) {
                 throw new ResourceParsingException('arguments is not an array');
             }
             if (count($arguments) !== 1 && count($arguments) !== 2) {
                 throw new ResourceParsingException(sprintf('Expected exactly one or two arguments passed to function %s in %s at line %s', $this->functionName, $resource, $node->getLine()));
             }
             if (!$arguments[0] instanceof ConstantFunction) {
                 throw new ResourceParsingException(sprintf('Argument passed to function %s must be text node to parse without context. File %s, line %s', $this->functionName, $resource, $node->getLine()));
             }
             $assets[] = $arguments[0]->getAttribute('value');
             return $assets;
         }
     }
     foreach ($node as $child) {
         if ($child instanceof Node) {
             $assets = array_merge($assets, $this->loadNode($child, $resource));
         }
     }
     return $assets;
 }
 /**
  * Removes node filters.
  *
  * This is mostly needed when another visitor adds filters (like the escaper one).
  *
  * @param Twig_Node $node A Node
  */
 protected function removeNodeFilter($node)
 {
     if ($node instanceof Twig_Node_Expression_Filter) {
         return $this->removeNodeFilter($node->getNode('node'));
     }
     return $node;
 }
 protected function doLeaveNode(\Twig_Node $node, \Twig_Environment $env)
 {
     if ($node instanceof \Twig_Node_Include) {
         if ($node->hasNode('expr') && $node->getNode('expr')->hasAttribute('value')) {
             $patternStoreKey = $node->getNode('expr')->getAttribute('value');
             $data = $this->dt->getProcessedPatternSpecificData($patternStoreKey);
             if ($node instanceof \Twig_Node_Embed) {
                 $dataNode = new PatternDataEmbedNode($node, $data);
             } else {
                 $dataNode = new PatternDataIncludeNode($node, $data);
             }
             return $dataNode;
         }
     }
     return $node;
 }
Esempio n. 11
0
 /**
  * Called after child nodes are visited.
  *
  * @param Twig_Node        $node The node to visit
  * @param Twig_Environment $env  The Twig environment instance
  *
  * @return Twig_Node The modified node
  */
 public function leaveNode(Twig_Node $node, Twig_Environment $env)
 {
     if ($node instanceof Twig_Node_Module) {
         $this->inAModule = false;
         $node->setNode('display_start', new Twig_Node(array(new Twig_Node_CheckSecurity($this->filters, $this->tags, $this->functions), $node->getNode('display_start'))));
     }
     return $node;
 }
Esempio n. 12
0
File: For.php Progetto: dunglas/Twig
 private function checkLoopUsageBody(Twig_TokenStream $stream, Twig_Node $node)
 {
     if ($node instanceof Twig_Node_Expression_GetAttr && $node->getNode('node') instanceof Twig_Node_Expression_Name && 'loop' == $node->getNode('node')->getAttribute('name')) {
         $attribute = $node->getNode('attribute');
         if ($attribute instanceof Twig_Node_Expression_Constant && in_array($attribute->getAttribute('value'), array('length', 'revindex0', 'revindex', 'last'))) {
             throw new Twig_Error_Syntax(sprintf('The "loop.%s" variable is not defined when looping with a condition', $attribute->getAttribute('value')), $node->getLine(), $stream->getFilename());
         }
     }
     // should check for parent.loop.XXX usage
     if ($node instanceof Twig_Node_For) {
         return;
     }
     foreach ($node as $n) {
         if (!$n) {
             continue;
         }
         $this->checkLoopUsageBody($stream, $n);
     }
 }
Esempio n. 13
0
 /**
  * {@inheritdoc}
  */
 protected function doEnterNode(Twig_Node $node, Twig_Environment $env)
 {
     if ($node instanceof Twig_Node_Module) {
         if ($env->hasExtension('escaper') && ($defaultStrategy = $env->getExtension('escaper')->getDefaultStrategy($node->getAttribute('filename')))) {
             $this->defaultStrategy = $defaultStrategy;
         }
         $this->safeVars = array();
     } elseif ($node instanceof Twig_Node_AutoEscape) {
         $this->statusStack[] = $node->getAttribute('value');
     } elseif ($node instanceof Twig_Node_Block) {
         $this->statusStack[] = isset($this->blocks[$node->getAttribute('name')]) ? $this->blocks[$node->getAttribute('name')] : $this->needEscaping($env);
     } elseif ($node instanceof Twig_Node_Import) {
         $this->safeVars[] = $node->getNode('var')->getAttribute('name');
     }
     return $node;
 }
Esempio n. 14
0
 public function parse(\Twig_Token $token)
 {
     $lineno = $token->getLine();
     $expression = $this->parser->getExpressionParser()->parseExpression();
     $this->parser->getStream()->expect(\Twig_Token::BLOCK_END_TYPE);
     $this->parser->subparse(array($this, 'decideCaseFork'));
     $cases = new \Twig_Node();
     $default = null;
     $end = false;
     $i = 0;
     while (!$end) {
         switch ($tag = $this->parser->getStream()->next()->getValue()) {
             case 'case':
                 $i++;
                 $expr = $this->parser->getExpressionParser()->parseExpression();
                 $this->parser->getStream()->expect(\Twig_Token::BLOCK_END_TYPE);
                 $body = $this->parser->subparse(array($this, 'decideCaseFork'));
                 $cases->setNode($i, new \Twig_Node(array('expression' => $expr, 'body' => $body)));
                 break;
             case 'default':
                 $i = null;
                 $this->parser->getStream()->expect(\Twig_Token::BLOCK_END_TYPE);
                 $body = $this->parser->subparse(array($this, 'decideCaseFork'));
                 $default = $body;
                 break;
             case 'break':
                 $this->parser->getStream()->expect(\Twig_Token::BLOCK_END_TYPE);
                 $this->parser->subparse(array($this, 'decideCaseFork'));
                 if ($cases->hasNode($i)) {
                     $cases->getNode($i)->setAttribute('break', true);
                 }
                 break;
             case 'endswitch':
                 $end = true;
                 break;
             default:
                 throw new \Twig_Error_Syntax(sprintf('Unexpected end of template at line %d' . $tag, $lineno), -1);
         }
     }
     $this->parser->getStream()->expect(\Twig_Token::BLOCK_END_TYPE);
     return new SwitchNode($cases, $default, $expression, $lineno, $this->getTag());
 }
Esempio n. 15
0
 /**
  * Extracts formulae from filter function nodes.
  *
  * @return array|null The formula
  */
 private function checkNode(\Twig_Node $node, \Twig_Environment $env, &$name = null)
 {
     if ($node instanceof \Twig_Node_Expression_Function) {
         $name = $node->getAttribute('name');
         if ($env->getFunction($name) instanceof AsseticFilterFunction) {
             $arguments = array();
             foreach ($node->getNode('arguments') as $argument) {
                 $arguments[] = eval('return ' . $env->compile($argument) . ';');
             }
             $invoker = $env->getExtension('assetic')->getFilterInvoker($name);
             $factory = $invoker->getFactory();
             $inputs = isset($arguments[0]) ? (array) $arguments[0] : array();
             $filters = $invoker->getFilters();
             $options = array_replace($invoker->getOptions(), isset($arguments[1]) ? $arguments[1] : array());
             if (!isset($options['name'])) {
                 $options['name'] = $factory->generateAssetName($inputs, $filters);
             }
             return array($inputs, $filters, $options);
         }
     }
 }
 /**
  * {@inheritdoc}
  */
 protected function doLeaveNode(\Twig_Node $node, \Twig_Environment $env)
 {
     if ($node instanceof \Twig_Node_Module) {
         $this->filename = null;
     }
     if ($this->shouldProcess()) {
         if ($node instanceof \Twig_Node_Module) {
             if ($this->shouldBufferize) {
                 $node->setNode('body', new \Twig_Node(array(new Initialize($this->settings['defaultExecutionPriority']), $node->getNode('body'), new Terminate($this->settings['defaultExecutionPriority']))));
             }
             $this->shouldBufferize = false;
             $this->blocks = array();
         }
         if ($this->isBufferizingNode($node) || $node instanceof \Twig_Node_BlockReference && $this->hasBufferizingNode($this->blocks[$node->getAttribute('name')])) {
             return new \Twig_Node(array(new BufferBreakPoint($this->settings['defaultExecutionPriority']), $node, new BufferBreakPoint($this->settings['defaultExecutionPriority'], array(), array(BaseBufferNode::BUFFERIZED_EXECUTION_PRIORITY_ATTRIBUTE_NAME => $this->getNodeExecutionPriority($node)))));
         } elseif ($this->currentScope && $node instanceof \Twig_Node_Block && $this->hasBufferizingNode($node)) {
             $node->setNode('body', new \Twig_Node(array(new Initialize($this->settings['defaultExecutionPriority']), $node->getNode('body'), new Terminate($this->settings['defaultExecutionPriority']))));
             return $node;
         }
     }
     return $node;
 }
 /**
  * {@inheritdoc}
  */
 protected function doEnterNode(\Twig_Node $node, \Twig_Environment $env)
 {
     if ($node instanceof \Twig_Node_Block || $node instanceof \Twig_Node_Module) {
         $this->scope = $this->scope->enter();
     }
     if ($node instanceof TransDefaultDomainNode) {
         if ($node->getNode('expr') instanceof \Twig_Node_Expression_Constant) {
             $this->scope->set('domain', $node->getNode('expr'));
             return $node;
         } else {
             $var = $env->getParser()->getVarName();
             $name = new \Twig_Node_Expression_AssignName($var, $node->getLine());
             $this->scope->set('domain', new \Twig_Node_Expression_Name($var, $node->getLine()));
             return new \Twig_Node_Set(false, new \Twig_Node(array($name)), new \Twig_Node(array($node->getNode('expr'))), $node->getLine());
         }
     }
     if (!$this->scope->has('domain')) {
         return $node;
     }
     if ($node instanceof \Twig_Node_Expression_Filter && in_array($node->getNode('filter')->getAttribute('value'), array('trans', 'transchoice'))) {
         $arguments = $node->getNode('arguments');
         $ind = 'trans' === $node->getNode('filter')->getAttribute('value') ? 1 : 2;
         if ($this->isNamedArguments($arguments)) {
             if (!$arguments->hasNode('domain') && !$arguments->hasNode($ind)) {
                 $arguments->setNode('domain', $this->scope->get('domain'));
             }
         } else {
             if (!$arguments->hasNode($ind)) {
                 if (!$arguments->hasNode($ind - 1)) {
                     $arguments->setNode($ind - 1, new \Twig_Node_Expression_Array(array(), $node->getLine()));
                 }
                 $arguments->setNode($ind, $this->scope->get('domain'));
             }
         }
     } elseif ($node instanceof TransNode) {
         if (null === $node->getNode('domain')) {
             $node->setNode('domain', $this->scope->get('domain'));
         }
     }
     return $node;
 }
Esempio n. 18
0
 /**
  * @param \Twig_Node $node
  * @param $name
  * @return null|\Twig_Node
  */
 public function getNode(\Twig_Node $node, $name)
 {
     return $node->hasNode($name) ? $node->getNode($name) : null;
 }
    /**
     * Extract a domain from a \Twig_Node_Print
     * Return null if no trans filter
     *
     * @param \Twig_Node $node
     */
    private function _extractDomain(\Twig_Node $node)
    {
        // must be a filter node
        if(!$node instanceof \Twig_Node_Expression_Filter) {
            return null;
        }
        // is a trans filter
        if($node->getNode('filter')->getAttribute('value') == 'trans') {
            if($node->getNode('arguments')->hasNode(1)) {
                return $node->getNode('arguments')->getNode(1)->getAttribute('value');
            } else {
                return $this->defaultDomain;
            }
        }

        return $this->_extractDomain($node->getNode('node'));
    }
Esempio n. 20
0
 /**
  * Removes "raw" filters.
  *
  * @param Twig_Node        $node A Node
  * @param Twig_Environment $env  The current Twig environment
  *
  * @return Twig_Node
  */
 protected function optimizeRawFilter(Twig_Node $node, Twig_Environment $env)
 {
     if ($node instanceof Twig_Node_Expression_Filter && 'raw' == $node->getNode('filter')->getAttribute('value')) {
         return $node->getNode('node');
     }
     return $node;
 }
Esempio n. 21
0
 /**
  * Determines at compile time whether the generated URL will be safe.
  *
  * Saves the unneeded automatic escaping for performance reasons.
  *
  * The URL generation process percent encodes non-alphanumeric characters.
  * Thus, the only character within a URL that must be escaped in HTML is the
  * ampersand ("&") which separates query params. Thus we cannot mark
  * the generated URL as always safe, but only when we are sure there won't be
  * multiple query params. This is the case when there are none or only one
  * constant parameter given. For instance, we know beforehand this will not
  * need to be escaped:
  * - path('route')
  * - path('route', {'param': 'value'})
  * But the following may need to be escaped:
  * - path('route', var)
  * - path('route', {'param': ['val1', 'val2'] }) // a sub-array
  * - path('route', {'param1': 'value1', 'param2': 'value2'})
  * If param1 and param2 reference placeholders in the route, it would not
  * need to be escaped, but we don't know that in advance.
  *
  * @param \Twig_Node $args_node
  *   The arguments of the path/url functions.
  *
  * @return array
  *   An array with the contexts the URL is safe
  */
 public function isUrlGenerationSafe(\Twig_Node $args_node)
 {
     // Support named arguments.
     $parameter_node = $args_node->hasNode('parameters') ? $args_node->getNode('parameters') : ($args_node->hasNode(1) ? $args_node->getNode(1) : NULL);
     if (!isset($parameter_node) || $parameter_node instanceof \Twig_Node_Expression_Array && count($parameter_node) <= 2 && (!$parameter_node->hasNode(1) || $parameter_node->getNode(1) instanceof \Twig_Node_Expression_Constant)) {
         return array('html');
     }
     return array();
 }
Esempio n. 22
0
    public function getTests()
    {
        $tests = array();
        // #1 switch with one case, without break
        $expression = new \Twig_Node_Expression_Name('foo', 0);
        $default = null;
        $cases = new \Twig_Node();
        $cases->setNode(0, new \Twig_Node(array('expression' => new \Twig_Node_Expression_Constant(0, 0), 'body' => new \Twig_Node_Text('case 0', 0))));
        $node = new SwitchNode($cases, $default, $expression, 0);
        $tests[] = array($node, <<<EOF
switch ({$this->getVariableGetter('foo')}) {
    case 0:
        echo "case 0";
}
EOF
);
        // #2 switch with two cases, second with break
        $expression = new \Twig_Node_Expression_Name('foo', 0);
        $default = null;
        $cases = new \Twig_Node();
        $cases->setNode(0, new \Twig_Node(array('expression' => new \Twig_Node_Expression_Constant(0, 0), 'body' => new \Twig_Node_Text('case 0', 0))));
        $cases->setNode(1, new \Twig_Node(array('expression' => new \Twig_Node_Expression_Constant(1, 0), 'body' => new \Twig_Node_Text('case 1', 0))));
        $cases->getNode(1)->setAttribute('break', true);
        $node = new SwitchNode($cases, $default, $expression, 0);
        $tests[] = array($node, <<<EOF
switch ({$this->getVariableGetter('foo')}) {
    case 0:
        echo "case 0";
    case 1:
        echo "case 1";
        break;
}
EOF
);
        // #3 switch with two cases (second with break) and default
        $expression = new \Twig_Node_Expression_Name('foo', 0);
        $default = new \Twig_Node_Text('default case', 0);
        $cases = new \Twig_Node();
        $cases->setNode(0, new \Twig_Node(array('expression' => new \Twig_Node_Expression_Constant(0, 0), 'body' => new \Twig_Node_Text('case 0', 0))));
        $cases->setNode(1, new \Twig_Node(array('expression' => new \Twig_Node_Expression_Constant(1, 0), 'body' => new \Twig_Node_Text('case 1', 0))));
        $cases->getNode(1)->setAttribute('break', true);
        $node = new SwitchNode($cases, $default, $expression, 0);
        $tests[] = array($node, <<<EOF
switch ({$this->getVariableGetter('foo')}) {
    case 0:
        echo "case 0";
    case 1:
        echo "case 1";
        break;
    default:
        echo "default case";
}
EOF
);
        // #4 switch with two cases (first without body, second with break) and default
        $expression = new \Twig_Node_Expression_Name('foo', 0);
        $default = new \Twig_Node_Text('default case', 0);
        $cases = new \Twig_Node();
        $cases->setNode(0, new \Twig_Node(array('expression' => new \Twig_Node_Expression_Constant(0, 0), 'body' => new \Twig_Node())));
        $cases->setNode(1, new \Twig_Node(array('expression' => new \Twig_Node_Expression_Constant(1, 0), 'body' => new \Twig_Node_Text('case 1', 0))));
        $cases->getNode(1)->setAttribute('break', true);
        $node = new SwitchNode($cases, $default, $expression, 0);
        $tests[] = array($node, <<<EOF
switch ({$this->getVariableGetter('foo')}) {
    case 0:
    case 1:
        echo "case 1";
        break;
    default:
        echo "default case";
}
EOF
);
        return $tests;
    }