Passed
Push — master ( c57dde...29e061 )
by Satoshi
02:16
created

CollectDependenciesVisitor::addUnknownDependency()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 2
nc 2
nop 3
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
declare(strict_types=1);
3
4
namespace DependencyAnalyzer\DependencyDumper;
5
6
use DependencyAnalyzer\DependencyGraph;
7
use DependencyAnalyzer\DependencyGraphBuilder;
8
use DependencyAnalyzer\Exceptions\ResolveDependencyException;
9
use PHPStan\Analyser\Scope;
10
use PHPStan\Reflection\ClassReflection;
11
use PHPStan\Reflection\Php\PhpFunctionReflection;
12
13
/**
14
 * @canOnlyUsedBy \DependencyAnalyzer\DependencyDumper
15
 */
16
class CollectDependenciesVisitor
17
{
18
    /**
19
     * @var DependencyResolver
20
     */
21
    protected $dependencyResolver;
22
23
    /**
24
     * @var DependencyGraphBuilder
25
     */
26
    protected $dependencyGraphBuilder;
27
28
    /**
29
     * @var ObserverInterface
30
     */
31
    protected $observer;
32
33
    /**
34
     * @var string
35
     */
36
    protected $file = null;
37
38
    public function __construct(DependencyResolver $dependencyResolver, DependencyGraphBuilder $dependencyGraphBuilder)
39
    {
40
        $this->dependencyResolver = $dependencyResolver;
41
        $this->dependencyGraphBuilder = $dependencyGraphBuilder;
42
    }
43
44
    public function setFile(string $file)
45
    {
46
        $this->file = $file;
47
    }
48
49
    public function setObserver(ObserverInterface $observer = null)
50
    {
51
        $this->observer = $observer;
52
    }
53
54
    public function __invoke(\PhpParser\Node $node, Scope $scope): void
55
    {
56
        try {
57
            foreach ($this->dependencyResolver->resolveDependencies($node, $scope) as $dependeeReflection) {
58
                if ($dependeeReflection instanceof ClassReflection) {
59
                    $this->addDependency($node, $scope, $dependeeReflection);
60
                } elseif ($dependeeReflection instanceof UnknownClassReflection) {
61
                    $this->addUnknownDependency($node, $scope, $dependeeReflection);
62
                } elseif ($dependeeReflection instanceof PhpFunctionReflection) {
63
                    // function call
64
                    // ex:
65
                    //   array_map(...);
66
                    //   var_dump(...);
67
                } else {
68
                    // error of DependencyResolver
69
                    throw new ResolveDependencyException($node, 'resolving node dependency is failed.');
70
                }
71
            }
72
        } catch (ResolveDependencyException $e) {
73
            if ($this->observer) {
74
                $this->observer->notifyResolveDependencyError($this->file, $e);
75
            }
76
        }
77
    }
78
79
    protected function addDependency(\PhpParser\Node $node, Scope $scope, ClassReflection $dependeeReflection): void
80
    {
81
        if ($scope->isInClass()) {
82
            if ($scope->getClassReflection()->getDisplayName() === $dependeeReflection->getDisplayName()) {
83
                // call same class method/property
84
            } else {
85
                $this->dependencyGraphBuilder->addDependency($scope->getClassReflection(), $dependeeReflection);
86
            }
87
        } else {
88
            // Maybe, class declare statement
89
            // ex:
90
            //   class Hoge {}
91
            //   abstract class Hoge {}
92
            //   interface Hoge {}
93
            if ($node instanceof \PhpParser\Node\Stmt\ClassLike) {
94
                $dependerReflection = $this->dependencyResolver->resolveClassReflection($node->namespacedName->toString());
95
                if ($dependerReflection instanceof ClassReflection) {
96
                    $this->dependencyGraphBuilder->addDependency($dependerReflection, $dependeeReflection);
97
                } else {
98
                    throw new ResolveDependencyException($node, 'resolving node dependency is failed, because unexpected node.');
99
                }
100
            }
101
        }
102
    }
103
104
    protected function addUnknownDependency(\PhpParser\Node $node, Scope $scope, UnknownClassReflection $classReflection)
0 ignored issues
show
Unused Code introduced by
The parameter $node is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

104
    protected function addUnknownDependency(/** @scrutinizer ignore-unused */ \PhpParser\Node $node, Scope $scope, UnknownClassReflection $classReflection)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
105
    {
106
        if ($scope->isInClass()) {
107
            $this->dependencyGraphBuilder->addUnknownDependency($scope->getClassReflection(), $classReflection->getDisplayName());
108
        }
109
    }
110
111
    public function createDependencyGraph(): DependencyGraph
112
    {
113
        return $this->dependencyGraphBuilder->build();
114
    }
115
}
116