Skip to content

Conversation

jackd248
Copy link
Owner

@jackd248 jackd248 commented Oct 1, 2025

Summary by CodeRabbit

  • Bug Fixes

    • Skip adding DocBlock headers to anonymous classes to avoid incorrect docblocks and formatting issues, improving compatibility and stability.
  • Tests

    • Adds tests validating anonymous vs. regular class handling, including attribute cases, to ensure correct detection and processing.

Copy link

coderabbitai bot commented Oct 1, 2025

Walkthrough

Adds detection of anonymous classes to DocBlockHeaderFixer by introducing a private helper that backtracks tokens (skipping whitespace and attributes) to detect a preceding T_NEW; applyFix now skips injecting docblocks for anonymous class definitions.

Changes

Cohort / File(s) Summary
Anonymous class handling in fixer
src/Rules/DocBlockHeaderFixer.php
Added private method isAnonymousClass(Tokens $tokens, int $classIndex): bool that backtracks from a T_CLASS token, skipping whitespace, attributes, and common modifiers, to detect a preceding T_NEW. Modified applyFix to skip processing when an anonymous class is detected.
Tests for anonymous class behavior
tests/src/Rules/DocBlockHeaderFixerTest.php
Added five tests (testSkipsAnonymousClasses, testSkipsAnonymousClassesButProcessesRegularClasses, testIsAnonymousClassDetectsAnonymousClass, testIsAnonymousClassReturnsFalseForRegularClass, testIsAnonymousClassWithAttribute) covering anonymous-class skipping and attribute scenarios.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant F as DocBlockHeaderFixer
  participant T as Tokens
  participant C as Class Token

  rect rgba(235,245,255,0.6)
    Note over F: iterate tokens
    F->>T: fetch next token
    alt token is T_CLASS
      F->>F: isAnonymousClass(T, index)
      alt isAnonymousClass == true
        Note right of C: Detected T_NEW before class (anonymous)
        F-->>T: continue (skip docblock)
      else isAnonymousClass == false
        Note right of C: Regular class detected
        F->>T: insert/adjust docblock before class
      end
    else other token
      F-->>T: continue
    end
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

I twitch my nose at classes new,
Anonymous burrows skip the queue—
No headers hatched where shadows pass,
I hop along to the next class. 🥕

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title accurately and concisely describes the main change by stating that support for skipping anonymous classes in DocBlock processing has been added, aligning well with the pull request’s contents and objectives.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch skip-anonymous-class

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3e12480 and 4b5d9bb.

📒 Files selected for processing (1)
  • src/Rules/DocBlockHeaderFixer.php (1 hunks)
🔇 Additional comments (2)
src/Rules/DocBlockHeaderFixer.php (2)

124-127: LGTM!

The guard clause correctly skips anonymous classes. The check is appropriately scoped to T_CLASS tokens only, since interfaces, traits, and enums cannot be anonymous.


134-178: LGTM! Past review feedback addressed.

The isAnonymousClass implementation correctly detects anonymous classes by backtracking to find T_NEW. The logic now properly separates attribute boundary tracking from modifier skipping, addressing the concern raised in the previous review.

The implementation correctly:

  • Skips whitespace and attribute contents when traversing backwards
  • Handles attribute boundaries independently of modifiers
  • Skips T_FINAL and T_READONLY modifiers that can appear between new and class
  • Returns true only when T_NEW is detected before any other meaningful token

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coveralls
Copy link

coveralls commented Oct 1, 2025

Pull Request Test Coverage Report for Build 18163462314

Details

  • 21 of 22 (95.45%) changed or added relevant lines in 1 file are covered.
  • No unchanged relevant lines lost coverage.
  • Overall coverage decreased (-0.4%) to 98.565%

Changes Missing Coverage Covered Lines Changed/Added Lines %
src/Rules/DocBlockHeaderFixer.php 21 22 95.45%
Totals Coverage Status
Change from base Build 17528454689: -0.4%
Covered Lines: 206
Relevant Lines: 209

💛 - Coveralls

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8082d2d and 75ce032.

📒 Files selected for processing (1)
  • src/Rules/DocBlockHeaderFixer.php (1 hunks)
🔇 Additional comments (1)
src/Rules/DocBlockHeaderFixer.php (1)

124-127: LGTM! Proper guard for anonymous classes.

The guard correctly identifies and skips anonymous classes before processing. The check is appropriately limited to T_CLASS tokens since interfaces, traits, and enums cannot be anonymous.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
tests/src/Rules/DocBlockHeaderFixerTest.php (1)

849-952: Consider adding a test for anonymous classes with modifiers.

While the existing tests provide solid coverage, consider adding a test case for anonymous classes with modifiers like new readonly class {} or new final class {} to ensure the modifier-skipping logic works correctly.

Example test:

public function testIsAnonymousClassWithModifier(): void
{
    $code = '<?php $obj = new readonly class {};';
    $tokens = Tokens::fromCode($code);

    $method = new ReflectionMethod($this->fixer, 'isAnonymousClass');

    // Find the class token index
    $classIndex = null;
    for ($i = 0; $i < $tokens->count(); ++$i) {
        if ($tokens[$i]->isGivenKind(T_CLASS)) {
            $classIndex = $i;
            break;
        }
    }

    $result = $method->invoke($this->fixer, $tokens, $classIndex);

    self::assertTrue($result);
}
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 75ce032 and 3e12480.

📒 Files selected for processing (2)
  • src/Rules/DocBlockHeaderFixer.php (1 hunks)
  • tests/src/Rules/DocBlockHeaderFixerTest.php (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
tests/src/Rules/DocBlockHeaderFixerTest.php (1)
src/Rules/DocBlockHeaderFixer.php (1)
  • configure (105-108)
🔇 Additional comments (6)
src/Rules/DocBlockHeaderFixer.php (1)

124-127: LGTM!

The guard correctly skips anonymous classes while processing only T_CLASS tokens, which is appropriate since interfaces, traits, and enums cannot be anonymous in PHP.

tests/src/Rules/DocBlockHeaderFixerTest.php (5)

849-866: LGTM!

The test correctly verifies that anonymous classes are skipped and remain unmodified when the fixer is applied.


868-889: LGTM!

This test effectively verifies that the fixer correctly distinguishes between regular and anonymous classes, processing only the former.


891-910: LGTM!

The test properly validates the isAnonymousClass helper method's ability to detect anonymous classes.


912-931: LGTM!

This negative test case properly validates that regular classes are not incorrectly identified as anonymous.


933-952: LGTM!

This test covers an important edge case—anonymous classes with attributes—ensuring the backward token traversal correctly handles attribute syntax.

@jackd248 jackd248 merged commit 750d791 into main Oct 1, 2025
12 checks passed
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.

2 participants