diff --git a/src/TodoByDateRule.php b/src/TodoByDateRule.php index ae9bbe9..27c92f5 100644 --- a/src/TodoByDateRule.php +++ b/src/TodoByDateRule.php @@ -68,7 +68,8 @@ public function processNode(Node $node, Scope $scope): array if (!checkdate((int) $month, (int) $day, (int) $year)) { $errors[] = $this->errorBuilder->buildError( - $comment, + $comment->getText(), + $comment->getStartLine(), 'Invalid date "'. $date .'". Expected format "YYYY-MM-DD".', self::ERROR_IDENTIFIER, null, @@ -96,7 +97,8 @@ public function processNode(Node $node, Scope $scope): array } $errors[] = $this->errorBuilder->buildError( - $comment, + $comment->getText(), + $comment->getStartLine(), $errorMessage, self::ERROR_IDENTIFIER, null, diff --git a/src/TodoByIssueUrlRule.php b/src/TodoByIssueUrlRule.php index 06eca18..c0dfc84 100644 --- a/src/TodoByIssueUrlRule.php +++ b/src/TodoByIssueUrlRule.php @@ -68,7 +68,8 @@ public function processNode(Node $node, Scope $scope): array if (!array_key_exists($apiUrl, $fetchedStatuses) || null === $fetchedStatuses[$apiUrl]) { $errors[] = $this->errorBuilder->buildError( - $comment, + $comment->getText(), + $comment->getStartLine(), "Ticket $url doesn't exist or provided credentials do not allow for viewing it.", self::ERROR_IDENTIFIER, null, @@ -90,7 +91,8 @@ public function processNode(Node $node, Scope $scope): array } $errors[] = $this->errorBuilder->buildError( - $comment, + $comment->getText(), + $comment->getStartLine(), $errorMessage, self::ERROR_IDENTIFIER, null, diff --git a/src/TodoByPackageVersionRule.php b/src/TodoByPackageVersionRule.php index 10dd429..e410de8 100644 --- a/src/TodoByPackageVersionRule.php +++ b/src/TodoByPackageVersionRule.php @@ -125,7 +125,8 @@ public function processNode(Node $node, Scope $scope): array } $errors[] = $this->errorBuilder->buildError( - $comment, + $comment->getText(), + $comment->getStartLine(), $errorMessage, self::ERROR_IDENTIFIER, null, @@ -154,7 +155,8 @@ private function satisfiesPhpPlatformPackage(string $package, string $version, C $constraint = $versionParser->parseConstraints($version); } catch (UnexpectedValueException $e) { return $this->errorBuilder->buildError( - $comment, + $comment->getText(), + $comment->getStartLine(), 'Invalid version constraint "' . $version . '" for package "' . $package . '".', self::ERROR_IDENTIFIER, null, @@ -177,7 +179,8 @@ private function satisfiesVirtualPackage(string $package, string $version, Comme ); } catch (UnexpectedValueException $e) { return $this->errorBuilder->buildError( - $comment, + $comment->getText(), + $comment->getStartLine(), 'Invalid virtual-package "' . $package . '": "' . $this->virtualPackages[$package] . '" provided via PHPStan config file.', self::ERROR_IDENTIFIER, null, @@ -189,7 +192,8 @@ private function satisfiesVirtualPackage(string $package, string $version, Comme $constraint = $versionParser->parseConstraints($version); } catch (UnexpectedValueException $e) { return $this->errorBuilder->buildError( - $comment, + $comment->getText(), + $comment->getStartLine(), 'Invalid version constraint "' . $version . '" for virtual-package "' . $package . '".', self::ERROR_IDENTIFIER, null, @@ -220,7 +224,8 @@ private function readPhpPlatformVersion(Comment $comment, int $wholeMatchStartOf if (null === $config) { return $this->phpPlatformVersion = $this->errorBuilder->buildError( - $comment, + $comment->getText(), + $comment->getStartLine(), 'Unable to find composer.json in '. $this->workingDirectory, self::ERROR_IDENTIFIER, null, @@ -235,7 +240,8 @@ private function readPhpPlatformVersion(Comment $comment, int $wholeMatchStartOf || !is_string($config['require']['php']) ) { return $this->phpPlatformVersion = $this->errorBuilder->buildError( - $comment, + $comment->getText(), + $comment->getStartLine(), 'Missing php platform requirement in '. $this->workingDirectory .'/composer.json', self::ERROR_IDENTIFIER, null, @@ -256,7 +262,8 @@ private function satisfiesInstalledPackage(string $package, string $version, Com // see https://getcomposer.org/doc/07-runtime.md#installed-versions if (!InstalledVersions::isInstalled($package)) { return $this->errorBuilder->buildError( - $comment, + $comment->getText(), + $comment->getStartLine(), 'Unknown package "' . $package . '". It is neither installed via composer.json nor declared as virtual package via PHPStan config.', self::ERROR_IDENTIFIER, null, @@ -268,7 +275,8 @@ private function satisfiesInstalledPackage(string $package, string $version, Com return InstalledVersions::satisfies($versionParser, $package, $version); } catch (UnexpectedValueException $e) { return $this->errorBuilder->buildError( - $comment, + $comment->getText(), + $comment->getStartLine(), 'Invalid version constraint "' . $version . '" for package "' . $package . '".', self::ERROR_IDENTIFIER, null, diff --git a/src/TodoByTicketCollector.php b/src/TodoByTicketCollector.php index fdb2225..c81221d 100644 --- a/src/TodoByTicketCollector.php +++ b/src/TodoByTicketCollector.php @@ -12,7 +12,7 @@ use function trim; /** - * @implements Collector> + * @implements Collector> */ final class TodoByTicketCollector implements Collector { @@ -37,19 +37,17 @@ public function processNode(Node $node, Scope $scope) // use deprecated method for nikic/php-parser 4.x compat $line = $comment->getLine(); + $text = $comment->getText(); + $startLine =$comment->getStartLine(); + /** @var array> $matches */ foreach ($matches as $match) { $ticketKey = $match['ticketKey'][0]; $todoText = trim($match['comment'][0]); - // collectors do not support serializing objects, pass a string instead. - $json = json_encode($comment); - if (false === $json) { - throw new RuntimeException('Failed to encode comment as JSON: ' . json_last_error_msg()); - } - $tickets[] = [ - $json, + $text, + $startLine, $ticketKey, $todoText, $match[0][1], // wholeMatchStartOffset diff --git a/src/TodoByTicketRule.php b/src/TodoByTicketRule.php index 7601220..c246549 100644 --- a/src/TodoByTicketRule.php +++ b/src/TodoByTicketRule.php @@ -43,7 +43,7 @@ public function processNode(Node $node, Scope $scope): array $ticketKeys = []; foreach ($collectorData as $collected) { foreach ($collected as $tickets) { - foreach ($tickets as [$json, $ticketKey, $todoText, $wholeMatchStartOffset, $line]) { + foreach ($tickets as [$comment, $startLine, $ticketKey, $todoText, $wholeMatchStartOffset, $line]) { if ([] !== $this->configuration->getKeyPrefixes() && !$this->hasPrefix($ticketKey)) { continue; } @@ -67,7 +67,7 @@ public function processNode(Node $node, Scope $scope): array $errors = []; foreach ($collectorData as $file => $collected) { foreach ($collected as $tickets) { - foreach ($tickets as [$json, $ticketKey, $todoText, $wholeMatchStartOffset, $line]) { + foreach ($tickets as [$comment, $startLine, $ticketKey, $todoText, $wholeMatchStartOffset, $line]) { if ([] !== $this->configuration->getKeyPrefixes() && !$this->hasPrefix($ticketKey)) { continue; } @@ -79,7 +79,8 @@ public function processNode(Node $node, Scope $scope): array if (null === $ticketStatus) { $errors[] = $this->errorBuilder->buildFileError( - $this->commentFromJson($json), + $comment, + $startLine, "Ticket $ticketKey doesn't exist or provided credentials do not allow for viewing it.", self::ERROR_IDENTIFIER, null, @@ -102,7 +103,8 @@ public function processNode(Node $node, Scope $scope): array } $errors[] = $this->errorBuilder->buildFileError( - $this->commentFromJson($json), + $comment, + $startLine, $errorMessage, self::ERROR_IDENTIFIER, "See {$this->configuration->getFetcher()->resolveTicketUrl($ticketKey)}", @@ -128,30 +130,4 @@ private function hasPrefix(string $ticketKey): bool return false; } - private function commentFromJson(string $json): Comment - { - $arr = json_decode($json, true); - - if ('Comment_Doc' === $arr['nodeType']) { - return new Comment\Doc( - $arr['text'], - $arr['line'], - $arr['filePos'], - $arr['tokenPos'], - $arr['endLine'], - $arr['endFilePos'], - $arr['endTokenPos'] - ); - } - - return new Comment( - $arr['text'], - $arr['line'], - $arr['filePos'], - $arr['tokenPos'], - $arr['endLine'], - $arr['endFilePos'], - $arr['endTokenPos'] - ); - } } diff --git a/src/TodoByVersionRule.php b/src/TodoByVersionRule.php index 031ec9b..8f310f3 100644 --- a/src/TodoByVersionRule.php +++ b/src/TodoByVersionRule.php @@ -100,7 +100,8 @@ public function processNode(Node $node, Scope $scope): array $constraint = $versionParser->parseConstraints($version); } catch (UnexpectedValueException $e) { $errors[] = $this->errorBuilder->buildError( - $comment, + $comment->getText(), + $comment->getStartLine(), 'Invalid version constraint "' . $version . '".', self::ERROR_IDENTIFIER, null, @@ -122,7 +123,8 @@ public function processNode(Node $node, Scope $scope): array } $errors[] = $this->errorBuilder->buildError( - $comment, + $comment->getText(), + $comment->getStartLine(), $errorMessage, self::ERROR_IDENTIFIER, "Calculated reference version is '". $referenceVersion ."'.\n\n See also:\n https://github.com/staabm/phpstan-todo-by#reference-version", diff --git a/src/utils/ExpiredCommentErrorBuilder.php b/src/utils/ExpiredCommentErrorBuilder.php index cc96b00..54f040a 100644 --- a/src/utils/ExpiredCommentErrorBuilder.php +++ b/src/utils/ExpiredCommentErrorBuilder.php @@ -17,7 +17,8 @@ public function __construct(bool $nonIgnorable) } public function buildError( - Comment $comment, + string $comment, + int $startLine, string $errorMessage, string $errorIdentifier, ?string $tip, @@ -25,6 +26,7 @@ public function buildError( ): \PHPStan\Rules\RuleError { return $this->build( $comment, + $startLine, $errorMessage, $errorIdentifier, $tip, @@ -35,7 +37,8 @@ public function buildError( } public function buildFileError( - Comment $comment, + string $comment, + int $startLine, string $errorMessage, string $errorIdentifier, ?string $tip, @@ -45,6 +48,7 @@ public function buildFileError( ): \PHPStan\Rules\RuleError { return $this->build( $comment, + $startLine, $errorMessage, $errorIdentifier, $tip, @@ -55,7 +59,8 @@ public function buildFileError( } private function build( - Comment $comment, + string $comment, + int $startLine, string $errorMessage, string $errorIdentifier, ?string $tip, @@ -64,10 +69,10 @@ private function build( ?int $line ): \PHPStan\Rules\RuleError { // Count the number of newlines between the start of the whole comment, and the start of the match. - $newLines = substr_count($comment->getText(), "\n", 0, $wholeMatchStartOffset); + $newLines = substr_count($comment, "\n", 0, $wholeMatchStartOffset); // Set the message line to match the line the comment actually starts on. - $messageLine = $comment->getStartLine() + $newLines; + $messageLine = $startLine + $newLines; $errBuilder = RuleErrorBuilder::message($errorMessage) ->line($messageLine)