subparse example

final class ForTokenParser extends AbstractTokenParser
{
    public function parse(Token $token): Node
    {
        $lineno = $token->getLine();
        $stream = $this->parser->getStream();
        $targets = $this->parser->getExpressionParser()->parseAssignmentExpression();
        $stream->expect(/* Token::OPERATOR_TYPE */ 8, 'in');
        $seq = $this->parser->getExpressionParser()->parseExpression();

        $stream->expect(/* Token::BLOCK_END_TYPE */ 3);
        $body = $this->parser->subparse([$this, 'decideForFork']);
        if ('else' == $stream->next()->getValue()) {
            $stream->expect(/* Token::BLOCK_END_TYPE */ 3);
            $else = $this->parser->subparse([$this, 'decideForEnd'], true);
        } else {
            $else = null;
        }
        $stream->expect(/* Token::BLOCK_END_TYPE */ 3);

        if (\count($targets) > 1) {
            $keyTarget = $targets->getNode(0);
            $keyTarget = new AssignNameExpression($keyTarget->getAttribute('name')$keyTarget->getTemplateLine());
            
if ($stream->test('into')) {
                // {% trans into "fr" %}                 $stream->next();
                $locale = $this->parser->getExpressionParser()->parseExpression();
            } elseif (!$stream->test(Token::BLOCK_END_TYPE)) {
                throw new SyntaxError('Unexpected token. Twig was looking for the "with", "from", or "into" keyword.', $stream->getCurrent()->getLine()$stream->getSourceContext());
            }
        }

        // {% trans %}message{% endtrans %}         $stream->expect(Token::BLOCK_END_TYPE);
        $body = $this->parser->subparse($this->decideTransFork(...), true);

        if (!$body instanceof TextNode && !$body instanceof AbstractExpression) {
            throw new SyntaxError('A message inside a trans tag must be a simple text.', $body->getTemplateLine()$stream->getSourceContext());
        }

        $stream->expect(Token::BLOCK_END_TYPE);

        return new TransNode($body$domain$count$vars$locale$lineno$this->getTag());
    }

    public function decideTransFork(Token $token): bool
    {
public function parse(Token $token): Node
    {
        $lineno = $token->getLine();
        $stream = $this->parser->getStream();

        // {% stopwatch 'bar' %}         $name = $this->parser->getExpressionParser()->parseExpression();

        $stream->expect(Token::BLOCK_END_TYPE);

        // {% endstopwatch %}         $body = $this->parser->subparse($this->decideStopwatchEnd(...), true);
        $stream->expect(Token::BLOCK_END_TYPE);

        if ($this->stopwatchIsAvailable) {
            return new StopwatchNode($name$bodynew AssignNameExpression($this->parser->getVarName()$token->getLine())$lineno$this->getTag());
        }

        return $body;
    }

    public function decideStopwatchEnd(Token $token): bool
    {
        

        $stream = $this->parser->getStream();

        // Parse the string field inside         $flagToken = $stream->expect(Token::STRING_TYPE);
        $flagName = $flagToken->getValue();

        // The feature flag is followed by an endblock token, remove it from the stream         $stream->next();

        // Parse the body of the tag inside         $body = $this->parser->subparse($this->decideBlockEnd(...), true);

        // We read until the string of the end of the block. But we need to parse the end tag as well, so the parser is on clean state again.         $stream->next();

        return new FeatureCallSilentToken($flagName$body$flagToken->getLine()$this->getTag());
    }

    public function getTag(): string
    {
        return 'sw_silent_feature_call';
    }

    
$stream = $this->parser->getStream();

        $variables = null;
        $only = false;
        if (!$stream->test(/* Token::BLOCK_END_TYPE */ 3)) {
            $variables = $this->parser->getExpressionParser()->parseExpression();
            $only = (bool) $stream->nextIf(/* Token::NAME_TYPE */ 5, 'only');
        }

        $stream->expect(/* Token::BLOCK_END_TYPE */ 3);

        $body = $this->parser->subparse([$this, 'decideWithEnd'], true);

        $stream->expect(/* Token::BLOCK_END_TYPE */ 3);

        return new WithNode($body$variables$only$token->getLine()$this->getTag());
    }

