Browse Source

Added ArrayElementNoSpaceBeforeCommaFixer and ArrayElementWhiteSpaceAfterCommaFixer

adam 9 years ago
parent
commit
a7a9850ff5

+ 10 - 0
README.rst

@@ -284,6 +284,16 @@ Choose from the list of available fixers:
                         visibility; static MUST be
                         declared after the visibility.
 
+* **array_element_no_space_before_comma** [symfony]
+                        In array declaration, there
+                        MUST NOT be a space before
+                        each comma.
+
+* **array_element_white_space_after_comma** [symfony]
+                        In array declaration, there
+                        MUST be a white wspace after
+                        each comma.
+
 * **blankline_after_open_tag** [symfony]
                         Ensure there is no code on the
                         same line as the PHP open tag

+ 99 - 0
Symfony/CS/Fixer/Symfony/ArrayElementNoSpaceBeforeCommaFixer.php

@@ -0,0 +1,99 @@
+<?php
+
+/*
+ * This file is part of the PHP CS utility.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+namespace Symfony\CS\Fixer\Symfony;
+
+use Symfony\CS\AbstractFixer;
+use Symfony\CS\Tokenizer\Tokens;
+
+/**
+ * @author Adam Marczuk <adam@marczuk.info>
+ */
+final class ArrayElementNoSpaceBeforeCommaFixer extends AbstractFixer
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function fix(\SplFileInfo $file, $content)
+    {
+        $tokens = Tokens::fromCode($content);
+
+        for ($index = $tokens->count() - 1; $index >= 0; --$index) {
+            if (!$tokens->isArray($index)) {
+                continue;
+            }
+
+            $this->fixSpacing($index, $tokens);
+        }
+
+        return $tokens->generateCode();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getDescription()
+    {
+        return 'In array declaration, there MUST NOT be a space before each comma.';
+    }
+
+    /**
+     * Method to fix spacing in array declaration.
+     *
+     * @param int    $index
+     * @param Tokens $tokens
+     */
+    private function fixSpacing($index, Tokens $tokens)
+    {
+        $multiLine = $tokens->isArrayMultiLine($index);
+        if ($tokens->isShortArray($index)) {
+            $startIndex = $index;
+            $endIndex = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_SQUARE_BRACE, $startIndex);
+        } else {
+            $startIndex = $tokens->getNextTokenOfKind($index, array('('));
+            $endIndex = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_PARENTHESIS_BRACE, $startIndex);
+        }
+
+        for ($i = $endIndex - 1; $i > $startIndex; --$i) {
+            $i = $this->skipNonArrayElements($i, $tokens);
+            $currentToken = $tokens[$i];
+            $prevIndex = $tokens->getPrevNonWhitespace($i - 1);
+            if ($currentToken->equals(',') && !$tokens[$prevIndex]->equals(array(T_END_HEREDOC))) {
+                $tokens->removeLeadingWhitespace($i);
+            }
+        }
+    }
+
+    /**
+     * Method to move index over the non-array elements like function calls or function declarations.
+     *
+     * @param int    $index
+     * @param Tokens $tokens
+     *
+     * @return int New index
+     */
+    private function skipNonArrayElements($index, Tokens $tokens)
+    {
+        if ($tokens[$index]->equals('}')) {
+            return $tokens->findBlockEnd(Tokens::BLOCK_TYPE_CURLY_BRACE, $index, false);
+        }
+
+        if ($tokens[$index]->equals(')')) {
+            $startIndex = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_PARENTHESIS_BRACE, $index, false);
+            $startIndex = $tokens->getPrevMeaningfulToken($startIndex);
+            if (!$tokens->isArray($startIndex)) {
+                return $startIndex;
+            }
+        }
+
+        return $index;
+    }
+}

+ 98 - 0
Symfony/CS/Fixer/Symfony/ArrayElementWhiteSpaceAfterCommaFixer.php

