From c61bba3e9aa34c789eef45e0b944d2451324ef8d Mon Sep 17 00:00:00 2001 From: Greg Sherwood Date: Thu, 19 Apr 2018 13:55:04 +1000 Subject: [PATCH] Initial work on a PSR-12 standard (ref #750) --- package.xml | 9 + .../ShortFormTypeKeywordsStandard.xml | 19 ++ .../CompoundNamespaceDepthStandard.xml | 28 ++ .../Keywords/ShortFormTypeKeywordsSniff.php | 68 +++++ .../CompoundNamespaceDepthSniff.php | 80 ++++++ .../ShortFormTypeKeywordsUnitTest.inc | 8 + .../ShortFormTypeKeywordsUnitTest.inc.fixed | 8 + .../ShortFormTypeKeywordsUnitTest.php | 52 ++++ .../CompoundNamespaceDepthUnitTest.inc | 31 +++ .../CompoundNamespaceDepthUnitTest.php | 52 ++++ src/Standards/PSR12/ruleset.xml | 247 ++++++++++++++++++ 11 files changed, 602 insertions(+) create mode 100644 src/Standards/PSR12/Docs/Keywords/ShortFormTypeKeywordsStandard.xml create mode 100644 src/Standards/PSR12/Docs/Namespaces/CompoundNamespaceDepthStandard.xml create mode 100644 src/Standards/PSR12/Sniffs/Keywords/ShortFormTypeKeywordsSniff.php create mode 100644 src/Standards/PSR12/Sniffs/Namespaces/CompoundNamespaceDepthSniff.php create mode 100644 src/Standards/PSR12/Tests/Keywords/ShortFormTypeKeywordsUnitTest.inc create mode 100644 src/Standards/PSR12/Tests/Keywords/ShortFormTypeKeywordsUnitTest.inc.fixed create mode 100644 src/Standards/PSR12/Tests/Keywords/ShortFormTypeKeywordsUnitTest.php create mode 100644 src/Standards/PSR12/Tests/Namespaces/CompoundNamespaceDepthUnitTest.inc create mode 100644 src/Standards/PSR12/Tests/Namespaces/CompoundNamespaceDepthUnitTest.php create mode 100644 src/Standards/PSR12/ruleset.xml diff --git a/package.xml b/package.xml index 10472737f7..4d78dc26e7 100644 --- a/package.xml +++ b/package.xml @@ -57,6 +57,10 @@ http://pear.php.net/dtd/package-2.0.xsd"> --- If the return type contains namespace information, it will be cleaned of whitespace and comments ---- To access the original return value string, use the main tokens array + - This release contains an incomplete version of the PSR-12 coding standard + -- Errors found using this standard should be valid, but it will miss a lot of violations until it is complete + -- If you'd like to test and help, you can use the standard by running PHPCS with --standard=PSR12 + - Config values set using --runtime-set now override any config values set in rulesets or the CodeSniffer.conf file - You can now apply include-pattern rules to individual message codes in a ruleset like you can with exclude-pattern rules -- Previously, include-pattern rules only applied to entire sniffs @@ -107,6 +111,11 @@ http://pear.php.net/dtd/package-2.0.xsd"> -- Allows the required spacing to be set using the spacing sniff property (default is 0) -- Allows newlines to be used by setting the ignoreNewlines sniff property (default is false) -- Thanks to Juliette Reinders Folmer for the contribution + - Added New PSR12.Keywords.ShortFormTypeKeywords sniff + -- Ensures the short form of PHP types is used when type casting + - Added New PSR12.Namespaces.CompundNamespaceDepth sniff + -- Ensures compund namespace use statements have a max depth of 2 levels + -- The max depth can be changed by setting the 'maxDepth' sniff property in a ruleset.xml file - Improved core support for grouped property declarations -- Also improves support in Squiz.WhiteSpace.ScopeKeywordSpacing and Squiz.WhiteSpace.MemberVarSpacing -- Thanks to Juliette Reinders Folmer for the patch diff --git a/src/Standards/PSR12/Docs/Keywords/ShortFormTypeKeywordsStandard.xml b/src/Standards/PSR12/Docs/Keywords/ShortFormTypeKeywordsStandard.xml new file mode 100644 index 0000000000..9bb5a8a558 --- /dev/null +++ b/src/Standards/PSR12/Docs/Keywords/ShortFormTypeKeywordsStandard.xml @@ -0,0 +1,19 @@ + + + + + + + + + + (boolean) $isValid; + ]]> + + + diff --git a/src/Standards/PSR12/Docs/Namespaces/CompoundNamespaceDepthStandard.xml b/src/Standards/PSR12/Docs/Namespaces/CompoundNamespaceDepthStandard.xml new file mode 100644 index 0000000000..b74e8b429f --- /dev/null +++ b/src/Standards/PSR12/Docs/Namespaces/CompoundNamespaceDepthStandard.xml @@ -0,0 +1,28 @@ + + + + + + + + + + SubnamespaceOne\AnotherNamespace\ClassA, + SubnamespaceOne\ClassB, + ClassZ, +}; + ]]> + + + diff --git a/src/Standards/PSR12/Sniffs/Keywords/ShortFormTypeKeywordsSniff.php b/src/Standards/PSR12/Sniffs/Keywords/ShortFormTypeKeywordsSniff.php new file mode 100644 index 0000000000..d76b493e63 --- /dev/null +++ b/src/Standards/PSR12/Sniffs/Keywords/ShortFormTypeKeywordsSniff.php @@ -0,0 +1,68 @@ + + * @copyright 2006-2015 Squiz Pty Ltd (ABN 77 084 670 600) + * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence + */ + +namespace PHP_CodeSniffer\Standards\PSR12\Sniffs\Keywords; + +use PHP_CodeSniffer\Sniffs\Sniff; +use PHP_CodeSniffer\Files\File; + +class ShortFormTypeKeywordsSniff implements Sniff +{ + + + /** + * Returns an array of tokens this test wants to listen for. + * + * @return array + */ + public function register() + { + return [ + T_BOOL_CAST, + T_INT_CAST, + ]; + + }//end register() + + + /** + * Processes this test, when one of its tokens is encountered. + * + * @param \PHP_CodeSniffer\Files\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(File $phpcsFile, $stackPtr) + { + $tokens = $phpcsFile->getTokens(); + + if (($tokens[$stackPtr]['code'] === T_BOOL_CAST + && strtolower($tokens[$stackPtr]['content']) === '(bool)') + || ($tokens[$stackPtr]['code'] === T_INT_CAST + && strtolower($tokens[$stackPtr]['content']) === '(int)') + ) { + return; + } + + $error = 'Short form type keywords must be used'; + $fix = $phpcsFile->addFixableError($error, $stackPtr, 'LongFound'); + if ($fix === true) { + if ($tokens[$stackPtr]['code'] === T_BOOL_CAST) { + $phpcsFile->fixer->replaceToken($stackPtr, '(bool)'); + } else { + $phpcsFile->fixer->replaceToken($stackPtr, '(int)'); + } + } + + }//end process() + + +}//end class diff --git a/src/Standards/PSR12/Sniffs/Namespaces/CompoundNamespaceDepthSniff.php b/src/Standards/PSR12/Sniffs/Namespaces/CompoundNamespaceDepthSniff.php new file mode 100644 index 0000000000..8839790df0 --- /dev/null +++ b/src/Standards/PSR12/Sniffs/Namespaces/CompoundNamespaceDepthSniff.php @@ -0,0 +1,80 @@ + + * @copyright 2006-2015 Squiz Pty Ltd (ABN 77 084 670 600) + * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence + */ + +namespace PHP_CodeSniffer\Standards\PSR12\Sniffs\Namespaces; + +use PHP_CodeSniffer\Sniffs\Sniff; +use PHP_CodeSniffer\Files\File; + +class CompoundNamespaceDepthSniff implements Sniff +{ + + /** + * The max depth for compound namespaces. + * + * @var integer + */ + public $maxDepth = 2; + + + /** + * Returns an array of tokens this test wants to listen for. + * + * @return array + */ + public function register() + { + return [T_OPEN_USE_GROUP]; + + }//end register() + + + /** + * Processes this test, when one of its tokens is encountered. + * + * @param \PHP_CodeSniffer\Files\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(File $phpcsFile, $stackPtr) + { + $this->maxDepth = (int) $this->maxDepth; + + $tokens = $phpcsFile->getTokens(); + + $end = $phpcsFile->findNext(T_CLOSE_USE_GROUP, ($stackPtr + 1)); + if ($end === false) { + return; + } + + $depth = 1; + for ($i = ($stackPtr + 1); $i <= $end; $i++) { + if ($tokens[$i]['code'] === T_NS_SEPARATOR) { + $depth++; + continue; + } + + if ($i === $end || $tokens[$i]['code'] === T_COMMA) { + // End of a namespace. + if ($depth > $this->maxDepth) { + $error = 'Compound namespaces cannot have a depth more than %s'; + $data = [$this->maxDepth]; + $phpcsFile->addError($error, $i, 'TooDeep', $data); + } + + $depth = 1; + } + } + + }//end process() + + +}//end class diff --git a/src/Standards/PSR12/Tests/Keywords/ShortFormTypeKeywordsUnitTest.inc b/src/Standards/PSR12/Tests/Keywords/ShortFormTypeKeywordsUnitTest.inc new file mode 100644 index 0000000000..cdc9f67add --- /dev/null +++ b/src/Standards/PSR12/Tests/Keywords/ShortFormTypeKeywordsUnitTest.inc @@ -0,0 +1,8 @@ + + * @copyright 2006-2015 Squiz Pty Ltd (ABN 77 084 670 600) + * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence + */ + +namespace PHP_CodeSniffer\Standards\PSR12\Tests\Keywords; + +use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest; + +class ShortFormTypeKeywordsUnitTest extends AbstractSniffUnitTest +{ + + + /** + * Returns the lines where errors should occur. + * + * The key of the array should represent the line number and the value + * should represent the number of errors that should occur on that line. + * + * @return array + */ + public function getErrorList() + { + return [ + 3 => 1, + 5 => 1, + 7 => 1, + ]; + + }//end getErrorList() + + + /** + * Returns the lines where warnings should occur. + * + * The key of the array should represent the line number and the value + * should represent the number of warnings that should occur on that line. + * + * @return array + */ + public function getWarningList() + { + return []; + + }//end getWarningList() + + +}//end class diff --git a/src/Standards/PSR12/Tests/Namespaces/CompoundNamespaceDepthUnitTest.inc b/src/Standards/PSR12/Tests/Namespaces/CompoundNamespaceDepthUnitTest.inc new file mode 100644 index 0000000000..3336fc2dc4 --- /dev/null +++ b/src/Standards/PSR12/Tests/Namespaces/CompoundNamespaceDepthUnitTest.inc @@ -0,0 +1,31 @@ + + * @copyright 2006-2015 Squiz Pty Ltd (ABN 77 084 670 600) + * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence + */ + +namespace PHP_CodeSniffer\Standards\PSR12\Tests\Namespaces; + +use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest; + +class CompoundNamespaceDepthUnitTest extends AbstractSniffUnitTest +{ + + + /** + * Returns the lines where errors should occur. + * + * The key of the array should represent the line number and the value + * should represent the number of errors that should occur on that line. + * + * @return array + */ + public function getErrorList() + { + return [ + 10 => 1, + 18 => 1, + 21 => 1, + ]; + + }//end getErrorList() + + + /** + * Returns the lines where warnings should occur. + * + * The key of the array should represent the line number and the value + * should represent the number of warnings that should occur on that line. + * + * @return array + */ + public function getWarningList() + { + return []; + + }//end getWarningList() + + +}//end class diff --git a/src/Standards/PSR12/ruleset.xml b/src/Standards/PSR12/ruleset.xml new file mode 100644 index 0000000000..bdecb6190c --- /dev/null +++ b/src/Standards/PSR12/ruleset.xml @@ -0,0 +1,247 @@ + + + The PSR-12 coding standard. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + + + 0 + + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +