From 0a25c52bb9ce309b1577c41e8d08f01342919560 Mon Sep 17 00:00:00 2001 From: Vossik Date: Wed, 2 Jun 2021 23:08:39 +0200 Subject: [PATCH] ConstructorPropertyPromotionSpacingSniff --- ...nstructorPropertyPromotionSpacingSniff.php | 108 ++++++++++++++++++ InfinityloopCodingStandard/ruleset.xml | 1 + README.md | 4 + 3 files changed, 113 insertions(+) create mode 100644 InfinityloopCodingStandard/Sniffs/Classes/ConstructorPropertyPromotionSpacingSniff.php diff --git a/InfinityloopCodingStandard/Sniffs/Classes/ConstructorPropertyPromotionSpacingSniff.php b/InfinityloopCodingStandard/Sniffs/Classes/ConstructorPropertyPromotionSpacingSniff.php new file mode 100644 index 0000000..81b41bb --- /dev/null +++ b/InfinityloopCodingStandard/Sniffs/Classes/ConstructorPropertyPromotionSpacingSniff.php @@ -0,0 +1,108 @@ +getTokens(); + + $namePointer = \SlevomatCodingStandard\Helpers\TokenHelper::findNextEffective($phpcsFile, $functionPointer + 1); + + if (\strtolower($tokens[$namePointer]['content']) !== '__construct') { + return; + } + + if (\SlevomatCodingStandard\Helpers\FunctionHelper::isAbstract($phpcsFile, $functionPointer)) { + return; + } + + $parameterPointers = $this->getParameterPointers($phpcsFile, $functionPointer); + + if (\count($parameterPointers) === 0) { + return; + } + + $containsPropertyPromotion = false; + + foreach ($parameterPointers as $parameterPointer) { + $pointerBefore = \SlevomatCodingStandard\Helpers\TokenHelper::findPrevious( + $phpcsFile, + [\T_COMMA, \T_OPEN_PARENTHESIS], + $parameterPointer - 1, + ); + + $visibilityPointer = \SlevomatCodingStandard\Helpers\TokenHelper::findNextEffective($phpcsFile, $pointerBefore + 1); + + if (\in_array($tokens[$visibilityPointer]['code'], \PHP_CodeSniffer\Util\Tokens::$scopeModifiers, true)) { + $containsPropertyPromotion = true; + } + } + + if (!$containsPropertyPromotion) { + return; + } + + $previousPointer = null; + + foreach ($parameterPointers as $parameterPointer) { + if ($previousPointer === null) { + $previousPointer = $parameterPointer; + + continue; + } + + if ($tokens[$previousPointer]['line'] !== $tokens[$parameterPointer]['line']) { + continue; + } + + $fix = $phpcsFile->addFixableError( + 'Constructor parameter should be reformatted to next line.', + $parameterPointer, + self::CONSTRUCTOR_PARAMETER_SAME_LINE, + ); + + if (!$fix) { + continue; + } + + $phpcsFile->fixer->beginChangeset(); + + $pointerBefore = \SlevomatCodingStandard\Helpers\TokenHelper::findPrevious( + $phpcsFile, + [\T_COMMA, \T_OPEN_PARENTHESIS], + $parameterPointer - 1, + ); + + $phpcsFile->fixer->addContent($pointerBefore, $phpcsFile->eolChar); + + $phpcsFile->fixer->endChangeset(); + } + } + + private function getParameterPointers(\PHP_CodeSniffer\Files\File $phpcsFile, int $functionPointer) : array + { + $tokens = $phpcsFile->getTokens(); + + return \SlevomatCodingStandard\Helpers\TokenHelper::findNextAll( + $phpcsFile, + \T_VARIABLE, + $tokens[$functionPointer]['parenthesis_opener'] + 1, + $tokens[$functionPointer]['parenthesis_closer'], + ); + } +} diff --git a/InfinityloopCodingStandard/ruleset.xml b/InfinityloopCodingStandard/ruleset.xml index e618450..a939741 100644 --- a/InfinityloopCodingStandard/ruleset.xml +++ b/InfinityloopCodingStandard/ruleset.xml @@ -502,4 +502,5 @@ + diff --git a/README.md b/README.md index 3e1ce40..e89517e 100644 --- a/README.md +++ b/README.md @@ -82,6 +82,10 @@ Checks that there is a certain number of blank lines between code and comment Improved version of Slevomat UnionTypeHintFormat with added formatting of multiline unions +#### InfinityloopCodingStandard.Classes.ConstructorPropertyPromotionSpacing :wrench: + +Space constructor arguments one per line when Constructor Property Promotion is used + ### Slevomat sniffs Detailed list of Slevomat sniffs with configured settings. Some sniffs are not included, either because we dont find them helpful, the are too strict, or collide with their counter-sniff (require/disallow pairs).