Skip to content

Commit 9cfa50d

Browse files
Majkl578kukulich
authored andcommitted
ReturnTypeHintSpacingSniff: Allow configurable spacing before colon
1 parent f84b2f4 commit 9cfa50d

File tree

6 files changed

+345
-3
lines changed

6 files changed

+345
-3
lines changed

SlevomatCodingStandard/Sniffs/TypeHints/ReturnTypeHintSpacingSniff.php

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace SlevomatCodingStandard\Sniffs\TypeHints;
44

5+
use SlevomatCodingStandard\Helpers\SniffSettingsHelper;
56
use SlevomatCodingStandard\Helpers\TokenHelper;
67

78
class ReturnTypeHintSpacingSniff implements \PHP_CodeSniffer_Sniff
@@ -17,8 +18,13 @@ class ReturnTypeHintSpacingSniff implements \PHP_CodeSniffer_Sniff
1718

1819
const CODE_WHITESPACE_BEFORE_COLON = 'WhitespaceBeforeColon';
1920

21+
const CODE_INCORRECT_SPACES_BEFORE_COLON = 'IncorrectWhitespaceBeforeColon';
22+
2023
const CODE_WHITESPACE_AFTER_NULLABILITY_SYMBOL = 'WhitespaceAfterNullabilitySymbol';
2124

25+
/** @var int */
26+
public $spacesCountBeforeColon = 0;
27+
2228
/**
2329
* @return int[]
2430
*/
@@ -87,11 +93,33 @@ public function process(\PHP_CodeSniffer_File $phpcsFile, $typeHintPointer)
8793
}
8894
}
8995

90-
if ($tokens[$colonPointer - 1]['code'] !== T_CLOSE_PARENTHESIS) {
91-
$fix = $phpcsFile->addFixableError('There must be no whitespace between closing parenthesis and return type colon.', $typeHintPointer, self::CODE_WHITESPACE_BEFORE_COLON);
96+
$spacesCountBeforeColon = SniffSettingsHelper::normalizeInteger($this->spacesCountBeforeColon);
97+
$expectedSpaces = str_repeat(' ', $spacesCountBeforeColon);
98+
99+
if ($tokens[$colonPointer - 1]['code'] !== T_CLOSE_PARENTHESIS && $tokens[$colonPointer - 1]['content'] !== $expectedSpaces) {
100+
if ($spacesCountBeforeColon === 0) {
101+
$fix = $phpcsFile->addFixableError('There must be no whitespace between closing parenthesis and return type colon.', $typeHintPointer, self::CODE_WHITESPACE_BEFORE_COLON);
102+
} else {
103+
$fix = $phpcsFile->addFixableError(
104+
sprintf('There must be exactly %d whitespace%s between closing parenthesis and return type colon.', $spacesCountBeforeColon, $spacesCountBeforeColon !== 1 ? 's' : ''),
105+
$typeHintPointer,
106+
self::CODE_INCORRECT_SPACES_BEFORE_COLON
107+
);
108+
}
109+
if ($fix) {
110+
$phpcsFile->fixer->beginChangeset();
111+
$phpcsFile->fixer->replaceToken($colonPointer - 1, $expectedSpaces);
112+
$phpcsFile->fixer->endChangeset();
113+
}
114+
} elseif ($tokens[$colonPointer - 1]['code'] === T_CLOSE_PARENTHESIS && $spacesCountBeforeColon !== 0) {
115+
$fix = $phpcsFile->addFixableError(
116+
sprintf('There must be exactly %d whitespace%s between closing parenthesis and return type colon.', $spacesCountBeforeColon, $spacesCountBeforeColon !== 1 ? 's' : ''),
117+
$typeHintPointer,
118+
self::CODE_INCORRECT_SPACES_BEFORE_COLON
119+
);
92120
if ($fix) {
93121
$phpcsFile->fixer->beginChangeset();
94-
$phpcsFile->fixer->replaceToken($colonPointer - 1, '');
122+
$phpcsFile->fixer->addContent($colonPointer - 1, $expectedSpaces);
95123
$phpcsFile->fixer->endChangeset();
96124
}
97125
}

tests/Sniffs/TypeHints/ReturnTypeHintSpacingSniffTest.php

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,50 @@ public function testReturnTypeHintsArrayIncorrect()
327327
$this->assertSniffError($report, 6, ReturnTypeHintSpacingSniff::CODE_WHITESPACE_BEFORE_COLON);
328328
}
329329

