• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

nette / latte / 16317493748

16 Jul 2025 10:49AM UTC coverage: 93.696% (-0.002%) from 93.698%
16317493748

push

github

dg
PrintContent: refactoring and updated operator precedence and associativity table

23 of 23 new or added lines in 1 file covered. (100.0%)

30 existing lines in 15 files now uncovered.

5187 of 5536 relevant lines covered (93.7%)

0.94 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

96.61
/src/Latte/Essential/Nodes/DefineNode.php
1
<?php
2

3
/**
4
 * This file is part of the Latte (https://latte.nette.org)
5
 * Copyright (c) 2008 David Grudl (https://davidgrudl.com)
6
 */
7

8
declare(strict_types=1);
9

10
namespace Latte\Essential\Nodes;
11

12
use Latte\Compiler\Block;
13
use Latte\Compiler\Nodes\AreaNode;
14
use Latte\Compiler\Nodes\Php\Expression\AssignNode;
15
use Latte\Compiler\Nodes\Php\Expression\VariableNode;
16
use Latte\Compiler\Nodes\Php\ParameterNode;
17
use Latte\Compiler\Nodes\Php\Scalar;
18
use Latte\Compiler\Nodes\StatementNode;
19
use Latte\Compiler\PrintContext;
20
use Latte\Compiler\Tag;
21
use Latte\Compiler\TemplateParser;
22
use Latte\Compiler\Token;
23
use Latte\Helpers;
24
use Latte\Runtime\Template;
25
use function is_string;
26

27

28
/**
29
 * {define [local] name}
30
 */
31
class DefineNode extends StatementNode
32
{
33
        public Block $block;
34
        public AreaNode $content;
35

36

37
        /** @return \Generator<int, ?array, array{AreaNode, ?Tag}, static> */
38
        public static function create(Tag $tag, TemplateParser $parser): \Generator
1✔
39
        {
40
                $tag->expectArguments();
1✔
41
                $layer = $tag->parser->tryConsumeTokenBeforeUnquotedString('local')
1✔
42
                        ? Template::LayerLocal
1✔
43
                        : $parser->blockLayer;
1✔
44
                $tag->parser->stream->tryConsume('#');
1✔
45
                $name = $tag->parser->parseUnquotedStringOrExpression();
1✔
46

47
                $node = $tag->node = new static;
1✔
48
                $node->block = new Block($name, $layer, $tag);
1✔
49
                if (!$node->block->isDynamic()) {
1✔
50
                        $parser->checkBlockIsUnique($node->block);
1✔
51
                        $tag->parser->stream->tryConsume(',');
1✔
52
                        $node->block->parameters = self::parseParameters($tag);
1✔
53
                }
54

55
                [$node->content, $endTag] = yield;
1✔
56
                if ($endTag && $name instanceof Scalar\StringNode) {
1✔
57
                        $endTag->parser->stream->tryConsume($name->value);
1✔
58
                }
59

60
                return $node;
1✔
61
        }
62

63

64
        private static function parseParameters(Tag $tag): array
1✔
65
        {
66
                $stream = $tag->parser->stream;
1✔
67
                $params = [];
1✔
68
                while (!$stream->is(Token::End)) {
1✔
69
                        $type = $tag->parser->parseType();
1✔
70

71
                        $save = $stream->getIndex();
1✔
72
                        $expr = $stream->is(Token::Php_Variable) ? $tag->parser->parseExpression() : null;
1✔
73
                        if ($expr instanceof VariableNode && is_string($expr->name)) {
1✔
74
                                $params[] = new ParameterNode($expr, new Scalar\NullNode, $type);
1✔
75
                        } elseif (
76
                                $expr instanceof AssignNode
1✔
77
                                && $expr->var instanceof VariableNode
1✔
78
                                && is_string($expr->var->name)
1✔
79
                        ) {
80
                                $params[] = new ParameterNode($expr->var, $expr->expr, $type);
1✔
81
                        } else {
82
                                $stream->seek($save);
×
UNCOV
83
                                $stream->throwUnexpectedException(addendum: ' in ' . $tag->getNotation());
×
84
                        }
85

86
                        if (!$stream->tryConsume(',')) {
1✔
87
                                break;
1✔
88
                        }
89
                }
90

91
                return $params;
1✔
92
        }
93

94

95
        public function print(PrintContext $context): string
1✔
96
        {
97
                return $this->block->isDynamic()
1✔
98
                        ? $this->printDynamic($context)
1✔
99
                        : $this->printStatic($context);
1✔
100
        }
101

102

103
        private function printStatic(PrintContext $context): string
1✔
104
        {
105
                $context->addBlock($this->block);
1✔
106
                $this->block->content = $this->content->print($context); // must be compiled after is added
1✔
107
                return '';
1✔
108
        }
109

110

111
        private function printDynamic(PrintContext $context): string
1✔
112
        {
113
                $context->addBlock($this->block);
1✔
114
                $this->block->content = $this->content->print($context); // must be compiled after is added
1✔
115

116
                return $context->format(
1✔
117
                        '$this->addBlock(%raw, %dump, [[$this, %dump]], %dump);',
1✔
118
                        $context->ensureString($this->block->name, 'Block name'),
1✔
119
                        $context->getEscaper()->export(),
1✔
120
                        $this->block->method,
1✔
121
                        $this->block->layer,
1✔
122
                );
123
        }
124

125

126
        public function &getIterator(): \Generator
1✔
127
        {
128
                yield $this->block->name;
1✔
129
                foreach ($this->block->parameters as &$param) {
1✔
130
                        yield $param;
1✔
131
                }
132
                Helpers::removeNulls($this->block->parameters);
1✔
133

134
                yield $this->content;
1✔
135
        }
1✔
136
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc