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

voku / Simple-PHP-Code-Parser / 24286329431

11 Apr 2026 04:09PM UTC coverage: 82.898% (+0.01%) from 82.886%
24286329431

Pull #83

github

web-flow
Merge e95fe6f21 into 90e1e60d3
Pull Request #83: Fix CI pipeline: phpunit.xml validation warning, php-parser v4 test skip, and comprehensive type-analysis regression coverage

178 of 221 new or added lines in 7 files covered. (80.54%)

33 existing lines in 4 files now uncovered.

1682 of 2029 relevant lines covered (82.9%)

36.9 hits per line

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

93.88
/src/voku/SimplePhpParser/Model/PHPConst.php
1
<?php
2

3
declare(strict_types=1);
4

5
namespace voku\SimplePhpParser\Model;
6

7
use PhpParser\Node\Const_;
8
use PhpParser\Node\Name;
9
use PhpParser\Node\Stmt\ClassConst;
10
use PhpParser\Node\Stmt\Namespace_;
11
use PhpParser\NodeAbstract;
12
use ReflectionClassConstant;
13
use voku\SimplePhpParser\Parsers\Helper\Utils;
14

15
class PHPConst extends BasePHPElement
16
{
17
    use PHPDocElement;
18

19
    public ?string $parentName = null;
20

21
    /**
22
     * @var array|bool|float|int|string|null
23
     *
24
     * @phpstan-var scalar|array<scalar>|null
25
     */
26
    public $value;
27

28
    public ?string $visibility = null;
29

30
    public ?string $type = null;
31

32
    /**
33
     * Type from the constant's native type declaration (PHP 8.3+).
34
     */
35
    public ?string $typeFromDeclaration = null;
36

37
    /**
38
     * PHP 8.0+ attributes on this constant.
39
     *
40
     * @var PHPAttribute[]
41
     */
42
    public array $attributes = [];
43

44
    /**
45
     * @param Const_ $node
46
     * @param null   $dummy
47
     *
48
     * @return $this
49
     */
50
    public function readObjectFromPhpNode($node, $dummy = null): self
51
    {
52
        $this->prepareNode($node);
40✔
53

54
        $this->name = $this->getConstantFQN($node, $node->name->name);
40✔
55

56
        $this->value = Utils::getPhpParserValueFromNode($node);
40✔
57

58
        $parentNode = $node->getAttribute('parent');
40✔
59

60
        if ($parentNode instanceof ClassConst) {
40✔
61
            if ($parentNode->type !== null) {
40✔
62
                $this->type = Utils::typeNodeToString($parentNode->type);
6✔
63
            }
64

65
            if ($parentNode->isPrivate()) {
40✔
66
                $this->visibility = 'private';
9✔
67
            } elseif ($parentNode->isProtected()) {
40✔
68
                $this->visibility = 'protected';
7✔
69
            } else {
70
                $this->visibility = 'public';
40✔
71
            }
72

73
            $this->parentName = self::getFQN($parentNode->getAttribute('parent'));
40✔
74

75
            // Typed class constants (PHP 8.3+)
76
            if ($parentNode->type !== null) {
40✔
77
                $typeDeclStr = Utils::typeNodeToString($parentNode->type);
6✔
78
                if ($typeDeclStr !== null) {
6✔
79
                    $this->typeFromDeclaration = $typeDeclStr;
6✔
80
                }
81
            }
82

83
            // Extract PHP 8.0+ attributes (only if not already populated by reflection)
84
            if (empty($this->attributes) && !empty($parentNode->attrGroups)) {
40✔
85
                $this->attributes = Utils::extractAttributesFromAstNode($parentNode->attrGroups);
3✔
86
            }
87
        }
88

89
        if ($this->type === null) {
40✔
90
            $this->type = Utils::normalizePhpType(\gettype($this->value));
40✔
91
        }
92

93
        $this->collectTags($node);
40✔
94

95
        if ($node->getAttribute('parent') instanceof ClassConst) {
40✔
96
            $this->parentName = static::getFQN($node->getAttribute('parent')->getAttribute('parent'));
40✔
97
        }
98

99
        return $this;
40✔
100
    }
101

102
    /**
103
     * @param ReflectionClassConstant $constant
104
     *
105
     * @return $this
106
     */
107
    public function readObjectFromReflection($constant): self
108
    {
109
        $this->name = $constant->getName();
49✔
110

111
        $file = $constant->getDeclaringClass()->getFileName();
49✔
112
        if ($file) {
49✔
113
            $this->file = $file;
49✔
114
        }
115

116
        /** @psalm-suppress InvalidPropertyAssignmentValue - upstream phpdoc error ? */
117
        $this->value = $constant->getValue();
49✔
118

119
        $this->type = \gettype($this->value);
49✔
120

121
        if ($constant->isPrivate()) {
49✔
122
            $this->visibility = 'private';
9✔
123
        } elseif ($constant->isProtected()) {
49✔
124
            $this->visibility = 'protected';
3✔
125
        } else {
126
            $this->visibility = 'public';
49✔
127
        }
128

129
        // Typed class constants (PHP 8.3+)
130
        if (\method_exists($constant, 'getType')) {
49✔
UNCOV
131
            $reflType = $constant->getType();
×
UNCOV
132
            if ($reflType !== null) {
×
UNCOV
133
                $this->typeFromDeclaration = (string) $reflType;
×
134
            }
135
        }
136

137
        // Extract PHP 8.0+ attributes
138
        $this->attributes = Utils::extractAttributesFromReflection($constant);
49✔
139

140
        return $this;
49✔
141
    }
142

143
    protected function getConstantFQN(NodeAbstract $node, string $nodeName): string
144
    {
145
        $parent = $node->getAttribute('parent');
43✔
146
        $parentParentNode = $parent ? $parent->getAttribute('parent') : null;
43✔
147

148
        if (
149
            $parentParentNode instanceof Namespace_
43✔
150
            &&
151
            $parentParentNode->name instanceof Name
43✔
152
        ) {
153
            $namespace = '\\' . $parentParentNode->name->toString() . '\\';
12✔
154
        } else {
155
            $namespace = '';
43✔
156
        }
157

158
        return $namespace . $nodeName;
43✔
159
    }
160
}
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