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

voku / Simple-PHP-Code-Parser / 5703591739

pending completion
5703591739

push

github

voku
Merge branch 'master' of ssh://github.com/voku/Simple-PHP-Code-Parser

* 'master' of ssh://github.com/voku/Simple-PHP-Code-Parser:
  Update actions/cache action to v3
  Apply fixes from StyleCI
  Update codecov/codecov-action action to v3
  Update shivammathur/setup-php action to v2.24.0
  Update actions/cache action to v2.1.8

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

1293 of 1572 relevant lines covered (82.25%)

20.24 hits per line

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

81.31
/src/voku/SimplePhpParser/Model/PHPProperty.php
1
<?php
2

3
declare(strict_types=1);
4

5
namespace voku\SimplePhpParser\Model;
6

7
use PhpParser\Comment\Doc;
8
use PhpParser\Node\Stmt\Property;
9
use ReflectionProperty;
10
use voku\SimplePhpParser\Parsers\Helper\Utils;
11

12
class PHPProperty extends BasePHPElement
13
{
14
    /**
15
     * @var mixed|null
16
     */
17
    public $defaultValue;
18

19
    /**
20
     * @var string|null
21
     */
22
    public $phpDocRaw;
23

24
    /**
25
     * @var string|null
26
     */
27
    public $type;
28

29
    /**
30
     * @var string|null
31
     */
32
    public $typeFromDefaultValue;
33

34
    /**
35
     * @var string|null
36
     */
37
    public $typeFromPhpDoc;
38

39
    /**
40
     * @var string|null
41
     */
42
    public $typeFromPhpDocSimple;
43

44
    /**
45
     * @var string|null
46
     */
47
    public $typeFromPhpDocExtended;
48

49
    /**
50
     * @var string|null
51
     */
52
    public $typeFromPhpDocMaybeWithComment;
53

54
    /**
55
     * @var string
56
     *
57
     * @phpstan-var ''|'private'|'protected'|'public'
58
     */
59
    public $access = '';
60

61
    /**
62
     * @var bool|null
63
     */
64
    public $is_static;
65

66
    /**
67
     * @var bool|null
68
     */
69
    public $is_inheritdoc;
70

71
    /**
72
     * @param Property    $node
73
     * @param string|null $classStr
74
     *
75
     * @phpstan-param class-string|null $classStr
76
     *
77
     * @return $this
78
     */
79
    public function readObjectFromPhpNode($node, $classStr = null): self
80
    {
81
        $this->name = $this->getConstantFQN($node, $node->props[0]->name->name);
28✔
82

83
        $this->is_static = $node->isStatic();
28✔
84

85
        $this->prepareNode($node);
28✔
86

87
        $docComment = $node->getDocComment();
28✔
88
        if ($docComment) {
28✔
89
            $docCommentText = $docComment->getText();
28✔
90

91
            if (\stripos($docCommentText, '@inheritdoc') !== false) {
28✔
92
                $this->is_inheritdoc = true;
×
93
            }
94

95
            $this->readPhpDoc($docComment);
28✔
96
        }
97

98
        if ($node->type !== null) {
28✔
99
            if (!$this->type) {
2✔
100
                if (empty($node->type->name)) {
×
101
                    if (!empty($node->type->parts)) {
×
102
                        $this->type = '\\' . \implode('\\', $node->type->parts);
×
103
                    }
104
                } else {
105
                    $this->type = $node->type->name;
×
106
                }
107
            }
108

109
            if ($node->type instanceof \PhpParser\Node\NullableType) {
2✔
110
                if ($this->type && $this->type !== 'null' && \strpos($this->type, 'null|') !== 0) {
2✔
111
                    $this->type = 'null|' . $this->type;
×
112
                } elseif (!$this->type) {
2✔
113
                    $this->type = 'null|mixed';
×
114
                }
115
            }
116
        }
117

118
        if ($node->props[0]->default !== null) {
28✔
119
            $defaultValue = Utils::getPhpParserValueFromNode($node->props[0]->default, $classStr);
19✔
120
            if ($defaultValue !== Utils::GET_PHP_PARSER_VALUE_FROM_NODE_HELPER) {
19✔
121
                $this->defaultValue = $defaultValue;
19✔
122

123
                $this->typeFromDefaultValue = Utils::normalizePhpType(\gettype($this->defaultValue));
19✔
124
            }
125
        }
126

127
        if ($node->isPrivate()) {
28✔
128
            $this->access = 'private';
×
129
        } elseif ($node->isProtected()) {
28✔
130
            $this->access = 'protected';
3✔
131
        } else {
132
            $this->access = 'public';
28✔
133
        }
134

135
        return $this;
28✔
136
    }
137

138
    /**
139
     * @param ReflectionProperty $property
140
     *
141
     * @return $this
142
     */
143
    public function readObjectFromReflection($property): self
144
    {
145
        $this->name = $property->getName();
35✔
146

147
        $file = $property->getDeclaringClass()->getFileName();
35✔
148
        if ($file) {
35✔
149
            $this->file = $file;
35✔
150
        }
151

152
        $this->is_static = $property->isStatic();
35✔
153

154
        if ($this->is_static) {
35✔
155
            try {
156
                if (\class_exists($property->getDeclaringClass()->getName(), true)) {
3✔
157
                    $this->defaultValue = $property->getValue();
3✔
158
                }
159
            } catch (\Exception $e) {
2✔
160
                // nothing
161
            }
162

163
            if ($this->defaultValue !== null) {
3✔
164
                $this->typeFromDefaultValue = Utils::normalizePhpType(\gettype($this->defaultValue));
1✔
165
            }
166
        }
167

168
        $docComment = $property->getDocComment();
35✔
169
        if ($docComment) {
35✔
170
            if (\stripos($docComment, '@inheritdoc') !== false) {
34✔
171
                $this->is_inheritdoc = true;
×
172
            }
173

174
            $this->readPhpDoc($docComment);
34✔
175
        }
176

177
        if (\method_exists($property, 'getType')) {
35✔
178
            $type = $property->getType();
35✔
179
            if ($type !== null) {
35✔
180
                if (\method_exists($type, 'getName')) {
3✔
181
                    $this->type = Utils::normalizePhpType($type->getName(), true);
3✔
182
                } else {
183
                    $this->type = Utils::normalizePhpType($type . '', true);
×
184
                }
185
                try {
186
                    if ($this->type && \class_exists($this->type, true)) {
3✔
187
                        $this->type = '\\' . \ltrim($this->type, '\\');
3✔
188
                    }
189
                } catch (\Exception $e) {
×
190
                    // nothing
191
                }
192

193
                if ($type->allowsNull()) {
3✔
194
                    if ($this->type && $this->type !== 'null' && \strpos($this->type, 'null|') !== 0) {
2✔
195
                        $this->type = 'null|' . $this->type;
2✔
196
                    } elseif (!$this->type) {
×
197
                        $this->type = 'null|mixed';
×
198
                    }
199
                }
200
            }
201
        }
202

203
        if ($property->isProtected()) {
35✔
204
            $access = 'protected';
11✔
205
        } elseif ($property->isPrivate()) {
32✔
206
            $access = 'private';
3✔
207
        } else {
208
            $access = 'public';
32✔
209
        }
210
        $this->access = $access;
35✔
211

212
        return $this;
35✔
213
    }
214

215
    /**
216
     * @return string|null
217
     */
218
    public function getType(): ?string
219
    {
220
        if ($this->typeFromPhpDocExtended) {
2✔
221
            return $this->typeFromPhpDocExtended;
2✔
222
        }
223

224
        if ($this->type) {
2✔
225
            return $this->type;
2✔
226
        }
227

228
        if ($this->typeFromPhpDocSimple) {
×
229
            return $this->typeFromPhpDocSimple;
×
230
        }
231

232
        return null;
×
233
    }
234

235
    /**
236
     * @param Doc|string $doc
237
     */
238
    private function readPhpDoc($doc): void
239
    {
240
        if ($doc instanceof Doc) {
34✔
241
            $docComment = $doc->getText();
28✔
242
        } else {
243
            $docComment = $doc;
34✔
244
        }
245
        if ($docComment === '') {
34✔
246
            return;
×
247
        }
248

249
        try {
250
            $phpDoc = Utils::createDocBlockInstance()->create($docComment);
34✔
251

252
            $parsedParamTags = $phpDoc->getTagsByName('var');
34✔
253

254
            if (!empty($parsedParamTags)) {
34✔
255
                foreach ($parsedParamTags as $parsedParamTag) {
34✔
256
                    if ($parsedParamTag instanceof \phpDocumentor\Reflection\DocBlock\Tags\Var_) {
34✔
257
                        $type = $parsedParamTag->getType();
34✔
258

259
                        $this->typeFromPhpDoc = Utils::normalizePhpType($type . '');
34✔
260

261
                        $typeFromPhpDocMaybeWithCommentTmp = \trim((string) $parsedParamTag);
34✔
262
                        if (
263
                            $typeFromPhpDocMaybeWithCommentTmp
34✔
264
                            &&
265
                            \strpos($typeFromPhpDocMaybeWithCommentTmp, '$') !== 0
34✔
266
                        ) {
267
                            $this->typeFromPhpDocMaybeWithComment = $typeFromPhpDocMaybeWithCommentTmp;
34✔
268
                        }
269

270
                        $typeTmp = Utils::parseDocTypeObject($type);
34✔
271
                        if ($typeTmp !== '') {
34✔
272
                            $this->typeFromPhpDocSimple = $typeTmp;
34✔
273
                        }
274
                    }
275

276
                    $this->phpDocRaw = (string) $parsedParamTag;
34✔
277
                    $this->typeFromPhpDocExtended = Utils::modernPhpdoc((string) $parsedParamTag);
34✔
278
                }
279
            }
280

281
            $parsedParamTags = $phpDoc->getTagsByName('psalm-var')
34✔
282
                               + $phpDoc->getTagsByName('phpstan-var');
34✔
283

284
            if (!empty($parsedParamTags)) {
34✔
285
                foreach ($parsedParamTags as $parsedParamTag) {
34✔
286
                    if ($parsedParamTag instanceof \phpDocumentor\Reflection\DocBlock\Tags\Generic) {
18✔
287
                        $spitedData = Utils::splitTypeAndVariable($parsedParamTag);
18✔
288
                        $parsedParamTagStr = $spitedData['parsedParamTagStr'];
18✔
289

290
                        $this->typeFromPhpDocExtended = Utils::modernPhpdoc($parsedParamTagStr);
18✔
291
                    }
292
                }
293
            }
294
        } catch (\Exception $e) {
×
295
            $tmpErrorMessage = $this->name . ':' . ($this->line ?? '?') . ' | ' . \print_r($e->getMessage(), true);
×
296

297
            // DEBUG
298
            //\var_dump($tmpErrorMessage, $e->getTraceAsString());
299

300
            $this->parseError[\md5($tmpErrorMessage)] = $tmpErrorMessage;
×
301
        }
302
    }
303
}
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