Skip to content

Commit 6f1584a

Browse files
committed
Handle more errors than ignore count in --ignore-new-errors
1 parent 0f6eaeb commit 6f1584a

File tree

1 file changed

+45
-93
lines changed

1 file changed

+45
-93
lines changed

src/Command/AnalyseCommand.php

+45-93
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use Nette\FileNotFoundException;
77
use Nette\InvalidStateException;
88
use OndraM\CiDetector\CiDetector;
9+
use PHPStan\Analyser\Error;
910
use PHPStan\Analyser\Ignore\IgnoredError;
1011
use PHPStan\Analyser\InternalError;
1112
use PHPStan\Command\ErrorFormatter\BaselineNeonErrorFormatter;
@@ -603,7 +604,9 @@ private function generateBaseline(string $generateBaselineFile, InceptionResult
603604
$baselineFileDirectory = dirname($generateBaselineFile);
604605
$fileHelper = $container->getByType(FileHelper::class);
605606
$baselinePathHelper = new ParentDirectoryRelativePathHelper($baselineFileDirectory);
606-
$analysisResult = $this->processFileSpecificErrorsFromAnalysisResult($analysisResult, $ignoreNewErrors, $generateBaselineFile, $inceptionResult, $fileHelper, $baselinePathHelper);
607+
if ($ignoreNewErrors) {
608+
$analysisResult = $this->filterAnalysisResultForExistingErrors($analysisResult, $generateBaselineFile, $inceptionResult, $fileHelper, $baselinePathHelper);
609+
}
607610

608611
if (!$allowEmptyBaseline && !$analysisResult->hasErrors()) {
609612
$inceptionResult->getStdOutput()->getStyle()->error('No errors were found during the analysis. Baseline could not be generated.');
@@ -689,39 +692,26 @@ private function generateBaseline(string $generateBaselineFile, InceptionResult
689692
return $inceptionResult->handleReturn($exitCode, $analysisResult->getPeakMemoryUsageBytes(), $this->analysisStartTime);
690693
}
691694

692-
private function processFileSpecificErrorsFromAnalysisResult(AnalysisResult $analysisResult, bool $ignoreNewErrors, string $generateBaselineFile, InceptionResult $inceptionResult, FileHelper $fileHelper, RelativePathHelper $baselinePathHelper): AnalysisResult
695+
private function filterAnalysisResultForExistingErrors(AnalysisResult $analysisResult, string $generateBaselineFile, InceptionResult $inceptionResult, FileHelper $fileHelper, RelativePathHelper $baselinePathHelper): AnalysisResult
693696
{
694697
$fileSpecificErrors = $analysisResult->getFileSpecificErrors();
695-
if (!$ignoreNewErrors) {
696-
return $analysisResult;
697-
}
698698

699699
$baselineIgnoreErrors = $this->getCurrentBaselineIgnoreErrors($generateBaselineFile, $inceptionResult);
700700
$ignoreErrorsByFile = $this->mapIgnoredErrors($baselineIgnoreErrors, $fileHelper);
701701

702+
$ignoreUseCount = [];
703+
702704
foreach ($fileSpecificErrors as $errorIndex => $error) {
703-
$filePath = $baselinePathHelper->getRelativePath($error->getFilePath());
704-
if (isset($ignoreErrorsByFile[$filePath])) {
705-
foreach ($ignoreErrorsByFile[$filePath] as $ignoreError) {
706-
$ignore = $ignoreError['ignoreError'];
707-
$shouldIgnore = IgnoredError::shouldIgnore($fileHelper, $error, $ignore['message'] ?? null, $ignore['identifier'] ?? null, null);
708-
if ($shouldIgnore) {
709-
continue 2;
710-
}
711-
}
705+
$hasMatchingIgnore = $this->checkIgnoreErrorByPath($error->getFilePath(), $ignoreErrorsByFile, $fileHelper, $error, $ignoreUseCount, $baselinePathHelper);
706+
if ($hasMatchingIgnore) {
707+
continue;
712708
}
713709

714710
$traitFilePath = $error->getTraitFilePath();
715711
if ($traitFilePath !== null) {
716-
$normalizedTraitFilePath = $baselinePathHelper->getRelativePath($traitFilePath);
717-
if (isset($ignoreErrorsByFile[$normalizedTraitFilePath])) {
718-
foreach ($ignoreErrorsByFile[$normalizedTraitFilePath] as $ignoreError) {
719-
$ignore = $ignoreError['ignoreError'];
720-
$shouldIgnore = IgnoredError::shouldIgnore($fileHelper, $error, $ignore['message'] ?? null, $ignore['identifier'] ?? null, null);
721-
if ($shouldIgnore) {
722-
continue 2;
723-
}
724-
}
712+
$hasMatchingIgnore = $this->checkIgnoreErrorByPath($traitFilePath, $ignoreErrorsByFile, $fileHelper, $error, $ignoreUseCount, $baselinePathHelper);
713+
if ($hasMatchingIgnore) {
714+
continue;
725715
}
726716
}
727717

@@ -746,6 +736,36 @@ private function processFileSpecificErrorsFromAnalysisResult(AnalysisResult $ana
746736
);
747737
}
748738

739+
/**
740+
* @param mixed[][] $ignoreErrorsByFile
741+
* @param int[] $ignoreUseCount map of indexes of ignores and how often they have been "used" to ignore an error
742+
*/
743+
private function checkIgnoreErrorByPath(string $filePath, array $ignoreErrorsByFile, FileHelper $fileHelper, Error $error, array &$ignoreUseCount, RelativePathHelper $baselinePathHelper): bool
744+
{
745+
$relativePath = $baselinePathHelper->getRelativePath($filePath);
746+
if (!isset($ignoreErrorsByFile[$relativePath])) {
747+
return false;
748+
}
749+
750+
foreach ($ignoreErrorsByFile[$relativePath] as $ignoreError) {
751+
$ignore = $ignoreError['ignoreError'];
752+
$shouldIgnore = IgnoredError::shouldIgnore($fileHelper, $error, $ignore['message'] ?? null, $ignore['identifier'] ?? null, null);
753+
if (!$shouldIgnore) {
754+
continue;
755+
}
756+
757+
$realCount = $ignoreUseCount[$ignoreError['index']] ?? 0;
758+
$realCount++;
759+
$ignoreUseCount[$ignoreError['index']] = $realCount;
760+
761+
if ($realCount <= $ignore['count']) {
762+
return true;
763+
}
764+
}
765+
766+
return false;
767+
}
768+
749769
/**
750770
* @param string[] $files
751771
*/
@@ -805,89 +825,21 @@ private function getCurrentBaselineIgnoreErrors(string $generateBaselineFile, In
805825
}
806826

807827
/**
808-
* @param (string|mixed[])[] $baselineIgnoreErrors
828+
* @param mixed[][] $baselineIgnoreErrors
809829
* @return mixed[][]
810-
* @throws ShouldNotHappenException
811830
*/
812831
private function mapIgnoredErrors(array $baselineIgnoreErrors, FileHelper $fileHelper): array
813832
{
814833
$ignoreErrorsByFile = [];
815834

816-
$expandedIgnoreErrors = [];
817-
foreach ($baselineIgnoreErrors as $ignoreError) {
818-
if (!is_array($ignoreError)) {
819-
throw new ShouldNotHappenException('Baseline should not have ignore error strings');
820-
}
821-
822-
if (!isset($ignoreError['message']) && !isset($ignoreError['messages']) && !isset($ignoreError['identifier'])) {
823-
continue;
824-
}
825-
if (isset($ignoreError['messages'])) {
826-
foreach ($ignoreError['messages'] as $message) {
827-
$expandedIgnoreError = $ignoreError;
828-
unset($expandedIgnoreError['messages']);
829-
$expandedIgnoreError['message'] = $message;
830-
$expandedIgnoreErrors[] = $expandedIgnoreError;
831-
}
832-
} else {
833-
$expandedIgnoreErrors[] = $ignoreError;
834-
}
835-
}
836-
$uniquedExpandedIgnoreErrors = [];
837-
foreach ($expandedIgnoreErrors as $ignoreError) {
838-
if (!isset($ignoreError['message']) && !isset($ignoreError['identifier'])) {
839-
$uniquedExpandedIgnoreErrors[] = $ignoreError;
840-
continue;
841-
}
842-
if (!isset($ignoreError['path'])) {
843-
$uniquedExpandedIgnoreErrors[] = $ignoreError;
844-
continue;
845-
}
846-
847-
$key = $ignoreError['path'];
848-
if (isset($ignoreError['message'])) {
849-
$key = sprintf("%s\n%s", $key, $ignoreError['message']);
850-
}
851-
if (isset($ignoreError['identifier'])) {
852-
$key = sprintf("%s\n%s", $key, $ignoreError['identifier']);
853-
}
854-
if ($key === '') {
855-
throw new ShouldNotHappenException();
856-
}
857-
858-
if (!array_key_exists($key, $uniquedExpandedIgnoreErrors)) {
859-
$uniquedExpandedIgnoreErrors[$key] = $ignoreError;
860-
continue;
861-
}
862-
863-
$uniquedExpandedIgnoreErrors[$key] = [
864-
'message' => $ignoreError['message'] ?? null,
865-
'path' => $ignoreError['path'],
866-
'identifier' => $ignoreError['identifier'] ?? null,
867-
'count' => ($uniquedExpandedIgnoreErrors[$key]['count'] ?? 1) + ($ignoreError['count'] ?? 1),
868-
'reportUnmatched' => false,
869-
];
870-
}
871-
$expandedIgnoreErrors = array_values($uniquedExpandedIgnoreErrors);
872-
873-
foreach ($expandedIgnoreErrors as $i => $ignoreError) {
835+
foreach ($baselineIgnoreErrors as $i => $ignoreError) {
874836
$ignoreErrorEntry = [
875837
'index' => $i,
876838
'ignoreError' => $ignoreError,
877839
];
878840

879-
if (!isset($ignoreError['message']) && !isset($ignoreError['identifier'])) {
880-
continue;
881-
}
882-
if (!isset($ignoreError['path'])) {
883-
throw new ShouldNotHappenException('Baseline should not have ignore errors without path');
884-
}
885-
886841
$normalizedPath = $fileHelper->normalizePath($ignoreError['path']);
887-
$ignoreError['path'] = $normalizedPath;
888842
$ignoreErrorsByFile[$normalizedPath][] = $ignoreErrorEntry;
889-
$ignoreError['realPath'] = $normalizedPath;
890-
$expandedIgnoreErrors[$i] = $ignoreError;
891843
}
892844

893845
return $ignoreErrorsByFile;

0 commit comments

Comments
 (0)