330+
public function testCorrectSpacingWithSpaceBeforeColon()
331+
{
332+
$report = $this->checkFile(__DIR__ . '/data/returnTypeHintsCorrectSpaceBeforeColon.php', [
333+
'spacesCountBeforeColon' => 1,
334+
]);
335+
$this->assertNoSniffErrorInFile($report);
336+
}
337+
338+
public function testIncorrectSpacingWithSpaceBeforeColon()
339+
{
340+
$report = $this->checkFile(__DIR__ . '/data/returnTypeHintsIncorrectSpaceBeforeColon.php', [
341+
'spacesCountBeforeColon' => 1,
342+
]);
343+
344+
$this->assertSame(24, $report->getErrorCount());
345+
346+
$message = 'There must be exactly 1 whitespace between closing parenthesis and return type colon.';
347+
348+
$this->assertSniffError($report, 3, ReturnTypeHintSpacingSniff::CODE_INCORRECT_SPACES_BEFORE_COLON, $message);
349+
$this->assertSniffError($report, 8, ReturnTypeHintSpacingSniff::CODE_INCORRECT_SPACES_BEFORE_COLON, $message);
350+
$this->assertSniffError($report, 13, ReturnTypeHintSpacingSniff::CODE_INCORRECT_SPACES_BEFORE_COLON, $message);
351+
$this->assertSniffError($report, 18, ReturnTypeHintSpacingSniff::CODE_INCORRECT_SPACES_BEFORE_COLON, $message);
352+
$this->assertSniffError($report, 23, ReturnTypeHintSpacingSniff::CODE_INCORRECT_SPACES_BEFORE_COLON, $message);
353+
$this->assertSniffError($report, 28, ReturnTypeHintSpacingSniff::CODE_INCORRECT_SPACES_BEFORE_COLON, $message);
354+
$this->assertSniffError($report, 36, ReturnTypeHintSpacingSniff::CODE_INCORRECT_SPACES_BEFORE_COLON, $message);
355+
$this->assertSniffError($report, 38, ReturnTypeHintSpacingSniff::CODE_INCORRECT_SPACES_BEFORE_COLON, $message);
356+
$this->assertSniffError($report, 40, ReturnTypeHintSpacingSniff::CODE_INCORRECT_SPACES_BEFORE_COLON, $message);
357+
$this->assertSniffError($report, 42, ReturnTypeHintSpacingSniff::CODE_INCORRECT_SPACES_BEFORE_COLON, $message);
358+
$this->assertSniffError($report, 44, ReturnTypeHintSpacingSniff::CODE_INCORRECT_SPACES_BEFORE_COLON, $message);
359+
$this->assertSniffError($report, 46, ReturnTypeHintSpacingSniff::CODE_INCORRECT_SPACES_BEFORE_COLON, $message);
360+
$this->assertSniffError($report, 48, ReturnTypeHintSpacingSniff::CODE_INCORRECT_SPACES_BEFORE_COLON, $message);
361+
$this->assertSniffError($report, 50, ReturnTypeHintSpacingSniff::CODE_INCORRECT_SPACES_BEFORE_COLON, $message);
362+
$this->assertSniffError($report, 52, ReturnTypeHintSpacingSniff::CODE_INCORRECT_SPACES_BEFORE_COLON, $message);
363+
$this->assertSniffError($report, 54, ReturnTypeHintSpacingSniff::CODE_INCORRECT_SPACES_BEFORE_COLON, $message);
364+
$this->assertSniffError($report, 56, ReturnTypeHintSpacingSniff::CODE_INCORRECT_SPACES_BEFORE_COLON, $message);
365+
$this->assertSniffError($report, 58, ReturnTypeHintSpacingSniff::CODE_INCORRECT_SPACES_BEFORE_COLON, $message);
366+
$this->assertSniffError($report, 65, ReturnTypeHintSpacingSniff::CODE_INCORRECT_SPACES_BEFORE_COLON, $message);
367+
$this->assertSniffError($report, 70, ReturnTypeHintSpacingSniff::CODE_INCORRECT_SPACES_BEFORE_COLON, $message);
368+
$this->assertSniffError($report, 75, ReturnTypeHintSpacingSniff::CODE_INCORRECT_SPACES_BEFORE_COLON, $message);
369+
$this->assertSniffError($report, 80, ReturnTypeHintSpacingSniff::CODE_INCORRECT_SPACES_BEFORE_COLON, $message);
370+
$this->assertSniffError($report, 85, ReturnTypeHintSpacingSniff::CODE_INCORRECT_SPACES_BEFORE_COLON, $message);
371+
$this->assertSniffError($report, 90, ReturnTypeHintSpacingSniff::CODE_INCORRECT_SPACES_BEFORE_COLON, $message);
372+
}
373+
330374
public function testFixableReturnTypeHintNoSpaceBetweenColonAndType()
331375
{
332376
$report = $this->checkFile(__DIR__ . '/data/fixableReturnTypeHintNoSpaceBetweenColonAndType.php', [], [ReturnTypeHintSpacingSniff::CODE_NO_SPACE_BETWEEN_COLON_AND_TYPE_HINT]);
@@ -363,4 +407,14 @@ public function testFixableReturnTypeHintWhitespaceBeforeColon()
363407
$this->assertAllFixedInFile($report);
364408
}
365409

