Completed
Push — master ( bdaaad...4f4372 )
by personal
06:57 queued 04:36
created

Analyze::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 4
nc 1
nop 3
dl 0
loc 6
rs 9.4285
c 0
b 0
f 0
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\Metric\Class_\ClassEnumVisitor;
8
use Hal\Metric\Class_\Complexity\CyclomaticComplexityVisitor;
9
use Hal\Metric\Class_\Complexity\KanDefectVisitor;
10
use Hal\Metric\Class_\Component\MaintainabilityIndexVisitor;
11
use Hal\Metric\Class_\Coupling\ExternalsVisitor;
12
use Hal\Metric\Class_\Structural\LcomVisitor;
13
use Hal\Metric\Class_\Structural\SystemComplexityVisitor;
14
use Hal\Metric\Class_\Text\HalsteadVisitor;
15
use Hal\Metric\Class_\Text\LengthVisitor;
16
use Hal\Metric\Metrics;
17
use Hal\Metric\System\Changes\GitChanges;
18
use Hal\Metric\System\Coupling\Coupling;
19
use Hal\Metric\System\Coupling\PageRank;
20
use Hal\Metric\System\UnitTesting\UnitTesting;
21
use PhpParser\Error;
22
use PhpParser\ParserFactory;
23
use Symfony\Component\Console\Helper\ProgressBar;
24
use Symfony\Component\Console\Output\OutputInterface;
25
26
27
/**
28
 * Class Analyze
29
 * @package Hal\Application
30
 */
31
class Analyze
32
{
33
34
    /**
35
     * @var OutputInterface
36
     */
37
    private $output;
38
39
    /**
40
     * @var Config
41
     */
42
    private $config;
43
44
    /**
45
     * @var Issuer
46
     */
47
    private $issuer;
48
49
    /**
50
     * Analyze constructor.
51
     * @param OutputInterface $output
52
     */
53
    public function __construct(Config $config, OutputInterface $output, Issuer $issuer)
54
    {
55
        $this->output = $output;
56
        $this->config = $config;
57
        $this->issuer = $issuer;
58
    }
59
60
    /**
61
     * Runs analyze
62
     */
63
    public function run($files)
64
    {
65
        // config
66
        ini_set('xdebug.max_nesting_level', 3000);
67
68
        $metrics = new Metrics();
69
70
        // traverse all
71
        $whenToStop = function() {
72
            return true;
73
        };
74
75
        // prepare parser
76
        $parser = (new ParserFactory)->create(ParserFactory::PREFER_PHP7);
77
        $traverser = new NodeTraverser(false, $whenToStop);
78
        $traverser->addVisitor(new \PhpParser\NodeVisitor\NameResolver());
79
        $traverser->addVisitor(new ClassEnumVisitor($metrics));
80
        $traverser->addVisitor(new CyclomaticComplexityVisitor($metrics));
81
        $traverser->addVisitor(new ExternalsVisitor($metrics));
82
        $traverser->addVisitor(new LcomVisitor($metrics));
83
        $traverser->addVisitor(new HalsteadVisitor($metrics));
84
        $traverser->addVisitor(new LengthVisitor($metrics));
85
        $traverser->addVisitor(new CyclomaticComplexityVisitor($metrics));
86
        $traverser->addVisitor(new MaintainabilityIndexVisitor($metrics));
87
        $traverser->addVisitor(new KanDefectVisitor($metrics));
88
        $traverser->addVisitor(new SystemComplexityVisitor($metrics));
89
90
        // create a new progress bar (50 units)
91
        $progress = new ProgressBar($this->output, sizeof($files));
92
        $this->output->setVerbosity(OutputInterface::VERBOSITY_VERBOSE);
93
        $progress->start();
94
95
        foreach ($files as $file) {
96
            $progress->advance();
97
            $code = file_get_contents($file);
98
            $this->issuer->set('filename', $file);
99
            try {
100
                $stmts = $parser->parse($code);
101
                $this->issuer->set('statements', $stmts);
102
                $traverser->traverse($stmts);
0 ignored issues
show
Bug introduced by
It seems like $stmts defined by $parser->parse($code) on line 100 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...
103
            } catch (Error $e) {
104
                $this->output->writeln(sprintf('<error>Cannot parse %s</error>', $file));
105
            }
106
            $this->issuer->clear('filename');
107
            $this->issuer->clear('statements');
108
        }
109
110
        //
111
        // System analyses
112
        (new PageRank())->calculate($metrics);
113
        (new Coupling())->calculate($metrics);
114
115
        //
116
        // File analyses
117
        (new GitChanges($this->config, $files))->calculate($metrics);
118
119
        //
120
        // Unit test
121
        (new UnitTesting($this->config, $files))->calculate($metrics);
122
123
        $progress->finish();
124
        $progress->clear();
125
126
        return $metrics;
127
    }
128
}
129