Ensure that all classes are imported via use
authorTim Düsterhus <duesterhus@woltlab.com>
Sat, 5 Jan 2013 15:42:56 +0000 (16:42 +0100)
committerTim Düsterhus <duesterhus@woltlab.com>
Sat, 5 Jan 2013 15:42:56 +0000 (16:42 +0100)
CodeSniff/WCF/Sniffs/Namespaces/ClassMustBeImportedSniff.php [new file with mode: 0644]
CodeSniff/WCF/Sniffs/Namespaces/SortedUseDeclarationSniff.php
CodeSniff/WCF/Sniffs/Namespaces/UseDeclarationSniff.php
CodeSniff/WCF/Sniffs/PHP/DiscouragePCRESniff.php
CodeSniff/WCF/ruleset.xml

diff --git a/CodeSniff/WCF/Sniffs/Namespaces/ClassMustBeImportedSniff.php b/CodeSniff/WCF/Sniffs/Namespaces/ClassMustBeImportedSniff.php
new file mode 100644 (file)
index 0000000..6a869d2
--- /dev/null
@@ -0,0 +1,66 @@
+<?php
+/**
+ * Disallows calling non global classes via FQN. Classes must be imported with use [...];
+ * 
+ * @author     Tim Duesterhus
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package    com.woltlab.wcf
+ * @category   Community Framework
+ */
+class WCF_Sniffs_Namespaces_ClassMustBeImportedSniff  implements PHP_CodeSniffer_Sniff {
+       /**
+        * Returns an array of tokens this test wants to listen for.
+        *
+        * @return array
+        */
+       public function register() {
+               return array(
+                       T_NS_SEPARATOR
+               );
+       }
+       
+       /**
+        * Processes this sniff, 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.
+        */
+       public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) {
+               $tokens = $phpcsFile->getTokens();
+               
+               // skip files in global namespace
+               if ($phpcsFile->findPrevious(T_NAMESPACE, $stackPtr) === false) {
+                       return;
+               }
+               
+               // no use found
+               if ($phpcsFile->findPrevious(array(T_NAMESPACE, T_USE), ($stackPtr - 1), null, false, null, true) === false) {
+                       // find previous class part and non class part
+                       $prevClassPart = $phpcsFile->findPrevious(array(T_STRING, T_NS_SEPARATOR), $stackPtr - 1);
+                       $prevNonClassPart = $phpcsFile->findPrevious(array(T_STRING, T_NS_SEPARATOR), $stackPtr - 1, null, true);
+                       
+                       // backslash as the very first character of the class is allowed (global classes)
+                       if ($prevClassPart >= $prevNonClassPart) {
+                               $nextNonClassPart = $phpcsFile->findNext(array(T_STRING, T_NS_SEPARATOR), $stackPtr + 1, null, true);
+                               $lastNSSep = $phpcsFile->findPrevious(T_NS_SEPARATOR, $nextNonClassPart);
+                               
+                               // check whether we are the last backslash (no multiple reporting)
+                               if ($lastNSSep === $stackPtr) {
+                                       $start = $phpcsFile->findPrevious(array(T_NS_SEPARATOR, T_STRING), $stackPtr - 1, null, true) + 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'];
+                                       }
+                                       
+                                       $error = 'Namespaced classes (%s) must be imported with use.';
+                                       $data = array(
+                                               $class
+                                       );
+                                       $phpcsFile->addError($error, $stackPtr, 'MustBeImported', $data);
+                               }
+                       }
+               }
+       }
+}
\ No newline at end of file
index 0f9281a9e988c13fe349858018ab9d7aab4663c4..be72338a552c8de799921e56d7572e5fc89458da 100644 (file)
@@ -5,7 +5,7 @@
  * 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>
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
  * @package    com.woltlab.wcf
  * @category   Community Framework
  */
index d9ba6632ed443be3105225226c60ecb1ac7a52fe..1d9bac295a4c2bf9789215d79d8400f0fb57c4d6 100644 (file)
@@ -5,7 +5,7 @@
  * 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>
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
  * @package    com.woltlab.wcf
  * @category   Community Framework
  */
index d47fa821935148f9bf0e97927c5075b83963666a..e221f6ba59851492e4412c6f99de77afeb102881 100644 (file)
@@ -3,7 +3,7 @@
  * Discourages use of raw PCRE functions. \wcf\system\Regex is a superior way to use Regex.
  * 
  * @author     Tim Duesterhus
- * @license    BSD Licence <https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt>
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
  * @package    com.woltlab.wcf
  * @category   Community Framework
  */
index 7f66d7cc1955907f8c12fdbee27168dc2281e6c8..78532763776c52fd312507450a255886b9c16f73 100644 (file)
@@ -32,6 +32,7 @@
        <rule ref="WCF.Classes.ClassFileName" />
        <rule ref="WCF.ControlStructures.ControlSignature" />
        <!--rule ref="WCF.PHP.DiscouragePCRE" /--> <!-- TODO: Sniff is disabled by commenting out the extends in the sniff file! -->
+       <rule ref="WCF.Namespaces.ClassMustBeImported" />
        <rule ref="WCF.Namespaces.SortedUseDeclaration" />
        <rule ref="WCF.Namespaces.UseDeclaration" />
        <rule ref="WCF.WhiteSpace.SuperfluousWhitespace" />