    public function decideWithEnd(Token $token): bool
    {
        return $token->test('endwith');
    }

    

    public function parse(Token $token): Node
    {
        $lineno = $token->getLine();
        $stream = $this->parser->getStream();
        $name = $stream->expect(/* Token::NAME_TYPE */ 5)->getValue();

        $arguments = $this->parser->getExpressionParser()->parseArguments(true, true);

        $stream->expect(/* Token::BLOCK_END_TYPE */ 3);
        $this->parser->pushLocalScope();
        $body = $this->parser->subparse([$this, 'decideBlockEnd'], true);
        if ($token = $stream->nextIf(/* Token::NAME_TYPE */ 5)) {
            $value = $token->getValue();

            if ($value != $name) {
                throw new SyntaxError(sprintf('Expected endmacro for macro "%s" (but "%s" given).', $name$value)$stream->getCurrent()->getLine()$stream->getSourceContext());
            }
        }
        $this->parser->popLocalScope();
        $stream->expect(/* Token::BLOCK_END_TYPE */ 3);

        $this->parser->setMacro($namenew MacroNode($namenew BodyNode([$body])$arguments$lineno$this->getTag()));

        
$lineno = $token->getLine();
        $stream = $this->parser->getStream();
        $name = $stream->expect(/* Token::NAME_TYPE */ 5)->getValue();
        if ($this->parser->hasBlock($name)) {
            throw new SyntaxError(sprintf("The block '%s' has already been defined line %d.", $name$this->parser->getBlock($name)->getTemplateLine())$stream->getCurrent()->getLine()$stream->getSourceContext());
        }
        $this->parser->setBlock($name$block = new BlockNode($namenew Node([])$lineno));
        $this->parser->pushLocalScope();
        $this->parser->pushBlockStack($name);

        if ($stream->nextIf(/* Token::BLOCK_END_TYPE */ 3)) {
            $body = $this->parser->subparse([$this, 'decideBlockEnd'], true);
            if ($token = $stream->nextIf(/* Token::NAME_TYPE */ 5)) {
                $value = $token->getValue();

                if ($value != $name) {
                    throw new SyntaxError(sprintf('Expected endblock for block "%s" (but "%s" given).', $name$value)$stream->getCurrent()->getLine()$stream->getSourceContext());
                }
            }
        } else {
            $body = new Node([
                new PrintNode($this->parser->getExpressionParser()->parseExpression()$lineno),
            ]);
        }
$plural = NULL;

    if (!$stream->test(Token::BLOCK_END_TYPE) && $stream->test(Token::STRING_TYPE)) {
      $body = $this->parser->getExpressionParser()->parseExpression();
    }
    if (!$stream->test(Token::BLOCK_END_TYPE) && $stream->test(Token::NAME_TYPE, 'with')) {
      $stream->next();
      $options = $this->parser->getExpressionParser()->parseExpression();
    }
    if (!$body) {
      $stream->expect(Token::BLOCK_END_TYPE);
      $body = $this->parser->subparse([$this, 'decideForFork']);
      if ('plural' === $stream->next()->getValue()) {
        $count = $this->parser->getExpressionParser()->parseExpression();
        $stream->expect(Token::BLOCK_END_TYPE);
        $plural = $this->parser->subparse([$this, 'decideForEnd'], TRUE);
      }
    }

    $stream->expect(Token::BLOCK_END_TYPE);

    $this->checkTransString($body$lineno);

    
if ($stream->test(/* Token::BLOCK_END_TYPE */ 3)) {
            $value = 'html';
        } else {
            $expr = $this->parser->getExpressionParser()->parseExpression();
            if (!$expr instanceof ConstantExpression) {
                throw new SyntaxError('An escaping strategy must be a string or false.', $stream->getCurrent()->getLine()$stream->getSourceContext());
            }
            $value = $expr->getAttribute('value');
        }

        $stream->expect(/* Token::BLOCK_END_TYPE */ 3);
        $body = $this->parser->subparse([$this, 'decideBlockEnd'], true);
        $stream->expect(/* Token::BLOCK_END_TYPE */ 3);

        return new AutoEscapeNode($value$body$lineno$this->getTag());
    }

