Completed
Push — master ( e1173d...cdf0e4 )
by Oskar
05:16 queued 03:02
created

Analyze::run()   B

Complexity

Conditions 3
Paths 5

Size

Total Lines 80
Code Lines 47

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 47
c 1
b 0
f 0
nc 5
nop 1
dl 0
loc 80
rs 8.8387

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
namespace Hal\Application;
3
4
use Hal\Application\Config\Config;
5
use Hal\Component\Ast\NodeTraverser;
6
use Hal\Component\Issue\Issuer;
7
use Hal\Component\Output\Output;
8
use Hal\Component\Output\ProgressBar;
9
use Hal\Metric\Class_\ClassEnumVisitor;
10
use Hal\Metric\Class_\Complexity\CyclomaticComplexityVisitor;
11
use Hal\Metric\Class_\Complexity\KanDefectVisitor;
12
use Hal\Metric\Class_\Component\MaintainabilityIndexVisitor;
13
use Hal\Metric\Class_\Coupling\ExternalsVisitor;
14
use Hal\Metric\Class_\Structural\LcomVisitor;
15
use Hal\Metric\Class_\Structural\SystemComplexityVisitor;
16
use Hal\Metric\Class_\Text\HalsteadVisitor;
17
use Hal\Metric\Class_\Text\LengthVisitor;
18
use Hal\Metric\Metrics;
19
use Hal\Metric\Package\PackageAbstraction;
20
use Hal\Metric\Package\PackageCollectingVisitor;
21
use Hal\Metric\Package\PackageDependencies;
22
use Hal\Metric\Package\PackageDistance;
23
use Hal\Metric\Package\PackageInstability;
24
use Hal\Metric\System\Changes\GitChanges;
25
use Hal\Metric\System\Coupling\Coupling;
26
use Hal\Metric\System\Coupling\DepthOfInheritanceTree;
27
use Hal\Metric\System\Coupling\PageRank;
28
use Hal\Metric\System\Packages\Composer\Composer;
29
use Hal\Metric\System\UnitTesting\UnitTesting;
30
use PhpParser\Error;
31
use PhpParser\ParserFactory;
32
33
34
/**
35
 * Class Analyze
36
 * @package Hal\Application
37
 */
38
class Analyze
39
{
40
41
    /**
42
     * @var Output
43
     */
44
    private $output;
45
46
    /**
47
     * @var Config
48
     */
49
    private $config;
50
51
    /**
52
     * @var Issuer
53
     */
54
    private $issuer;
55
56
    /**
57
     * Analyze constructor.
58
     * @param Output $output
59
     */
60
    public function __construct(Config $config, Output $output, Issuer $issuer)
61
    {
62
        $this->output = $output;
63
        $this->config = $config;
64
        $this->issuer = $issuer;
65
    }
66
67
    /**
68
     * Runs analyze
69
     */
70
    public function run($files)
71
    {
72
        // config
73
        ini_set('xdebug.max_nesting_level', 3000);
74
75
        $metrics = new Metrics();
76
77
        // traverse all
78
        $whenToStop = function() {
79
            return true;
80
        };
81
82
        // prepare parser
83
        $parser = (new ParserFactory)->create(ParserFactory::PREFER_PHP7);
84
        $traverser = new NodeTraverser(false, $whenToStop);
85
        $traverser->addVisitor(new \PhpParser\NodeVisitor\NameResolver());
86
        $traverser->addVisitor(new ClassEnumVisitor($metrics));
87
        $traverser->addVisitor(new CyclomaticComplexityVisitor($metrics));
88
        $traverser->addVisitor(new ExternalsVisitor($metrics));
89
        $traverser->addVisitor(new LcomVisitor($metrics));
90
        $traverser->addVisitor(new HalsteadVisitor($metrics));
91
        $traverser->addVisitor(new LengthVisitor($metrics));
92
        $traverser->addVisitor(new CyclomaticComplexityVisitor($metrics));
93
        $traverser->addVisitor(new MaintainabilityIndexVisitor($metrics));
94
        $traverser->addVisitor(new KanDefectVisitor($metrics));
95
        $traverser->addVisitor(new SystemComplexityVisitor($metrics));
96
        $traverser->addVisitor(new PackageCollectingVisitor($metrics));
97
98
        // create a new progress bar (50 units)
99
        $progress = new ProgressBar($this->output, sizeof($files));
100
        $progress->start();
101
102
        foreach ($files as $file) {
103
            $progress->advance();
104
            $code = file_get_contents($file);
105
            $this->issuer->set('filename', $file);
106
            try {
107
                $stmts = $parser->parse($code);
108
                $this->issuer->set('statements', $stmts);
109
                $traverser->traverse($stmts);
0 ignored issues
show
Bug introduced by
It seems like $stmts defined by $parser->parse($code) on line 107 can also be of type null; however, PhpParser\NodeTraverser::traverse() does only seem to accept array<integer,object<PhpParser\Node>>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
110
            } catch (Error $e) {
111
                $this->output->writeln(sprintf('<error>Cannot parse %s</error>', $file));
112
            }
113
            $this->issuer->clear('filename');
114
            $this->issuer->clear('statements');
115
        }
116
117
        $progress->clear();
118
119
        $this->output->write('Executing system analyzes...');
120
121
        //
122
        // System analyses
123
        (new PageRank())->calculate($metrics);
124
        (new Coupling())->calculate($metrics);
125
        (new DepthOfInheritanceTree())->calculate($metrics);
126
127
        //
128
        // Package analyses
129
        (new PackageDependencies())->calculate($metrics);
130
        (new PackageAbstraction())->calculate($metrics);
131
        (new PackageInstability())->calculate($metrics);
132
        (new PackageDistance())->calculate($metrics);
133
134
        //
135
        // File analyses
136
        (new GitChanges($this->config, $files))->calculate($metrics);
137
138
        //
139
        // Unit test
140
        (new UnitTesting($this->config, $files))->calculate($metrics);
141
142
        //
143
        // Composer
144
        (new Composer($this->config, $files))->calculate($metrics);
145
146
        $this->output->clearln();
147
148
        return $metrics;
149
    }
150
}
151