Issues (52)

src/AnalyzeComments/Analyzer/Analyzer.php (1 issue)

Labels
Severity
1
<?php
2
3
declare(strict_types=1);
4
5
namespace SavinMikhail\CommentsDensity\AnalyzeComments\Analyzer;
6
7
use Psr\Cache\InvalidArgumentException;
8
use SavinMikhail\CommentsDensity\AnalyzeComments\Analyzer\DTO\Output\CommentDTO;
9
use SavinMikhail\CommentsDensity\AnalyzeComments\Analyzer\DTO\Output\CommentStatisticsDTO;
10
use SavinMikhail\CommentsDensity\AnalyzeComments\Analyzer\DTO\Output\Report;
11
use SavinMikhail\CommentsDensity\AnalyzeComments\Comments\CommentTypeFactory;
12
use SavinMikhail\CommentsDensity\AnalyzeComments\Config\DTO\Config;
13
use SavinMikhail\CommentsDensity\AnalyzeComments\Exception\CommentsDensityException;
14
use SavinMikhail\CommentsDensity\AnalyzeComments\File\CommentFinder;
15
use SavinMikhail\CommentsDensity\AnalyzeComments\File\FileContentExtractor;
16
use SavinMikhail\CommentsDensity\AnalyzeComments\File\FileFinder;
17
use SavinMikhail\CommentsDensity\AnalyzeComments\File\FileTotalLinesCounter;
18
use SavinMikhail\CommentsDensity\AnalyzeComments\Metrics\MetricsFacade;
19
use SavinMikhail\CommentsDensity\Baseline\Storage\BaselineStorageInterface;
20
use SplFileInfo;
21
use Symfony\Contracts\Cache\CacheInterface;
22
23
final readonly class Analyzer
0 ignored issues
show
A parse error occurred: Syntax error, unexpected T_READONLY, expecting T_CLASS on line 23 at column 6
Loading history...
24
{
25
    public function __construct(
26
        private Config $config,
27
        private CommentTypeFactory $commentFactory,
28
        private MetricsFacade $metrics,
29
        private BaselineStorageInterface $baselineStorage,
30
        private CacheInterface $cache,
31
        private CommentStatisticsAggregator $statisticsAggregator,
32
    ) {}
33
34
    /**
35
     * @throws CommentsDensityException
36
     * @throws InvalidArgumentException
37
     */
38
    public function analyze(): Report
39
    {
40
        $this->metrics->startPerformanceMonitoring();
41
        $comments = [];
42
        $filesAnalyzed = 0;
43
        $totalLinesOfCode = 0;
44
        $fileFinder = new FileFinder($this->config);
45
        foreach ($fileFinder() as $file) {
46
            $commentFinder = new CommentFinder(
47
                $this->commentFactory,
48
                $this->config,
49
            );
50
            $contentExtractor = new FileContentExtractor($file);
51
52
            $fileComments = $this->cache->get(
53
                $this->getCacheKey($file),
54
                static fn(): array => $commentFinder($contentExtractor->getContent(), $file->getRealPath()),
55
            );
56
57
            $lines = (new FileTotalLinesCounter($file))();
58
59
            $comments = [...$comments, ...$fileComments];
60
            $totalLinesOfCode += $lines;
61
            ++$filesAnalyzed;
62
        }
63
64
        if ($this->config->useBaseline) {
65
            $comments = $this->baselineStorage->filterComments($comments);
66
        }
67
68
        $commentStatistics = $this->statisticsAggregator->calculateCommentStatistics($comments);
69
        $report = $this->createReport($comments, $commentStatistics, $filesAnalyzed, $totalLinesOfCode);
70
71
        foreach ($this->config->plugins as $plugin) { // todo make it async
72
            $plugin->handle($report, $this->config);
73
        }
74
75
        return $report;
76
    }
77
78
    private function getCacheKey(SplFileInfo $file): string
79
    {
80
        $filePath = $file->getRealPath();
81
        $lastModified = filemtime($filePath);
82
83
        return md5($filePath . $lastModified);
84
    }
85
86
    private function checkThresholdsExceeded(): bool
87
    {
88
        if ($this->metrics->hasExceededThreshold()) {
89
            return true;
90
        }
91
        foreach ($this->commentFactory->getCommentTypes() as $commentType) {
92
            if ($commentType->hasExceededThreshold()) {
93
                return true;
94
            }
95
        }
96
97
        return false;
98
    }
99
100
    /**
101
     * @param CommentDTO[] $comments
102
     * @param CommentStatisticsDTO[] $preparedStatistics
103
     */
104
    private function createReport(
105
        array $comments,
106
        array $preparedStatistics,
107
        int $filesAnalyzed,
108
        int $totalLinesOfCode,
109
    ): Report {
110
        $comToLoc = $this->metrics->prepareComToLoc($preparedStatistics, $totalLinesOfCode);
111
        $cds = $this->metrics->prepareCDS($this->metrics->calculateCDS($preparedStatistics));
112
        $exceedThreshold = $this->checkThresholdsExceeded();
113
        $this->metrics->stopPerformanceMonitoring();
114
        $performanceMetrics = $this->metrics->getPerformanceMetrics();
115
116
        return new Report(
117
            $filesAnalyzed,
118
            $preparedStatistics,
119
            $comments,
120
            $performanceMetrics,
121
            $comToLoc,
122
            $cds,
123
            $exceedThreshold,
124
        );
125
    }
126
}
127