Test Failed
Push — master ( f235c1...2c36df )
by Nuno
01:49
created

AbstractExtension::subjectInstanceOf()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
nc 2
nop 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
/**
6
 * This file is part of Laravel Code Analyse.
7
 *
8
 * (c) Nuno Maduro <[email protected]>
9
 *
10
 *  For the full copyright and license information, please view the LICENSE
11
 *  file that was distributed with this source code.
12
 */
13
14
namespace NunoMaduro\LaravelCodeAnalyse;
15
16
use Mockery;
17
use PHPStan\Reflection\ClassReflection;
18
use PHPStan\Reflection\MethodReflection;
19
use PHPStan\Reflection\BrokerAwareExtension;
20
use PHPStan\Reflection\MethodsClassReflectionExtension;
21
22
/**
23
 * @internal
24
 */
25
abstract class AbstractExtension implements MethodsClassReflectionExtension, BrokerAwareExtension
26
{
27
    use Concerns\HasBroker;
28
29
    /**
30
     * Whether the methods can be accessed statically
31
     */
32
    protected $staticAccess = false;
33
34
    /**
35
     * Holds already discovered methods.
36
     *
37
     * @var array
38
     */
39
    private $cache = [];
40
41
    /**
42
     * {@inheritdoc}
43
     */
44
    public function hasMethod(ClassReflection $classReflection, string $methodName): bool
45
    {
46
        $hasMethod = false;
47
48
        if ($this->subjectInstanceOf($classReflection)) {
49
            foreach ($this->searchIn($classReflection) as $toBeSearchClass) {
50
                $hasMethod = $this->broker->getClass($toBeSearchClass)
51
                    ->hasNativeMethod($methodName);
52
53
                if ($hasMethod) {
54
                    $this->pushToCache($classReflection, $methodName, $toBeSearchClass);
55
                    break;
56
                }
57
            }
58
        }
59
60
        return $hasMethod;
61
    }
62
63
    /**
64
     * {@inheritdoc}
65
     */
66
    public function getMethod(ClassReflection $classReflection, string $methodName): MethodReflection
67
    {
68
        $methodReflection = $this->broker->getClass($this->cache[$classReflection->getName()][$methodName])
69
            ->getNativeMethod($methodName);
70
71
        if ($this->staticAccess) {
72
            $methodReflection = Mockery::mock($methodReflection);
73
            $methodReflection->shouldReceive('isStatic')
74
                ->andReturn(true);
75
        }
76
77
        return $methodReflection;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $methodReflection could return the type Mockery\MockInterface which is incompatible with the type-hinted return PHPStan\Reflection\MethodReflection. Consider adding an additional type-check to rule them out.
Loading history...
78
    }
79
80
    /**
81
     * @param \PHPStan\Reflection\ClassReflection $classReflection
82
     *
83
     * @return bool
84
     */
85
    protected function subjectInstanceOf(ClassReflection $classReflection): bool
86
    {
87
        return $classReflection->getName() === $this->subject() || $classReflection->isSubclassOf($this->subject());
88
    }
89
90
    /**
91
     * @param \PHPStan\Reflection\ClassReflection $classReflection
92
     * @param string $methodName
93
     * @param string $toBeSearchClass
94
     */
95
    protected function pushToCache(ClassReflection $classReflection, string $methodName, string $toBeSearchClass): void
96
    {
97
        if (! array_key_exists($classReflection->getName(), $this->cache)) {
98
            $this->cache[$classReflection->getName()] = [];
99
        }
100
101
        $this->cache[$classReflection->getName()][$methodName] = $toBeSearchClass;
102
    }
103
104
    /**
105
     * Returns the class under analyse.
106
     *
107
     * @return string
108
     */
109
    abstract protected function subject(): string;
110
111
    /**
112
     * Returns the classes where the native method should be search for.
113
     *
114
     * @param \PHPStan\Reflection\ClassReflection $classReflection
115
     *
116
     * @return array
117
     */
118
    abstract protected function searchIn(ClassReflection $classReflection): array;
119
}
120