Skip to content

Commit d96d4e2

Browse files
authored
Add EmptyFunctionBodyFixer (#883)
1 parent 1eef5bd commit d96d4e2

File tree

4 files changed

+285
-1
lines changed

4 files changed

+285
-1
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
# CHANGELOG for PHP CS Fixer: custom fixers
22

3+
## v3.14.0
4+
- Add EmptyFunctionBodyFixer
5+
36
## v3.13.0
47
- MultilinePromotedPropertiesFixer - add option "keep_blank_lines"
58

README.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
[![Latest stable version](https://img.shields.io/packagist/v/kubawerlos/php-cs-fixer-custom-fixers.svg?label=current%20version)](https://packagist.org/packages/kubawerlos/php-cs-fixer-custom-fixers)
44
[![PHP version](https://img.shields.io/packagist/php-v/kubawerlos/php-cs-fixer-custom-fixers.svg)](https://php.net)
55
[![License](https://img.shields.io/github/license/kubawerlos/php-cs-fixer-custom-fixers.svg)](LICENSE)
6-
![Tests](https://img.shields.io/badge/tests-3411-brightgreen.svg)
6+
![Tests](https://img.shields.io/badge/tests-3439-brightgreen.svg)
77
[![Downloads](https://img.shields.io/packagist/dt/kubawerlos/php-cs-fixer-custom-fixers.svg)](https://packagist.org/packages/kubawerlos/php-cs-fixer-custom-fixers)
88

99
[![CI Status](https://github.com/kubawerlos/php-cs-fixer-custom-fixers/workflows/CI/badge.svg?branch=main)](https://github.com/kubawerlos/php-cs-fixer-custom-fixers/actions)
@@ -135,6 +135,17 @@ Declare statement for strict types must be placed in the same line, after openin
135135
$bar;
136136
```
137137

138+
#### EmptyFunctionBodyFixer
139+
Empty function body must be abbreviated as `{}` and placed on the same line as the previous symbol, separated by a space.
140+
```diff
141+
<?php function foo(
142+
int $x
143+
-)
144+
-{
145+
-}
146+
+) {}
147+
```
148+
138149
#### InternalClassCasingFixer
139150
Classes defined internally by extension or core must be referenced with the correct case.
140151
DEPRECATED: use `class_reference_name_casing` instead.
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
<?php declare(strict_types=1);
2+
3+
/*
4+
* This file is part of PHP CS Fixer: custom fixers.
5+
*
6+
* (c) 2018 Kuba Werłos
7+
*
8+
* For the full copyright and license information, please view
9+
* the LICENSE file that was distributed with this source code.
10+
*/
11+
12+
namespace PhpCsFixerCustomFixers\Fixer;
13+
14+
use PhpCsFixer\FixerDefinition\CodeSample;
15+
use PhpCsFixer\FixerDefinition\FixerDefinition;
16+
use PhpCsFixer\FixerDefinition\FixerDefinitionInterface;
17+
use PhpCsFixer\Tokenizer\Tokens;
18+
19+
final class EmptyFunctionBodyFixer extends AbstractFixer
20+
{
21+
public function getDefinition(): FixerDefinitionInterface
22+
{
23+
return new FixerDefinition(
24+
'Empty function body must be abbreviated as `{}` and placed on the same line as the previous symbol, separated by a space.',
25+
[new CodeSample('<?php function foo(
26+
int $x
27+
)
28+
{
29+
}
30+
')],
31+
);
32+
}
33+
34+
public function getPriority(): int
35+
{
36+
return 0;
37+
}
38+
39+
public function isCandidate(Tokens $tokens): bool
40+
{
41+
return $tokens->isTokenKindFound(\T_FUNCTION);
42+
}
43+
44+
public function isRisky(): bool
45+
{
46+
return false;
47+
}
48+
49+
public function fix(\SplFileInfo $file, Tokens $tokens): void
50+
{
51+
for ($index = $tokens->count() - 1; $index > 0; $index--) {
52+
if (!$tokens[$index]->isGivenKind(\T_FUNCTION)) {
53+
continue;
54+
}
55+
56+
$openBraceIndex = $tokens->getNextTokenOfKind($index, ['{', ';']);
57+
\assert(\is_int($openBraceIndex));
58+
if (!$tokens[$openBraceIndex]->equals('{')) {
59+
continue;
60+
}
61+
62+
$closeBraceIndex = $tokens->getNextNonWhitespace($openBraceIndex);
63+
\assert(\is_int($closeBraceIndex));
64+
if (!$tokens[$closeBraceIndex]->equals('}')) {
65+
continue;
66+
}
67+
68+
$tokens->ensureWhitespaceAtIndex($openBraceIndex + 1, 0, '');
69+
70+
$beforeOpenBraceIndex = $tokens->getPrevNonWhitespace($openBraceIndex);
71+
if (!$tokens[$beforeOpenBraceIndex]->isGivenKind([\T_COMMENT, \T_DOC_COMMENT])) {
72+
$tokens->ensureWhitespaceAtIndex($openBraceIndex - 1, 1, ' ');
73+
}
74+
}
75+
}
76+
}
Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
<?php declare(strict_types=1);
2+
3+
/*
4+
* This file is part of PHP CS Fixer: custom fixers.
5+
*
6+
* (c) 2018 Kuba Werłos
7+
*
8+
* For the full copyright and license information, please view
9+
* the LICENSE file that was distributed with this source code.
10+
*/
11+
12+
namespace Tests\Fixer;
13+
14+
/**
15+
* @internal
16+
*
17+
* @covers \PhpCsFixerCustomFixers\Fixer\EmptyFunctionBodyFixer
18+
*/
19+
final class EmptyFunctionBodyFixerTest extends AbstractFixerTestCase
20+
{
21+
public function testIsRisky(): void
22+
{
23+
self::assertFalse($this->fixer->isRisky());
24+
}
25+
26+
/**
27+
* @dataProvider provideFixCases
28+
*/
29+
public function testFix(string $expected, ?string $input = null): void
30+
{
31+
$this->doTest($expected, $input);
32+
}
33+
34+
/**
35+
* @return iterable<array{0: string, 1?: string}>
36+
*/
37+
public static function provideFixCases(): iterable
38+
{
39+
yield 'non-empty body' => [
40+
'<?php
41+
function f1()
42+
{ /* foo */ }
43+
function f2()
44+
{ /** foo */ }
45+
function f3()
46+
{ // foo
47+
}
48+
function f4()
49+
{
50+
return true;
51+
}
52+
',
53+
];
54+
55+
yield 'functions' => [
56+
'<?php
57+
function notThis1() { return 1; }
58+
function f1() {}
59+
function f2() {}
60+
function f3() {}
61+
function notThis2(){ return 1; }
62+
',
63+
'<?php
64+
function notThis1() { return 1; }
65+
function f1()
66+
{}
67+
function f2() {
68+
}
69+
function f3()
70+
{
71+
}
72+
function notThis2(){ return 1; }
73+
',
74+
];
75+
76+
yield 'remove spaces' => [
77+
'<?php
78+
function f1() {}
79+
function f2() {}
80+
function f3() {}
81+
',
82+
'<?php
83+
function f1() { }
84+
function f2() { }
85+
function f3() { }
86+
',
87+
];
88+
89+
yield 'add spaces' => [
90+
'<?php
91+
function f1() {}
92+
function f2() {}
93+
function f3() {}
94+
',
95+
'<?php
96+
function f1(){}
97+
function f2(){}
98+
function f3(){}
99+
',
100+
];
101+
102+
yield 'with return types' => [
103+
'<?php
104+
function f1(): void {}
105+
function f2(): \Foo\Bar {}
106+
function f3(): ?string {}
107+
',
108+
'<?php
109+
function f1(): void
110+
{}
111+
function f2(): \Foo\Bar { }
112+
function f3(): ?string {
113+
114+
115+
}
116+
',
117+
];
118+
119+
yield 'abstract function' => [
120+
'<?php abstract class C {
121+
abstract function f1();
122+
function f2() {}
123+
abstract function f3();
124+
}
125+
if (true) { }
126+
',
127+
'<?php abstract class C {
128+
abstract function f1();
129+
function f2() { }
130+
abstract function f3();
131+
}
132+
if (true) { }
133+
',
134+
];
135+
136+
yield 'every token in separate line' => [
137+
'<?php
138+
function
139+
foo
140+
(
141+
)
142+
:
143+
void {}
144+
',
145+
'<?php
146+
function
147+
foo
148+
(
149+
)
150+
:
151+
void
152+
{
153+
}
154+
',
155+
];
156+
157+
yield 'comment before body' => [
158+
'<?php
159+
function f1()
160+
// foo
161+
{}
162+
function f2()
163+
/* foo */
164+
{}
165+
function f3()
166+
/** foo */
167+
{}
168+
function f3()
169+
/** foo */
170+
/** bar */
171+
{}
172+
',
173+
'<?php
174+
function f1()
175+
// foo
176+
{
177+
}
178+
function f2()
179+
/* foo */
180+
{
181+
182+
}
183+
function f3()
184+
/** foo */
185+
{
186+
}
187+
function f3()
188+
/** foo */
189+
/** bar */
190+
{ }
191+
',
192+
];
193+
}
194+
}

0 commit comments

Comments
 (0)