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

nette / latte / 20711295966

05 Jan 2026 09:41AM UTC coverage: 94.752% (-0.09%) from 94.845%
20711295966

push

github

dg
added support for Partial Function Application WIP

172 of 179 new or added lines in 7 files covered. (96.09%)

29 existing lines in 8 files now uncovered.

5507 of 5812 relevant lines covered (94.75%)

0.95 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
        /**
65
         * @return ParameterNode[]
66
         */
67
        private static function parseParameters(Tag $tag): array
1✔
68
        {
69
                $stream = $tag->parser->stream;
1✔
70
                $params = [];
1✔
71
                while (!$stream->is(Token::End)) {
1✔
72
                        $type = $tag->parser->parseType();
1✔
73

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

89
                        if (!$stream->tryConsume(',')) {
1✔
90
                                break;
1✔
91
                        }
92
                }
93

94
                return $params;
1✔
95
        }
96

97

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

105

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

113

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

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

128

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

137
                yield $this->content;
1✔
138
        }
1✔
139
}
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