Skip to content

Commit 920e0aa

Browse files
authored
Merge pull request #13 from vossik/cpp_spacing
ConstructorPropertyPromotionSpacingSniff
2 parents 6958894 + 0a25c52 commit 920e0aa

File tree

3 files changed

+113
-0
lines changed

3 files changed

+113
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
<?php
2+
3+
declare(strict_types = 1);
4+
5+
namespace InfinityloopCodingStandard\Sniffs\Classes;
6+
7+
class ConstructorPropertyPromotionSpacingSniff implements \PHP_CodeSniffer\Sniffs\Sniff
8+
{
9+
public const CONSTRUCTOR_PARAMETER_SAME_LINE = 'ConstructorParametersOnSameLine';
10+
11+
public function register() : array
12+
{
13+
return [\T_FUNCTION];
14+
}
15+
16+
public function process(\PHP_CodeSniffer\Files\File $phpcsFile, $functionPointer) : void
17+
{
18+
if (!\SlevomatCodingStandard\Helpers\SniffSettingsHelper::isEnabledByPhpVersion(null, 80000)) {
19+
return;
20+
}
21+
22+
$tokens = $phpcsFile->getTokens();
23+
24+
$namePointer = \SlevomatCodingStandard\Helpers\TokenHelper::findNextEffective($phpcsFile, $functionPointer + 1);
25+
26+
if (\strtolower($tokens[$namePointer]['content']) !== '__construct') {
27+
return;
28+
}
29+
30+
if (\SlevomatCodingStandard\Helpers\FunctionHelper::isAbstract($phpcsFile, $functionPointer)) {
31+
return;
32+
}
33+
34+
$parameterPointers = $this->getParameterPointers($phpcsFile, $functionPointer);
35+
36+
if (\count($parameterPointers) === 0) {
37+
return;
38+
}
39+
40+
$containsPropertyPromotion = false;
41+
42+
foreach ($parameterPointers as $parameterPointer) {
43+
$pointerBefore = \SlevomatCodingStandard\Helpers\TokenHelper::findPrevious(
44+
$phpcsFile,
45+
[\T_COMMA, \T_OPEN_PARENTHESIS],
46+
$parameterPointer - 1,
47+
);
48+
49+
$visibilityPointer = \SlevomatCodingStandard\Helpers\TokenHelper::findNextEffective($phpcsFile, $pointerBefore + 1);
50+
51+
if (\in_array($tokens[$visibilityPointer]['code'], \PHP_CodeSniffer\Util\Tokens::$scopeModifiers, true)) {
52+
$containsPropertyPromotion = true;
53+
}
54+
}
55+
56+
if (!$containsPropertyPromotion) {
57+
return;
58+
}
59+
60+
$previousPointer = null;
61+
62+
foreach ($parameterPointers as $parameterPointer) {
63+
if ($previousPointer === null) {
64+
$previousPointer = $parameterPointer;
65+
66+
continue;
67+
}
68+
69+
if ($tokens[$previousPointer]['line'] !== $tokens[$parameterPointer]['line']) {
70+
continue;
71+
}
72+
73+
$fix = $phpcsFile->addFixableError(
74+
'Constructor parameter should be reformatted to next line.',
75+
$parameterPointer,
76+
self::CONSTRUCTOR_PARAMETER_SAME_LINE,
77+
);
78+
79+
if (!$fix) {
80+
continue;
81+
}
82+
83+
$phpcsFile->fixer->beginChangeset();
84+
85+
$pointerBefore = \SlevomatCodingStandard\Helpers\TokenHelper::findPrevious(
86+
$phpcsFile,
87+
[\T_COMMA, \T_OPEN_PARENTHESIS],
88+
$parameterPointer - 1,
89+
);
90+
91+
$phpcsFile->fixer->addContent($pointerBefore, $phpcsFile->eolChar);
92+
93+
$phpcsFile->fixer->endChangeset();
94+
}
95+
}
96+
97+
private function getParameterPointers(\PHP_CodeSniffer\Files\File $phpcsFile, int $functionPointer) : array
98+
{
99+
$tokens = $phpcsFile->getTokens();
100+
101+
return \SlevomatCodingStandard\Helpers\TokenHelper::findNextAll(
102+
$phpcsFile,
103+
\T_VARIABLE,
104+
$tokens[$functionPointer]['parenthesis_opener'] + 1,
105+
$tokens[$functionPointer]['parenthesis_closer'],
106+
);
107+
}
108+
}

InfinityloopCodingStandard/ruleset.xml

+1
Original file line numberDiff line numberDiff line change
@@ -502,4 +502,5 @@
502502
<rule ref="InfinityloopCodingStandard.ControlStructures.RequireMultiLineNullCoalesce"/>
503503
<rule ref="InfinityloopCodingStandard.ControlStructures.SwitchCommentSpacing"/>
504504
<rule ref="InfinityloopCodingStandard.TypeHints.UnionTypeHintFormat"/>
505+
<rule ref="InfinityloopCodingStandard.Classes.ConstructorPropertyPromotionSpacing"/>
505506
</ruleset>

README.md

+4
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,10 @@ Checks that there is a certain number of blank lines between code and comment
8282

8383
Improved version of Slevomat UnionTypeHintFormat with added formatting of multiline unions
8484

85+
#### InfinityloopCodingStandard.Classes.ConstructorPropertyPromotionSpacing :wrench:
86+
87+
Space constructor arguments one per line when Constructor Property Promotion is used
88+
8589
### Slevomat sniffs
8690

8791
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).

0 commit comments

Comments
 (0)