    public function decideBlockEnd(Token $token): bool
    {
        return $token->test('endautoescape');
    }

    public function getTag(): string
    {

final class IfTokenParser extends AbstractTokenParser
{
    public function parse(Token $token): Node
    {
        $lineno = $token->getLine();
        $expr = $this->parser->getExpressionParser()->parseExpression();
        $stream = $this->parser->getStream();
        $stream->expect(/* Token::BLOCK_END_TYPE */ 3);
        $body = $this->parser->subparse([$this, 'decideIfFork']);
        $tests = [$expr$body];
        $else = null;

        $end = false;
        while (!$end) {
            switch ($stream->next()->getValue()) {
                case 'else':
                    $stream->expect(/* Token::BLOCK_END_TYPE */ 3);
                    $else = $this->parser->subparse([$this, 'decideIfEnd']);
                    break;

                
throw new SyntaxError('When using set, you must have the same number of variables and assignments.', $stream->getCurrent()->getLine()$stream->getSourceContext());
            }
        } else {
            $capture = true;

            if (\count($names) > 1) {
                throw new SyntaxError('When using set with a block, you cannot have a multi-target.', $stream->getCurrent()->getLine()$stream->getSourceContext());
            }

            $stream->expect(/* Token::BLOCK_END_TYPE */ 3);

            $values = $this->parser->subparse([$this, 'decideBlockEnd'], true);
            $stream->expect(/* Token::BLOCK_END_TYPE */ 3);
        }

        return new SetNode($capture$names$values$lineno$this->getTag());
    }

    public function decideBlockEnd(Token $token): bool
    {
        return $token->test('endset');
    }

    

final class SandboxTokenParser extends AbstractTokenParser
{
    public function parse(Token $token): Node
    {
        $stream = $this->parser->getStream();
        $stream->expect(/* Token::BLOCK_END_TYPE */ 3);
        $body = $this->parser->subparse([$this, 'decideBlockEnd'], true);
        $stream->expect(/* Token::BLOCK_END_TYPE */ 3);

        // in a sandbox tag, only include tags are allowed         if (!$body instanceof IncludeNode) {
            foreach ($body as $node) {
                if ($node instanceof TextNode && ctype_space($node->getAttribute('data'))) {
                    continue;
                }

                if (!$node instanceof IncludeNode) {
                    throw new SyntaxError('Only "include" tags are allowed within a "sandbox" section.', $node->getTemplateLine()$stream->getSourceContext());
                }
$this->stream = $stream;
        $this->parent = null;
        $this->blocks = [];
        $this->macros = [];
        $this->traits = [];
        $this->blockStack = [];
        $this->importedSymbols = [[]];
        $this->embeddedTemplates = [];

        try {
            $body = $this->subparse($test$dropNeedle);

            if (null !== $this->parent && null === $body = $this->filterBodyNodes($body)) {
                $body = new Node();
            }
        } catch (SyntaxError $e) {
            if (!$e->getSourceContext()) {
                $e->setSourceContext($this->stream->getSourceContext());
            }

            if (!$e->getTemplateLine()) {
                $e->setTemplateLine($this->stream->getCurrent()->getLine());
            }
public function parse(Token $token): Node
    {
        $lineno = $token->getLine();
        $name = $this->parser->getVarName();

        $ref = new TempNameExpression($name$lineno);
        $ref->setAttribute('always_defined', true);

        $filter = $this->parser->getExpressionParser()->parseFilterExpressionRaw($ref$this->getTag());

        $this->parser->getStream()->expect(Token::BLOCK_END_TYPE);
        $body = $this->parser->subparse([$this, 'decideApplyEnd'], true);
        $this->parser->getStream()->expect(Token::BLOCK_END_TYPE);

        return new Node([
            new SetNode(true, $ref$body$lineno$this->getTag()),
            new PrintNode($filter$lineno$this->getTag()),
        ]);
    }

    public function decideApplyEnd(Token $token): bool
    {
        return $token->test('endapply');
    }
Home | Imprint | This part of the site doesn't use cookies.