Skip to content

feat: Add ConvertMultilineDocblockToSingleLineRector#7152

Closed
imliam wants to merge 1 commit intorectorphp:mainfrom
imliam:single-line-docblocks
Closed

feat: Add ConvertMultilineDocblockToSingleLineRector#7152
imliam wants to merge 1 commit intorectorphp:mainfrom
imliam:single-line-docblocks

Conversation

@imliam
Copy link
Contributor

@imliam imliam commented Aug 17, 2025

This rule shortens verbose single-line docblocks into their compact one-line form, reducing visual noise while preserving all information.

For example, this:

/**
 * @return string[]
 */
function list(): array

becomes this:

/** @return string[] */
function list(): array

This change does not alter functionality, but it enforces a cleaner, more consistent code style. By collapsing trivial multi-line docblocks, we save vertical space and make code easier to scan, especially as these kinds of docblocks are commonplace in codebases trying to conform to static analysis tooling.

Copilot AI review requested due to automatic review settings August 17, 2025 23:11
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR introduces a new Rector rule to automatically convert verbose multi-line docblocks containing only a single tag into compact single-line format, improving code readability and reducing visual noise.

Key changes:

  • Adds ConvertMultilineDocblockToSingleLineRector class that converts multi-line docblocks with single statements to single-line format
  • Implements logic to detect docblocks with exactly one tag and no text content
  • Includes comprehensive test coverage with both transformation and skip scenarios

Reviewed Changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
rules/CodingStyle/Rector/FunctionLike/ConvertMultilineDocblockToSingleLineRector.php Main rector implementation with docblock parsing and conversion logic
rules-tests/CodingStyle/Rector/FunctionLike/ConvertMultilineDocblockToSingleLineRector/config/configured_rule.php Test configuration file
rules-tests/CodingStyle/Rector/FunctionLike/ConvertMultilineDocblockToSingleLineRector/Fixture/skip_single_line_statements.php.inc Test fixture for already single-line docblocks that should be skipped
rules-tests/CodingStyle/Rector/FunctionLike/ConvertMultilineDocblockToSingleLineRector/Fixture/skip_multiple_line_statements.php.inc Test fixture for multi-line docblocks with multiple statements that should be skipped
rules-tests/CodingStyle/Rector/FunctionLike/ConvertMultilineDocblockToSingleLineRector/Fixture/single_statements.php.inc Test fixture showing before/after transformation of single-statement docblocks
rules-tests/CodingStyle/Rector/FunctionLike/ConvertMultilineDocblockToSingleLineRector/ConvertMultilineDocblockToSingleLineRectorTest.php PHPUnit test class for the rector

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
You can also share your feedback on Copilot code review for a chance to win a $100 gift card. Take the survey.

$content = substr($content, 3); // Remove "/**"
$content = substr($content, 0, -2); // Remove "*/"

$lines = preg_split('/\r\n|\r|\n/', $content) ?: [];
Copy link

Copilot AI Aug 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The preg_split function call should include proper error handling. If preg_split fails due to a PCRE error, it returns false, but the current fallback to empty array might not be the appropriate response for a malformed regex pattern.

Suggested change
$lines = preg_split('/\r\n|\r|\n/', $content) ?: [];
$lines = preg_split('/\r\n|\r|\n/', $content);
if ($lines === false) {
throw new \RuntimeException('preg_split failed in convertToSingleLine: invalid regex or input');
}

Copilot uses AI. Check for mistakes.

foreach ($lines as $line) {
$line = trim($line);
$line = preg_replace('/^\*\s?/', '', $line) ?: '';
Copy link

Copilot AI Aug 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The preg_replace function call should include proper error handling. If preg_replace fails due to a PCRE error, it returns null, but the current fallback to empty string might not be appropriate and could mask underlying issues.

Suggested change
$line = preg_replace('/^\*\s?/', '', $line) ?: '';
$replacedLine = preg_replace('/^\*\s?/', '', $line);
if ($replacedLine === null) {
throw new \RuntimeException('PCRE error occurred in preg_replace while processing docblock line: ' . $line);
}
$line = $replacedLine;

Copilot uses AI. Check for mistakes.

/**
* @param int $i
*/
Copy link

Copilot AI Aug 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The @param annotation is incorrectly placed on an if statement. The @param tag should only be used in function/method docblocks to document parameters, not in inline variable annotations within method bodies.

Suggested change
*/

Copilot uses AI. Check for mistakes.
@calebdw
Copy link
Contributor

calebdw commented Aug 17, 2025

This really looks like something that should be part of PHPCsFixer or some other formatter, not rector...

@TomasVotruba
Copy link
Member

Thanks for proposal, this is better done by coding standard tools, as there can be many token edge cases.

Rector better suits AST and context-aware code changes.

On another note: any idea how to disable this "AI" reviews? 😅 Started popping up yesterday without any change on our side.

@calebdw
Copy link
Contributor

calebdw commented Sep 12, 2025

@imliam, can you try to PR something like this to php-cs-fixer (used by pint)?

@imliam
Copy link
Contributor Author

imliam commented Sep 12, 2025

@imliam, can you try to PR something like this to php-cs-fixer (used by pint)?

@calebdw I did - but turns out this is already a thing in php-cs-fixer and has been for some time!

    'phpdoc_line_span' => [
        'const' => 'single',
        'property' => 'single',
        'method' => 'single',
    ],

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants