Check whether imports are correctly ordered
authorTim Düsterhus <duesterhus@woltlab.com>
Fri, 4 Jan 2013 16:30:23 +0000 (17:30 +0100)
committerTim Düsterhus <duesterhus@woltlab.com>
Fri, 4 Jan 2013 16:30:23 +0000 (17:30 +0100)
Closes #987

16 files changed:
CodeSniff/WCF/Sniffs/Namespaces/SortedUseDeclarationSniff.php [new file with mode: 0644]
CodeSniff/WCF/Sniffs/Namespaces/UseDeclarationSniff.php
CodeSniff/WCF/ruleset.xml
wcfsetup/install/files/lib/acp/form/LanguageMultilingualismForm.class.php
wcfsetup/install/files/lib/acp/form/LanguageServerAddForm.class.php
wcfsetup/install/files/lib/acp/form/LanguageServerEditForm.class.php
wcfsetup/install/files/lib/acp/form/StyleAddForm.class.php
wcfsetup/install/files/lib/acp/page/CacheListPage.class.php
wcfsetup/install/files/lib/data/acl/option/ACLOptionAction.class.php
wcfsetup/install/files/lib/data/application/ApplicationAction.class.php
wcfsetup/install/files/lib/data/category/CategoryNode.class.php
wcfsetup/install/files/lib/data/category/CategoryNodeList.class.php
wcfsetup/install/files/lib/data/option/Option.class.php
wcfsetup/install/files/lib/system/cache/builder/CategoryACLOptionCacheBuilder.class.php
wcfsetup/install/files/lib/system/category/CategoryHandler.class.php
wcfsetup/install/files/lib/system/version/VersionHandler.class.php

