Skip to content

Commit aa1bbd9

Browse files
authored
Add NoTrailingCommaInSinglelineFixer (#727)
1 parent f5105e4 commit aa1bbd9

7 files changed

+294
-3
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.7.0
4+
- Add NoTrailingCommaInSinglelineFixer
5+
-
36
## v3.6.0
47
- Add IssetToArrayKeyExistsFixer
58
- Add PhpdocVarAnnotationToAssertFixer

README.md

Lines changed: 9 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-3322-brightgreen.svg)
6+
![Tests](https://img.shields.io/badge/tests-3365-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)
@@ -291,6 +291,14 @@ Configuration options:
291291
+echo 'foobar';
292292
```
293293

294+
#### NoTrailingCommaInSinglelineFixer
295+
Trailing comma in the list on the same line as the end of the block must be removed.
296+
```diff
297+
<?php
298+
-$x = ['foo', 'bar', ];
299+
+$x = ['foo', 'bar'];
300+
```
301+
294302
#### NoUselessCommentFixer
295303
There must be no useless comments.
296304
```diff
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
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\CT;
18+
use PhpCsFixer\Tokenizer\Tokens;
19+
20+
final class NoTrailingCommaInSinglelineFixer extends AbstractFixer
21+
{
22+
public function getDefinition(): FixerDefinitionInterface
23+
{
24+
return new FixerDefinition(
25+
'Trailing comma in the list on the same line as the end of the block must be removed.',
26+
[
27+
new CodeSample("<?php\n\$x = ['foo', 'bar', ];\n"),
28+
]
29+
);
30+
}
31+
32+
/**
33+
* Must run after MethodArgumentSpaceFixer, TrailingCommaInMultilineFixer.
34+
*/
35+
public function getPriority(): int
36+
{
37+
return -1;
38+
}
39+
40+
public function isCandidate(Tokens $tokens): bool
41+
{
42+
return $tokens->isAnyTokenKindsFound([\T_ARRAY, CT::T_ARRAY_SQUARE_BRACE_OPEN, CT::T_DESTRUCTURING_SQUARE_BRACE_CLOSE, '(']);
43+
}
44+
45+
public function isRisky(): bool
46+
{
47+
return false;
48+
}
49+
50+
public function fix(\SplFileInfo $file, Tokens $tokens): void
51+
{
52+
for ($index = $tokens->count() - 1; $index >= 0; $index--) {
53+
if (!$tokens[$index]->equalsAny([')', [CT::T_ARRAY_SQUARE_BRACE_CLOSE], [CT::T_DESTRUCTURING_SQUARE_BRACE_CLOSE]])) {
54+
continue;
55+
}
56+
57+
$commaIndex = $tokens->getPrevMeaningfulToken($index);
58+
\assert(\is_int($commaIndex));
59+
60+
while ($tokens[$commaIndex]->equals(',')) {
61+
if ($tokens->isPartialCodeMultiline($commaIndex, $index)) {
62+
break;
63+
}
64+
65+
$tokens->removeLeadingWhitespace($commaIndex);
66+
$tokens->removeTrailingWhitespace($commaIndex);
67+
$tokens->clearAt($commaIndex);
68+
69+
$commaIndex = $tokens->getPrevMeaningfulToken($index);
70+
\assert(\is_int($commaIndex));
71+
}
72+
}
73+
}
74+
}
Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
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\NoTrailingCommaInSinglelineFixer
18+
*/
19+
final class NoTrailingCommaInSinglelineFixerTest 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 [
40+
'<?php $x = [
41+
1,
42+
2,
43+
];',
44+
];
45+
46+
yield [
47+
'<?php $x = [1, 2,// foo
48+
];',
49+
];
50+
51+
yield [
52+
'<?php $array = [1, 2];',
53+
'<?php $array = [1, 2,];',
54+
];
55+
56+
yield [
57+
'<?php $array = [1, 2];',
58+
'<?php $array = [1, 2, ];',
59+
];
60+
61+
yield [
62+
'<?php $array = [1, 2,
63+
3, 4];',
64+
'<?php $array = [1, 2,
65+
3, 4, ];',
66+
];
67+
68+
yield [
69+
'<?php $array = [1, 2] + [3, 4] + [5, 6];',
70+
'<?php $array = [1, 2, ] + [3, 4, ] + [5, 6, ];',
71+
];
72+
73+
yield [
74+
'<?php $array = [1, 2/* foo */];',
75+
'<?php $array = [1, 2, /* foo */];',
76+
];
77+
78+
yield [
79+
'<?php $array = array(1, 2);',
80+
'<?php $array = array(1, 2, );',
81+
];
82+
83+
yield [
84+
'<?php list($x, $y) = $list;',
85+
'<?php list($x, $y,) = $list;',
86+
];
87+
88+
yield [
89+
'<?php [$x, $y] = $list;',
90+
'<?php [$x, $y,] = $list;',
91+
];
92+
93+
yield [
94+
'<?php list($x, $y) = $list;',
95+
'<?php list($x, $y, , ,) = $list;',
96+
];
97+
98+
yield [
99+
'<?php list($x, $y) = $list;',
100+
'<?php list($x, $y , , , ) = $list;',
101+
];
102+
}
103+
104+
/**
105+
* @requires PHP ^7.3
106+
* @dataProvider provideFix73Cases
107+
*/
108+
public function testFix73(string $expected, ?string $input = null): void
109+
{
110+
$this->doTest($expected, $input);
111+
}
112+
113+
/**
114+
* @return iterable<array{0: string, 1?: string}>
115+
*/
116+
public static function provideFix73Cases(): iterable
117+
{
118+
yield [
119+
'<?php foo($x, $y);',
120+
'<?php foo($x, $y, );',
121+
];
122+
123+
yield [
124+
'<?php
125+
$array = [1, 2] + [3, 4] + [5, 6];
126+
foo(
127+
1,
128+
2,
129+
);
130+
list($x, $y) = $list;
131+
',
132+
'<?php
133+
$array = [1, 2, ] + [3, 4] + [5, 6, ];
134+
foo(
135+
1,
136+
2,
137+
);
138+
list($x, $y,) = $list;
139+
',
140+
];
141+
}
142+
143+
/**
144+
* @requires PHP ^8.0
145+
* @dataProvider provideFix80Cases
146+
*/
147+
public function testFix80(string $expected, ?string $input = null): void
148+
{
149+
$this->doTest($expected, $input);
150+
}
151+
152+
/**
153+
* @return iterable<array{0: string, 1?: string}>
154+
*/
155+
public static function provideFix80Cases(): iterable
156+
{
157+
yield [
158+
'<?php function foo($x, $y) {}',
159+
'<?php function foo($x, $y, ) {}',
160+
];
161+
162+
yield [
163+
'<?php $f = function ($x, $y) {};',
164+
'<?php $f = function ($x, $y, ) {};',
165+
];
166+
}
167+
}

