From 724fbf26eac6fa0d0accdba2d21a04e8364a4653 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Tim=20D=C3=BCsterhus?= Date: Fri, 4 Jan 2013 16:03:24 +0100 Subject: [PATCH] Validate declaration of use --- .../Sniffs/Namespaces/UseDeclarationSniff.php | 85 +++++++++++++++++++ CodeSniff/WCF/ruleset.xml | 1 + 2 files changed, 86 insertions(+) create mode 100644 CodeSniff/WCF/Sniffs/Namespaces/UseDeclarationSniff.php diff --git a/CodeSniff/WCF/Sniffs/Namespaces/UseDeclarationSniff.php b/CodeSniff/WCF/Sniffs/Namespaces/UseDeclarationSniff.php new file mode 100644 index 0000000000..38c47fcc4c --- /dev/null +++ b/CodeSniff/WCF/Sniffs/Namespaces/UseDeclarationSniff.php @@ -0,0 +1,85 @@ + 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 + * @package com.woltlab.wcf + * @category Community Framework + */ +class WCF_Sniffs_Namespaces_UseDeclarationSniff implements PHP_CodeSniffer_Sniff { + /** + * Returns an array of tokens this test wants to listen for. + * + * @return array + */ + public function register() { + return array(T_USE); + + } + + /** + * 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(); + + // Ignore USE keywords inside closures. + $next = $phpcsFile->findNext(T_WHITESPACE, ($stackPtr + 1), null, true); + if ($tokens[$next]['code'] === T_OPEN_PARENTHESIS) { + return; + } + + // Only one USE declaration allowed per statement. + $next = $phpcsFile->findNext(array(T_COMMA, T_SEMICOLON), ($stackPtr + 1)); + if ($tokens[$next]['code'] === T_COMMA) { + $error = 'There must be one USE keyword per declaration'; + $phpcsFile->addError($error, $stackPtr, 'MultipleDeclarations'); + } + + // Leading NS_SEPARATOR must be omitted + $next = $phpcsFile->findNext(array(T_NS_SEPARATOR, T_STRING), ($stackPtr + 1)); + if ($tokens[$next]['code'] === T_NS_SEPARATOR) { + $error = 'Leading backslash must be omitted.'; + $phpcsFile->addError($error, $stackPtr, 'LeadingNSSeparator'); + } + + // Make sure this USE comes after the first namespace declaration. + $prev = $phpcsFile->findPrevious(T_NAMESPACE, ($stackPtr - 1)); + if ($prev !== false) { + $first = $phpcsFile->findNext(T_NAMESPACE, 1); + if ($prev !== $first) { + $error = 'USE declarations must go after the first namespace declaration'; + $phpcsFile->addError($error, $stackPtr, 'UseAfterNamespace'); + } + } + + // Only interested in the last USE statement from here onwards. + $nextUse = $phpcsFile->findNext(T_USE, ($stackPtr + 1)); + if ($nextUse !== false) { + return; + } + + $end = $phpcsFile->findNext(T_SEMICOLON, ($stackPtr + 1)); + $next = $phpcsFile->findNext(T_WHITESPACE, ($end + 1), null, true); + $diff = ($tokens[$next]['line'] - $tokens[$end]['line'] - 1); + if ($diff !== 1) { + if ($diff < 0) { + $diff = 0; + } + + $error = 'There must be one blank line after the last USE statement; %s found;'; + $data = array($diff); + $phpcsFile->addError($error, $stackPtr, 'SpaceAfterLastUse', $data); + } + + } +} diff --git a/CodeSniff/WCF/ruleset.xml b/CodeSniff/WCF/ruleset.xml index 4bd6de83d8..8d6a7820ce 100644 --- a/CodeSniff/WCF/ruleset.xml +++ b/CodeSniff/WCF/ruleset.xml @@ -31,6 +31,7 @@ + -- 2.20.1