@@ -0,0 +1,98 @@
+<?php
+
+/*
+ * This file is part of the PHP CS utility.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+namespace Symfony\CS\Fixer\Symfony;
+
+use Symfony\CS\AbstractFixer;
+use Symfony\CS\Tokenizer\Token;
+use Symfony\CS\Tokenizer\Tokens;
+
+/**
+ * @author Adam Marczuk <adam@marczuk.info>
+ */
+final class ArrayElementWhiteSpaceAfterCommaFixer extends AbstractFixer
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function fix(\SplFileInfo $file, $content)
+    {
+        $tokens = Tokens::fromCode($content);
+
+        for ($index = $tokens->count() - 1; $index >= 0; --$index) {
+            if (!$tokens->isArray($index)) {
+                continue;
+            }
+
+            $this->fixSpacing($index, $tokens);
+        }
+
+        return $tokens->generateCode();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getDescription()
+    {
+        return 'In array declaration, there MUST be a white wspace after each comma.';
+    }
+
+    /**
+     * Method to fix spacing in array declaration.
+     *
+     * @param int    $index
+     * @param Tokens $tokens
+     */
+    private function fixSpacing($index, Tokens $tokens)
+    {
+        $multiLine = $tokens->isArrayMultiLine($index);
+        if ($tokens->isShortArray($index)) {
+            $startIndex = $index;
+            $endIndex = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_SQUARE_BRACE, $startIndex);
+        } else {
+            $startIndex = $tokens->getNextTokenOfKind($index, array('('));
+            $endIndex = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_PARENTHESIS_BRACE, $startIndex);
+        }
+
+        for ($i = $endIndex - 1; $i > $startIndex; --$i) {
+            $i = $this->skipNonArrayElements($i, $tokens);
+            if ($tokens[$i]->equals(',') && !$tokens[$i + 1]->isWhitespace()) {
+                $tokens->insertAt($i + 1, new Token(array(T_WHITESPACE, ' ')));
+            }
+        }
+    }
+
+    /**
+     * Method to move index over the non-array elements like function calls or function declarations.
+     *
+     * @param int    $index
+     * @param Tokens $tokens
+     *
+     * @return int New index
+     */
+    private function skipNonArrayElements($index, Tokens $tokens)
+    {
+        if ($tokens[$index]->equals('}')) {
+            return $tokens->findBlockEnd(Tokens::BLOCK_TYPE_CURLY_BRACE, $index, false);
+        }
+
+        if ($tokens[$index]->equals(')')) {
+            $startIndex = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_PARENTHESIS_BRACE, $index, false);
+            $startIndex = $tokens->getPrevMeaningfulToken($startIndex);
+            if (!$tokens->isArray($startIndex)) {
+                return $startIndex;
+            }
+        }
+
+        return $index;
+    }
+}

+ 126 - 0
Symfony/CS/Tests/Fixer/Symfony/ArrayElementNoSpaceBeforeCommaFixerTest.php

@@ -0,0 +1,126 @@
+<?php
+
+/*
+ * This file is part of the PHP CS utility.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+namespace Symfony\CS\Tests\Fixer\Symfony;
+
+use Symfony\CS\Tests\Fixer\AbstractFixerTestBase;
+
+/**
+ * @author Adam Marczuk <adam@marczuk.info>
+ */
+final class ArrayElementNoSpaceBeforeCommaFixerTest extends AbstractFixerTestBase
+{
+    /**
+     * @dataProvider testFixProvider
+     */
+    public function testFix($expected, $input = null)
+    {
+        $this->makeTest($expected, $input);
+    }
+
+    public function testFixProvider()
+    {
+        return array(
+            //old style array
+            array(
+                '<?php $x = array(1, "2",3);',
+                '<?php $x = array(1 , "2",3);',
+            ),
+            //old style array with comments
+            array(
+                '<?php $x = array /* comment */ (1,  "2", 3);',
+                '<?php $x = array /* comment */ (1  ,  "2", 3);',
+            ),
+
+            //short array
+            array(
+                '<?php $x = [1,  "2", 3,$y];',
+                '<?php $x = [1 ,  "2", 3 ,$y];',
+            ),
+            // don't change function calls
+            array(
+                '<?php $x = [ 1, "2",getValue(1,2  ,3 ),$y];',
+                '<?php $x = [ 1 , "2",getValue(1,2  ,3 )   ,$y];',
+            ),
+            // don't change function declarations
+            array(
+                '<?php $x = [1, "2", function( $x ,$y) { return $x + $y; }, $y];',
+                '<?php $x = [1 , "2", function( $x ,$y) { return $x + $y; }, $y];',
+            ),
+            // don't change function declarations but change array inside
+            array(
+                '<?php $x = [ 1,  "2","c" => function( $x ,$y) { return [$x, $y]; }, $y];',
+                '<?php $x = [ 1 ,  "2","c" => function( $x ,$y) { return [$x , $y]; }, $y];',
+            ),
+            // associative array (old)
+            array(
+                '<?php $x = array( "a" => $a, "b" =>  "b",3=>$this->foo(), "d" => 30);',
+                '<?php $x = array( "a" => $a , "b" =>  "b",3=>$this->foo()  , "d" => 30);',
+            ),
+            // associative array (short)
+            array(
+                '<?php $x = [  "a" => $a, "b"=>"b",3 => $this->foo(), "d" =>30  ];',
+                '<?php $x = [  "a" => $a , "b"=>"b",3 => $this->foo()    , "d" =>30  ];',
+            ),
+            // nested arrays
+            array(
+                '<?php $x = ["a" => $a, "b" => "b", 3=> [5,6, 7], "d" => array(1, 2,3,4)];',
+                '<?php $x = ["a" => $a , "b" => "b", 3=> [5 ,6, 7]  , "d" => array(1, 2,3 ,4)];',
+            ),
+            // multi line array
+            array(
+                '<?php $x = [  "a" =>$a,
+                    "b"=>  
+                "b",
+                    3 => $this->foo(), 
+                    "d" => 30  ];',
+                '<?php $x = [  "a" =>$a ,
+                    "b"=>  
+                "b",
+                    3 => $this->foo()  , 
+                    "d" => 30  ];',
+            ),
+            // multi line array
+            array(
+                '<?php $a = [
+                            "foo",
+                            "bar", 
+                        ];',
+                '<?php $a = [
+                            "foo" ,
+                            "bar"
+                            , 
+                        ];',
+            ),
+            // nested multiline
+            array(
+                '<?php $a = array(array(
+                                    array(T_OPEN_TAG),
+                                    array(T_VARIABLE, "$x"),
+                        ), 1);',
+            ),
+            array(
+                '<?php $a = array( // comment
+                    123,
+                );',
+            ),
+            array(
+                "<?php \$x = array(<<<'EOF'
+<?php \$a = '\\foo\\bar\\\\';
+EOF
+                , <<<'EOF'
+<?php \$a = \"\\foo\\bar\\\\\";
+EOF
+                    );",
+            ),
+        );
+    }
+}

