diff --git a/src/TodoByDateRule.php b/src/TodoByDateRule.php index f3a1f73..2acd29c 100644 --- a/src/TodoByDateRule.php +++ b/src/TodoByDateRule.php @@ -8,6 +8,7 @@ use PHPStan\Rules\Rule; use PHPStan\Rules\RuleErrorBuilder; use PHPStan\ShouldNotHappenException; +use staabm\PHPStanTodoBy\utils\CommentMatcher; use staabm\PHPStanTodoBy\utils\ExpiredCommentErrorBuilder; use function preg_match_all; use function strtotime; @@ -57,35 +58,10 @@ public function getNodeType(): string public function processNode(Node $node, Scope $scope): array { - if ( - $node instanceof VirtualNode - || $node instanceof Node\Expr - ) { - // prevent duplicate errors - return []; - } + $it = CommentMatcher::matchComments($node, self::PATTERN); $errors = []; - - foreach ($node->getComments() as $comment) { - - $text = $comment->getText(); - - /** - * PHP doc comments have the entire multi-line comment as the text. - * Since this could potentially contain multiple "todo" comments, we need to check all lines. - * This works for single line comments as well. - * - * PREG_OFFSET_CAPTURE: Track where each "todo" comment starts within the whole comment text. - * PREG_SET_ORDER: Make each value of $matches be structured the same as if from preg_match(). - */ - if ( - preg_match_all(self::PATTERN, $text, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER) === false - || count($matches) === 0 - ) { - continue; - } - + foreach($it as $comment => $matches) { /** @var array> $matches */ foreach ($matches as $match) { diff --git a/src/TodoByVersionRule.php b/src/TodoByVersionRule.php index 4e61a46..741ef3a 100644 --- a/src/TodoByVersionRule.php +++ b/src/TodoByVersionRule.php @@ -8,6 +8,7 @@ use PHPStan\Node\VirtualNode; use PHPStan\Rules\Rule; use PHPStan\Rules\RuleErrorBuilder; +use staabm\PHPStanTodoBy\utils\CommentMatcher; use staabm\PHPStanTodoBy\utils\ExpiredCommentErrorBuilder; use staabm\PHPStanTodoBy\utils\ReferenceVersionFinder; use staabm\PHPStanTodoBy\utils\VersionNormalizer; @@ -67,35 +68,10 @@ public function getNodeType(): string public function processNode(Node $node, Scope $scope): array { - if ( - $node instanceof VirtualNode - || $node instanceof Node\Expr - ) { - // prevent duplicate errors - return []; - } + $it = CommentMatcher::matchComments($node, self::PATTERN); $errors = []; - - foreach ($node->getComments() as $comment) { - - $text = $comment->getText(); - - /** - * PHP doc comments have the entire multi-line comment as the text. - * Since this could potentially contain multiple "todo" comments, we need to check all lines. - * This works for single line comments as well. - * - * PREG_OFFSET_CAPTURE: Track where each "todo" comment starts within the whole comment text. - * PREG_SET_ORDER: Make each value of $matches be structured the same as if from preg_match(). - */ - if ( - preg_match_all(self::PATTERN, $text, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER) === false - || count($matches) === 0 - ) { - continue; - } - + foreach($it as $comment => $matches) { $referenceVersion = $this->getReferenceVersion($scope); /** @var array> $matches */ diff --git a/src/utils/CommentMatcher.php b/src/utils/CommentMatcher.php new file mode 100644 index 0000000..cdf45bd --- /dev/null +++ b/src/utils/CommentMatcher.php @@ -0,0 +1,46 @@ +> + */ + public static function matchComments(Node $node, string $pattern): iterable + { + if ( + $node instanceof VirtualNode + || $node instanceof Node\Expr + ) { + // prevent duplicate errors + return []; + } + + foreach ($node->getComments() as $comment) { + + $text = $comment->getText(); + + /** + * PHP doc comments have the entire multi-line comment as the text. + * Since this could potentially contain multiple "todo" comments, we need to check all lines. + * This works for single line comments as well. + * + * PREG_OFFSET_CAPTURE: Track where each "todo" comment starts within the whole comment text. + * PREG_SET_ORDER: Make each value of $matches be structured the same as if from preg_match(). + */ + if ( + preg_match_all($pattern, $text, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER) === false + || count($matches) === 0 + ) { + continue; + } + + yield $comment => $matches; + } + } +}