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

nette / di / 6027138074

30 Aug 2023 03:26PM UTC coverage: 94.171% (-0.02%) from 94.186%
6027138074

push

github

dg
ParametersExtension: parameters containing expressions have static value '* unavailable value *'

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

2181 of 2316 relevant lines covered (94.17%)

0.94 hits per line

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

96.94
/src/DI/PhpGenerator.php
1
<?php
2

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

8
declare(strict_types=1);
9

10
namespace Nette\DI;
11

12
use Nette;
13
use Nette\DI\Definitions\Reference;
14
use Nette\DI\Definitions\Statement;
15
use Nette\PhpGenerator as Php;
16
use Nette\Utils\Strings;
17

18

19
/**
20
 * Container PHP code generator.
21
 */
22
class PhpGenerator
23
{
24
        use Nette\SmartObject;
25

26
        /** @var ContainerBuilder */
27
        private $builder;
28

29
        /** @var string */
30
        private $className;
31

32

33
        public function __construct(ContainerBuilder $builder)
1✔
34
        {
35
                $this->builder = $builder;
1✔
36
        }
1✔
37

38

39
        /**
40
         * Generates PHP classes. First class is the container.
41
         */
42
        public function generate(string $className): Php\ClassType
1✔
43
        {
44
                $this->className = $className;
1✔
45
                $class = new Php\ClassType($this->className);
1✔
46
                $class->setExtends(Container::class);
1✔
47
                $class->addMethod('__construct')
1✔
48
                        ->addBody('parent::__construct($params);')
1✔
49
                        ->addParameter('params', [])
1✔
50
                                ->setType('array');
1✔
51

52
                foreach ($this->builder->exportMeta() as $key => $value) {
1✔
53
                        $class->addProperty($key)
1✔
54
                                ->setProtected()
1✔
55
                                ->setValue($value);
1✔
56
                }
57

58
                $definitions = $this->builder->getDefinitions();
1✔
59
                ksort($definitions);
1✔
60

61
                foreach ($definitions as $def) {
1✔
62
                        $class->addMember($this->generateMethod($def));
1✔
63
                }
64

65
                $class->getMethod(Container::getMethodName(ContainerBuilder::ThisContainer))
1✔
66
                        ->setReturnType($className)
1✔
67
                        ->setBody('return $this;');
1✔
68

69
                $class->addMethod('initialize');
1✔
70

71
                return $class;
1✔
72
        }
73

74

75
        public function toString(Php\ClassType $class): string
1✔
76
        {
77
                return '/** @noinspection PhpParamsInspection,PhpMethodMayBeStaticInspection */
78

79
declare(strict_types=1);
80

81
' . $class->__toString();
1✔
82
        }
83

84

85
        public function addInitialization(Php\ClassType $class, CompilerExtension $extension): void
1✔
86
        {
87
                $closure = $extension->getInitialization();
1✔
88
                if ($closure->getBody()) {
1✔
89
                        $class->getMethod('initialize')
1✔
90
                                ->addBody('// ' . $extension->prefix(''))
1✔
91
                                ->addBody("($closure)();");
1✔
92
                }
93
        }
1✔
94

95

96
        public function generateMethod(Definitions\Definition $def): Php\Method
1✔
97
        {
98
                $name = $def->getName();
1✔
99
                try {
100
                        $method = new Php\Method(Container::getMethodName($name));
1✔
101
                        $method->setPublic();
1✔
102
                        $method->setReturnType($def->getType());
1✔
103
                        $def->generateMethod($method, $this);
1✔
104
                        return $method;
1✔
105

106
                } catch (\Throwable $e) {
×
107
                        throw new ServiceCreationException("Service '$name': " . $e->getMessage(), 0, $e);
×
108
                }
109
        }
110

111

112
        /**
113
         * Formats PHP code for class instantiating, function calling or property setting in PHP.
114
         */
115
        public function formatStatement(Statement $statement): string
1✔
116
        {
117
                $entity = $statement->getEntity();
1✔
118
                $arguments = $statement->arguments;
1✔
119

120
                switch (true) {
121
                        case is_string($entity) && Strings::contains($entity, '?'): // PHP literal
1✔
122
                                return $this->formatPhp($entity, $arguments);
1✔
123

124
                        case is_string($entity): // create class
1✔
125
                                return $arguments
1✔
126
                                        ? $this->formatPhp("new $entity(...?:)", [$arguments])
1✔
127
                                        : $this->formatPhp("new $entity", []);
1✔
128

129
                        case is_array($entity):
1✔
130
                                switch (true) {
131
                                        case $entity[1][0] === '$': // property getter, setter or appender
1✔
132
                                                $name = substr($entity[1], 1);
1✔
133
                                                if ($append = (substr($name, -2) === '[]')) {
1✔
134
                                                        $name = substr($name, 0, -2);
1✔
135
                                                }
136

137
                                                $prop = $entity[0] instanceof Reference
1✔
138
                                                        ? $this->formatPhp('?->?', [$entity[0], $name])
1✔
139
                                                        : $this->formatPhp('?::$?', [$entity[0], $name]);
1✔
140
                                                return $arguments
1✔
141
                                                        ? $this->formatPhp(($append ? '?[]' : '?') . ' = ?', [new Php\Literal($prop), $arguments[0]])
1✔
142
                                                        : $prop;
1✔
143

144
                                        case $entity[0] instanceof Statement:
1✔
145
                                                $inner = $this->formatPhp('?', [$entity[0]]);
1✔
146
                                                if (substr($inner, 0, 4) === 'new ') {
1✔
147
                                                        $inner = "($inner)";
1✔
148
                                                }
149

150
                                                return $this->formatPhp('?->?(...?:)', [new Php\Literal($inner), $entity[1], $arguments]);
1✔
151

152
                                        case $entity[0] instanceof Reference:
1✔
153
                                                return $this->formatPhp('?->?(...?:)', [$entity[0], $entity[1], $arguments]);
1✔
154

155
                                        case $entity[0] === '': // function call
1✔
156
                                                return $this->formatPhp('?(...?:)', [new Php\Literal($entity[1]), $arguments]);
1✔
157

158
                                        case is_string($entity[0]): // static method call
1✔
159
                                                return $this->formatPhp('?::?(...?:)', [new Php\Literal($entity[0]), $entity[1], $arguments]);
1✔
160
                                }
161
                }
162

163
                throw new Nette\InvalidStateException;
×
164
        }
165

166

167
        /**
168
         * Formats PHP statement.
169
         * @internal
170
         */
171
        public function formatPhp(string $statement, array $args): string
1✔
172
        {
173
                array_walk_recursive($args, function (&$val): void {
1✔
174
                        if ($val instanceof Statement) {
1✔
175
                                $val = new Php\Literal($this->formatStatement($val));
1✔
176

177
                        } elseif ($val instanceof Reference) {
1✔
178
                                $name = $val->getValue();
1✔
179
                                if ($val->isSelf()) {
1✔
180
                                        $val = new Php\Literal('$service');
1✔
181
                                } elseif ($name === ContainerBuilder::ThisContainer) {
1✔
182
                                        $val = new Php\Literal('$this');
1✔
183
                                } else {
184
                                        $val = ContainerBuilder::literal('$this->getService(?)', [$name]);
1✔
185
                                }
186
                        }
187
                });
1✔
188
                return (new Php\Dumper)->format($statement, ...$args);
1✔
189
        }
190

191

192
        /**
193
         * Converts parameters from Definition to PhpGenerator.
194
         * @return Php\Parameter[]
195
         */
196
        public function convertParameters(array $parameters): array
1✔
197
        {
198
                $res = [];
1✔
199
                foreach ($parameters as $k => $v) {
1✔
200
                        $tmp = explode(' ', is_int($k) ? $v : $k);
1✔
201
                        $param = $res[] = new Php\Parameter(end($tmp));
1✔
202
                        if (!is_int($k)) {
1✔
203
                                $param->setDefaultValue($v);
1✔
204
                        }
205

206
                        if (isset($tmp[1])) {
1✔
207
                                $param->setType($tmp[0]);
1✔
208
                        }
209
                }
210

211
                return $res;
1✔
212
        }
213

214

215
        public function getClassName(): ?string
216
        {
217
                return $this->className;
1✔
218
        }
219
}
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