410+
public function testFixableReturnTypeHintWhitespaceBeforeColonWithSpace()
411+
{
412+
$report = $this->checkFile(
413+
__DIR__ . '/data/fixableReturnTypeHintWhitespaceBeforeColonWithSpace.php',
414+
['spacesCountBeforeColon' => 1],
415+
[ReturnTypeHintSpacingSniff::CODE_WHITESPACE_BEFORE_COLON, ReturnTypeHintSpacingSniff::CODE_INCORRECT_SPACES_BEFORE_COLON]
416+
);
417+
$this->assertAllFixedInFile($report);
418+
}
419+
366420
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
<?php
2+
3+
function foo() : Foo
4+
{
5+
6+
}
7+
8+
function bar() : Bar
9+
{
10+
11+
}
12+
13+
function baz() : Baz
14+
{
15+
16+
}
17+
18+
$callback = function() : Foo
19+
{
20+
21+
};
22+
23+
$callback = function() : Foo
24+
{
25+
26+
};
27+
28+
$callback = function() : Foo
29+
{
30+
31+
};
32+
33+
interface Foo
34+
{
35+
36+
public function doFoo($param) : Foo;
37+
38+
public function dooFoo($param) : Foo;
39+
40+
public function doooFoo($param) : Foo;
41+
42+
}
43+
44+
class FooBar implements Foo
45+
{
46+
47+
public function doFoo($param) : Foo
48+
{
49+
50+
}
51+
52+
public function dooFoo($param) : Foo
53+
{
54+
55+
}
56+
57+
public function doooFoo($param) : Foo
58+
{
59+
60+
}
61+
62+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
<?php
2+
3+
function foo(): Foo
4+
{
5+
6+
}
7+
8+
function bar() : Bar
9+
{
10+
11+
}
12+
13+
function baz() : Baz
14+
{
15+
16+
}
17+
18+
$callback = function(): Foo
19+
{
20+
21+
};
22+
23+
$callback = function() : Foo
24+
{
25+
26+
};
27+
28+
$callback = function() : Foo
29+
{
30+
31+
};
32+
33+
interface Foo
34+
{
35+
36+
public function doFoo($param): Foo;
37+
38+
public function dooFoo($param) : Foo;
39+
40+
public function doooFoo($param) : Foo;
41+
42+
}
43+
44+
class FooBar implements Foo
45+
{
46+
47+
public function doFoo($param): Foo
48+
{
49+
50+
}
51+
52+
public function dooFoo($param) : Foo
53+
{
54+
55+
}
56+
57+
public function doooFoo($param) : Foo
58+
{
59+
60+
}
61+
62+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
3+
function foo() : Foo
4+
{
5+
6+
}
7+
8+
$callback = function () use ($x, $y) : Foo {
9+
10+
};
11+
12+
interface Foo
13+
{
14+
15+
public function doFoo($param) : Foo;
16+
17+
public function doBar($param) : \Bar;
18+
19+
public function doBaz($param) : \Foo\Bar;
20+
21+
}
22+
23+
class FooBar implements Foo
24+
{
25+
26+
public function doFoo($param) : Foo
27+
{
28+
29+
}
30+
31+
public function doBar($param) : \Bar
32+
{
33+
34+
}
35+
36+
public function doBaz($param) : \Foo\Bar
37+
{
38+
39+
}
40+
41+
}
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
<?php
2+
3+
function foo(): Foo
4+
{
5+
6+
}
7+
8+
function fooo() : Foo
9+
{
10+
11+
}
12+
13+
$callback = function(): Foo
14+
{
15+
16+
};
17+
18+
$callback = function () : Foo
19+
{
20+
21+
};
22+
23+
$callback = function () use ($test): Foo
24+
{
25+
26+
};
27+
28+
$callback = function () use ($test) : Foo
29+
{
30+
31+
};
32+
33+
interface Foo
34+
{
35+
36+
public function doFoo($param): Foo;
37+
38+
public function doBar($param): \Bar;
39+
40+
public function doBaz($param): \Foo\Bar;
41+
42+
public function dooFoo($param): Foo;
43+
44+
public function dooBar($param): \Bar;
45+
46+
public function dooBaz($param): \Foo\Bar;
47+
48+
public function doFoo2($param) : Foo;
49+
50+
public function doBar2($param) : \Bar;
51+
52+
public function doBaz2($param) : \Foo\Bar;
53+
54+
public function dooFoo2($param) : Foo;
55+
56+
public function dooBar2($param) : \Bar;
57+
58+
public function dooBaz2($param) : \Foo\Bar;
59+
60+
}
61+
62+
class FooBar implements Foo
63+
{
64+
65+
public function doFoo($param): Foo
66+
{
67+
68+
}
69+
70+
public function doBar($param): \Bar
71+
{
72+
73+
}
74+
75+
public function doBaz($param): \Foo\Bar
76+
{
77+
78+
}
79+
80+
public function dooFoo($param) : Foo
81+
{
82+
83+
}
84+
85+
public function dooBar($param) : \Bar
86+
{
87+
88+
}
89+
90+
public function dooBaz($param) : \Foo\Bar
91+
{
92+
93+
}
94+
95+
}

0 commit comments

Comments
 (0)