From eb8db2ecc6da61deb4442bd013f1f3984b474c4e Mon Sep 17 00:00:00 2001 From: Simon Podlipsky Date: Thu, 3 Feb 2022 12:37:47 +0100 Subject: [PATCH 01/15] Port ValidVariableNameSniff https://github.com/squizlabs/PHP_CodeSniffer/blob/498a939c8ff49f0b00769144bdd07933352d77e8/src/Standards/Squiz/Sniffs/NamingConventions/ValidVariableNameSniff.php --- .../ValidVariableNameSniff.php | 191 ++++++++++++++++++ .../ValidVariableNameSniffTest.php | 60 ++++++ .../data/ValidVariableNameSniffTest.inc | 148 ++++++++++++++ 3 files changed, 399 insertions(+) create mode 100644 src/Cdn77/Sniffs/NamingConventions/ValidVariableNameSniff.php create mode 100644 tests/Sniffs/NamingConventions/ValidVariableNameSniffTest.php create mode 100644 tests/Sniffs/NamingConventions/data/ValidVariableNameSniffTest.inc diff --git a/src/Cdn77/Sniffs/NamingConventions/ValidVariableNameSniff.php b/src/Cdn77/Sniffs/NamingConventions/ValidVariableNameSniff.php new file mode 100644 index 0000000..114bc08 --- /dev/null +++ b/src/Cdn77/Sniffs/NamingConventions/ValidVariableNameSniff.php @@ -0,0 +1,191 @@ +getTokens(); + $varName = ltrim($tokens[$stackPtr]['content'], '$'); + + // If it's a php reserved var, then its ok. + if (isset($this->phpReservedVars[$varName]) === true) { + return; + } + + $objOperator = $phpcsFile->findNext([T_WHITESPACE], ($stackPtr + 1), null, true); + if ($tokens[$objOperator]['code'] === T_OBJECT_OPERATOR + || $tokens[$objOperator]['code'] === T_NULLSAFE_OBJECT_OPERATOR + ) { + // Check to see if we are using a variable from an object. + $var = $phpcsFile->findNext([T_WHITESPACE], ($objOperator + 1), null, true); + if ($tokens[$var]['code'] === T_STRING) { + $bracket = $phpcsFile->findNext([T_WHITESPACE], ($var + 1), null, true); + if ($tokens[$bracket]['code'] !== T_OPEN_PARENTHESIS) { + $objVarName = $tokens[$var]['content']; + + // There is no way for us to know if the var is public or + // private, so we have to ignore a leading underscore if there is + // one and just check the main part of the variable name. + $originalVarName = $objVarName; + if (substr($objVarName, 0, 1) === '_') { + $objVarName = substr($objVarName, 1); + } + + if (Common::isCamelCaps($objVarName, false, true, false) === false) { + $error = 'Member variable "%s" is not in valid camel caps format'; + $data = [$originalVarName]; + $phpcsFile->addError($error, $var, 'MemberNotCamelCaps', $data); + } + }//end if + }//end if + }//end if + + $objOperator = $phpcsFile->findPrevious(T_WHITESPACE, ($stackPtr - 1), null, true); + if ($tokens[$objOperator]['code'] === T_DOUBLE_COLON) { + // The variable lives within a class, and is referenced like + // this: MyClass::$_variable, so we don't know its scope. + $objVarName = $varName; + if (substr($objVarName, 0, 1) === '_') { + $objVarName = substr($objVarName, 1); + } + + if (Common::isCamelCaps($objVarName, false, true, false) === false) { + $error = 'Member variable "%s" is not in valid camel caps format'; + $data = [$tokens[$stackPtr]['content']]; + $phpcsFile->addError($error, $stackPtr, 'MemberNotCamelCaps', $data); + } + + return; + } + + // There is no way for us to know if the var is public or private, + // so we have to ignore a leading underscore if there is one and just + // check the main part of the variable name. + $originalVarName = $varName; + if (substr($varName, 0, 1) === '_') { + $inClass = $phpcsFile->hasCondition($stackPtr, Tokens::$ooScopeTokens); + if ($inClass === true) { + $varName = substr($varName, 1); + } + } + + if (Common::isCamelCaps($varName, false, true, false) === false) { + $error = 'Variable "%s" is not in valid camel caps format'; + $data = [$originalVarName]; + $phpcsFile->addError($error, $stackPtr, 'NotCamelCaps', $data); + } + + }//end processVariable() + + + /** + * Processes class member variables. + * + * @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 + */ + protected function processMemberVar(File $phpcsFile, $stackPtr) + { + $tokens = $phpcsFile->getTokens(); + + $varName = ltrim($tokens[$stackPtr]['content'], '$'); + $memberProps = $phpcsFile->getMemberProperties($stackPtr); + if (empty($memberProps) === true) { + // Couldn't get any info about this variable, which + // generally means it is invalid or possibly has a parse + // error. Any errors will be reported by the core, so + // we can ignore it. + return; + } + + $public = ($memberProps['scope'] !== 'private'); + $errorData = [$varName]; + + if ($public === true) { + if (substr($varName, 0, 1) === '_') { + $error = '%s member variable "%s" must not contain a leading underscore'; + $data = [ + ucfirst($memberProps['scope']), + $errorData[0], + ]; + $phpcsFile->addError($error, $stackPtr, 'PublicHasUnderscore', $data); + } + } else { + if (substr($varName, 0, 1) !== '_') { + $error = 'Private member variable "%s" must contain a leading underscore'; + $phpcsFile->addError($error, $stackPtr, 'PrivateNoUnderscore', $errorData); + } + } + + // Remove a potential underscore prefix for testing CamelCaps. + $varName = ltrim($varName, '_'); + + if (Common::isCamelCaps($varName, false, true, false) === false) { + $error = 'Member variable "%s" is not in valid camel caps format'; + $phpcsFile->addError($error, $stackPtr, 'MemberNotCamelCaps', $errorData); + } + + }//end processMemberVar() + + + /** + * Processes the variable found within a double quoted string. + * + * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned. + * @param int $stackPtr The position of the double quoted + * string. + * + * @return void + */ + protected function processVariableInString(File $phpcsFile, $stackPtr) + { + $tokens = $phpcsFile->getTokens(); + + if (preg_match_all('|[^\\\]\${?([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)|', $tokens[$stackPtr]['content'], $matches) !== 0) { + foreach ($matches[1] as $varName) { + // If it's a php reserved var, then its ok. + if (isset($this->phpReservedVars[$varName]) === true) { + continue; + } + + if (Common::isCamelCaps($varName, false, true, false) === false) { + $error = 'Variable "%s" is not in valid camel caps format'; + $data = [$varName]; + $phpcsFile->addError($error, $stackPtr, 'StringNotCamelCaps', $data); + } + } + } + + }//end processVariableInString() + + +}//end class diff --git a/tests/Sniffs/NamingConventions/ValidVariableNameSniffTest.php b/tests/Sniffs/NamingConventions/ValidVariableNameSniffTest.php new file mode 100644 index 0000000..838a4d3 --- /dev/null +++ b/tests/Sniffs/NamingConventions/ValidVariableNameSniffTest.php @@ -0,0 +1,60 @@ +getErrorCount()); + + self::assertSniffError($file, 3, self::CODE_NOT_CAMEL_CAPS); + self::assertSniffError($file, 5, self::CODE_NOT_CAMEL_CAPS); + self::assertSniffError($file, 10, self::CODE_MEMBER_NOT_CAMEL_CAPS); + self::assertSniffError($file, 12, self::CODE_PUBLIC_HAS_UNDERSCORE); + self::assertSniffError($file, 15, self::CODE_MEMBER_NOT_CAMEL_CAPS); + self::assertSniffError($file, 17, self::CODE_PUBLIC_HAS_UNDERSCORE); + self::assertSniffError($file, 20, self::CODE_MEMBER_NOT_CAMEL_CAPS); + self::assertSniffError($file, 22, self::CODE_PUBLIC_HAS_UNDERSCORE); + self::assertSniffError($file, 25, self::CODE_MEMBER_NOT_CAMEL_CAPS); + self::assertSniffError($file, 27, self::CODE_PRIVATE_NO_UNDERSCORE); + self::assertSniffError($file, 31, self::CODE_NOT_CAMEL_CAPS); + self::assertSniffError($file, 33, self::CODE_NOT_CAMEL_CAPS); + self::assertSniffError($file, 36, self::CODE_STRING_NOT_CAMEL_CAPS); + self::assertSniffError($file, 37, self::CODE_STRING_NOT_CAMEL_CAPS); + self::assertSniffError($file, 39, self::CODE_STRING_NOT_CAMEL_CAPS); + self::assertSniffError($file, 42, self::CODE_NOT_CAMEL_CAPS); + self::assertSniffError($file, 44, self::CODE_NOT_CAMEL_CAPS); + self::assertSniffError($file, 53, self::CODE_MEMBER_NOT_CAMEL_CAPS); + self::assertSniffError($file, 58, self::CODE_MEMBER_NOT_CAMEL_CAPS); + self::assertSniffError($file, 62, self::CODE_MEMBER_NOT_CAMEL_CAPS); + self::assertSniffError($file, 63, self::CODE_NOT_CAMEL_CAPS); + self::assertSniffError($file, 64, self::CODE_NOT_CAMEL_CAPS); + self::assertSniffError($file, 67, self::CODE_NOT_CAMEL_CAPS); + self::assertSniffError($file, 81, self::CODE_STRING_NOT_CAMEL_CAPS); + self::assertSniffError($file, 106, self::CODE_PUBLIC_HAS_UNDERSCORE); + self::assertSniffError($file, 107, self::CODE_PUBLIC_HAS_UNDERSCORE); + self::assertSniffError($file, 107, self::CODE_MEMBER_NOT_CAMEL_CAPS); + self::assertSniffError($file, 108, self::CODE_PUBLIC_HAS_UNDERSCORE); + self::assertSniffError($file, 111, self::CODE_PRIVATE_NO_UNDERSCORE); + self::assertSniffError($file, 112, self::CODE_PRIVATE_NO_UNDERSCORE); + self::assertSniffError($file, 113, self::CODE_PRIVATE_NO_UNDERSCORE); + self::assertSniffError($file, 114, self::CODE_PRIVATE_NO_UNDERSCORE); + self::assertSniffError($file, 123, self::CODE_PUBLIC_HAS_UNDERSCORE); + self::assertSniffError($file, 138, self::CODE_NOT_CAMEL_CAPS); + self::assertSniffError($file, 141, self::CODE_NOT_CAMEL_CAPS); + self::assertSniffError($file, 146, self::CODE_MEMBER_NOT_CAMEL_CAPS); + } +} diff --git a/tests/Sniffs/NamingConventions/data/ValidVariableNameSniffTest.inc b/tests/Sniffs/NamingConventions/data/ValidVariableNameSniffTest.inc new file mode 100644 index 0000000..afa3a2a --- /dev/null +++ b/tests/Sniffs/NamingConventions/data/ValidVariableNameSniffTest.inc @@ -0,0 +1,148 @@ +varName2; +echo $this->var_name2; +echo $this->varname2; +echo $this->_varName2; +echo $object->varName2; +echo $object->var_name2; +echo $object_name->varname2; +echo $object_name->_varName2; + +echo $this->myFunction($one, $two); +echo $object->myFunction($one_two); + +$error = "format is \$GLOBALS['$varName']"; + +echo $_SESSION['var_name']; +echo $_FILES['var_name']; +echo $_ENV['var_name']; +echo $_COOKIE['var_name']; + +$XML = 'hello'; +$myXML = 'hello'; +$XMLParser = 'hello'; +$xmlParser = 'hello'; + +echo "{$_SERVER['HOSTNAME']} $var_name"; + +// Need to be the last thing in this test file. +$obj->$classVar = $prefix.'-'.$type; + +class foo +{ + const bar = <<varName; +echo $obj?->var_name; +echo $obj?->varname; +echo $obj?->_varName; From 8cbe10141d914c748bd68f8fe185592508962a0c Mon Sep 17 00:00:00 2001 From: Simon Podlipsky Date: Thu, 3 Feb 2022 12:45:04 +0100 Subject: [PATCH 02/15] Apply CS so something can be coded, actually. Also, use `strpos()` and assert to rule out impossible types. Drop `empty()`. --- .../ValidVariableNameSniff.php | 150 ++++++++++-------- 1 file changed, 83 insertions(+), 67 deletions(-) diff --git a/src/Cdn77/Sniffs/NamingConventions/ValidVariableNameSniff.php b/src/Cdn77/Sniffs/NamingConventions/ValidVariableNameSniff.php index 114bc08..318db7c 100644 --- a/src/Cdn77/Sniffs/NamingConventions/ValidVariableNameSniff.php +++ b/src/Cdn77/Sniffs/NamingConventions/ValidVariableNameSniff.php @@ -5,32 +5,38 @@ namespace Cdn77\Sniffs\NamingConventions; use PHP_CodeSniffer\Files\File; -use PHP_CodeSniffer\Sniffs\Sniff; -use const T_COMMA; -use const T_OPEN_PARENTHESIS; -use const T_OPEN_SHORT_ARRAY; -use const T_WHITESPACE; - use PHP_CodeSniffer\Sniffs\AbstractVariableSniff; use PHP_CodeSniffer\Util\Common; use PHP_CodeSniffer\Util\Tokens; -class ValidVariableNameSniff extends AbstractVariableSniff -{ +use function assert; +use function ltrim; +use function preg_match_all; +use function strpos; +use function substr; +use function ucfirst; +use const T_DOUBLE_COLON; +use const T_NULLSAFE_OBJECT_OPERATOR; +use const T_OBJECT_OPERATOR; +use const T_OPEN_PARENTHESIS; +use const T_STRING; +use const T_WHITESPACE; +class ValidVariableNameSniff extends AbstractVariableSniff +{ /** * Processes this test, when one of its tokens is encountered. * - * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned. + * @param File $phpcsFile The file being scanned. * @param int $stackPtr The position of the current token in the * stack passed in $tokens. * - * @return void + * @phpcsSuppress SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint */ - protected function processVariable(File $phpcsFile, $stackPtr) + protected function processVariable(File $phpcsFile, $stackPtr): void { - $tokens = $phpcsFile->getTokens(); + $tokens = $phpcsFile->getTokens(); $varName = ltrim($tokens[$stackPtr]['content'], '$'); // If it's a php reserved var, then its ok. @@ -38,14 +44,19 @@ protected function processVariable(File $phpcsFile, $stackPtr) return; } - $objOperator = $phpcsFile->findNext([T_WHITESPACE], ($stackPtr + 1), null, true); - if ($tokens[$objOperator]['code'] === T_OBJECT_OPERATOR + $objOperator = $phpcsFile->findNext([T_WHITESPACE], $stackPtr + 1, null, true); + assert($objOperator !== false); + + if ( + $tokens[$objOperator]['code'] === T_OBJECT_OPERATOR || $tokens[$objOperator]['code'] === T_NULLSAFE_OBJECT_OPERATOR ) { // Check to see if we are using a variable from an object. - $var = $phpcsFile->findNext([T_WHITESPACE], ($objOperator + 1), null, true); + $var = $phpcsFile->findNext([T_WHITESPACE], $objOperator + 1, null, true); + assert($var !== false); + if ($tokens[$var]['code'] === T_STRING) { - $bracket = $phpcsFile->findNext([T_WHITESPACE], ($var + 1), null, true); + $bracket = $phpcsFile->findNext([T_WHITESPACE], $var + 1, null, true); if ($tokens[$bracket]['code'] !== T_OPEN_PARENTHESIS) { $objVarName = $tokens[$var]['content']; @@ -53,31 +64,31 @@ protected function processVariable(File $phpcsFile, $stackPtr) // private, so we have to ignore a leading underscore if there is // one and just check the main part of the variable name. $originalVarName = $objVarName; - if (substr($objVarName, 0, 1) === '_') { + if (strpos($objVarName, '_') === 0) { $objVarName = substr($objVarName, 1); } if (Common::isCamelCaps($objVarName, false, true, false) === false) { $error = 'Member variable "%s" is not in valid camel caps format'; - $data = [$originalVarName]; + $data = [$originalVarName]; $phpcsFile->addError($error, $var, 'MemberNotCamelCaps', $data); } - }//end if - }//end if - }//end if + } + } + } - $objOperator = $phpcsFile->findPrevious(T_WHITESPACE, ($stackPtr - 1), null, true); + $objOperator = $phpcsFile->findPrevious(T_WHITESPACE, $stackPtr - 1, null, true); if ($tokens[$objOperator]['code'] === T_DOUBLE_COLON) { // The variable lives within a class, and is referenced like // this: MyClass::$_variable, so we don't know its scope. $objVarName = $varName; - if (substr($objVarName, 0, 1) === '_') { + if (strpos($objVarName, '_') === 0) { $objVarName = substr($objVarName, 1); } if (Common::isCamelCaps($objVarName, false, true, false) === false) { $error = 'Member variable "%s" is not in valid camel caps format'; - $data = [$tokens[$stackPtr]['content']]; + $data = [$tokens[$stackPtr]['content']]; $phpcsFile->addError($error, $stackPtr, 'MemberNotCamelCaps', $data); } @@ -88,38 +99,38 @@ protected function processVariable(File $phpcsFile, $stackPtr) // so we have to ignore a leading underscore if there is one and just // check the main part of the variable name. $originalVarName = $varName; - if (substr($varName, 0, 1) === '_') { + if (strpos($varName, '_') === 0) { $inClass = $phpcsFile->hasCondition($stackPtr, Tokens::$ooScopeTokens); if ($inClass === true) { $varName = substr($varName, 1); } } - if (Common::isCamelCaps($varName, false, true, false) === false) { - $error = 'Variable "%s" is not in valid camel caps format'; - $data = [$originalVarName]; - $phpcsFile->addError($error, $stackPtr, 'NotCamelCaps', $data); + if (Common::isCamelCaps($varName, false, true, false) !== false) { + return; } - }//end processVariable() - + $error = 'Variable "%s" is not in valid camel caps format'; + $data = [$originalVarName]; + $phpcsFile->addError($error, $stackPtr, 'NotCamelCaps', $data); + } /** * Processes class member variables. * - * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned. + * @param File $phpcsFile The file being scanned. * @param int $stackPtr The position of the current token in the * stack passed in $tokens. * - * @return void + * @phpcsSuppress SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint */ - protected function processMemberVar(File $phpcsFile, $stackPtr) + protected function processMemberVar(File $phpcsFile, $stackPtr): void { $tokens = $phpcsFile->getTokens(); - $varName = ltrim($tokens[$stackPtr]['content'], '$'); + $varName = ltrim($tokens[$stackPtr]['content'], '$'); $memberProps = $phpcsFile->getMemberProperties($stackPtr); - if (empty($memberProps) === true) { + if ($memberProps === []) { // Couldn't get any info about this variable, which // generally means it is invalid or possibly has a parse // error. Any errors will be reported by the core, so @@ -127,65 +138,70 @@ protected function processMemberVar(File $phpcsFile, $stackPtr) return; } - $public = ($memberProps['scope'] !== 'private'); + $public = ($memberProps['scope'] !== 'private'); $errorData = [$varName]; if ($public === true) { - if (substr($varName, 0, 1) === '_') { + if (strpos($varName, '_') === 0) { $error = '%s member variable "%s" must not contain a leading underscore'; - $data = [ + $data = [ ucfirst($memberProps['scope']), $errorData[0], ]; $phpcsFile->addError($error, $stackPtr, 'PublicHasUnderscore', $data); } - } else { - if (substr($varName, 0, 1) !== '_') { - $error = 'Private member variable "%s" must contain a leading underscore'; - $phpcsFile->addError($error, $stackPtr, 'PrivateNoUnderscore', $errorData); - } + } elseif (strpos($varName, '_') !== 0) { + $error = 'Private member variable "%s" must contain a leading underscore'; + $phpcsFile->addError($error, $stackPtr, 'PrivateNoUnderscore', $errorData); } // Remove a potential underscore prefix for testing CamelCaps. $varName = ltrim($varName, '_'); - if (Common::isCamelCaps($varName, false, true, false) === false) { - $error = 'Member variable "%s" is not in valid camel caps format'; - $phpcsFile->addError($error, $stackPtr, 'MemberNotCamelCaps', $errorData); + if (Common::isCamelCaps($varName, false, true, false) !== false) { + return; } - }//end processMemberVar() - + $error = 'Member variable "%s" is not in valid camel caps format'; + $phpcsFile->addError($error, $stackPtr, 'MemberNotCamelCaps', $errorData); + } /** * Processes the variable found within a double quoted string. * - * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned. + * @param File $phpcsFile The file being scanned. * @param int $stackPtr The position of the double quoted * string. * - * @return void + * @phpcsSuppress SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint */ - protected function processVariableInString(File $phpcsFile, $stackPtr) + protected function processVariableInString(File $phpcsFile, $stackPtr): void { $tokens = $phpcsFile->getTokens(); - if (preg_match_all('|[^\\\]\${?([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)|', $tokens[$stackPtr]['content'], $matches) !== 0) { - foreach ($matches[1] as $varName) { - // If it's a php reserved var, then its ok. - if (isset($this->phpReservedVars[$varName]) === true) { - continue; - } - - if (Common::isCamelCaps($varName, false, true, false) === false) { - $error = 'Variable "%s" is not in valid camel caps format'; - $data = [$varName]; - $phpcsFile->addError($error, $stackPtr, 'StringNotCamelCaps', $data); - } - } + if ( + preg_match_all( + '|[^\\\]\${?([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)|', + $tokens[$stackPtr]['content'], + $matches + ) === 0 + ) { + return; } - }//end processVariableInString() + foreach ($matches[1] as $varName) { + // If it's a php reserved var, then its ok. + if (isset($this->phpReservedVars[$varName]) === true) { + continue; + } + if (Common::isCamelCaps($varName, false, true, false) !== false) { + continue; + } -}//end class + $error = 'Variable "%s" is not in valid camel caps format'; + $data = [$varName]; + $phpcsFile->addError($error, $stackPtr, 'StringNotCamelCaps', $data); + } + } +} From 6a1ed607e3d79c6d8c5da40ff5e670cfdc47fcb5 Mon Sep 17 00:00:00 2001 From: Simon Podlipsky Date: Thu, 3 Feb 2022 13:16:27 +0100 Subject: [PATCH 03/15] Refactor ValidVariableNameSniffTest for better maintenance --- composer.json | 1 + .../ValidVariableNameSniffTest.php | 96 ++++++++++++------- 2 files changed, 60 insertions(+), 37 deletions(-) diff --git a/composer.json b/composer.json index cfb0d4b..9cd90eb 100644 --- a/composer.json +++ b/composer.json @@ -18,6 +18,7 @@ "doctrine/coding-standard": "^9.0" }, "require-dev": { + "ext-json": "*", "phpstan/phpstan": "^0.12.51", "phpstan/phpstan-phpunit": "^0.12.16", "phpstan/phpstan-strict-rules": "^0.12.5", diff --git a/tests/Sniffs/NamingConventions/ValidVariableNameSniffTest.php b/tests/Sniffs/NamingConventions/ValidVariableNameSniffTest.php index 838a4d3..478e1a4 100644 --- a/tests/Sniffs/NamingConventions/ValidVariableNameSniffTest.php +++ b/tests/Sniffs/NamingConventions/ValidVariableNameSniffTest.php @@ -6,6 +6,12 @@ use Cdn77\TestCase; +use function array_keys; +use function is_array; +use function json_encode; + +use const JSON_THROW_ON_ERROR; + class ValidVariableNameSniffTest extends TestCase { public const CODE_NOT_CAMEL_CAPS = 'NotCamelCaps'; @@ -18,43 +24,59 @@ public function testErrors(): void { $file = self::checkFile(__DIR__ . '/data/ValidVariableNameSniffTest.inc'); - self::assertSame(36, $file->getErrorCount()); + $errorTypesPerLine = [ + 3 => self::CODE_NOT_CAMEL_CAPS, + 5 => self::CODE_NOT_CAMEL_CAPS, + 10 => self::CODE_MEMBER_NOT_CAMEL_CAPS, + 12 => self::CODE_PUBLIC_HAS_UNDERSCORE, + 15 => self::CODE_MEMBER_NOT_CAMEL_CAPS, + 17 => self::CODE_PUBLIC_HAS_UNDERSCORE, + 20 => self::CODE_MEMBER_NOT_CAMEL_CAPS, + 22 => self::CODE_PUBLIC_HAS_UNDERSCORE, + 25 => self::CODE_MEMBER_NOT_CAMEL_CAPS, + 27 => self::CODE_PRIVATE_NO_UNDERSCORE, + 31 => self::CODE_NOT_CAMEL_CAPS, + 33 => self::CODE_NOT_CAMEL_CAPS, + 36 => self::CODE_STRING_NOT_CAMEL_CAPS, + 37 => self::CODE_STRING_NOT_CAMEL_CAPS, + 39 => self::CODE_STRING_NOT_CAMEL_CAPS, + 42 => self::CODE_NOT_CAMEL_CAPS, + 44 => self::CODE_NOT_CAMEL_CAPS, + 53 => self::CODE_MEMBER_NOT_CAMEL_CAPS, + 58 => self::CODE_MEMBER_NOT_CAMEL_CAPS, + 62 => self::CODE_MEMBER_NOT_CAMEL_CAPS, + 63 => self::CODE_NOT_CAMEL_CAPS, + 64 => self::CODE_NOT_CAMEL_CAPS, + 67 => self::CODE_NOT_CAMEL_CAPS, + 81 => self::CODE_STRING_NOT_CAMEL_CAPS, + 106 => self::CODE_PUBLIC_HAS_UNDERSCORE, + 107 => [self::CODE_PUBLIC_HAS_UNDERSCORE,self::CODE_MEMBER_NOT_CAMEL_CAPS], + 108 => self::CODE_PUBLIC_HAS_UNDERSCORE, + 111 => self::CODE_PRIVATE_NO_UNDERSCORE, + 112 => self::CODE_PRIVATE_NO_UNDERSCORE, + 113 => self::CODE_PRIVATE_NO_UNDERSCORE, + 114 => self::CODE_PRIVATE_NO_UNDERSCORE, + 123 => self::CODE_PUBLIC_HAS_UNDERSCORE, + 138 => self::CODE_NOT_CAMEL_CAPS, + 141 => self::CODE_NOT_CAMEL_CAPS, + 146 => self::CODE_MEMBER_NOT_CAMEL_CAPS, + ]; + $possibleLines = array_keys($errorTypesPerLine); + + $errors = $file->getErrors(); + foreach ($errors as $line => $error) { + self::assertContains($line, $possibleLines, json_encode($error, JSON_THROW_ON_ERROR)); - self::assertSniffError($file, 3, self::CODE_NOT_CAMEL_CAPS); - self::assertSniffError($file, 5, self::CODE_NOT_CAMEL_CAPS); - self::assertSniffError($file, 10, self::CODE_MEMBER_NOT_CAMEL_CAPS); - self::assertSniffError($file, 12, self::CODE_PUBLIC_HAS_UNDERSCORE); - self::assertSniffError($file, 15, self::CODE_MEMBER_NOT_CAMEL_CAPS); - self::assertSniffError($file, 17, self::CODE_PUBLIC_HAS_UNDERSCORE); - self::assertSniffError($file, 20, self::CODE_MEMBER_NOT_CAMEL_CAPS); - self::assertSniffError($file, 22, self::CODE_PUBLIC_HAS_UNDERSCORE); - self::assertSniffError($file, 25, self::CODE_MEMBER_NOT_CAMEL_CAPS); - self::assertSniffError($file, 27, self::CODE_PRIVATE_NO_UNDERSCORE); - self::assertSniffError($file, 31, self::CODE_NOT_CAMEL_CAPS); - self::assertSniffError($file, 33, self::CODE_NOT_CAMEL_CAPS); - self::assertSniffError($file, 36, self::CODE_STRING_NOT_CAMEL_CAPS); - self::assertSniffError($file, 37, self::CODE_STRING_NOT_CAMEL_CAPS); - self::assertSniffError($file, 39, self::CODE_STRING_NOT_CAMEL_CAPS); - self::assertSniffError($file, 42, self::CODE_NOT_CAMEL_CAPS); - self::assertSniffError($file, 44, self::CODE_NOT_CAMEL_CAPS); - self::assertSniffError($file, 53, self::CODE_MEMBER_NOT_CAMEL_CAPS); - self::assertSniffError($file, 58, self::CODE_MEMBER_NOT_CAMEL_CAPS); - self::assertSniffError($file, 62, self::CODE_MEMBER_NOT_CAMEL_CAPS); - self::assertSniffError($file, 63, self::CODE_NOT_CAMEL_CAPS); - self::assertSniffError($file, 64, self::CODE_NOT_CAMEL_CAPS); - self::assertSniffError($file, 67, self::CODE_NOT_CAMEL_CAPS); - self::assertSniffError($file, 81, self::CODE_STRING_NOT_CAMEL_CAPS); - self::assertSniffError($file, 106, self::CODE_PUBLIC_HAS_UNDERSCORE); - self::assertSniffError($file, 107, self::CODE_PUBLIC_HAS_UNDERSCORE); - self::assertSniffError($file, 107, self::CODE_MEMBER_NOT_CAMEL_CAPS); - self::assertSniffError($file, 108, self::CODE_PUBLIC_HAS_UNDERSCORE); - self::assertSniffError($file, 111, self::CODE_PRIVATE_NO_UNDERSCORE); - self::assertSniffError($file, 112, self::CODE_PRIVATE_NO_UNDERSCORE); - self::assertSniffError($file, 113, self::CODE_PRIVATE_NO_UNDERSCORE); - self::assertSniffError($file, 114, self::CODE_PRIVATE_NO_UNDERSCORE); - self::assertSniffError($file, 123, self::CODE_PUBLIC_HAS_UNDERSCORE); - self::assertSniffError($file, 138, self::CODE_NOT_CAMEL_CAPS); - self::assertSniffError($file, 141, self::CODE_NOT_CAMEL_CAPS); - self::assertSniffError($file, 146, self::CODE_MEMBER_NOT_CAMEL_CAPS); + $errorTypes = $errorTypesPerLine[$line]; + if (! is_array($errorTypes)) { + $errorTypes = [$errorTypes]; + } + + foreach ($errorTypes as $errorType) { + self::assertSniffError($file, $line, $errorType); + } + } + + self::assertSame(36, $file->getErrorCount()); } } From 6e4a2bde2f77b7cb75759f2adc65d53e34371fb0 Mon Sep 17 00:00:00 2001 From: Simon Podlipsky Date: Thu, 3 Feb 2022 13:26:25 +0100 Subject: [PATCH 04/15] Add two test errors on line 150 --- tests/Sniffs/NamingConventions/ValidVariableNameSniffTest.php | 3 ++- .../NamingConventions/data/ValidVariableNameSniffTest.inc | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/Sniffs/NamingConventions/ValidVariableNameSniffTest.php b/tests/Sniffs/NamingConventions/ValidVariableNameSniffTest.php index 478e1a4..5d943f8 100644 --- a/tests/Sniffs/NamingConventions/ValidVariableNameSniffTest.php +++ b/tests/Sniffs/NamingConventions/ValidVariableNameSniffTest.php @@ -60,6 +60,7 @@ public function testErrors(): void 138 => self::CODE_NOT_CAMEL_CAPS, 141 => self::CODE_NOT_CAMEL_CAPS, 146 => self::CODE_MEMBER_NOT_CAMEL_CAPS, + 150 => [self::CODE_NOT_CAMEL_CAPS, self::CODE_NOT_CAMEL_CAPS], ]; $possibleLines = array_keys($errorTypesPerLine); @@ -77,6 +78,6 @@ public function testErrors(): void } } - self::assertSame(36, $file->getErrorCount()); + self::assertSame(38, $file->getErrorCount()); } } diff --git a/tests/Sniffs/NamingConventions/data/ValidVariableNameSniffTest.inc b/tests/Sniffs/NamingConventions/data/ValidVariableNameSniffTest.inc index afa3a2a..724e5e7 100644 --- a/tests/Sniffs/NamingConventions/data/ValidVariableNameSniffTest.inc +++ b/tests/Sniffs/NamingConventions/data/ValidVariableNameSniffTest.inc @@ -146,3 +146,5 @@ echo $obj?->varName; echo $obj?->var_name; echo $obj?->varname; echo $obj?->_varName; + +$var_name . $var_name; From 38b50a9f889aba79be1c91c5f91deebbd77e73ab Mon Sep 17 00:00:00 2001 From: Simon Podlipsky Date: Thu, 3 Feb 2022 13:29:15 +0100 Subject: [PATCH 05/15] Use regex pattern instead of `Common::isCamelCaps()` - parity with original --- .../ValidVariableNameSniff.php | 20 +++++++++++++------ .../ValidVariableNameSniffTest.php | 4 ++-- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/Cdn77/Sniffs/NamingConventions/ValidVariableNameSniff.php b/src/Cdn77/Sniffs/NamingConventions/ValidVariableNameSniff.php index 318db7c..f343c87 100644 --- a/src/Cdn77/Sniffs/NamingConventions/ValidVariableNameSniff.php +++ b/src/Cdn77/Sniffs/NamingConventions/ValidVariableNameSniff.php @@ -6,12 +6,13 @@ use PHP_CodeSniffer\Files\File; use PHP_CodeSniffer\Sniffs\AbstractVariableSniff; -use PHP_CodeSniffer\Util\Common; use PHP_CodeSniffer\Util\Tokens; use function assert; use function ltrim; +use function preg_match; use function preg_match_all; +use function sprintf; use function strpos; use function substr; use function ucfirst; @@ -25,6 +26,8 @@ class ValidVariableNameSniff extends AbstractVariableSniff { + public string $pattern = '\b[a-zA-Z][a-zA-Z0-9]*?([A-Z][a-zA-Z0-9]*?)*?\b'; + /** * Processes this test, when one of its tokens is encountered. * @@ -68,7 +71,7 @@ protected function processVariable(File $phpcsFile, $stackPtr): void $objVarName = substr($objVarName, 1); } - if (Common::isCamelCaps($objVarName, false, true, false) === false) { + if (! $this->matchesRegex($objVarName)) { $error = 'Member variable "%s" is not in valid camel caps format'; $data = [$originalVarName]; $phpcsFile->addError($error, $var, 'MemberNotCamelCaps', $data); @@ -86,7 +89,7 @@ protected function processVariable(File $phpcsFile, $stackPtr): void $objVarName = substr($objVarName, 1); } - if (Common::isCamelCaps($objVarName, false, true, false) === false) { + if (! $this->matchesRegex($objVarName)) { $error = 'Member variable "%s" is not in valid camel caps format'; $data = [$tokens[$stackPtr]['content']]; $phpcsFile->addError($error, $stackPtr, 'MemberNotCamelCaps', $data); @@ -106,7 +109,7 @@ protected function processVariable(File $phpcsFile, $stackPtr): void } } - if (Common::isCamelCaps($varName, false, true, false) !== false) { + if ($this->matchesRegex($varName)) { return; } @@ -158,7 +161,7 @@ protected function processMemberVar(File $phpcsFile, $stackPtr): void // Remove a potential underscore prefix for testing CamelCaps. $varName = ltrim($varName, '_'); - if (Common::isCamelCaps($varName, false, true, false) !== false) { + if ($this->matchesRegex($varName)) { return; } @@ -195,7 +198,7 @@ protected function processVariableInString(File $phpcsFile, $stackPtr): void continue; } - if (Common::isCamelCaps($varName, false, true, false) !== false) { + if ($this->matchesRegex($varName)) { continue; } @@ -204,4 +207,9 @@ protected function processVariableInString(File $phpcsFile, $stackPtr): void $phpcsFile->addError($error, $stackPtr, 'StringNotCamelCaps', $data); } } + + private function matchesRegex(string $varName): bool + { + return preg_match(sprintf('~%s~', $this->pattern), $varName) === 1; + } } diff --git a/tests/Sniffs/NamingConventions/ValidVariableNameSniffTest.php b/tests/Sniffs/NamingConventions/ValidVariableNameSniffTest.php index 5d943f8..5558f22 100644 --- a/tests/Sniffs/NamingConventions/ValidVariableNameSniffTest.php +++ b/tests/Sniffs/NamingConventions/ValidVariableNameSniffTest.php @@ -50,7 +50,7 @@ public function testErrors(): void 67 => self::CODE_NOT_CAMEL_CAPS, 81 => self::CODE_STRING_NOT_CAMEL_CAPS, 106 => self::CODE_PUBLIC_HAS_UNDERSCORE, - 107 => [self::CODE_PUBLIC_HAS_UNDERSCORE,self::CODE_MEMBER_NOT_CAMEL_CAPS], + 107 => self::CODE_PUBLIC_HAS_UNDERSCORE, 108 => self::CODE_PUBLIC_HAS_UNDERSCORE, 111 => self::CODE_PRIVATE_NO_UNDERSCORE, 112 => self::CODE_PRIVATE_NO_UNDERSCORE, @@ -78,6 +78,6 @@ public function testErrors(): void } } - self::assertSame(38, $file->getErrorCount()); + self::assertSame(37, $file->getErrorCount()); } } From 821b348734d0196c65578e8a4e5c1abe0c332eb3 Mon Sep 17 00:00:00 2001 From: Simon Podlipsky Date: Thu, 3 Feb 2022 13:41:11 +0100 Subject: [PATCH 06/15] Allow names marking unused variable (`$_`, `$__` etc.) --- src/Cdn77/Sniffs/NamingConventions/ValidVariableNameSniff.php | 2 +- tests/Sniffs/NamingConventions/ValidVariableNameSniffTest.php | 3 ++- .../NamingConventions/data/ValidVariableNameSniffTest.inc | 2 ++ 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Cdn77/Sniffs/NamingConventions/ValidVariableNameSniff.php b/src/Cdn77/Sniffs/NamingConventions/ValidVariableNameSniff.php index f343c87..707b176 100644 --- a/src/Cdn77/Sniffs/NamingConventions/ValidVariableNameSniff.php +++ b/src/Cdn77/Sniffs/NamingConventions/ValidVariableNameSniff.php @@ -26,7 +26,7 @@ class ValidVariableNameSniff extends AbstractVariableSniff { - public string $pattern = '\b[a-zA-Z][a-zA-Z0-9]*?([A-Z][a-zA-Z0-9]*?)*?\b'; + public string $pattern = '\b(([a-zA-Z][a-zA-Z0-9]*?([A-Z][a-zA-Z0-9]*?)*?)|_+)\b'; /** * Processes this test, when one of its tokens is encountered. diff --git a/tests/Sniffs/NamingConventions/ValidVariableNameSniffTest.php b/tests/Sniffs/NamingConventions/ValidVariableNameSniffTest.php index 5558f22..48d0a16 100644 --- a/tests/Sniffs/NamingConventions/ValidVariableNameSniffTest.php +++ b/tests/Sniffs/NamingConventions/ValidVariableNameSniffTest.php @@ -61,6 +61,7 @@ public function testErrors(): void 141 => self::CODE_NOT_CAMEL_CAPS, 146 => self::CODE_MEMBER_NOT_CAMEL_CAPS, 150 => [self::CODE_NOT_CAMEL_CAPS, self::CODE_NOT_CAMEL_CAPS], + 152 => self::CODE_NOT_CAMEL_CAPS, ]; $possibleLines = array_keys($errorTypesPerLine); @@ -78,6 +79,6 @@ public function testErrors(): void } } - self::assertSame(37, $file->getErrorCount()); + self::assertSame(38, $file->getErrorCount()); } } diff --git a/tests/Sniffs/NamingConventions/data/ValidVariableNameSniffTest.inc b/tests/Sniffs/NamingConventions/data/ValidVariableNameSniffTest.inc index 724e5e7..2823013 100644 --- a/tests/Sniffs/NamingConventions/data/ValidVariableNameSniffTest.inc +++ b/tests/Sniffs/NamingConventions/data/ValidVariableNameSniffTest.inc @@ -148,3 +148,5 @@ echo $obj?->varname; echo $obj?->_varName; $var_name . $var_name; + +fn($_, $__, $_x) => true; From 445727526a77c10b556d638aaa42851e7ce8f1ac Mon Sep 17 00:00:00 2001 From: Simon Podlipsky Date: Thu, 3 Feb 2022 13:44:29 +0100 Subject: [PATCH 07/15] Include Cdn77.NamingConventions.ValidVariableName in ruleset --- src/Cdn77/ruleset.xml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Cdn77/ruleset.xml b/src/Cdn77/ruleset.xml index 8539736..8633f36 100644 --- a/src/Cdn77/ruleset.xml +++ b/src/Cdn77/ruleset.xml @@ -24,7 +24,8 @@ - + + @@ -35,6 +36,8 @@ + + From 641462e029125c2d50921744016e9c6ce21f1be3 Mon Sep 17 00:00:00 2001 From: Simon Podlipsky Date: Thu, 3 Feb 2022 13:53:26 +0100 Subject: [PATCH 08/15] Remove PrivateNoUnderscore since it's ancient and nobody writes php like that --- .../ValidVariableNameSniff.php | 19 +++++++------------ .../ValidVariableNameSniffTest.php | 8 +------- 2 files changed, 8 insertions(+), 19 deletions(-) diff --git a/src/Cdn77/Sniffs/NamingConventions/ValidVariableNameSniff.php b/src/Cdn77/Sniffs/NamingConventions/ValidVariableNameSniff.php index 707b176..751d9ce 100644 --- a/src/Cdn77/Sniffs/NamingConventions/ValidVariableNameSniff.php +++ b/src/Cdn77/Sniffs/NamingConventions/ValidVariableNameSniff.php @@ -144,18 +144,13 @@ protected function processMemberVar(File $phpcsFile, $stackPtr): void $public = ($memberProps['scope'] !== 'private'); $errorData = [$varName]; - if ($public === true) { - if (strpos($varName, '_') === 0) { - $error = '%s member variable "%s" must not contain a leading underscore'; - $data = [ - ucfirst($memberProps['scope']), - $errorData[0], - ]; - $phpcsFile->addError($error, $stackPtr, 'PublicHasUnderscore', $data); - } - } elseif (strpos($varName, '_') !== 0) { - $error = 'Private member variable "%s" must contain a leading underscore'; - $phpcsFile->addError($error, $stackPtr, 'PrivateNoUnderscore', $errorData); + if (($public === true) && strpos($varName, '_') === 0) { + $error = '%s member variable "%s" must not contain a leading underscore'; + $data = [ + ucfirst($memberProps['scope']), + $errorData[0], + ]; + $phpcsFile->addError($error, $stackPtr, 'PublicHasUnderscore', $data); } // Remove a potential underscore prefix for testing CamelCaps. diff --git a/tests/Sniffs/NamingConventions/ValidVariableNameSniffTest.php b/tests/Sniffs/NamingConventions/ValidVariableNameSniffTest.php index 48d0a16..b636f67 100644 --- a/tests/Sniffs/NamingConventions/ValidVariableNameSniffTest.php +++ b/tests/Sniffs/NamingConventions/ValidVariableNameSniffTest.php @@ -17,7 +17,6 @@ class ValidVariableNameSniffTest extends TestCase public const CODE_NOT_CAMEL_CAPS = 'NotCamelCaps'; public const CODE_MEMBER_NOT_CAMEL_CAPS = 'MemberNotCamelCaps'; public const CODE_PUBLIC_HAS_UNDERSCORE = 'PublicHasUnderscore'; - public const CODE_PRIVATE_NO_UNDERSCORE = 'PrivateNoUnderscore'; public const CODE_STRING_NOT_CAMEL_CAPS = 'StringNotCamelCaps'; public function testErrors(): void @@ -34,7 +33,6 @@ public function testErrors(): void 20 => self::CODE_MEMBER_NOT_CAMEL_CAPS, 22 => self::CODE_PUBLIC_HAS_UNDERSCORE, 25 => self::CODE_MEMBER_NOT_CAMEL_CAPS, - 27 => self::CODE_PRIVATE_NO_UNDERSCORE, 31 => self::CODE_NOT_CAMEL_CAPS, 33 => self::CODE_NOT_CAMEL_CAPS, 36 => self::CODE_STRING_NOT_CAMEL_CAPS, @@ -52,10 +50,6 @@ public function testErrors(): void 106 => self::CODE_PUBLIC_HAS_UNDERSCORE, 107 => self::CODE_PUBLIC_HAS_UNDERSCORE, 108 => self::CODE_PUBLIC_HAS_UNDERSCORE, - 111 => self::CODE_PRIVATE_NO_UNDERSCORE, - 112 => self::CODE_PRIVATE_NO_UNDERSCORE, - 113 => self::CODE_PRIVATE_NO_UNDERSCORE, - 114 => self::CODE_PRIVATE_NO_UNDERSCORE, 123 => self::CODE_PUBLIC_HAS_UNDERSCORE, 138 => self::CODE_NOT_CAMEL_CAPS, 141 => self::CODE_NOT_CAMEL_CAPS, @@ -79,6 +73,6 @@ public function testErrors(): void } } - self::assertSame(38, $file->getErrorCount()); + self::assertSame(33, $file->getErrorCount()); } } From 278cc68e6e275373d9972c49cae30751bcc259d3 Mon Sep 17 00:00:00 2001 From: Simon Podlipsky Date: Thu, 3 Feb 2022 14:08:52 +0100 Subject: [PATCH 09/15] Do not juggle with stripping `_`. Just don't use it for prefixing. We have better ways of defining property visibility nowadays. --- .../ValidVariableNameSniff.php | 49 ++----------------- .../ValidVariableNameSniffTest.php | 24 ++++++--- 2 files changed, 19 insertions(+), 54 deletions(-) diff --git a/src/Cdn77/Sniffs/NamingConventions/ValidVariableNameSniff.php b/src/Cdn77/Sniffs/NamingConventions/ValidVariableNameSniff.php index 751d9ce..0460a2f 100644 --- a/src/Cdn77/Sniffs/NamingConventions/ValidVariableNameSniff.php +++ b/src/Cdn77/Sniffs/NamingConventions/ValidVariableNameSniff.php @@ -6,16 +6,12 @@ use PHP_CodeSniffer\Files\File; use PHP_CodeSniffer\Sniffs\AbstractVariableSniff; -use PHP_CodeSniffer\Util\Tokens; use function assert; use function ltrim; use function preg_match; use function preg_match_all; use function sprintf; -use function strpos; -use function substr; -use function ucfirst; use const T_DOUBLE_COLON; use const T_NULLSAFE_OBJECT_OPERATOR; @@ -63,17 +59,9 @@ protected function processVariable(File $phpcsFile, $stackPtr): void if ($tokens[$bracket]['code'] !== T_OPEN_PARENTHESIS) { $objVarName = $tokens[$var]['content']; - // There is no way for us to know if the var is public or - // private, so we have to ignore a leading underscore if there is - // one and just check the main part of the variable name. - $originalVarName = $objVarName; - if (strpos($objVarName, '_') === 0) { - $objVarName = substr($objVarName, 1); - } - if (! $this->matchesRegex($objVarName)) { $error = 'Member variable "%s" is not in valid camel caps format'; - $data = [$originalVarName]; + $data = [$objVarName]; $phpcsFile->addError($error, $var, 'MemberNotCamelCaps', $data); } } @@ -82,14 +70,7 @@ protected function processVariable(File $phpcsFile, $stackPtr): void $objOperator = $phpcsFile->findPrevious(T_WHITESPACE, $stackPtr - 1, null, true); if ($tokens[$objOperator]['code'] === T_DOUBLE_COLON) { - // The variable lives within a class, and is referenced like - // this: MyClass::$_variable, so we don't know its scope. - $objVarName = $varName; - if (strpos($objVarName, '_') === 0) { - $objVarName = substr($objVarName, 1); - } - - if (! $this->matchesRegex($objVarName)) { + if (! $this->matchesRegex($varName)) { $error = 'Member variable "%s" is not in valid camel caps format'; $data = [$tokens[$stackPtr]['content']]; $phpcsFile->addError($error, $stackPtr, 'MemberNotCamelCaps', $data); @@ -98,23 +79,12 @@ protected function processVariable(File $phpcsFile, $stackPtr): void return; } - // There is no way for us to know if the var is public or private, - // so we have to ignore a leading underscore if there is one and just - // check the main part of the variable name. - $originalVarName = $varName; - if (strpos($varName, '_') === 0) { - $inClass = $phpcsFile->hasCondition($stackPtr, Tokens::$ooScopeTokens); - if ($inClass === true) { - $varName = substr($varName, 1); - } - } - if ($this->matchesRegex($varName)) { return; } $error = 'Variable "%s" is not in valid camel caps format'; - $data = [$originalVarName]; + $data = [$varName]; $phpcsFile->addError($error, $stackPtr, 'NotCamelCaps', $data); } @@ -141,21 +111,8 @@ protected function processMemberVar(File $phpcsFile, $stackPtr): void return; } - $public = ($memberProps['scope'] !== 'private'); $errorData = [$varName]; - if (($public === true) && strpos($varName, '_') === 0) { - $error = '%s member variable "%s" must not contain a leading underscore'; - $data = [ - ucfirst($memberProps['scope']), - $errorData[0], - ]; - $phpcsFile->addError($error, $stackPtr, 'PublicHasUnderscore', $data); - } - - // Remove a potential underscore prefix for testing CamelCaps. - $varName = ltrim($varName, '_'); - if ($this->matchesRegex($varName)) { return; } diff --git a/tests/Sniffs/NamingConventions/ValidVariableNameSniffTest.php b/tests/Sniffs/NamingConventions/ValidVariableNameSniffTest.php index b636f67..71860a2 100644 --- a/tests/Sniffs/NamingConventions/ValidVariableNameSniffTest.php +++ b/tests/Sniffs/NamingConventions/ValidVariableNameSniffTest.php @@ -27,12 +27,14 @@ public function testErrors(): void 3 => self::CODE_NOT_CAMEL_CAPS, 5 => self::CODE_NOT_CAMEL_CAPS, 10 => self::CODE_MEMBER_NOT_CAMEL_CAPS, - 12 => self::CODE_PUBLIC_HAS_UNDERSCORE, + 12 => self::CODE_MEMBER_NOT_CAMEL_CAPS, 15 => self::CODE_MEMBER_NOT_CAMEL_CAPS, - 17 => self::CODE_PUBLIC_HAS_UNDERSCORE, + 17 => self::CODE_MEMBER_NOT_CAMEL_CAPS, 20 => self::CODE_MEMBER_NOT_CAMEL_CAPS, - 22 => self::CODE_PUBLIC_HAS_UNDERSCORE, + 22 => self::CODE_MEMBER_NOT_CAMEL_CAPS, + 24 => self::CODE_MEMBER_NOT_CAMEL_CAPS, 25 => self::CODE_MEMBER_NOT_CAMEL_CAPS, + 26 => self::CODE_MEMBER_NOT_CAMEL_CAPS, 31 => self::CODE_NOT_CAMEL_CAPS, 33 => self::CODE_NOT_CAMEL_CAPS, 36 => self::CODE_STRING_NOT_CAMEL_CAPS, @@ -41,19 +43,25 @@ public function testErrors(): void 42 => self::CODE_NOT_CAMEL_CAPS, 44 => self::CODE_NOT_CAMEL_CAPS, 53 => self::CODE_MEMBER_NOT_CAMEL_CAPS, + 55 => self::CODE_MEMBER_NOT_CAMEL_CAPS, 58 => self::CODE_MEMBER_NOT_CAMEL_CAPS, + 60 => self::CODE_MEMBER_NOT_CAMEL_CAPS, 62 => self::CODE_MEMBER_NOT_CAMEL_CAPS, 63 => self::CODE_NOT_CAMEL_CAPS, 64 => self::CODE_NOT_CAMEL_CAPS, 67 => self::CODE_NOT_CAMEL_CAPS, 81 => self::CODE_STRING_NOT_CAMEL_CAPS, - 106 => self::CODE_PUBLIC_HAS_UNDERSCORE, - 107 => self::CODE_PUBLIC_HAS_UNDERSCORE, - 108 => self::CODE_PUBLIC_HAS_UNDERSCORE, - 123 => self::CODE_PUBLIC_HAS_UNDERSCORE, + 106 => self::CODE_MEMBER_NOT_CAMEL_CAPS, + 107 => self::CODE_MEMBER_NOT_CAMEL_CAPS, + 108 => self::CODE_MEMBER_NOT_CAMEL_CAPS, + 123 => self::CODE_MEMBER_NOT_CAMEL_CAPS, + 124 => self::CODE_MEMBER_NOT_CAMEL_CAPS, + 134 => self::CODE_MEMBER_NOT_CAMEL_CAPS, 138 => self::CODE_NOT_CAMEL_CAPS, + 140 => self::CODE_NOT_CAMEL_CAPS, 141 => self::CODE_NOT_CAMEL_CAPS, 146 => self::CODE_MEMBER_NOT_CAMEL_CAPS, + 148 => self::CODE_MEMBER_NOT_CAMEL_CAPS, 150 => [self::CODE_NOT_CAMEL_CAPS, self::CODE_NOT_CAMEL_CAPS], 152 => self::CODE_NOT_CAMEL_CAPS, ]; @@ -73,6 +81,6 @@ public function testErrors(): void } } - self::assertSame(33, $file->getErrorCount()); + self::assertSame(43, $file->getErrorCount()); } } From ce7eda73e675aa1bd2433163840d8ebd54578193 Mon Sep 17 00:00:00 2001 From: Simon Podlipsky Date: Thu, 3 Feb 2022 14:31:34 +0100 Subject: [PATCH 10/15] Use baseline to ignore a bug in loading constant from phpcs --- phpstan-baseline.neon | 12 ++++++++++++ phpstan.neon.dist | 1 + 2 files changed, 13 insertions(+) create mode 100644 phpstan-baseline.neon diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon new file mode 100644 index 0000000..125e5e3 --- /dev/null +++ b/phpstan-baseline.neon @@ -0,0 +1,12 @@ +parameters: + ignoreErrors: + - + message: "#^Constant T_OPEN_PARENTHESIS not found\\.$#" + count: 1 + path: src/Cdn77/Sniffs/NamingConventions/ValidVariableNameSniff.php + + - + message: "#^Used constant T_OPEN_PARENTHESIS not found\\.$#" + count: 1 + path: src/Cdn77/Sniffs/NamingConventions/ValidVariableNameSniff.php + diff --git a/phpstan.neon.dist b/phpstan.neon.dist index e1690b3..b9d05b4 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -9,5 +9,6 @@ parameters: - %currentWorkingDirectory% includes: + - phpstan-baseline.neon - vendor/phpstan/phpstan-phpunit/rules.neon - vendor/phpstan/phpstan-strict-rules/rules.neon From af69a6eaf990bcb6576565fe466e97f8bcf07159 Mon Sep 17 00:00:00 2001 From: Simon Podlipsky Date: Thu, 3 Feb 2022 14:25:42 +0100 Subject: [PATCH 11/15] Rename error codes and use proper messages. Also allow specifying patterns for member and string variables --- .../ValidVariableNameSniff.php | 43 +++++---- .../ValidVariableNameSniffTest.php | 88 +++++++++---------- 2 files changed, 68 insertions(+), 63 deletions(-) diff --git a/src/Cdn77/Sniffs/NamingConventions/ValidVariableNameSniff.php b/src/Cdn77/Sniffs/NamingConventions/ValidVariableNameSniff.php index 0460a2f..de7a17b 100644 --- a/src/Cdn77/Sniffs/NamingConventions/ValidVariableNameSniff.php +++ b/src/Cdn77/Sniffs/NamingConventions/ValidVariableNameSniff.php @@ -22,7 +22,14 @@ class ValidVariableNameSniff extends AbstractVariableSniff { - public string $pattern = '\b(([a-zA-Z][a-zA-Z0-9]*?([A-Z][a-zA-Z0-9]*?)*?)|_+)\b'; + public const CODE_DOES_NOT_MATCH_PATTERN = 'DoesNotMatchPattern'; + public const CODE_MEMBER_DOES_NOT_MATCH_PATTERN = 'MemberDoesNotMatchPattern'; + public const CODE_STRING_DOES_NOT_MATCH_PATTERN = 'StringDoesNotMatchPattern'; + private const PATTERN_CAMEL_CASE_OR_UNUSED = '\b(([a-zA-Z][a-zA-Z0-9]*?([A-Z][a-zA-Z0-9]*?)*?)|_+)\b'; + + public string $pattern = self::PATTERN_CAMEL_CASE_OR_UNUSED; + public string $memberPattern = self::PATTERN_CAMEL_CASE_OR_UNUSED; + public string $stringPattern = self::PATTERN_CAMEL_CASE_OR_UNUSED; /** * Processes this test, when one of its tokens is encountered. @@ -59,10 +66,10 @@ protected function processVariable(File $phpcsFile, $stackPtr): void if ($tokens[$bracket]['code'] !== T_OPEN_PARENTHESIS) { $objVarName = $tokens[$var]['content']; - if (! $this->matchesRegex($objVarName)) { - $error = 'Member variable "%s" is not in valid camel caps format'; + if (! $this->matchesRegex($objVarName, $this->memberPattern)) { + $error = sprintf('Member variable "%%s" does not match pattern "%s"', $this->memberPattern); $data = [$objVarName]; - $phpcsFile->addError($error, $var, 'MemberNotCamelCaps', $data); + $phpcsFile->addError($error, $var, self::CODE_MEMBER_DOES_NOT_MATCH_PATTERN, $data); } } } @@ -70,22 +77,22 @@ protected function processVariable(File $phpcsFile, $stackPtr): void $objOperator = $phpcsFile->findPrevious(T_WHITESPACE, $stackPtr - 1, null, true); if ($tokens[$objOperator]['code'] === T_DOUBLE_COLON) { - if (! $this->matchesRegex($varName)) { - $error = 'Member variable "%s" is not in valid camel caps format'; + if (! $this->matchesRegex($varName, $this->memberPattern)) { + $error = sprintf('Member variable "%%s" does not match pattern "%s"', $this->memberPattern); $data = [$tokens[$stackPtr]['content']]; - $phpcsFile->addError($error, $stackPtr, 'MemberNotCamelCaps', $data); + $phpcsFile->addError($error, $stackPtr, self::CODE_MEMBER_DOES_NOT_MATCH_PATTERN, $data); } return; } - if ($this->matchesRegex($varName)) { + if ($this->matchesRegex($varName, $this->pattern)) { return; } - $error = 'Variable "%s" is not in valid camel caps format'; + $error = sprintf('Variable "%%s" does not match pattern "%s"', $this->pattern); $data = [$varName]; - $phpcsFile->addError($error, $stackPtr, 'NotCamelCaps', $data); + $phpcsFile->addError($error, $stackPtr, self::CODE_DOES_NOT_MATCH_PATTERN, $data); } /** @@ -113,12 +120,12 @@ protected function processMemberVar(File $phpcsFile, $stackPtr): void $errorData = [$varName]; - if ($this->matchesRegex($varName)) { + if ($this->matchesRegex($varName, $this->memberPattern)) { return; } - $error = 'Member variable "%s" is not in valid camel caps format'; - $phpcsFile->addError($error, $stackPtr, 'MemberNotCamelCaps', $errorData); + $error = sprintf('Member variable "%%s" does not match pattern "%s"', $this->memberPattern); + $phpcsFile->addError($error, $stackPtr, self::CODE_MEMBER_DOES_NOT_MATCH_PATTERN, $errorData); } /** @@ -150,18 +157,18 @@ protected function processVariableInString(File $phpcsFile, $stackPtr): void continue; } - if ($this->matchesRegex($varName)) { + if ($this->matchesRegex($varName, $this->stringPattern)) { continue; } - $error = 'Variable "%s" is not in valid camel caps format'; + $error = sprintf('Variable "%%s" does not match pattern "%s"', $this->stringPattern); $data = [$varName]; - $phpcsFile->addError($error, $stackPtr, 'StringNotCamelCaps', $data); + $phpcsFile->addError($error, $stackPtr, self::CODE_STRING_DOES_NOT_MATCH_PATTERN, $data); } } - private function matchesRegex(string $varName): bool + private function matchesRegex(string $varName, string $pattern): bool { - return preg_match(sprintf('~%s~', $this->pattern), $varName) === 1; + return preg_match(sprintf('~%s~', $pattern), $varName) === 1; } } diff --git a/tests/Sniffs/NamingConventions/ValidVariableNameSniffTest.php b/tests/Sniffs/NamingConventions/ValidVariableNameSniffTest.php index 71860a2..1d626a8 100644 --- a/tests/Sniffs/NamingConventions/ValidVariableNameSniffTest.php +++ b/tests/Sniffs/NamingConventions/ValidVariableNameSniffTest.php @@ -14,56 +14,54 @@ class ValidVariableNameSniffTest extends TestCase { - public const CODE_NOT_CAMEL_CAPS = 'NotCamelCaps'; - public const CODE_MEMBER_NOT_CAMEL_CAPS = 'MemberNotCamelCaps'; - public const CODE_PUBLIC_HAS_UNDERSCORE = 'PublicHasUnderscore'; - public const CODE_STRING_NOT_CAMEL_CAPS = 'StringNotCamelCaps'; - public function testErrors(): void { $file = self::checkFile(__DIR__ . '/data/ValidVariableNameSniffTest.inc'); $errorTypesPerLine = [ - 3 => self::CODE_NOT_CAMEL_CAPS, - 5 => self::CODE_NOT_CAMEL_CAPS, - 10 => self::CODE_MEMBER_NOT_CAMEL_CAPS, - 12 => self::CODE_MEMBER_NOT_CAMEL_CAPS, - 15 => self::CODE_MEMBER_NOT_CAMEL_CAPS, - 17 => self::CODE_MEMBER_NOT_CAMEL_CAPS, - 20 => self::CODE_MEMBER_NOT_CAMEL_CAPS, - 22 => self::CODE_MEMBER_NOT_CAMEL_CAPS, - 24 => self::CODE_MEMBER_NOT_CAMEL_CAPS, - 25 => self::CODE_MEMBER_NOT_CAMEL_CAPS, - 26 => self::CODE_MEMBER_NOT_CAMEL_CAPS, - 31 => self::CODE_NOT_CAMEL_CAPS, - 33 => self::CODE_NOT_CAMEL_CAPS, - 36 => self::CODE_STRING_NOT_CAMEL_CAPS, - 37 => self::CODE_STRING_NOT_CAMEL_CAPS, - 39 => self::CODE_STRING_NOT_CAMEL_CAPS, - 42 => self::CODE_NOT_CAMEL_CAPS, - 44 => self::CODE_NOT_CAMEL_CAPS, - 53 => self::CODE_MEMBER_NOT_CAMEL_CAPS, - 55 => self::CODE_MEMBER_NOT_CAMEL_CAPS, - 58 => self::CODE_MEMBER_NOT_CAMEL_CAPS, - 60 => self::CODE_MEMBER_NOT_CAMEL_CAPS, - 62 => self::CODE_MEMBER_NOT_CAMEL_CAPS, - 63 => self::CODE_NOT_CAMEL_CAPS, - 64 => self::CODE_NOT_CAMEL_CAPS, - 67 => self::CODE_NOT_CAMEL_CAPS, - 81 => self::CODE_STRING_NOT_CAMEL_CAPS, - 106 => self::CODE_MEMBER_NOT_CAMEL_CAPS, - 107 => self::CODE_MEMBER_NOT_CAMEL_CAPS, - 108 => self::CODE_MEMBER_NOT_CAMEL_CAPS, - 123 => self::CODE_MEMBER_NOT_CAMEL_CAPS, - 124 => self::CODE_MEMBER_NOT_CAMEL_CAPS, - 134 => self::CODE_MEMBER_NOT_CAMEL_CAPS, - 138 => self::CODE_NOT_CAMEL_CAPS, - 140 => self::CODE_NOT_CAMEL_CAPS, - 141 => self::CODE_NOT_CAMEL_CAPS, - 146 => self::CODE_MEMBER_NOT_CAMEL_CAPS, - 148 => self::CODE_MEMBER_NOT_CAMEL_CAPS, - 150 => [self::CODE_NOT_CAMEL_CAPS, self::CODE_NOT_CAMEL_CAPS], - 152 => self::CODE_NOT_CAMEL_CAPS, + 3 => ValidVariableNameSniff::CODE_DOES_NOT_MATCH_PATTERN, + 5 => ValidVariableNameSniff::CODE_DOES_NOT_MATCH_PATTERN, + 10 => ValidVariableNameSniff::CODE_MEMBER_DOES_NOT_MATCH_PATTERN, + 12 => ValidVariableNameSniff::CODE_MEMBER_DOES_NOT_MATCH_PATTERN, + 15 => ValidVariableNameSniff::CODE_MEMBER_DOES_NOT_MATCH_PATTERN, + 17 => ValidVariableNameSniff::CODE_MEMBER_DOES_NOT_MATCH_PATTERN, + 20 => ValidVariableNameSniff::CODE_MEMBER_DOES_NOT_MATCH_PATTERN, + 22 => ValidVariableNameSniff::CODE_MEMBER_DOES_NOT_MATCH_PATTERN, + 24 => ValidVariableNameSniff::CODE_MEMBER_DOES_NOT_MATCH_PATTERN, + 25 => ValidVariableNameSniff::CODE_MEMBER_DOES_NOT_MATCH_PATTERN, + 26 => ValidVariableNameSniff::CODE_MEMBER_DOES_NOT_MATCH_PATTERN, + 31 => ValidVariableNameSniff::CODE_DOES_NOT_MATCH_PATTERN, + 33 => ValidVariableNameSniff::CODE_DOES_NOT_MATCH_PATTERN, + 36 => ValidVariableNameSniff::CODE_STRING_DOES_NOT_MATCH_PATTERN, + 37 => ValidVariableNameSniff::CODE_STRING_DOES_NOT_MATCH_PATTERN, + 39 => ValidVariableNameSniff::CODE_STRING_DOES_NOT_MATCH_PATTERN, + 42 => ValidVariableNameSniff::CODE_DOES_NOT_MATCH_PATTERN, + 44 => ValidVariableNameSniff::CODE_DOES_NOT_MATCH_PATTERN, + 53 => ValidVariableNameSniff::CODE_MEMBER_DOES_NOT_MATCH_PATTERN, + 55 => ValidVariableNameSniff::CODE_MEMBER_DOES_NOT_MATCH_PATTERN, + 58 => ValidVariableNameSniff::CODE_MEMBER_DOES_NOT_MATCH_PATTERN, + 60 => ValidVariableNameSniff::CODE_MEMBER_DOES_NOT_MATCH_PATTERN, + 62 => ValidVariableNameSniff::CODE_MEMBER_DOES_NOT_MATCH_PATTERN, + 63 => ValidVariableNameSniff::CODE_DOES_NOT_MATCH_PATTERN, + 64 => ValidVariableNameSniff::CODE_DOES_NOT_MATCH_PATTERN, + 67 => ValidVariableNameSniff::CODE_DOES_NOT_MATCH_PATTERN, + 81 => ValidVariableNameSniff::CODE_STRING_DOES_NOT_MATCH_PATTERN, + 106 => ValidVariableNameSniff::CODE_MEMBER_DOES_NOT_MATCH_PATTERN, + 107 => ValidVariableNameSniff::CODE_MEMBER_DOES_NOT_MATCH_PATTERN, + 108 => ValidVariableNameSniff::CODE_MEMBER_DOES_NOT_MATCH_PATTERN, + 123 => ValidVariableNameSniff::CODE_MEMBER_DOES_NOT_MATCH_PATTERN, + 124 => ValidVariableNameSniff::CODE_MEMBER_DOES_NOT_MATCH_PATTERN, + 134 => ValidVariableNameSniff::CODE_MEMBER_DOES_NOT_MATCH_PATTERN, + 138 => ValidVariableNameSniff::CODE_DOES_NOT_MATCH_PATTERN, + 140 => ValidVariableNameSniff::CODE_DOES_NOT_MATCH_PATTERN, + 141 => ValidVariableNameSniff::CODE_DOES_NOT_MATCH_PATTERN, + 146 => ValidVariableNameSniff::CODE_MEMBER_DOES_NOT_MATCH_PATTERN, + 148 => ValidVariableNameSniff::CODE_MEMBER_DOES_NOT_MATCH_PATTERN, + 150 => [ + ValidVariableNameSniff::CODE_DOES_NOT_MATCH_PATTERN, + ValidVariableNameSniff::CODE_DOES_NOT_MATCH_PATTERN, + ], + 152 => ValidVariableNameSniff::CODE_DOES_NOT_MATCH_PATTERN, ]; $possibleLines = array_keys($errorTypesPerLine); From 1fb8d2fc403a8021f17281030617b03f53aab1c3 Mon Sep 17 00:00:00 2001 From: Simon Podlipsky Date: Thu, 3 Feb 2022 14:38:47 +0100 Subject: [PATCH 12/15] Method doc culture --- .../Sniffs/NamingConventions/ValidVariableNameSniff.php | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/Cdn77/Sniffs/NamingConventions/ValidVariableNameSniff.php b/src/Cdn77/Sniffs/NamingConventions/ValidVariableNameSniff.php index de7a17b..0a6f792 100644 --- a/src/Cdn77/Sniffs/NamingConventions/ValidVariableNameSniff.php +++ b/src/Cdn77/Sniffs/NamingConventions/ValidVariableNameSniff.php @@ -35,8 +35,7 @@ class ValidVariableNameSniff extends AbstractVariableSniff * Processes this test, when one of its tokens is encountered. * * @param File $phpcsFile The file being scanned. - * @param int $stackPtr The position of the current token in the - * stack passed in $tokens. + * @param int $stackPtr The position of the current token in the stack passed in $tokens. * * @phpcsSuppress SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint */ @@ -99,8 +98,7 @@ protected function processVariable(File $phpcsFile, $stackPtr): void * Processes class member variables. * * @param File $phpcsFile The file being scanned. - * @param int $stackPtr The position of the current token in the - * stack passed in $tokens. + * @param int $stackPtr The position of the current token in the stack passed in $tokens. * * @phpcsSuppress SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint */ @@ -132,8 +130,7 @@ protected function processMemberVar(File $phpcsFile, $stackPtr): void * Processes the variable found within a double quoted string. * * @param File $phpcsFile The file being scanned. - * @param int $stackPtr The position of the double quoted - * string. + * @param int $stackPtr The position of the double quoted string. * * @phpcsSuppress SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint */ From f7ce1a31d4c072dffbd119570daff60913a63f0d Mon Sep 17 00:00:00 2001 From: Simon Podlipsky Date: Thu, 3 Feb 2022 16:10:06 +0100 Subject: [PATCH 13/15] Cleanup test --- .../ValidVariableNameSniffTest.php | 62 +++++++++---------- .../data/ValidVariableNameSniffTest.inc | 6 -- 2 files changed, 30 insertions(+), 38 deletions(-) diff --git a/tests/Sniffs/NamingConventions/ValidVariableNameSniffTest.php b/tests/Sniffs/NamingConventions/ValidVariableNameSniffTest.php index 1d626a8..440e92c 100644 --- a/tests/Sniffs/NamingConventions/ValidVariableNameSniffTest.php +++ b/tests/Sniffs/NamingConventions/ValidVariableNameSniffTest.php @@ -25,43 +25,41 @@ public function testErrors(): void 12 => ValidVariableNameSniff::CODE_MEMBER_DOES_NOT_MATCH_PATTERN, 15 => ValidVariableNameSniff::CODE_MEMBER_DOES_NOT_MATCH_PATTERN, 17 => ValidVariableNameSniff::CODE_MEMBER_DOES_NOT_MATCH_PATTERN, + 19 => ValidVariableNameSniff::CODE_MEMBER_DOES_NOT_MATCH_PATTERN, 20 => ValidVariableNameSniff::CODE_MEMBER_DOES_NOT_MATCH_PATTERN, - 22 => ValidVariableNameSniff::CODE_MEMBER_DOES_NOT_MATCH_PATTERN, - 24 => ValidVariableNameSniff::CODE_MEMBER_DOES_NOT_MATCH_PATTERN, - 25 => ValidVariableNameSniff::CODE_MEMBER_DOES_NOT_MATCH_PATTERN, - 26 => ValidVariableNameSniff::CODE_MEMBER_DOES_NOT_MATCH_PATTERN, - 31 => ValidVariableNameSniff::CODE_DOES_NOT_MATCH_PATTERN, - 33 => ValidVariableNameSniff::CODE_DOES_NOT_MATCH_PATTERN, - 36 => ValidVariableNameSniff::CODE_STRING_DOES_NOT_MATCH_PATTERN, - 37 => ValidVariableNameSniff::CODE_STRING_DOES_NOT_MATCH_PATTERN, - 39 => ValidVariableNameSniff::CODE_STRING_DOES_NOT_MATCH_PATTERN, - 42 => ValidVariableNameSniff::CODE_DOES_NOT_MATCH_PATTERN, - 44 => ValidVariableNameSniff::CODE_DOES_NOT_MATCH_PATTERN, + 21 => ValidVariableNameSniff::CODE_MEMBER_DOES_NOT_MATCH_PATTERN, + 26 => ValidVariableNameSniff::CODE_DOES_NOT_MATCH_PATTERN, + 28 => ValidVariableNameSniff::CODE_DOES_NOT_MATCH_PATTERN, + 31 => ValidVariableNameSniff::CODE_STRING_DOES_NOT_MATCH_PATTERN, + 32 => ValidVariableNameSniff::CODE_STRING_DOES_NOT_MATCH_PATTERN, + 34 => ValidVariableNameSniff::CODE_STRING_DOES_NOT_MATCH_PATTERN, + 37 => ValidVariableNameSniff::CODE_DOES_NOT_MATCH_PATTERN, + 39 => ValidVariableNameSniff::CODE_DOES_NOT_MATCH_PATTERN, + 48 => ValidVariableNameSniff::CODE_MEMBER_DOES_NOT_MATCH_PATTERN, + 50 => ValidVariableNameSniff::CODE_MEMBER_DOES_NOT_MATCH_PATTERN, 53 => ValidVariableNameSniff::CODE_MEMBER_DOES_NOT_MATCH_PATTERN, 55 => ValidVariableNameSniff::CODE_MEMBER_DOES_NOT_MATCH_PATTERN, - 58 => ValidVariableNameSniff::CODE_MEMBER_DOES_NOT_MATCH_PATTERN, - 60 => ValidVariableNameSniff::CODE_MEMBER_DOES_NOT_MATCH_PATTERN, - 62 => ValidVariableNameSniff::CODE_MEMBER_DOES_NOT_MATCH_PATTERN, - 63 => ValidVariableNameSniff::CODE_DOES_NOT_MATCH_PATTERN, - 64 => ValidVariableNameSniff::CODE_DOES_NOT_MATCH_PATTERN, - 67 => ValidVariableNameSniff::CODE_DOES_NOT_MATCH_PATTERN, - 81 => ValidVariableNameSniff::CODE_STRING_DOES_NOT_MATCH_PATTERN, - 106 => ValidVariableNameSniff::CODE_MEMBER_DOES_NOT_MATCH_PATTERN, - 107 => ValidVariableNameSniff::CODE_MEMBER_DOES_NOT_MATCH_PATTERN, - 108 => ValidVariableNameSniff::CODE_MEMBER_DOES_NOT_MATCH_PATTERN, - 123 => ValidVariableNameSniff::CODE_MEMBER_DOES_NOT_MATCH_PATTERN, - 124 => ValidVariableNameSniff::CODE_MEMBER_DOES_NOT_MATCH_PATTERN, - 134 => ValidVariableNameSniff::CODE_MEMBER_DOES_NOT_MATCH_PATTERN, - 138 => ValidVariableNameSniff::CODE_DOES_NOT_MATCH_PATTERN, - 140 => ValidVariableNameSniff::CODE_DOES_NOT_MATCH_PATTERN, - 141 => ValidVariableNameSniff::CODE_DOES_NOT_MATCH_PATTERN, - 146 => ValidVariableNameSniff::CODE_MEMBER_DOES_NOT_MATCH_PATTERN, - 148 => ValidVariableNameSniff::CODE_MEMBER_DOES_NOT_MATCH_PATTERN, - 150 => [ + 57 => ValidVariableNameSniff::CODE_MEMBER_DOES_NOT_MATCH_PATTERN, + 58 => ValidVariableNameSniff::CODE_DOES_NOT_MATCH_PATTERN, + 59 => ValidVariableNameSniff::CODE_DOES_NOT_MATCH_PATTERN, + 62 => ValidVariableNameSniff::CODE_DOES_NOT_MATCH_PATTERN, + 76 => ValidVariableNameSniff::CODE_STRING_DOES_NOT_MATCH_PATTERN, + 100 => ValidVariableNameSniff::CODE_MEMBER_DOES_NOT_MATCH_PATTERN, + 101 => ValidVariableNameSniff::CODE_MEMBER_DOES_NOT_MATCH_PATTERN, + 102 => ValidVariableNameSniff::CODE_MEMBER_DOES_NOT_MATCH_PATTERN, + 117 => ValidVariableNameSniff::CODE_MEMBER_DOES_NOT_MATCH_PATTERN, + 118 => ValidVariableNameSniff::CODE_MEMBER_DOES_NOT_MATCH_PATTERN, + 128 => ValidVariableNameSniff::CODE_MEMBER_DOES_NOT_MATCH_PATTERN, + 132 => ValidVariableNameSniff::CODE_DOES_NOT_MATCH_PATTERN, + 134 => ValidVariableNameSniff::CODE_DOES_NOT_MATCH_PATTERN, + 135 => ValidVariableNameSniff::CODE_DOES_NOT_MATCH_PATTERN, + 140 => ValidVariableNameSniff::CODE_MEMBER_DOES_NOT_MATCH_PATTERN, + 142 => ValidVariableNameSniff::CODE_MEMBER_DOES_NOT_MATCH_PATTERN, + 144 => [ ValidVariableNameSniff::CODE_DOES_NOT_MATCH_PATTERN, ValidVariableNameSniff::CODE_DOES_NOT_MATCH_PATTERN, ], - 152 => ValidVariableNameSniff::CODE_DOES_NOT_MATCH_PATTERN, + 146 => ValidVariableNameSniff::CODE_DOES_NOT_MATCH_PATTERN, ]; $possibleLines = array_keys($errorTypesPerLine); @@ -79,6 +77,6 @@ public function testErrors(): void } } - self::assertSame(43, $file->getErrorCount()); + self::assertSame(41, $file->getErrorCount()); } } diff --git a/tests/Sniffs/NamingConventions/data/ValidVariableNameSniffTest.inc b/tests/Sniffs/NamingConventions/data/ValidVariableNameSniffTest.inc index 2823013..0754a39 100644 --- a/tests/Sniffs/NamingConventions/data/ValidVariableNameSniffTest.inc +++ b/tests/Sniffs/NamingConventions/data/ValidVariableNameSniffTest.inc @@ -6,11 +6,6 @@ $_varName = 'hello'; class MyClass { -$varName = 'hello'; -$var_name = 'hello'; -$varname = 'hello'; -$_varName = 'hello'; - public $varName = 'hello'; public bool $var_name = false; public $varname = 'hello'; @@ -80,7 +75,6 @@ $xmlParser = 'hello'; echo "{$_SERVER['HOSTNAME']} $var_name"; -// Need to be the last thing in this test file. $obj->$classVar = $prefix.'-'.$type; class foo From 8aeb62c432d6992bf10d53eae7be7fe56d6fb933 Mon Sep 17 00:00:00 2001 From: Simon Podlipsky Date: Thu, 3 Feb 2022 16:35:05 +0100 Subject: [PATCH 14/15] Add potato case --- .../NamingConventions/data/ValidVariableNameSniffTest.inc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/Sniffs/NamingConventions/data/ValidVariableNameSniffTest.inc b/tests/Sniffs/NamingConventions/data/ValidVariableNameSniffTest.inc index 0754a39..53c46ba 100644 --- a/tests/Sniffs/NamingConventions/data/ValidVariableNameSniffTest.inc +++ b/tests/Sniffs/NamingConventions/data/ValidVariableNameSniffTest.inc @@ -144,3 +144,5 @@ echo $obj?->_varName; $var_name . $var_name; fn($_, $__, $_x) => true; + +$var = Potato::new(); From 81b865cfa57dc1b57f53093c4e71280bed03d5d6 Mon Sep 17 00:00:00 2001 From: Simon Podlipsky Date: Fri, 4 Feb 2022 17:06:31 +0100 Subject: [PATCH 15/15] Allow unused vars only in DoesNotMatchPattern --- .../Sniffs/NamingConventions/ValidVariableNameSniff.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Cdn77/Sniffs/NamingConventions/ValidVariableNameSniff.php b/src/Cdn77/Sniffs/NamingConventions/ValidVariableNameSniff.php index 0a6f792..917b5f6 100644 --- a/src/Cdn77/Sniffs/NamingConventions/ValidVariableNameSniff.php +++ b/src/Cdn77/Sniffs/NamingConventions/ValidVariableNameSniff.php @@ -25,11 +25,12 @@ class ValidVariableNameSniff extends AbstractVariableSniff public const CODE_DOES_NOT_MATCH_PATTERN = 'DoesNotMatchPattern'; public const CODE_MEMBER_DOES_NOT_MATCH_PATTERN = 'MemberDoesNotMatchPattern'; public const CODE_STRING_DOES_NOT_MATCH_PATTERN = 'StringDoesNotMatchPattern'; + private const PATTERN_CAMEL_CASE = '\b([a-zA-Z][a-zA-Z0-9]*?([A-Z][a-zA-Z0-9]*?)*?)\b'; private const PATTERN_CAMEL_CASE_OR_UNUSED = '\b(([a-zA-Z][a-zA-Z0-9]*?([A-Z][a-zA-Z0-9]*?)*?)|_+)\b'; public string $pattern = self::PATTERN_CAMEL_CASE_OR_UNUSED; - public string $memberPattern = self::PATTERN_CAMEL_CASE_OR_UNUSED; - public string $stringPattern = self::PATTERN_CAMEL_CASE_OR_UNUSED; + public string $memberPattern = self::PATTERN_CAMEL_CASE; + public string $stringPattern = self::PATTERN_CAMEL_CASE; /** * Processes this test, when one of its tokens is encountered.