FunctionAbstract   A
last analyzed

Complexity

Total Complexity 22

Size/Duplication

Total Lines 64
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 5

Importance

Changes 0
Metric Value
wmc 22
lcom 1
cbo 5
dl 0
loc 64
rs 10
c 0
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A returnDocBlockTypes() 0 12 2
A missingReturnType() 0 5 2
A missingReturnTypeWithDocBlock() 0 7 4
C returnTypeDoesNotCoincideWithDocBlock() 0 21 13
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Marcosh\PhpTypeChecker\Check;
6
7
use phpDocumentor\Reflection\Type;
8
use phpDocumentor\Reflection\Types\Array_;
9
use phpDocumentor\Reflection\Types\Mixed;
10
use phpDocumentor\Reflection\Types\Object_;
11
use phpDocumentor\Reflection\Types\Self_;
12
use Roave\BetterReflection\Reflection\ReflectionFunctionAbstract;
13
use Roave\BetterReflection\Reflection\ReflectionMethod;
14
use Roave\BetterReflection\Reflection\ReflectionType;
15
16
final class FunctionAbstract
17
{
18
    /**
19
     * @var ReflectionFunctionAbstract
20
     */
21
    private $function;
22
23
    public function __construct(ReflectionFunctionAbstract $function)
24
    {
25
        $this->function = $function;
26
    }
27
28
    /**
29
     * @return Type[]
30
     */
31
    private function returnDocBlockTypes(): array
32
    {
33
        $docBlockReturnTypes = [];
34
35
        try {
36
            $docBlockReturnTypes = $this->function->getDocBlockReturnTypes();
37
        } catch (\InvalidArgumentException $e) {
38
            // we need this here to prevent reflection-bocblock errors on @see invalid Fqsen
39
        }
40
41
        return $docBlockReturnTypes;
42
    }
43
44
    public function missingReturnType(): bool
45
    {
46
        return null === $this->function->getReturnType() &&
47
            empty($this->returnDocBlockTypes());
48
    }
49
50
    public function missingReturnTypeWithDocBlock(): bool
51
    {
52
        return null === $this->function->getReturnType() &&
53
            !empty($this->returnDocBlockTypes()) &&
54
            !$this->returnDocBlockTypes()[0] instanceof Mixed &&
55
            !$this->returnDocBlockTypes()[0] instanceof Object_;
56
    }
57
58
    public function returnTypeDoesNotCoincideWithDocBlock(): bool
59
    {
60
        $docBlockReturnTypes = $this->returnDocBlockTypes();
61
62
        return !empty($docBlockReturnTypes) &&
63
            $this->function->getReturnType() instanceof ReflectionType &&
64
            !in_array($this->function->getReturnType()->getTypeObject(), $docBlockReturnTypes, false) &&
65
            !($this->function->getReturnType()->getTypeObject() instanceof Array_ &&
66
                $docBlockReturnTypes[0] instanceof Array_
67
            ) &&
68
            !($this->function->getReturnType()->getTypeObject() instanceof Self_ &&
69
                $docBlockReturnTypes[0] instanceof Object_ &&
70
                $this->function instanceof  ReflectionMethod &&
71
                $this->function->getDeclaringClass()->getName() === ltrim((string) $docBlockReturnTypes[0]->getFqsen(), '\\')
72
            ) &&
73
            !($this->function->getReturnType()->getTypeObject() instanceof Object_ &&
74
                $docBlockReturnTypes[0] instanceof Self_ &&
75
                $this->function instanceof ReflectionMethod &&
76
                $this->function->getDeclaringClass()->getName() === ltrim((string) $this->function->getReturnType()->getTypeObject()->getFqsen(), '\\')
77
            );
78
    }
79
}
80