Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
29 / 29
100.00% covered (success)
100.00%
2 / 2
CRAP
100.00% covered (success)
100.00%
1 / 1
PropertyReflection
100.00% covered (success)
100.00%
29 / 29
100.00% covered (success)
100.00%
2 / 2
14
100.00% covered (success)
100.00%
1 / 1
 parse
100.00% covered (success)
100.00%
28 / 28
100.00% covered (success)
100.00%
1 / 1
12
 resolveType
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2declare(strict_types=1);
3/**
4 * Pop PHP Framework (https://www.popphp.org/)
5 *
6 * @link       https://github.com/popphp/popphp-framework
7 * @author     Nick Sagona, III <dev@noladev.com>
8 * @copyright  Copyright (c) 2009-2027 NOLA Interactive, LLC.
9 * @license    https://www.popphp.org/license     New BSD License
10 */
11
12/**
13 * @namespace
14 */
15namespace Pop\Code\Reflection;
16
17use Pop\Code\Generator;
18use Pop\Code\Reflection\Support\TypeNormalizer;
19use Pop\Code\Reflection\Support\AttributeCollector;
20
21/**
22 * Property reflection code class
23 *
24 * @category   Pop
25 * @package    Pop\Code
26 * @author     Nick Sagona, III <dev@noladev.com>
27 * @copyright  Copyright (c) 2009-2027 NOLA Interactive, LLC.
28 * @license    https://www.popphp.org/license     New BSD License
29 * @version    6.0.0
30 */
31class PropertyReflection extends AbstractReflection
32{
33
34    /**
35     * Method to parse a property
36     *
37     * @param  mixed   $code
38     * @param  ?string $name
39     * @param  mixed   $value
40     * @return Generator\PropertyGenerator
41     */
42    public static function parse(mixed $code, ?string $name = null, mixed $value = null): Generator\PropertyGenerator
43    {
44        if ($code->isProtected()) {
45            $visibility = 'protected';
46        } else if ($code->isPrivate()) {
47            $visibility = 'private';
48        } else {
49            $visibility = 'public';
50        }
51
52        $docblock = null;
53        $desc     = null;
54        $type     = self::resolveType($code);
55
56        $doc = $code->getDocComment();
57        if (($doc !== false) && (str_contains($doc, '/*'))) {
58            $docblock = DocblockReflection::parse($doc);
59            $docblock->setIndent(4);
60            $desc = $docblock->getDesc();
61            if ($type === null) {
62                $type = $docblock->getTag('var');
63            }
64        }
65
66        if (($type === null) && ($value !== null)) {
67            $type = TypeNormalizer::normalize(strtolower(gettype($value)));
68        }
69
70        if (is_array($value)) {
71            $formattedValue = (count($value) == 0) ? null : $value;
72        } else {
73            $formattedValue = $value;
74        }
75
76        $property = new Generator\PropertyGenerator($code->getName(), $type, $formattedValue, $visibility, $code->isStatic());
77        $property->setAsReadonly($code->isReadOnly());
78        if ($docblock !== null) {
79            $property->setDocblock($docblock);
80        }
81        $property->setDesc($desc);
82
83        foreach ($code->getAttributes() as $reflectionAttribute) {
84            $property->addAttribute(AttributeCollector::build($reflectionAttribute));
85        }
86
87        return $property;
88    }
89
90    /**
91     * Resolve a property's declared type (if any) into a bare, pipe-joined type-hint string
92     *
93     * @param  \ReflectionProperty $property
94     * @return string|null
95     */
96    protected static function resolveType(\ReflectionProperty $property): string|null
97    {
98        return $property->hasType() ? TypeNormalizer::resolveReflectionType($property->getType()) : null;
99    }
100
101}