Skip to content

Commit 1ef75e0

Browse files
authored
Add NoUselessSprintfFixer (#118)
1 parent 66c9e4c commit 1ef75e0

File tree

4 files changed

+177
-1
lines changed

4 files changed

+177
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
- Add SingleLineThrowFixer
55
- Add PhpUnitNoUselessReturnFixer
66
- Add DataProviderNameFixer
7+
- Add NoUselessSprintfFixer
78
- Feature: NoCommentedOutCodeFixer - handle class method
89
- Deprecate SingleLineThrowFixer
910

README.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
[![Build status](https://img.shields.io/travis/kubawerlos/php-cs-fixer-custom-fixers/master.svg)](https://travis-ci.org/kubawerlos/php-cs-fixer-custom-fixers)
1010
[![Code coverage](https://img.shields.io/coveralls/github/kubawerlos/php-cs-fixer-custom-fixers/master.svg)](https://coveralls.io/github/kubawerlos/php-cs-fixer-custom-fixers?branch=master)
11-
![Tests](https://img.shields.io/badge/tests-957-brightgreen.svg)
11+
![Tests](https://img.shields.io/badge/tests-990-brightgreen.svg)
1212
[![Mutation testing badge](https://badge.stryker-mutator.io/github.com/kubawerlos/php-cs-fixer-custom-fixers/master)](https://stryker-mutator.github.io)
1313

1414
A set of custom fixers for [PHP CS Fixer](https://github.com/FriendsOfPHP/PHP-CS-Fixer).
@@ -225,6 +225,14 @@ In your PHP CS Fixer configuration register fixers and use them:
225225
class FooRepository extends EntityRepository {}
226226
```
227227

228+
- **NoUselessSprintfFixer** - function `sprintf` without parameters should not be used.
229+
*Risky: when the function `sprintf` is overridden.*
230+
```diff
231+
<?php
232+
-$foo = sprintf('Foo');
233+
+$foo = 'Foo';
234+
```
235+
228236
- **NullableParamStyleFixer** - nullable parameters must be written in the consistent style.
229237
Configuration options:
230238
- `style` (`'with_question_mark'`, `'without_question_mark'`): whether nullable parameter type should be prefixed or not with question mark; defaults to `with_question_mark`
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
<?php
2+
3+
declare(strict_types = 1);
4+
5+
namespace PhpCsFixerCustomFixers\Fixer;
6+
7+
use PhpCsFixer\FixerDefinition\CodeSample;
8+
use PhpCsFixer\FixerDefinition\FixerDefinition;
9+
use PhpCsFixer\FixerDefinition\FixerDefinitionInterface;
10+
use PhpCsFixer\Tokenizer\Analyzer\ArgumentsAnalyzer;
11+
use PhpCsFixer\Tokenizer\Analyzer\FunctionsAnalyzer;
12+
use PhpCsFixer\Tokenizer\Tokens;
13+
14+
final class NoUselessSprintfFixer extends AbstractFixer
15+
{
16+
public function getDefinition(): FixerDefinitionInterface
17+
{
18+
return new FixerDefinition(
19+
'function `sprintf` without parameters should not be used',
20+
[new CodeSample("<?php\n\$foo = sprintf('Foo');\n")],
21+
null,
22+
'when the function `sprintf` is overridden'
23+
);
24+
}
25+
26+
public function isCandidate(Tokens $tokens): bool
27+
{
28+
return $tokens->isTokenKindFound(T_STRING);
29+
}
30+
31+
public function isRisky(): bool
32+
{
33+
return true;
34+
}
35+
36+
public function fix(\SplFileInfo $file, Tokens $tokens): void
37+
{
38+
$argumentsAnalyzer = new ArgumentsAnalyzer();
39+
$functionsAnalyzer = new FunctionsAnalyzer();
40+
41+
foreach ($tokens as $index => $token) {
42+
if (!$token->equals([T_STRING, 'sprintf'], false)) {
43+
continue;
44+
}
45+
46+
if (!$functionsAnalyzer->isGlobalFunctionCall($tokens, $index)) {
47+
continue;
48+
}
49+
50+
/** @var int $openParenthesis */
51+
$openParenthesis = $tokens->getNextTokenOfKind($index, ['(']);
52+
53+
$closeParenthesis = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_PARENTHESIS_BRACE, $openParenthesis);
54+
55+
if ($argumentsAnalyzer->countArguments($tokens, $openParenthesis, $closeParenthesis) !== 1) {
56+
continue;
57+
}
58+
59+
$tokens->clearAt($index);
60+
$tokens->clearAt($openParenthesis);
61+
if ($tokens[$openParenthesis + 1]->isWhitespace()) {
62+
$tokens->clearAt($openParenthesis + 1);
63+
}
64+
if ($tokens[$closeParenthesis - 1]->isWhitespace()) {
65+
$tokens->clearAt($closeParenthesis - 1);
66+
}
67+
$tokens->clearAt($closeParenthesis);
68+
}
69+
}
70+
71+
public function getPriority(): int
72+
{
73+
return 0;
74+
}
75+
}
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
<?php
2+
3+
declare(strict_types = 1);
4+
5+
namespace Tests\Fixer;
6+
7+
/**
8+
* @internal
9+
*
10+
* @covers \PhpCsFixerCustomFixers\Fixer\NoUselessSprintfFixer
11+
*/
12+
final class NoUselessSprintfFixerTest extends AbstractFixerTestCase
13+
{
14+
public function testPriority(): void
15+
{
16+
static::assertSame(0, $this->fixer->getPriority());
17+
}
18+
19+
public function testIsRisky(): void
20+
{
21+
static::assertTrue($this->fixer->isRisky());
22+
}
23+
24+
/**
25+
* @param string $expected
26+
* @param null|string $input
27+
*
28+
* @dataProvider provideFixCases
29+
*/
30+
public function testFix(string $expected, ?string $input = null): void
31+
{
32+
$this->doTest($expected, $input);
33+
}
34+
35+
public function provideFixCases(): iterable
36+
{
37+
yield ['<?php $foo = sprintf($format, $value);'];
38+
yield ['<?php $foo = sprintf("My name is %s.", "Earl");'];
39+
yield ['<?php $foo = sprintf("Sum of %d and %d is %d.", 2, 2, 4);'];
40+
yield ['<?php $foo = sprintf();'];
41+
yield ['<?php $foo = sprintf[0]("Bar");'];
42+
yield ['<?php $foo = $printingHelper->sprintf($bar);'];
43+
yield ['<?php $foo = PrintingHelper::sprintf($bar);'];
44+
yield ['<?php $foo = PrintingHelper\sprintf($bar);'];
45+
yield ['<?php define("sprintf", "foo"); sprintf; bar($baz);'];
46+
yield ['<?php namespace Foo; function sprintf($bar) { return $baz; }'];
47+
48+
yield [
49+
'<?php $foo;',
50+
'<?php sprintf($foo);',
51+
];
52+
53+
yield [
54+
'<?php $foo;',
55+
'<?php SPRINTF($foo);',
56+
];
57+
58+
yield [
59+
'<?php $foo;',
60+
'<?php sprintf(sprintf(sprintf($foo)));',
61+
];
62+
63+
yield [
64+
'<?php sprintf($foo, 7);',
65+
'<?php sprintf(sprintf(sprintf($foo), 7));',
66+
];
67+
68+
yield [
69+
'<?php
70+
$foo = "Foo";',
71+
'<?php
72+
$foo = sprintf(
73+
"Foo"
74+
);',
75+
];
76+
77+
yield [
78+
'<?php
79+
PrintingHelper::sprintf("Message");
80+
$foo = sprintf("Hello, %s!", "Foo");
81+
$bar = "Bar";
82+
$baz = "Baz";
83+
',
84+
'<?php
85+
PrintingHelper::sprintf("Message");
86+
$foo = sprintf("Hello, %s!", "Foo");
87+
$bar = sprintf("Bar");
88+
$baz = sprintf("Baz");
89+
',
90+
];
91+
}
92+
}

0 commit comments

Comments
 (0)