diff --git a/coder_sniffer/Drupal/Sniffs/NamingConventions/ValidClassNameSniff.php b/coder_sniffer/Drupal/Sniffs/NamingConventions/ValidClassNameSniff.php index 0ff3a569..82b54d0e 100644 --- a/coder_sniffer/Drupal/Sniffs/NamingConventions/ValidClassNameSniff.php +++ b/coder_sniffer/Drupal/Sniffs/NamingConventions/ValidClassNameSniff.php @@ -63,7 +63,7 @@ public function process(File $phpcsFile, $stackPtr) // Make sure the first letter is a capital. if (preg_match('|^[A-Z]|', $name) === 0) { $error = '%s name must use UpperCamel naming and begin with a capital letter'; - $phpcsFile->addError($error, $stackPtr, 'StartWithCapital', $errorData); + $this->processUpperLowerCase($className, $phpcsFile, 'StartWithCapital', $error, $errorData); } // Search for underscores. @@ -72,16 +72,47 @@ public function process(File $phpcsFile, $stackPtr) $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 anywhere, but not decided yet. - // See https://www.drupal.org/project/coder/issues/3497433 - if (preg_match('|^[A-Z]{3}[^a-z]*$|', $name) === 1) { + // Ensure the name does not contain acronyms. + if (preg_match('|[A-Z]{3}|', $name) === 1) { $error = '%s name must use UpperCamel naming and not contain multiple upper case letters in a row'; - $phpcsFile->addError($error, $stackPtr, 'NoUpperAcronyms', $errorData); + $this->processUpperLowerCase($className, $phpcsFile, 'NoUpperAcronyms', $error, $errorData); } }//end process() + protected function processUpperLowerCase(int $stackPtr, File $phpcsFile, string $errorCode, string $errorMessage, array $errorData): void + { + $fix = $phpcsFile->addFixableError($errorMessage, $stackPtr, $errorCode, $errorData); + if ($fix === false) { + return; + } + + $tokens = $phpcsFile->getTokens(); + $name = ucfirst($tokens[$stackPtr]['content']); + $upperCaseStarted = false; + for ($i = 0; $i < strlen($name); $i++) { + if ($upperCaseStarted === true + && ctype_upper($name[$i]) === true + && isset($name[($i + 1)]) + && (ctype_upper($name[($i + 1)]) === true || $name[($i + 1)] === '_') + ) { + $name[$i] = strtolower($name[$i]); + } else { + if (ctype_upper($name[$i]) === true) { + $upperCaseStarted = true; + } else { + $upperCaseStarted = false; + } + } + } + + $name[(strlen($name) - 1)] = strtolower($name[(strlen($name) - 1)]); + $phpcsFile->fixer->replaceToken($stackPtr, $name); + + // @todo Can we move files? + + }//end processUpperLowerCase() + + }//end class diff --git a/tests/Drupal/NamingConventions/ValidClassNameUnitTest.inc b/tests/Drupal/NamingConventions/ValidClassNameUnitTest.inc index dfcf852e..6b5dd4ad 100644 --- a/tests/Drupal/NamingConventions/ValidClassNameUnitTest.inc +++ b/tests/Drupal/NamingConventions/ValidClassNameUnitTest.inc @@ -2,24 +2,28 @@ class CorrectClassName {} class CorrectClassWithAReallyLongName {} +class IncorrectJSONClassName {} class INCORRECT_CLASS_NAME {} class INCORRECTCLASSNAME {} class incorrectLowercaseClassName {} interface CorrectInterfaceName {} interface CorrectInterfaceWithAReallyLongName {} +interface IncorrectJSONInterfaceName {} interface INCORRECT_INTERFACE_NAME {} interface INCORRECTINTERFACENAME {} interface incorrectLowercaseInterfaceName {} trait CorrectTraitName {} trait CorrectTraitWithAReallyLongName {} +trait IncorrectJSONTraitName {} trait INCORRECT_TRAIT_NAME {} trait INCORRECTTRAITNAME {} trait incorrectLowercaseTraitName {} enum CorrectEnumName {} enum CorrectEnumWithAReallyLongName {} +enum IncorrectJSONEnumName {} enum INCORRECT_ENUM_NAME {} enum INCORRECTENUMNAME {} enum incorrectLowercaseEnumName {} diff --git a/tests/Drupal/NamingConventions/ValidClassNameUnitTest.php b/tests/Drupal/NamingConventions/ValidClassNameUnitTest.php index 37803750..4492d219 100644 --- a/tests/Drupal/NamingConventions/ValidClassNameUnitTest.php +++ b/tests/Drupal/NamingConventions/ValidClassNameUnitTest.php @@ -21,18 +21,22 @@ class ValidClassNameUnitTest extends CoderSniffUnitTest protected function getErrorList(string $testFile): array { return [ - 5 => 2, - 6 => 1, + 5 => 1, + 6 => 2, 7 => 1, - 11 => 2, + 8 => 1, 12 => 1, - 13 => 1, - 17 => 2, - 18 => 1, + 13 => 2, + 14 => 1, + 15 => 1, 19 => 1, - 23 => 2, - 24 => 1, - 25 => 1, + 20 => 2, + 21 => 1, + 22 => 1, + 26 => 1, + 27 => 2, + 28 => 1, + 29 => 1, ]; }//end getErrorList() diff --git a/tests/Drupal/NamingConventions/ValidEnumCaseUnitTest.inc b/tests/Drupal/NamingConventions/ValidEnumCaseUnitTest.inc index d037f5ba..97ee71a4 100644 --- a/tests/Drupal/NamingConventions/ValidEnumCaseUnitTest.inc +++ b/tests/Drupal/NamingConventions/ValidEnumCaseUnitTest.inc @@ -7,10 +7,10 @@ enum Test: int { case TWO_TEST = 2; // Must not contain only upper case. case THREE = 3; - // Upper case parts are allowed for now. + // Upper case parts are not allowed. case FourJSONCase = 4; case FiveAndAHorseCorrect = 5; - case UIExample = 6; + case UiExample = 6; } // Those are all ok. diff --git a/tests/Drupal/NamingConventions/ValidEnumCaseUnitTest.php b/tests/Drupal/NamingConventions/ValidEnumCaseUnitTest.php index 28a5135b..ee810ff3 100644 --- a/tests/Drupal/NamingConventions/ValidEnumCaseUnitTest.php +++ b/tests/Drupal/NamingConventions/ValidEnumCaseUnitTest.php @@ -21,9 +21,10 @@ class ValidEnumCaseUnitTest extends CoderSniffUnitTest protected function getErrorList(string $testFile): array { return [ - 5 => 1, - 7 => 2, - 9 => 1, + 5 => 1, + 7 => 2, + 9 => 1, + 11 => 1, ]; }//end getErrorList()