diff --git a/.github/workflows/testing.yml b/.github/workflows/testing.yml index 4b9df6593ff183e8e0c6c5d54a1377279a68f45a..b7d917d0492c1628fec05f299fa0ef5f1da4dfc8 100644 --- a/.github/workflows/testing.yml +++ b/.github/workflows/testing.yml @@ -84,4 +84,4 @@ jobs: # core is updated to that version. run: | cd drupal/core - ../../vendor/bin/phpcs -p -s --ignore=lib/Drupal/Core/Entity/EntityType.php,lib/Drupal/Core/Recipe/RecipeInputFormTrait.php,lib/Drupal/Core/Form/FormState.php,modules/migrate/src/Plugin/Migration.php,modules/views/src/ViewExecutable.php,modules/views/src/Plugin/views/style/StylePluginBase.php + ../../vendor/bin/phpcs -p -s --ignore=lib/Drupal/Core/Entity/EntityType.php,lib/Drupal/Core/Recipe/RecipeInputFormTrait.php,lib/Drupal/Core/Form/FormState.php,modules/migrate/src/Plugin/Migration.php,modules/views/src/ViewExecutable.php,modules/views/src/Plugin/views/style/StylePluginBase.php,core/lib/Drupal/Core/FileTransfer/FTP.php,core/lib/Drupal/Core/FileTransfer/SSH.php diff --git a/coder_sniffer/Drupal/Sniffs/Commenting/ClassCommentSniff.php b/coder_sniffer/Drupal/Sniffs/Commenting/ClassCommentSniff.php index a0c6bb6c48d090a1e825738150f461d65452656b..75de9c9b2ad1eea9507921a50698dc0a9c7c7ec5 100644 --- a/coder_sniffer/Drupal/Sniffs/Commenting/ClassCommentSniff.php +++ b/coder_sniffer/Drupal/Sniffs/Commenting/ClassCommentSniff.php @@ -53,16 +53,23 @@ class ClassCommentSniff implements Sniff */ public function process(File $phpcsFile, $stackPtr) { - $tokens = $phpcsFile->getTokens(); - $find = Tokens::$methodPrefixes; - $find[T_WHITESPACE] = T_WHITESPACE; - $find[T_READONLY] = T_READONLY; + $tokens = $phpcsFile->getTokens(); + $find = ([ + T_ABSTRACT => T_ABSTRACT, + T_FINAL => T_FINAL, + T_READONLY => T_READONLY, + T_WHITESPACE => T_WHITESPACE, + ] + Tokens::$phpcsCommentTokens); $name = $tokens[$stackPtr]['content']; $classCodeStart = $stackPtr; $previousContent = null; for ($commentEnd = ($stackPtr - 1); $commentEnd >= 0; $commentEnd--) { if (isset($find[$tokens[$commentEnd]['code']]) === true) { + if (isset(Tokens::$phpcsCommentTokens[$tokens[$commentEnd]['code']]) === true) { + $classCodeStart = $commentEnd; + } + continue; } @@ -78,7 +85,7 @@ class ClassCommentSniff implements Sniff } break; - } + }//end for if ($tokens[$commentEnd]['code'] !== T_DOC_COMMENT_CLOSE_TAG && $tokens[$commentEnd]['code'] !== T_COMMENT diff --git a/coder_sniffer/Drupal/Sniffs/NamingConventions/ValidClassNameSniff.php b/coder_sniffer/Drupal/Sniffs/NamingConventions/ValidClassNameSniff.php index 11ae5f89d08dea60323bafe8fbbde45b610059d2..a7df880c666c49429d2ebd7d994f037975afc6e3 100644 --- a/coder_sniffer/Drupal/Sniffs/NamingConventions/ValidClassNameSniff.php +++ b/coder_sniffer/Drupal/Sniffs/NamingConventions/ValidClassNameSniff.php @@ -15,7 +15,7 @@ use PHP_CodeSniffer\Sniffs\Sniff; /** * \Drupal\Sniffs\NamingConventions\ValidClassNameSniff. * - * Ensures class and interface names start with a capital letter + * Ensures class, enum, interface and trait names start with a capital letter * and do not use _ separators. * * @category PHP @@ -35,7 +35,9 @@ class ValidClassNameSniff implements Sniff { return [ T_CLASS, + T_ENUM, T_INTERFACE, + T_TRAIT, ]; }//end register() @@ -60,7 +62,7 @@ class ValidClassNameSniff implements Sniff // Make sure the first letter is a capital. if (preg_match('|^[A-Z]|', $name) === 0) { - $error = '%s name must begin with a capital letter'; + $error = '%s name must use UpperCamel naming and begin with a capital letter'; $phpcsFile->addError($error, $stackPtr, 'StartWithCapital', $errorData); } @@ -70,6 +72,15 @@ class ValidClassNameSniff implements Sniff $phpcsFile->addError($error, $stackPtr, 'NoUnderscores', $errorData); } + // Ensure the name is not all uppercase. + // @todo We could make this more strict to check if there are more than + // 2 upper case characters in a row, but not decided yet. + // See https://www.drupal.org/project/coder/issues/3497433 + if (strtoupper($name) === $name) { + $error = '%s name must use UpperCamel naming and not contain multiple upper case letters in a row'; + $phpcsFile->addError($error, $stackPtr, 'NoUpperAcronyms', $errorData); + } + }//end process() diff --git a/tests/Drupal/NamingConventions/ValidClassNameUnitTest.inc b/tests/Drupal/NamingConventions/ValidClassNameUnitTest.inc new file mode 100644 index 0000000000000000000000000000000000000000..dfcf852ec55c720d9dbe8eeb37b235a93315e2d5 --- /dev/null +++ b/tests/Drupal/NamingConventions/ValidClassNameUnitTest.inc @@ -0,0 +1,25 @@ +<?php + +class CorrectClassName {} +class CorrectClassWithAReallyLongName {} +class INCORRECT_CLASS_NAME {} +class INCORRECTCLASSNAME {} +class incorrectLowercaseClassName {} + +interface CorrectInterfaceName {} +interface CorrectInterfaceWithAReallyLongName {} +interface INCORRECT_INTERFACE_NAME {} +interface INCORRECTINTERFACENAME {} +interface incorrectLowercaseInterfaceName {} + +trait CorrectTraitName {} +trait CorrectTraitWithAReallyLongName {} +trait INCORRECT_TRAIT_NAME {} +trait INCORRECTTRAITNAME {} +trait incorrectLowercaseTraitName {} + +enum CorrectEnumName {} +enum CorrectEnumWithAReallyLongName {} +enum INCORRECT_ENUM_NAME {} +enum INCORRECTENUMNAME {} +enum incorrectLowercaseEnumName {} diff --git a/tests/Drupal/NamingConventions/ValidClassNameUnitTest.php b/tests/Drupal/NamingConventions/ValidClassNameUnitTest.php new file mode 100644 index 0000000000000000000000000000000000000000..37803750f1d99cf36588591cb7d2a9289eed290d --- /dev/null +++ b/tests/Drupal/NamingConventions/ValidClassNameUnitTest.php @@ -0,0 +1,58 @@ +<?php + +namespace Drupal\Test\NamingConventions; + +use Drupal\Test\CoderSniffUnitTest; + +class ValidClassNameUnitTest extends CoderSniffUnitTest +{ + + + /** + * 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. + * + * @param string $testFile The name of the file being tested. + * + * @return array<int, int> + */ + protected function getErrorList(string $testFile): array + { + return [ + 5 => 2, + 6 => 1, + 7 => 1, + 11 => 2, + 12 => 1, + 13 => 1, + 17 => 2, + 18 => 1, + 19 => 1, + 23 => 2, + 24 => 1, + 25 => 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<int, int> + */ + protected function getWarningList(string $testFile): array + { + return []; + + }//end getWarningList() + + +}//end class diff --git a/tests/Drupal/NamingConventions/ValidEnumCaseUnitTest.inc b/tests/Drupal/NamingConventions/ValidEnumCaseUnitTest.inc index d1819d99d1d2295f9f1471f4bf2ab71107467708..b6b428076dad14e09c1cffafeae473b4a73a55e3 100644 --- a/tests/Drupal/NamingConventions/ValidEnumCaseUnitTest.inc +++ b/tests/Drupal/NamingConventions/ValidEnumCaseUnitTest.inc @@ -5,4 +5,9 @@ enum Test: int { case one = 1; // Must not contain underscores. case TWO_TEST = 2; + // Must not contain only upper case. + case THREE = 3; + // Upper case parts are allowed for now. + case FourJSONCase = 4; + case FiveAndAHorseCorrect = 5; } diff --git a/tests/Drupal/NamingConventions/ValidEnumCaseUnitTest.php b/tests/Drupal/NamingConventions/ValidEnumCaseUnitTest.php index eea3216c331193c0ea88e6ca930cbbbebb96c561..28a5135b11fa3829ba933bdf508232ff4051a64c 100644 --- a/tests/Drupal/NamingConventions/ValidEnumCaseUnitTest.php +++ b/tests/Drupal/NamingConventions/ValidEnumCaseUnitTest.php @@ -22,7 +22,8 @@ class ValidEnumCaseUnitTest extends CoderSniffUnitTest { return [ 5 => 1, - 7 => 1, + 7 => 2, + 9 => 1, ]; }//end getErrorList() diff --git a/tests/Drupal/bad/BadUnitTest.php b/tests/Drupal/bad/BadUnitTest.php index 15c4f0459f2717c6fa05809228a382d4f1d78449..e9a855ce8c4fa6a45b64523ba64a38b95ad34605 100644 --- a/tests/Drupal/bad/BadUnitTest.php +++ b/tests/Drupal/bad/BadUnitTest.php @@ -380,7 +380,7 @@ class BadUnitTest extends CoderSniffUnitTest 827 => 1, 829 => 1, 836 => 1, - 838 => 1, + 838 => 3, 849 => 2, 860 => 2, 867 => 1, diff --git a/tests/Drupal/good/good.php b/tests/Drupal/good/good.php index b3b828b7488082c38cdf7e0502c91abe84794fee..bd8d911bd520c6a9fc19ec50a48578dbc2593892 100644 --- a/tests/Drupal/good/good.php +++ b/tests/Drupal/good/good.php @@ -1905,3 +1905,12 @@ class CronHook { ) {} } + +/** + * Doc block is here and an ignore directive is ok. + */ +// phpcs:ignore Drupal.NamingConventions.ValidClassName +enum PUROSELY_WRONG_BUT_OK: int { + case One = 1; + case Two = 2; +}