Skip to content

Update flip sniffs to handle object properties better#2839

Merged
Crabcyborg merged 1 commit into
masterfrom
update_flip_sniffs_to_handle_object_properties_better
Jan 20, 2026
Merged

Update flip sniffs to handle object properties better#2839
Crabcyborg merged 1 commit into
masterfrom
update_flip_sniffs_to_handle_object_properties_better

Conversation

@Crabcyborg
Copy link
Copy Markdown
Contributor

@Crabcyborg Crabcyborg commented Jan 20, 2026

Some conditions would change to something like if ( empty( $body - <= success ) ) {, which is totally invalid.

Summary by CodeRabbit

  • Bug Fixes

    • Improved accuracy of code analysis suggestions by fixing false positives when detecting and flipping comparison operators in conditional statements.
  • Refactor

    • Enhanced internal logic for handling comparison operators to be more robust and avoid misinterpreting edge cases with similar-looking operators.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jan 20, 2026

📝 Walkthrough

Walkthrough

The PR enhances comparison operator flipping logic in five PHP CodeSniffer sniffs. Each sniff receives a new findComparisonOperator() helper method and an improved flipComparisonOperator() method that better handles single < and > operators while avoiding false positives from arrow tokens or multi-character comparisons.

Changes

Cohort / File(s) Summary
PHPCS Sniff Operator Flipping Logic
phpcs-sniffs/Formidable/Sniffs/CodeAnalysis/FlipForeachIfToContinueSniff.php, FlipIfToEarlyReturnSniff.php, FlipIfToEarlyReturnVariableSniff.php, FlipLargeIfSmallElseSniff.php, FlipLoopIfElseToContinueSniff.php
Added new private method findComparisonOperator() to safely locate standalone single-character < or > operators while excluding arrow tokens (\->, =>) and multi-character comparisons. Enhanced flipComparisonOperator() to reject conditions containing top-level && or || operators early, flip longer operators via a dedicated map (===, !==, ==, !=, >=, <=), and delegate single < and > handling to the new helper. Returns false when no simple flip is applicable.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • #2806 — Modifies the same sniffs' comparison-flipping logic and flipComparisonOperator enhancements
  • #2833 — Updates flipComparisonOperator and adds findComparisonOperator in FlipLoopIfElseToContinueSniff with overlapping operator-flipping logic
  • #2828 — Modifies the same set of Formidable PHPCS sniff files with related comparison operator handling

Poem

🐰 With whiskers twitching at each sign,
I find the < and > so fine,
No arrows hide within my care,
Just operators, flipped with flair!
Early returns and loops rejoice,
When sniffs have logic, clear voice! 🎯

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title contains a typo ('Updae' instead of 'Update') and accurately describes the main changes across all affected sniff files, which involve improved handling of object properties and comparison operators.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

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.

Copy link
Copy Markdown
Contributor

@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: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
phpcs-sniffs/Formidable/Sniffs/CodeAnalysis/FlipIfToEarlyReturnVariableSniff.php (1)

600-637: Consider handling bitshift operators << and >>.

The helper correctly avoids arrow tokens (->, =>) and multi-character comparisons (<=, >=). However, bitshift operators like $x << 2 or $x >> 2 would be incorrectly matched as comparison operators since < before < isn't in the skip list.

This may be a rare edge case in conditions, but could cause incorrect flips for expressions like $flags >> 1.

🔧 Suggested fix
 			// Check character after to avoid matching <=, >=, =>.
 			if ( $pos < strlen( $condition ) - 1 ) {
 				$charAfter = $condition[ $pos + 1 ];

-				if ( $charAfter === '=' || $charAfter === '>' ) {
+				if ( $charAfter === '=' || $charAfter === '>' || $charAfter === '<' ) {
 					++$pos;
 					continue;
 				}
 			}

And add < to the before-check as well to handle cases like $x << 1 where we're looking for >:

 				// Skip if this is part of ->, =>, <=, >=, or a multi-char comparison.
-				if ( $charBefore === '-' || $charBefore === '=' || $charBefore === '<' || $charBefore === '>' || $charBefore === '!' ) {
+				if ( $charBefore === '-' || $charBefore === '=' || $charBefore === '<' || $charBefore === '>' || $charBefore === '!' || $charBefore === $operator ) {
🧹 Nitpick comments (1)
phpcs-sniffs/Formidable/Sniffs/CodeAnalysis/FlipLoopIfElseToContinueSniff.php (1)

424-461: Consider extracting shared helper methods into a trait.

The findComparisonOperator(), flipComparisonOperator(), hasTopLevelOperator(), negateCondition(), dedentCode(), and getIndentation() methods are duplicated across all five Flip*Sniff classes. Consolidating them into a trait (e.g., ConditionFlippingTrait) would reduce maintenance burden and ensure consistent behavior.

♻️ Example trait structure
<?php
namespace Formidable\Sniffs\CodeAnalysis;

trait ConditionFlippingTrait {
    private function findComparisonOperator( $condition, $operator ) {
        // shared implementation
    }

    private function flipComparisonOperator( $condition ) {
        // shared implementation
    }

    private function hasTopLevelOperator( $condition ) {
        // shared implementation
    }

    private function negateCondition( $condition ) {
        // shared implementation
    }

    private function dedentCode( $code ) {
        // shared implementation
    }

    private function getIndentation( File $phpcsFile, $stackPtr ) {
        // shared implementation
    }
}

Then in each sniff class:

class FlipLoopIfElseToContinueSniff implements Sniff {
    use ConditionFlippingTrait;
    // ...
}

@Crabcyborg Crabcyborg merged commit 007da1b into master Jan 20, 2026
35 of 38 checks passed
@Crabcyborg Crabcyborg deleted the update_flip_sniffs_to_handle_object_properties_better branch January 20, 2026 01:41
@Crabcyborg Crabcyborg changed the title Updae flip sniffs to handle object properties better Update flip sniffs to handle object properties better Jan 20, 2026
stephywells pushed a commit that referenced this pull request Apr 4, 2026
…_object_properties_better

Updae flip sniffs to handle object properties better
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant