diff --git a/conf/config.neon b/conf/config.neon index 454e77f2c8..f10b154d1a 100644 --- a/conf/config.neon +++ b/conf/config.neon @@ -314,13 +314,13 @@ parametersSchema: anyOf( string(), structure([ - message: string() - path: string() + messages: listOf(string()) + ?path: string() ?reportUnmatched: bool() ]), structure([ - messages: listOf(string()) - path: string() + message: string() + ?path: string() ?reportUnmatched: bool() ]), structure([ diff --git a/src/DependencyInjection/ValidateIgnoredErrorsExtension.php b/src/DependencyInjection/ValidateIgnoredErrorsExtension.php index 2a16d820d8..756d1a7bd2 100644 --- a/src/DependencyInjection/ValidateIgnoredErrorsExtension.php +++ b/src/DependencyInjection/ValidateIgnoredErrorsExtension.php @@ -101,35 +101,28 @@ public function getRegistry(): OperatorTypeSpecifyingExtensionRegistry ), ), ); - $errors = []; + $errors = []; foreach ($ignoreErrors as $ignoreError) { - try { - if (is_array($ignoreError)) { - if (isset($ignoreError['count'])) { - continue; // ignoreError coming from baseline will be correct - } - $ignoreMessage = $ignoreError['message']; - } else { - $ignoreMessage = $ignoreError; - } - - Strings::match('', $ignoreMessage); - $validationResult = $ignoredRegexValidator->validate($ignoreMessage); - $ignoredTypes = $validationResult->getIgnoredTypes(); - if (count($ignoredTypes) > 0) { - $errors[] = $this->createIgnoredTypesError($ignoreMessage, $ignoredTypes); + if (is_array($ignoreError)) { + if (isset($ignoreError['count'])) { + continue; // ignoreError coming from baseline will be correct } - - if ($validationResult->hasAnchorsInTheMiddle()) { - $errors[] = $this->createAnchorInTheMiddleError($ignoreMessage); + if (isset($ignoreError['messages'])) { + $ignoreMessages = $ignoreError['messages']; + } else { + $ignoreMessages = [$ignoreError['message']]; } + } else { + $ignoreMessages = [$ignoreError]; + } - if ($validationResult->areAllErrorsIgnored()) { - $errors[] = sprintf("Ignored error %s has an unescaped '%s' which leads to ignoring all errors. Use '%s' instead.", $ignoreMessage, $validationResult->getWrongSequence(), $validationResult->getEscapedWrongSequence()); + foreach ($ignoreMessages as $ignoreMessage) { + $error = $this->validateMessage($ignoredRegexValidator, $ignoreMessage); + if ($error === null) { + continue; } - } catch (RegexpException $e) { - $errors[] = $e->getMessage(); + $errors[] = $error; } } @@ -140,6 +133,29 @@ public function getRegistry(): OperatorTypeSpecifyingExtensionRegistry throw new InvalidIgnoredErrorPatternsException($errors); } + private function validateMessage(IgnoredRegexValidator $ignoredRegexValidator, string $ignoreMessage): ?string + { + try { + Strings::match('', $ignoreMessage); + $validationResult = $ignoredRegexValidator->validate($ignoreMessage); + $ignoredTypes = $validationResult->getIgnoredTypes(); + if (count($ignoredTypes) > 0) { + return $this->createIgnoredTypesError($ignoreMessage, $ignoredTypes); + } + + if ($validationResult->hasAnchorsInTheMiddle()) { + return $this->createAnchorInTheMiddleError($ignoreMessage); + } + + if ($validationResult->areAllErrorsIgnored()) { + return sprintf("Ignored error %s has an unescaped '%s' which leads to ignoring all errors. Use '%s' instead.", $ignoreMessage, $validationResult->getWrongSequence(), $validationResult->getEscapedWrongSequence()); + } + } catch (RegexpException $e) { + return $e->getMessage(); + } + return null; + } + /** * @param array $ignoredTypes */ diff --git a/tests/PHPStan/DependencyInjection/IgnoreErrorsTest.php b/tests/PHPStan/DependencyInjection/IgnoreErrorsTest.php new file mode 100644 index 0000000000..b767c6b7d4 --- /dev/null +++ b/tests/PHPStan/DependencyInjection/IgnoreErrorsTest.php @@ -0,0 +1,25 @@ +assertCount(10, self::getContainer()->getParameter('ignoreErrors')); + } + + /** + * @return string[] + */ + public static function getAdditionalConfigFiles(): array + { + return [ + __DIR__ . '/ignoreErrors.neon', + ]; + } + +} diff --git a/tests/PHPStan/DependencyInjection/ignoreErrors.neon b/tests/PHPStan/DependencyInjection/ignoreErrors.neon new file mode 100644 index 0000000000..e24eaaf807 --- /dev/null +++ b/tests/PHPStan/DependencyInjection/ignoreErrors.neon @@ -0,0 +1,42 @@ +parameters: + ignoreErrors: + - "#error#" + - + message: '#error#' + reportUnmatched: false + - + message: '#error#' + path: '/dir/*' + - + message: '#error#' + path: '/dir/*' + reportUnmatched: false + - + messages: + - '#error#' + path: '/dir/*' + - + messages: + - '#error#' + path: '/dir/*' + reportUnmatched: false + - + message: '#error#' + paths: + - '/dir/*' + - + message: '#error#' + paths: + - '/dir/*' + reportUnmatched: false + - + messages: + - '#error#' + paths: + - '/dir/*' + - + messages: + - '#error#' + paths: + - '/dir/*' + reportUnmatched: false