Browse Source

bug #3265 YodaFixer - fix problems of block statements followed by ternary statements (weareoutman, keradus, SpacePossum)

This PR was squashed before being merged into the 2.9 branch (closes #3265).

Discussion
----------

YodaFixer - fix problems of block statements followed by ternary statements

Fix #3264.

Solution:

In YodaStyleFixer::findComparisonStart(), during traversing tokens backward, when we met a block curly brace, If already found a non-block-brace meaningful token on the left side of the comparison, we can tell that the comparison started here.

Commits
-------

da812302 YodaFixer - fix problems of block statements followed by ternary statements
Dariusz Ruminski 7 years ago
parent
commit
2396fe0445

+ 2 - 0
circle.yml

@@ -14,6 +14,8 @@ dependencies:
         - brew update
         - brew tap homebrew/homebrew-php
         - brew install php71
+        - mkdir $(brew --prefix)/etc/php/7.1/conf.d
+        - echo "memory_limit = 512M" > $(brew --prefix)/etc/php/7.1/conf.d/memory.ini
         - curl -sS https://getcomposer.org/installer | php
         - php composer.phar global show hirak/prestissimo -q || php composer.phar global require --no-interaction --no-progress --optimize-autoloader hirak/prestissimo
     override:

+ 19 - 5
src/Fixer/ControlStructure/YodaStyleFixer.php

@@ -136,6 +136,12 @@ final class YodaStyleFixer extends AbstractFixer implements ConfigurationDefinit
         $count = count($tokens);
         while ($index < $count) {
             $token = $tokens[$index];
+            if ($token->isGivenKind([T_WHITESPACE, T_COMMENT, T_DOC_COMMENT])) {
+                ++$index;
+
+                continue;
+            }
+
             if ($this->isOfLowerPrecedence($token)) {
                 break;
             }
@@ -175,8 +181,16 @@ final class YodaStyleFixer extends AbstractFixer implements ConfigurationDefinit
     private function findComparisonStart(Tokens $tokens, $index)
     {
         --$index;
+        $nonBlockFound = false;
+
         while (0 <= $index) {
             $token = $tokens[$index];
+            if ($token->isGivenKind([T_WHITESPACE, T_COMMENT, T_DOC_COMMENT])) {
+                --$index;
+
+                continue;
+            }
+
             if ($this->isOfLowerPrecedence($token)) {
                 break;
             }
@@ -184,11 +198,15 @@ final class YodaStyleFixer extends AbstractFixer implements ConfigurationDefinit
             $block = Tokens::detectBlockType($token);
             if (null === $block) {
                 --$index;
+                $nonBlockFound = true;
 
                 continue;
             }
 
-            if ($block['isStart']) {
+            if (
+                $block['isStart']
+                || ($nonBlockFound && Tokens::BLOCK_TYPE_CURLY_BRACE === $block['type']) // closing of structure not related to the comparison
+            ) {
                 break;
             }
 
@@ -400,10 +418,6 @@ final class YodaStyleFixer extends AbstractFixer implements ConfigurationDefinit
      */
     private function isOfLowerPrecedence(Token $token)
     {
-        if ($token->isGivenKind([T_WHITESPACE, T_COMMENT, T_DOC_COMMENT])) {
-            return false;
-        }
-
         static $tokens;
 
         if (null === $tokens) {

+ 33 - 9
tests/Fixer/ControlStructure/YodaStyleFixerTest.php

@@ -211,7 +211,7 @@ if ($a = $obj instanceof A === true) {
             ['<?php $j = 2 * $myVar % 3 === $a;'],
             ['<?php return $k === 2 * $myVar % 3;'],
             ['<?php $l = $c > 2;'],
-            ['<?php return $this->myObject->{$index}+$b === "";'],
+            ['<?php return $this->myObject1->{$index}+$b === "";'],
             ['<?php return $m[2]+1 == 2;'],
             // https://github.com/FriendsOfPHP/PHP-CS-Fixer/pull/693
             ['<?php return array(2) == $o;'],
@@ -267,16 +267,20 @@ if ($a = $obj instanceof A === true) {
                 '<?php return $this->myArray[$index]->a === "";',
             ],
             [
-                '<?php return "" === $this->myObject->  {$index};',
-                '<?php return $this->myObject->  {$index} === "";',
+                '<?php return "" === $this->myObject2->  {$index};',
+                '<?php return $this->myObject2->  {$index} === "";',
             ],
             [
-                '<?php return "" === $this->myObject->{$index}->a;',
-                '<?php return $this->myObject->{$index}->a === "";',
+                '<?php return "" === $this->myObject3->{$index}->a;',
+                '<?php return $this->myObject3->{$index}->a === "";',
             ],
             [
-                '<?php return "" === $this->myObject->$index->a;',
-                '<?php return $this->myObject->$index->a === "";',
+                '<?php return "" === $this->myObject4->{$index}->{$index}->a;',
+                '<?php return $this->myObject4->{$index}->{$index}->a === "";',
+            ],
+            [
+                '<?php return "" === $this->myObject4->$index->a;',
+                '<?php return $this->myObject4->$index->a === "";',
             ],
             [
                 '<?php return self::MY_CONST === self::$myVariable;',
@@ -363,8 +367,28 @@ $a#4
                 '<?php $i = $this/*a*//*b*//*c*//*d*//*e*//*f*/->getStuff() === 2;',
             ],
             [
-                '<?php return "" === $this->myObject->{$index}->/*1*//*2*/b;',
-                '<?php return $this->myObject->{$index}->/*1*//*2*/b === "";',
+                '<?php return "" === $this->myObject5->{$index}->/*1*//*2*/b;',
+                '<?php return $this->myObject5->{$index}->/*1*//*2*/b === "";',
+            ],
+            [
+                '<?php
+                function hello() {}
+                1 === $a ? b() : c();
+                ',
+                '<?php
+                function hello() {}
+                $a === 1 ? b() : c();
+                ',
+            ],
+            [
+                '<?php
+                class A{}
+                1 === $a ? b() : c();
+                ',
+                '<?php
+                class A{}
+                $a === 1 ? b() : c();
+                ',
             ],
         ];
     }