diff --git a/coder_sniffer/Drupal/Sniffs/Functions/MultiLineTrailingCommaSniff.php b/coder_sniffer/Drupal/Sniffs/Functions/MultiLineTrailingCommaSniff.php new file mode 100644 index 00000000..805996fb --- /dev/null +++ b/coder_sniffer/Drupal/Sniffs/Functions/MultiLineTrailingCommaSniff.php @@ -0,0 +1,82 @@ + + */ + public function register() + { + if (version_compare(PHP_VERSION, '8.0.0') < 0) { + return []; + } + + return [ + T_FUNCTION, + T_CLOSURE, + ]; + + }//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(); + + $function = $tokens[$stackPtr]; + if ($tokens[$function['parenthesis_opener']]['line'] === $tokens[$function['parenthesis_closer']]['line']) { + return; + } + + $lastTrailingComma = $phpcsFile->findPrevious( + Tokens::$emptyTokens, + ($function['parenthesis_closer'] - 1), + $function['parenthesis_opener'], + true + ); + if ($tokens[$lastTrailingComma]['code'] !== T_COMMA) { + $error = 'Multi-line function declarations must have a trailing comma after the last parameter'; + $fix = $phpcsFile->addFixableError($error, $lastTrailingComma, 'MissingTrailingComma'); + if ($fix === true) { + $phpcsFile->fixer->addContent($lastTrailingComma, ','); + } + } + + }//end process() + + +}//end class diff --git a/tests/Drupal/Functions/MultiLineTrailingCommaUnitTest.inc b/tests/Drupal/Functions/MultiLineTrailingCommaUnitTest.inc new file mode 100644 index 00000000..09dac066 --- /dev/null +++ b/tests/Drupal/Functions/MultiLineTrailingCommaUnitTest.inc @@ -0,0 +1,23 @@ + + */ + protected function getErrorList(string $testFile): array + { + return [ + 8 => 1, + 17 => 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. + * + * @param string $testFile The name of the file being tested. + * + * @return array + */ + protected function getWarningList(string $testFile): array + { + return []; + + }//end getWarningList() + + + /** + * Skip this test on PHP versions lower than 8 because the syntax is not allowed there. + * + * @return bool + */ + protected function shouldSkipTest() + { + if (version_compare(PHP_VERSION, '8.0.0') < 0) { + return true; + } + + return false; + + }//end shouldSkipTest() + + +}//end class diff --git a/tests/Drupal/Functions/MultiLineTrailingCommaUnitTestinc.fixed b/tests/Drupal/Functions/MultiLineTrailingCommaUnitTestinc.fixed new file mode 100644 index 00000000..1c31bf5c --- /dev/null +++ b/tests/Drupal/Functions/MultiLineTrailingCommaUnitTestinc.fixed @@ -0,0 +1,23 @@ + 1, 838 => 1, 849 => 2, - 860 => 1, + 860 => 2, 864 => 2, ]; }//end switch @@ -480,4 +480,20 @@ protected function checkAllSniffCodes() }//end checkAllSniffCodes() + /** + * Skip this test on PHP versions lower than 8 because of MultiLineTrailingCommaSniff. + * + * @return bool + */ + protected function shouldSkipTest() + { + if (version_compare(PHP_VERSION, '8.0.0') < 0) { + return true; + } + + return false; + + }//end shouldSkipTest() + + }//end class diff --git a/tests/Drupal/bad/bad.php.fixed b/tests/Drupal/bad/bad.php.fixed index c68773c0..26abaa2e 100644 --- a/tests/Drupal/bad/bad.php.fixed +++ b/tests/Drupal/bad/bad.php.fixed @@ -911,7 +911,7 @@ class ScopeKeyword { */ function test29( int $a, - string $b + string $b, ) { echo "Hello"; } diff --git a/tests/Drupal/good/good.php b/tests/Drupal/good/good.php index 0076a3c8..3c9ecacb 100644 --- a/tests/Drupal/good/good.php +++ b/tests/Drupal/good/good.php @@ -1476,7 +1476,7 @@ function test18( CacheTagsInvalidatorInterface $cache_invalidator, ModuleHandlerInterface $module_handler, EntityFieldManagerInterface $entity_field_manager, - EntityTypeBundleInfoInterface $entity_type_bundle_info + EntityTypeBundleInfoInterface $entity_type_bundle_info, ) { return 0; }