GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — master ( e83674...a22227 )
by SignpostMarv
03:31
created

PropertyReflectionExtension   A

Complexity

Total Complexity 21

Size/Duplication

Total Lines 161
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
dl 0
loc 161
rs 10
c 0
b 0
f 0
wmc 21

11 Methods

Rating   Name   Duplication   Size   Complexity  
A isStatic() 0 3 1
C __construct() 0 37 7
A isReadable() 0 3 1
A isWritable() 0 3 1
A SetGetterProps() 0 17 3
A getDeclaringClass() 0 7 2
A DetermineDeclaringClass() 0 8 1
A isPrivate() 0 3 1
A isPublic() 0 3 1
A getType() 0 3 1
A SetSetterProps() 0 16 2
1
<?php
2
/**
3
* Base daft objects.
4
*
5
* @author SignpostMarv
6
*/
7
declare(strict_types=1);
8
9
namespace SignpostMarv\DaftObject\PHPStan;
10
11
use InvalidArgumentException;
12
use PHPStan\Broker\Broker;
13
use PHPStan\Reflection\ClassReflection;
14
use PHPStan\Reflection\PropertyReflection;
15
use PHPStan\Type\MixedType;
16
use PHPStan\Type\Type;
17
use PHPStan\Type\TypehintHelper;
18
use ReflectionMethod;
19
use SignpostMarv\DaftObject\DaftObject;
20
use SignpostMarv\DaftObject\DefinesOwnUntypedIdInterface;
21
22
class PropertyReflectionExtension implements PropertyReflection
23
{
24
    /**
25
    * @var Type
26
    */
27
    private $type;
28
29
    /**
30
    * @var Broker
31
    */
32
    private $broker;
33
34
    /**
35
    * @var bool
36
    */
37
    private $readable = false;
38
39
    /**
40
    * @var bool
41
    */
42
    private $writeable = false;
43
44
    /**
45
    * @var bool
46
    */
47
    private $public;
48
49
    /**
50
    * @var ClassReflection
51
    */
52
    private $readableDeclaringClass;
53
54
    /**
55
    * @var ClassReflection
56
    */
57
    private $writeableDeclaringClass;
58
59
    public function __construct(ClassReflection $classReflection, Broker $broker, string $property)
60
    {
61
        if (false === is_a($classReflection->getName(), DaftObject::class, true)) {
62
            throw new InvalidArgumentException(
63
                $classReflection->getName() .
64
                ' is not an implementation of ' .
65
                DaftObject::class
66
            );
67
        }
68
69
        $this->broker = $broker;
70
71
        $className = $classReflection->getName();
72
73
        $this->public =
74
            (is_a($className, DefinesOwnUntypedIdInterface::class, true) && 'id' === $property) ||
75
            in_array($property, $className::DaftObjectPublicGetters(), true) ||
76
            in_array($property, $className::DaftObjectPublicSetters(), true);
77
78
        $this->type = new MixedType();
79
80
        $getter = 'Get' . ucfirst($property);
81
        $setter = 'Set' . ucfirst($property);
82
83
        $this->readableDeclaringClass = $classReflection;
84
        $this->writeableDeclaringClass = $classReflection;
85
86
        if ($classReflection->getNativeReflection()->hasMethod($getter)) {
87
            $refMethod = new ReflectionMethod($className, $getter);
88
89
            $this->readableDeclaringClass = $this->SetGetterProps($refMethod);
90
        }
91
92
        if ($classReflection->getNativeReflection()->hasMethod($setter)) {
93
            $refMethod = new ReflectionMethod($className, $setter);
94
95
            $this->writeableDeclaringClass = $this->SetSetterProps($className, $refMethod);
96
        }
97
    }
98
99
    public function getType() : Type
100
    {
101
        return $this->type;
102
    }
103
104
    public function isReadable() : bool
105
    {
106
        return $this->readable;
107
    }
108
109
    public function isWritable() : bool
110
    {
111
        return $this->writeable;
112
    }
113
114
    public function isPublic() : bool
115
    {
116
        return $this->public;
117
    }
118
119
    public function isPrivate() : bool
120
    {
121
        return false === $this->isPublic();
122
    }
123
124
    public function isStatic() : bool
125
    {
126
        return false;
127
    }
128
129
    public function getDeclaringClass() : ClassReflection
130
    {
131
        if ($this->readable) {
132
            return $this->readableDeclaringClass;
133
        }
134
135
        return $this->writeableDeclaringClass;
136
    }
137
138
    private function SetGetterProps(ReflectionMethod $refMethod) : ClassReflection
139
    {
140
        $this->readable = true;
141
142
        if ($refMethod->isStatic()) {
143
            throw new InvalidArgumentException(
144
                'Implementations of ' .
145
                DaftObject::class .
146
                ' must not contain static getters.'
147
            );
148
        }
149
150
        if ($refMethod->hasReturnType()) {
151
            $this->type = TypehintHelper::decideTypeFromReflection($refMethod->getReturnType());
152
        }
153
154
        return static::DetermineDeclaringClass($this->broker, $refMethod);
155
    }
156
157
    private function SetSetterProps(string $class, ReflectionMethod $refMethod) : ClassReflection
158
    {
159
        $this->writeable = true;
160
161
        $refParam = $refMethod->getParameters()[0];
162
163
        if ($refParam->hasType()) {
164
            $this->type = TypehintHelper::decideTypeFromReflection(
165
                $refParam->getType(),
166
                null,
167
                $class,
168
                false
169
            );
170
        }
171
172
        return static::DetermineDeclaringClass($this->broker, $refMethod);
173
    }
174
175
    private static function DetermineDeclaringClass(
176
        Broker $broker,
177
        ReflectionMethod $refMethod
178
    ) : ClassReflection {
179
        return $broker->getClassFromReflection(
180
            $refMethod->getDeclaringClass(),
181
            $refMethod->getDeclaringClass()->getName(),
182
            $refMethod->getDeclaringClass()->isAnonymous()
183
        );
184
    }
185
}
186