diff --git a/src/Analyser/Analyser.php b/src/Analyser/Analyser.php index 4ab99fc5d3..31599aaee4 100644 --- a/src/Analyser/Analyser.php +++ b/src/Analyser/Analyser.php @@ -12,6 +12,9 @@ use function count; use function memory_get_peak_usage; +/** + * @phpstan-import-type CollectorData from CollectedData + */ final class Analyser { @@ -59,7 +62,7 @@ public function analyse( $linesToIgnore = []; $unmatchedLineIgnores = []; - /** @var list $collectedData */ + /** @var CollectorData $collectedData */ $collectedData = []; $internalErrorsCount = 0; diff --git a/src/Analyser/AnalyserResult.php b/src/Analyser/AnalyserResult.php index 212fdcf422..4226e76fbd 100644 --- a/src/Analyser/AnalyserResult.php +++ b/src/Analyser/AnalyserResult.php @@ -8,6 +8,7 @@ /** * @phpstan-import-type LinesToIgnore from FileAnalyserResult + * @phpstan-import-type CollectorData from CollectedData */ final class AnalyserResult { @@ -22,7 +23,7 @@ final class AnalyserResult * @param list $locallyIgnoredErrors * @param array $linesToIgnore * @param array $unmatchedLineIgnores - * @param list $collectedData + * @param CollectorData $collectedData * @param list $internalErrors * @param array>|null $dependencies * @param array> $exportedNodes @@ -125,7 +126,7 @@ public function getInternalErrors(): array } /** - * @return list + * @return CollectorData */ public function getCollectedData(): array { diff --git a/src/Analyser/FileAnalyser.php b/src/Analyser/FileAnalyser.php index 969154c3c8..80724ea18a 100644 --- a/src/Analyser/FileAnalyser.php +++ b/src/Analyser/FileAnalyser.php @@ -37,6 +37,9 @@ use const E_USER_WARNING; use const E_WARNING; +/** + * @phpstan-import-type CollectorData from CollectedData + */ final class FileAnalyser { @@ -76,7 +79,7 @@ public function analyseFile( /** @var list $locallyIgnoredErrors */ $locallyIgnoredErrors = []; - /** @var list $fileCollectedData */ + /** @var CollectorData $fileCollectedData */ $fileCollectedData = []; $fileDependencies = []; @@ -195,11 +198,7 @@ public function analyseFile( continue; } - $fileCollectedData[] = new CollectedData( - $collectedData, - $scope->getFile(), - get_class($collector), - ); + $fileCollectedData[$scope->getFile()][get_class($collector)][] = $collectedData; } try { diff --git a/src/Analyser/FileAnalyserResult.php b/src/Analyser/FileAnalyserResult.php index d1727f5824..2aba60730f 100644 --- a/src/Analyser/FileAnalyserResult.php +++ b/src/Analyser/FileAnalyserResult.php @@ -7,6 +7,7 @@ /** * @phpstan-type LinesToIgnore = array|null>> + * @phpstan-import-type CollectorData from CollectedData */ final class FileAnalyserResult { @@ -16,7 +17,7 @@ final class FileAnalyserResult * @param list $filteredPhpErrors * @param list $allPhpErrors * @param list $locallyIgnoredErrors - * @param list $collectedData + * @param CollectorData $collectedData * @param list $dependencies * @param list $exportedNodes * @param LinesToIgnore $linesToIgnore @@ -69,7 +70,7 @@ public function getLocallyIgnoredErrors(): array } /** - * @return list + * @return CollectorData */ public function getCollectedData(): array { diff --git a/src/Analyser/ResultCache/ResultCache.php b/src/Analyser/ResultCache/ResultCache.php index f409f9c062..1708a1f53b 100644 --- a/src/Analyser/ResultCache/ResultCache.php +++ b/src/Analyser/ResultCache/ResultCache.php @@ -9,6 +9,7 @@ /** * @phpstan-import-type LinesToIgnore from FileAnalyserResult + * @phpstan-import-type CollectorData from CollectedData */ final class ResultCache { @@ -20,7 +21,7 @@ final class ResultCache * @param array> $locallyIgnoredErrors * @param array $linesToIgnore * @param array $unmatchedLineIgnores - * @param array> $collectedData + * @param CollectorData $collectedData * @param array> $dependencies * @param array> $exportedNodes * @param array $projectExtensionFiles @@ -101,7 +102,7 @@ public function getUnmatchedLineIgnores(): array } /** - * @return array> + * @return CollectorData */ public function getCollectedData(): array { diff --git a/src/Analyser/ResultCache/ResultCacheManager.php b/src/Analyser/ResultCache/ResultCacheManager.php index 0db2ffc546..80ea03ac06 100644 --- a/src/Analyser/ResultCache/ResultCacheManager.php +++ b/src/Analyser/ResultCache/ResultCacheManager.php @@ -49,6 +49,7 @@ /** * @phpstan-import-type LinesToIgnore from FileAnalyserResult + * @phpstan-import-type CollectorData from CollectedData */ final class ResultCacheManager { @@ -406,10 +407,7 @@ public function process(AnalyserResult $analyserResult, ResultCache $resultCache $freshLocallyIgnoredErrorsByFile[$error->getFilePath()][] = $error; } - $freshCollectedDataByFile = []; - foreach ($analyserResult->getCollectedData() as $collectedData) { - $freshCollectedDataByFile[$collectedData->getFilePath()][] = $collectedData; - } + $freshCollectedDataByFile = $analyserResult->getCollectedData(); $meta = $resultCache->getMeta(); $projectConfigArray = $meta['projectConfig']; @@ -524,13 +522,6 @@ public function process(AnalyserResult $analyserResult, ResultCache $resultCache } } - $flatCollectedData = []; - foreach ($collectedDataByFile as $fileCollectedData) { - foreach ($fileCollectedData as $collectedData) { - $flatCollectedData[] = $collectedData; - } - } - return new ResultCacheProcessResult(new AnalyserResult( $flatErrors, $analyserResult->getFilteredPhpErrors(), @@ -539,7 +530,7 @@ public function process(AnalyserResult $analyserResult, ResultCache $resultCache $linesToIgnore, $unmatchedLineIgnores, $internalErrors, - $flatCollectedData, + $collectedDataByFile, $dependencies, $exportedNodes, $analyserResult->hasReachedInternalErrorsCountLimit(), @@ -584,8 +575,8 @@ private function mergeLocallyIgnoredErrors(ResultCache $resultCache, array $fres } /** - * @param array> $freshCollectedDataByFile - * @return array> + * @param CollectorData $freshCollectedDataByFile + * @return CollectorData */ private function mergeCollectedData(ResultCache $resultCache, array $freshCollectedDataByFile): array { @@ -704,7 +695,7 @@ private function mergeUnmatchedLineIgnores(ResultCache $resultCache, array $fres * @param array> $locallyIgnoredErrors * @param array $linesToIgnore * @param array $unmatchedLineIgnores - * @param array> $collectedData + * @param array>> $collectedData * @param array> $dependencies * @param array> $exportedNodes * @param array $projectExtensionFiles @@ -760,6 +751,10 @@ private function save( ksort($collectedData); ksort($invertedDependencies); + foreach ($collectedData as & $collectedDataPerFile) { + ksort($collectedDataPerFile); + } + foreach ($invertedDependencies as $file => $fileData) { $dependentFiles = $fileData['dependentFiles']; sort($dependentFiles); diff --git a/src/Collectors/CollectedData.php b/src/Collectors/CollectedData.php index 1ae0078880..f6057f8cf8 100644 --- a/src/Collectors/CollectedData.php +++ b/src/Collectors/CollectedData.php @@ -8,6 +8,8 @@ /** * @api + * + * @phpstan-type CollectorData = array>, list>> */ final class CollectedData implements JsonSerializable { diff --git a/src/Command/AnalyseApplication.php b/src/Command/AnalyseApplication.php index 88589db6cc..81793c6ba0 100644 --- a/src/Command/AnalyseApplication.php +++ b/src/Command/AnalyseApplication.php @@ -6,6 +6,7 @@ use PHPStan\Analyser\AnalyserResultFinalizer; use PHPStan\Analyser\Ignore\IgnoredErrorHelper; use PHPStan\Analyser\ResultCache\ResultCacheManagerFactory; +use PHPStan\Collectors\CollectedData; use PHPStan\Internal\BytesHelper; use PHPStan\PhpDoc\StubFilesProvider; use PHPStan\PhpDoc\StubValidator; @@ -19,6 +20,9 @@ use function sha1_file; use function sprintf; +/** + * @phpstan-import-type CollectorData from CollectedData + */ final class AnalyseApplication { @@ -150,7 +154,7 @@ public function analyse( $notFileSpecificErrors, $internalErrors, [], - $collectedData, + $this->mapCollectedData($collectedData), $defaultLevelUsed, $projectConfigFile, $savedResultCache, @@ -160,6 +164,22 @@ public function analyse( ); } + /** + * @param CollectorData $collectedData + * + * @return list + */ + private function mapCollectedData(array $collectedData): array + { + $result = []; + foreach ($collectedData as $file => $dataPerCollector) { + foreach ($dataPerCollector as $collectorType => $rawData) { + $result[] = new CollectedData($rawData, $file, $collectorType); + } + } + return $result; + } + /** * @param string[] $files * @param string[] $allAnalysedFiles diff --git a/src/Command/WorkerCommand.php b/src/Command/WorkerCommand.php index 6e44a11217..27fdb1ce80 100644 --- a/src/Command/WorkerCommand.php +++ b/src/Command/WorkerCommand.php @@ -226,8 +226,12 @@ private function runWorker( foreach ($fileAnalyserResult->getLocallyIgnoredErrors() as $locallyIgnoredError) { $locallyIgnoredErrors[] = $locallyIgnoredError; } - foreach ($fileAnalyserResult->getCollectedData() as $data) { - $collectedData[] = $data; + foreach ($fileAnalyserResult->getCollectedData() as $collectedFile => $dataPerCollector) { + foreach ($dataPerCollector as $collectorType => $collectorData) { + foreach ($collectorData as $data) { + $collectedData[$collectedFile][$collectorType][] = $data; + } + } } } catch (Throwable $t) { $internalErrorsCount++; diff --git a/src/Node/CollectedDataNode.php b/src/Node/CollectedDataNode.php index 8c0f52dc3b..acc4f24f2d 100644 --- a/src/Node/CollectedDataNode.php +++ b/src/Node/CollectedDataNode.php @@ -6,16 +6,16 @@ use PhpParser\NodeAbstract; use PHPStan\Collectors\CollectedData; use PHPStan\Collectors\Collector; -use function array_key_exists; /** * @api + * @phpstan-import-type CollectorData from CollectedData */ final class CollectedDataNode extends NodeAbstract implements VirtualNode { /** - * @param CollectedData[] $collectedData + * @param CollectorData $collectedData */ public function __construct(private array $collectedData, private bool $onlyFiles) { @@ -31,17 +31,14 @@ public function __construct(private array $collectedData, private bool $onlyFile public function get(string $collectorType): array { $result = []; - foreach ($this->collectedData as $collectedData) { - if ($collectedData->getCollectorType() !== $collectorType) { + foreach ($this->collectedData as $filePath => $collectedDataPerCollector) { + if (!isset($collectedDataPerCollector[$collectorType])) { continue; } - $filePath = $collectedData->getFilePath(); - if (!array_key_exists($filePath, $result)) { - $result[$filePath] = []; + foreach ($collectedDataPerCollector[$collectorType] as $rawData) { + $result[$filePath][] = $rawData; } - - $result[$filePath][] = $collectedData->getData(); } return $result; diff --git a/src/Parallel/ParallelAnalyser.php b/src/Parallel/ParallelAnalyser.php index 4c31b63050..96dcd36820 100644 --- a/src/Parallel/ParallelAnalyser.php +++ b/src/Parallel/ParallelAnalyser.php @@ -9,7 +9,6 @@ use PHPStan\Analyser\AnalyserResult; use PHPStan\Analyser\Error; use PHPStan\Analyser\InternalError; -use PHPStan\Collectors\CollectedData; use PHPStan\Dependency\RootExportedNode; use PHPStan\Process\ProcessHelper; use React\EventLoop\LoopInterface; @@ -211,8 +210,12 @@ public function analyse( $locallyIgnoredErrors[] = $locallyIgnoredFileError; } - foreach ($json['collectedData'] as $jsonData) { - $collectedData[] = CollectedData::decode($jsonData); + foreach ($json['collectedData'] as $file => $jsonDataByCollector) { + foreach ($jsonDataByCollector as $collectorType => $listOfCollectedData) { + foreach ($listOfCollectedData as $rawCollectedData) { + $collectedData[$file][$collectorType][] = $rawCollectedData; + } + } } /**