Browse Source

NativeFunctionCasingFixer - Add

Possum 9 years ago
parent
commit
27b0c0320b

+ 5 - 0
README.rst

@@ -615,6 +615,11 @@ Choose from the list of available fixers:
                         closing semicolon are
                         prohibited.
 
+* **native_function_casing** [contrib]
+                        Function defined by PHP should
+                        be called using the correct
+                        casing.
+
 * **newline_after_open_tag** [contrib]
                         Ensure there is no code on the
                         same line as the PHP open tag.

+ 87 - 0
Symfony/CS/Fixer/Contrib/NativeFunctionCasingFixer.php

@@ -0,0 +1,87 @@
+<?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\Contrib;
+
+use Symfony\CS\AbstractFixer;
+use Symfony\CS\Tokenizer\Tokens;
+
+/**
+ * @author SpacePossum
+ */
+final class NativeFunctionCasingFixer extends AbstractFixer
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function fix(\SplFileInfo $file, $content)
+    {
+        $tokens = Tokens::fromCode($content);
+        for ($index = 0, $count = $tokens->count(); $index < $count; ++$index) {
+            // test if we are at a function all
+            if (!$tokens[$index]->isGivenKind(T_STRING)) {
+                continue;
+            }
+
+            $next = $tokens->getNextMeaningfulToken($index);
+            if (!$tokens[$next]->equals('(')) {
+                $index = $next;
+                continue;
+            }
+
+            $functionNamePrefix = $tokens->getPrevMeaningfulToken($index);
+            if ($tokens[$functionNamePrefix]->isGivenKind(array(T_DOUBLE_COLON, T_NEW, T_OBJECT_OPERATOR, T_FUNCTION))) {
+                continue;
+            }
+
+            // do not though the function call if it is to a function in a namespace other than the default
+            if ($tokens[$functionNamePrefix]->isGivenKind(T_NS_SEPARATOR) && $tokens[$tokens->getPrevMeaningfulToken($functionNamePrefix)]->isGivenKind(T_STRING)) {
+                continue;
+            }
+
+            // test if the function call is to a native PHP function
+            static $nativeFunctionNames = null;
+            if (null === $nativeFunctionNames) {
+                $nativeFunctionNames = $this->getNativeFunctionNames();
+            }
+
+            $lower = strtolower($tokens[$index]->getContent());
+            if (!array_key_exists($lower, $nativeFunctionNames)) {
+                continue;
+            }
+
+            $tokens[$index]->setContent($nativeFunctionNames[$lower]);
+
+            $index = $next;
+        }
+
+        return $tokens->generateCode();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getDescription()
+    {
+        return 'Function defined by PHP should be called using the correct casing.';
+    }
+
+    private function getNativeFunctionNames()
+    {
+        $allFunctions = get_defined_functions();
+        $functions = array();
+        foreach ($allFunctions['internal'] as $function) {
+            $functions[strtolower($function)] = $function;
+        }
+
+        return $functions;
+    }
+}

+ 117 - 0
Symfony/CS/Tests/Fixer/Contrib/NativeFunctionCasingFixerTest.php

@@ -0,0 +1,117 @@
+<?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\Contrib;
+
+use Symfony\CS\Tests\Fixer\AbstractFixerTestBase;
+
+/**
+ * @author SpacePossum
+ */
+class NativeFunctionCasingFixerTest extends AbstractFixerTestBase
+{
+    /**
+     * @dataProvider provideFixCases
+     */
+    public function testFix($expected, $input = null)
+    {
+        $this->makeTest($expected, $input);
+    }
+
+    public function provideFixCases()
+    {
+        return array(
+            array(
+                '<?php
+                namespace Bar {
+                    function STRLEN($str) {
+                        return "overriden" . \strlen($str);
+                    }
+                }
+
+                namespace {
+                    echo \Bar\STRLEN("xxx");
+                }',
+            ),
+            array(
+                '<?php
+                    echo strtolower("hello 1");
+                ',
+                '<?php
+                    echo STRTOLOWER("hello 1");
+                ',
+            ),
+            array(
+                '<?php
+                    echo strtolower //a
+                        ("hello 2");
+                ',
+                '<?php
+                    echo STRTOLOWER //a
+                        ("hello 2");
+                ',
+            ),
+            array(
+                '<?php
+                    echo strtolower /**/   ("hello 3");
+                ',
+                '<?php
+                    echo STRTOLOWER /**/   ("hello 3");
+                ',
+            ),
+            array(
+                '<?php
+                    echo \sqrt(4);
+                ',
+                '<?php
+                    echo \sQrT(4);
+                ',
+            ),
+            array(
+                '<?php
+                    echo "1".\sqrt("hello 5");
+                ',
+                '<?php
+                    echo "1".\SQRT("hello 5");
+                ',
+            ),
+            array(
+                '<?php
+                    class Test{
+                        public function gettypE()
+                        {
+                            return 1;
+                        }
+                    }
+
+                    function sqrT($a)
+                    {
+                    }
+                ',
+            ),
+            array(
+                '<?php
+                    new STRTOLOWER();
+                ',
+            ),
+            array(
+                '<?php
+                    a::STRTOLOWER();
+                ',
+            ),
+            array(
+                '<?php
+                    $a->STRTOLOWER();
+                ',
+            ),
+        );
+    }
+}