+ 110 - 0
Symfony/CS/Tests/Fixer/Symfony/ArrayElementWhiteSpaceAfterCommaFixerTest.php

@@ -0,0 +1,110 @@
+<?php
+
+/*
+ * This file is part of the PHP CS utility.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+namespace Symfony\CS\Tests\Fixer\Symfony;
+
+use Symfony\CS\Tests\Fixer\AbstractFixerTestBase;
+
+/**
+ * @author Adam Marczuk <adam@marczuk.info>
+ */
+final class ArrayElementWhiteSpaceAfterCommaFixerTest extends AbstractFixerTestBase
+{
+    /**
+     * @dataProvider testFixProvider
+     */
+    public function testFix($expected, $input = null)
+    {
+        $this->makeTest($expected, $input);
+    }
+
+    public function testFixProvider()
+    {
+        return array(
+            //old style array
+            array(
+                '<?php $x = array( 1 , "2", 3);',
+                '<?php $x = array( 1 ,"2",3);',
+            ),
+            //old style array with comments
+            array(
+                '<?php $x = array /* comment */ ( 1 ,  "2", 3);',
+                '<?php $x = array /* comment */ ( 1 ,  "2",3);',
+            ),
+
+            //short array
+            array(
+                '<?php $x = [ 1 ,  "2", 3 , $y];',
+                '<?php $x = [ 1 ,  "2",3 ,$y];',
+            ),
+            // don't change function calls
+            array(
+                '<?php $x = [1, "2", getValue(1,2  ,3 ) , $y];',
+                '<?php $x = [1, "2",getValue(1,2  ,3 ) ,$y];',
+            ),
+            // don't change function declarations
+            array(
+                '<?php $x = [1,  "2", function( $x ,$y) { return $x + $y; }, $y];',
+                '<?php $x = [1,  "2",function( $x ,$y) { return $x + $y; },$y];',
+            ),
+            // don't change function declarations but change array inside
+            array(
+                '<?php $x = [1,  "2", "c" => function( $x ,$y) { return [$x , $y]; }, $y ];',
+                '<?php $x = [1,  "2","c" => function( $x ,$y) { return [$x ,$y]; },$y ];',
+            ),
+            // associative array (old)
+            array(
+                '<?php $x = array("a" => $a , "b" =>  "b", 3=>$this->foo(),  "d" => 30  );',
+                '<?php $x = array("a" => $a , "b" =>  "b",3=>$this->foo(),  "d" => 30  );',
+            ),
+            // associative array (short)
+            array(
+                '<?php $x = [  "a" => $a ,  "b"=>"b", 3 => $this->foo(), "d" =>30];',
+                '<?php $x = [  "a" => $a ,  "b"=>"b",3 => $this->foo(), "d" =>30];',
+            ),
+            // nested arrays
+            array(
+                '<?php $x = ["a" => $a, "b" => "b", 3=> [5, 6,  7] , "d" => array(1,  2, 3 , 4)];',
+                '<?php $x = ["a" => $a, "b" => "b",3=> [5,6,  7] , "d" => array(1,  2,3 ,4)];',
+            ),
+            // multi line array
+            array(
+                '<?php $x = ["a" =>$a,
+                    "b"=> "b",
+                    3 => $this->foo(), 
+                    "d" => 30];',
+            ),
+            // multi line array
+            array(
+                '<?php $a = [
+                            "foo" ,
+                            "bar", 
+                        ];',
+            ),
+            // nested multiline
+            array(
+                '<?php $a = array(array(
+                                    array(T_OPEN_TAG),
+                                    array(T_VARIABLE, "$x"),
+                        ), 1, );',
+                '<?php $a = array(array(
+                                    array(T_OPEN_TAG),
+                                    array(T_VARIABLE,"$x"),
+                        ),1,);',
+            ),
+            array(
+                '<?php $a = array( // comment
+                    123,
+                );',
+            ),
+        );
+    }
+}