diff --git a/CodeSniff/WCF/Sniffs/Namespaces/SortedUseDeclarationSniff.php b/CodeSniff/WCF/Sniffs/Namespaces/SortedUseDeclarationSniff.php
new file mode 100644 (file)
index 0000000..0f9281a
--- /dev/null
@@ -0,0 +1,95 @@
+<?php
+/**
+ * This sniff is based on Squiz_Sniffs_Classes_ClassFileNameSniff. Originally written
+ * by Greg Sherwood <gsherwood@squiz.net> and released under the terms of the BSD Licence.
+ * See: https://github.com/squizlabs/PHP_CodeSniffer/blob/master/CodeSniffer/Standards/PSR2/Sniffs/Namespaces/UseDeclarationSniff.php
+ * 
+ * @author     Tim Duesterhus
+ * @license    BSD Licence <https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt>
+ * @package    com.woltlab.wcf
+ * @category   Community Framework
+ */
+class WCF_Sniffs_Namespaces_SortedUseDeclarationSniff implements PHP_CodeSniffer_Sniff {
+       /**
+        * Returns an array of tokens this test wants to listen for.
+        *
+        * @return array
+        */
+       public function register() {
+               return array(T_OPEN_TAG);
+       }
+
+       /**
+        * Processes this test, when one of its tokens is encountered.
+        *
+        * @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
+        * @param int                             $stackPtr  The position of the current token in
+        *                                                                              the stack passed in $tokens.
+        *
+        * @return void
+        */
+       public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) {
+               $tokens = $phpcsFile->getTokens();
+               
+               $classes = array();
+               while (true) {
+                       $stackPtr = $phpcsFile->findNext(T_USE, ($stackPtr + 1));
+                       if ($stackPtr === false) break;
+                       
+                       // Ignore USE keywords inside closures.
+                       $next = $phpcsFile->findNext(T_WHITESPACE, ($stackPtr + 1), null, true);
+                       if ($tokens[$next]['code'] === T_OPEN_PARENTHESIS) {
+                               break;
+                       }
+                       $start = $phpcsFile->findNext(array(T_NS_SEPARATOR, T_STRING), ($stackPtr + 1));
+                       $end = $phpcsFile->findNext(array(T_NS_SEPARATOR, T_STRING), ($start + 1), null, true);
+                       $class = '';
+                       for ($i = $start; $i < $end; $i++) {
+                               $class .= $tokens[$i]['content'];
+                       }
+                       $classes[$stackPtr] = $class;
+               }
+               $previous = '';
+               foreach ($classes as $stackPtr => $class) {
+                       if ($previous !== '') {
+                               if ($class == $previous) {
+                                       $error = 'Using class %s twice;';
+                                       $data = array($class);
+                                       $phpcsFile->addError($error, $stackPtr, 'DuplicateUse', $data);
+                                       
+                               }
+                               else if (!$this->compare($previous, $class)) {
+                                       $error = 'Uses are misordered; check %s and %s';
+                                       $data = array($previous, $class);
+                                       $phpcsFile->addError($error, $stackPtr, 'MisorderedUse', $data);
+                               }
+                       }
+                       $previous = $class;
+               }
+       }
+       
+       public function compare($classA, $classB) {
+               if ($classA == $classB) return true;
+               
+               $classA = explode('\\', $classA);
+               $classB = explode('\\', $classB);
+               
+               for ($i = 0, $max = min(count($classA), count($classB)); $i < $max; $i++) {
+                       if ($classA[$i] == $classB[$i]) {
+                               unset($classA[$i], $classB[$i]);
+                       }
+               }
+               $classA = array_values($classA);
+               $classB = array_values($classB);
+               
+               for ($i = 0, $max = min(count($classA), count($classB)); $i < $max; $i++) {
+                       if (ucfirst($classB[$i]) == $classB[$i] && ucfirst($classA[$i]) != $classA[$i]) return true;
+                       if (ucfirst($classB[$i]) != $classB[$i] && ucfirst($classA[$i]) == $classA[$i]) return false;
+                       
+                       if (strcasecmp($classA[$i], $classB[$i]) < 0) {
+                               return true;
+                       }
+               }
+               return false;
+       }
+}
index b5adfc30459f8b1219c89fb1f5dccb014c7f5fce..d9ba6632ed443be3105225226c60ecb1ac7a52fe 100644 (file)
@@ -17,7 +17,6 @@ class WCF_Sniffs_Namespaces_UseDeclarationSniff implements PHP_CodeSniffer_Sniff
         */
        public function register() {
                return array(T_USE);
-
        }
 
        /**
index 4c1e73d580c3e027e296d36db297a559c5b50e38..4794a9cee036367ee93f958359c9d2f3fe27171a 100644 (file)
@@ -32,6 +32,7 @@
        <rule ref="WCF.Classes.ClassFileName" />
        <rule ref="WCF.ControlStructures.ControlSignature" />
        <rule ref="WCF.PHP.DiscouragePCRE" />
+       <rule ref="WCF.Namespaces.SortedUseDeclaration" />
        <rule ref="WCF.Namespaces.UseDeclaration" />
        <rule ref="WCF.WhiteSpace.SuperfluousWhitespace" />
        <rule ref="Zend.Files.ClosingTag" />
index 7c1e326fa31a074f1eaa729113cf0522937e3eea..1ee730f6075f7d201e8b33562703a5c606322028 100644 (file)
@@ -2,9 +2,9 @@
 namespace wcf\acp\form;
 use wcf\data\language\LanguageEditor;
 use wcf\form\AbstractForm;
-use wcf\system\language\LanguageFactory;
-use wcf\system\exception\UserInputException;
 use wcf\system\cache\CacheHandler;
+use wcf\system\exception\UserInputException;
+use wcf\system\language\LanguageFactory;
 use wcf\system\WCF;
 use wcf\system\WCFACP;
 use wcf\util\ArrayUtil;
index bde18715e569de3c6b8e06e8aff3e579b8178393..1117c16e3614ab8b10c602965b0b38a8b6160151 100644 (file)
@@ -3,9 +3,9 @@ namespace wcf\acp\form;
 use wcf\data\language\server\LanguageServerAction;
 use wcf\data\package\update\server\PackageUpdateServer;
 use wcf\form\AbstractForm;
+use wcf\system\exception\UserInputException;
 use wcf\system\WCF;
 use wcf\system\WCFACP;
-use wcf\system\exception\UserInputException;
 use wcf\util\StringUtil;
 
 /**
index 30f2981a13d2fffee5f295d982020c332b26619a..2d34d060c78ff623619a3a3c9b065b7cd07fbfa3 100644 (file)
@@ -3,8 +3,8 @@ namespace wcf\acp\form;
 use wcf\data\language\server\LanguageServer;
 use wcf\data\language\server\LanguageServerAction;
 use wcf\form\AbstractForm;
-use wcf\system\WCF;
 use wcf\system\exception\IllegalLinkException;
+use wcf\system\WCF;
 
 /**
  * Shows the language server edit form.
index 3e76477890798399c575fa7561d0f533196028cb..9b188f295a30abb9b3135702c2c1a99efce84201 100644 (file)
@@ -1,8 +1,8 @@
 <?php
 namespace wcf\acp\form;
-use wcf\data\style\StyleEditor;
 use wcf\data\package\Package;
 use wcf\data\style\StyleAction;
+use wcf\data\style\StyleEditor;
 use wcf\data\template\group\TemplateGroupList;
 use wcf\form\AbstractForm;
 use wcf\system\event\EventHandler;
index 155f111310019743d1143b2697f6dde7518c6e19..9e385dfada02be5fc70cf19a665f0440f9b8f944 100755 (executable)
@@ -5,8 +5,8 @@ use wcf\system\cache\CacheHandler;
 use wcf\system\exception\SystemException;
 use wcf\system\Regex;
 use wcf\system\WCF;
-use wcf\util\FileUtil;
 use wcf\util\DirectoryUtil;
+use wcf\util\FileUtil;
 
 /**
  * Shows a list of all cache resources.
index 1036433abb7231c9e8cba168fe7f25ef3e9f01cc..4890f9561e0f4dc2f76fd82593b1b8e6a396fadc 100644 (file)
@@ -1,8 +1,8 @@
 <?php
 namespace wcf\data\acl\option;
 use wcf\data\AbstractDatabaseObjectAction;
-use wcf\system\exception\UserInputException;
 use wcf\system\acl\ACLHandler;
+use wcf\system\exception\UserInputException;
 
 /**
  * Executes acl option-related actions.
index fa0242c03441c297e102c662244f3f6da124fd5f..4a59a0374e881759d84412a85bc54b5d786e56ce 100644 (file)
@@ -1,8 +1,8 @@
 <?php
 namespace wcf\data\application;
-use wcf\data\AbstractDatabaseObjectAction;
 use wcf\data\package\Package;
 use wcf\data\package\PackageCache;
+use wcf\data\AbstractDatabaseObjectAction;
 use wcf\system\cache\CacheHandler;
 use wcf\system\exception\PermissionDeniedException;
 use wcf\system\exception\UserInputException;
index bb5ded386835cdb252dea7f5fec3dfb899ff7e6a..4a154a3feb5503ba5c0a95e7047572fda912fbeb 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 namespace wcf\data\category;
-use wcf\data\DatabaseObjectDecorator;
 use wcf\data\DatabaseObject;
+use wcf\data\DatabaseObjectDecorator;
 use wcf\system\category\CategoryHandler;
 
 /**
index b5b4366e547b023adbc0a0bee1a6881c483a7e26..0f2fbf3fbf4adfa326c5bb901abc45c883d213bd 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 namespace wcf\data\category;
-use wcf\system\exception\SystemException;
 use wcf\system\category\CategoryHandler;
+use wcf\system\exception\SystemException;
 
 /**
  * Represents a category node list.
index 7df9afa9e14a643e1b8b65f8fd804bffba162fa3..6d35e2d566e613e1edaeef5baa727fa076cf8a57 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 namespace wcf\data\option;
-use wcf\data\DatabaseObject;
 use wcf\data\package\Package;
+use wcf\data\DatabaseObject;
 use wcf\system\WCF;
 use wcf\util\StringUtil;
 
index dba03167f0d4f8e79f4824cc9b4010daf20b3275..b99d6e135dd3416008147cb76c32d2ee191aa231 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 namespace wcf\system\cache\builder;
-use wcf\system\category\CategoryHandler;
 use wcf\system\acl\ACLHandler;
+use wcf\system\category\CategoryHandler;
 
 /**
  * Caches the acl options of categories.
index 8442e4d787e7239be2e5e59a442b71cea1b5c2c7..1cc40ce4af02c6e71199ff4560f1861463fcf919 100644 (file)
@@ -1,12 +1,12 @@
 <?php
 namespace wcf\system\category;
 use wcf\data\category\Category;
+use wcf\data\object\type\ObjectTypeCache;
 use wcf\data\DatabaseObject;
 use wcf\data\DatabaseObjectDecorator;
-use wcf\system\SingletonFactory;
-use wcf\data\object\type\ObjectTypeCache;
 use wcf\system\cache\CacheHandler;
 use wcf\system\exception\SystemException;
+use wcf\system\SingletonFactory;
 
 /**
  * Handles the categories.
index be1ec7d9e0f701bcbb226efa122756a97216155d..a01decd83c57401159b6eb789b2dbb2528bd4d49 100644 (file)
@@ -1,9 +1,9 @@
 <?php
 namespace wcf\system\version;
-use wcf\data\VersionableDatabaseObject;
-use wcf\system\SingletonFactory;
 use wcf\data\object\type\ObjectTypeCache;
+use wcf\data\VersionableDatabaseObject;
 use wcf\system\cache\CacheHandler;
+use wcf\system\SingletonFactory;
 
 /**
  * Handles versions of DatabaseObjects.