Passed
Push — master ( 6f63e3...ed99b4 )
by Nuno
01:52
created

AbstractExtension   A

Complexity

Total Complexity 8

Size/Duplication

Total Lines 74
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
wmc 8
dl 0
loc 74
ccs 0
cts 20
cp 0
rs 10
c 0
b 0
f 0

2 Methods

Rating   Name   Duplication   Size   Complexity  
B hasMethod() 0 22 6
A getMethod() 0 12 2
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\Extensions;
15
16
use Illuminate\Support\Facades\Facade;
17
use Mockery;
18
use PHPStan\Reflection\ClassReflection;
19
use PHPStan\Reflection\MethodReflection;
20
use PHPStan\Reflection\BrokerAwareExtension;
21
use PHPStan\Reflection\MethodsClassReflectionExtension;
22
23
/**
24
 * @internal
25
 */
26
abstract class AbstractExtension implements MethodsClassReflectionExtension, BrokerAwareExtension
27
{
28
    use Concerns\HasBroker;
29
30
    /**
31
     * Returns the class under analyse.
32
     *
33
     * @return string
34
     */
35
    abstract protected function subject(): string;
36
37
    /**
38
     * Returns the classes where the native method should be search for.
39
     *
40
     * @param \PHPStan\Reflection\ClassReflection $classReflection
41
     *
42
     * @return array
43
     */
44
    abstract protected function searchIn(ClassReflection $classReflection): array;
45
46
    /**
47
     * Whether the methods can be accessed statically
48
     */
49
    protected $staticAccess = false;
50
51
    /**
52
     * Holds already discovered methods.
53
     *
54
     * @var array
55
     */
56
    private $cache = [];
57
58
    /**
59
     * {@inheritdoc}
60
     */
61
    public function hasMethod(ClassReflection $classReflection, string $methodName): bool
62
    {
63
        $hasMethod = false;
64
65
        if ($classReflection->getName() === $this->subject() || $classReflection->isSubclassOf($this->subject())) {
66
            foreach ($this->searchIn($classReflection) as $toBeSearchClass) {
67
                $hasMethod = $this->broker->getClass($toBeSearchClass)
68
                    ->hasNativeMethod($methodName);
69
70
                if ($hasMethod) {
71
72
                    if (! array_key_exists($classReflection->getName(), $this->cache)) {
73
                        $this->cache[$classReflection->getName()] = [];
74
                    }
75
76
                    $this->cache[$classReflection->getName()][$methodName] = $toBeSearchClass;
77
                    break;
78
                }
79
            }
80
        }
81
82
        return $hasMethod;
83
    }
84
85
    /**
86
     * {@inheritdoc}
87
     */
88
    public function getMethod(ClassReflection $classReflection, string $methodName): MethodReflection
89
    {
90
        $methodReflection = $this->broker->getClass($this->cache[$classReflection->getName()][$methodName])
91
            ->getNativeMethod($methodName);
92
93
        if ($this->staticAccess) {
94
            $methodReflection = Mockery::mock($methodReflection);
95
            $methodReflection->shouldReceive('isStatic')
96
                ->andReturn(true);
97
        }
98
99
        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...
100
    }
101
}
102