Subversion-Projekte lars-tiefland.laravel_shop

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
148 lars 1
<?php declare(strict_types=1);
2
/*
3
 * This file is part of sebastian/complexity.
4
 *
5
 * (c) Sebastian Bergmann <sebastian@phpunit.de>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
namespace SebastianBergmann\Complexity;
11
 
12
use function assert;
13
use function is_array;
14
use PhpParser\Node;
15
use PhpParser\Node\Name;
16
use PhpParser\Node\Stmt;
17
use PhpParser\Node\Stmt\Class_;
18
use PhpParser\Node\Stmt\ClassMethod;
19
use PhpParser\Node\Stmt\Function_;
20
use PhpParser\Node\Stmt\Trait_;
21
use PhpParser\NodeTraverser;
22
use PhpParser\NodeVisitorAbstract;
23
 
24
final class ComplexityCalculatingVisitor extends NodeVisitorAbstract
25
{
26
    /**
27
     * @psalm-var list<Complexity>
28
     */
29
    private $result = [];
30
 
31
    /**
32
     * @var bool
33
     */
34
    private $shortCircuitTraversal;
35
 
36
    public function __construct(bool $shortCircuitTraversal)
37
    {
38
        $this->shortCircuitTraversal = $shortCircuitTraversal;
39
    }
40
 
41
    public function enterNode(Node $node): ?int
42
    {
43
        if (!$node instanceof ClassMethod && !$node instanceof Function_) {
44
            return null;
45
        }
46
 
47
        if ($node instanceof ClassMethod) {
48
            $name = $this->classMethodName($node);
49
        } else {
50
            $name = $this->functionName($node);
51
        }
52
 
53
        $statements = $node->getStmts();
54
 
55
        assert(is_array($statements));
56
 
57
        $this->result[] = new Complexity(
58
            $name,
59
            $this->cyclomaticComplexity($statements)
60
        );
61
 
62
        if ($this->shortCircuitTraversal) {
63
            return NodeTraverser::DONT_TRAVERSE_CHILDREN;
64
        }
65
 
66
        return null;
67
    }
68
 
69
    public function result(): ComplexityCollection
70
    {
71
        return ComplexityCollection::fromList(...$this->result);
72
    }
73
 
74
    /**
75
     * @param Stmt[] $statements
76
     */
77
    private function cyclomaticComplexity(array $statements): int
78
    {
79
        $traverser = new NodeTraverser;
80
 
81
        $cyclomaticComplexityCalculatingVisitor = new CyclomaticComplexityCalculatingVisitor;
82
 
83
        $traverser->addVisitor($cyclomaticComplexityCalculatingVisitor);
84
 
85
        /* @noinspection UnusedFunctionResultInspection */
86
        $traverser->traverse($statements);
87
 
88
        return $cyclomaticComplexityCalculatingVisitor->cyclomaticComplexity();
89
    }
90
 
91
    private function classMethodName(ClassMethod $node): string
92
    {
93
        $parent = $node->getAttribute('parent');
94
 
95
        assert($parent instanceof Class_ || $parent instanceof Trait_);
96
        assert(isset($parent->namespacedName));
97
        assert($parent->namespacedName instanceof Name);
98
 
99
        return $parent->namespacedName->toString() . '::' . $node->name->toString();
100
    }
101
 
102
    private function functionName(Function_ $node): string
103
    {
104
        assert(isset($node->namespacedName));
105
        assert($node->namespacedName instanceof Name);
106
 
107
        return $node->namespacedName->toString();
108
    }
109
}