tests/Fixer/PhpdocNoIncorrectVarAnnotationFixerTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,13 @@ public static function provideFixCases(): iterable
4545
'<?php
4646
/** @var \Foo $foo */
4747
$foo = new Foo();
48-
', ];
48+
'];
4949

5050
yield 'keep correct PHPDoc with nullable' => [
5151
'<?php
5252
/** @var ?Foo $foo */
5353
$foo = new Foo();
54-
', ];
54+
'];
5555

5656
yield 'remove PHPDoc when variable name is different' => [
5757
'<?php
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
--CONFIGURATION--
2+
{ "method_argument_space": {"on_multiline": "ensure_single_line"}, "PhpCsFixerCustomFixers/no_trailing_comma_in_singleline": true }
3+
--EXPECTED--
4+
<?php
5+
6+
foo(1, 2, 3);
7+
8+
function bar($x, $y, $x) {}
9+
10+
--INPUT--
11+
<?php
12+
13+
foo(1, 2,
14+
3,
15+
);
16+
17+
function bar($x,
18+
$y,
19+
$x,
20+
) {}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
--CONFIGURATION--
2+
{ "trailing_comma_in_multiline": true, "PhpCsFixerCustomFixers/no_trailing_comma_in_singleline": true }
3+
--EXPECTED--
4+
<?php
5+
$foo = [1, 2,
6+
3, 4];
7+
$bar = [5, 6,
8+
7, 8];
9+
$baz = [11, 12,
10+
13, 14];
11+
12+
--INPUT--
13+
<?php
14+
$foo = [1, 2,
15+
3, 4];
16+
$bar = [5, 6,
17+
7, 8,];
18+
$baz = [11, 12,
19+
13, 14, ];

0 commit comments

Comments
 (0)