Skip to content

Commit fb9c6e8

Browse files
authored
Add OrderedClassElementsInternalFixer (#169)
1 parent 1063223 commit fb9c6e8

34 files changed

+295
-147
lines changed

.php_cs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,11 @@
22

33
declare(strict_types = 1);
44

5+
require_once __DIR__ . '/dev-tools/vendor/autoload.php';
6+
57
return PhpCsFixer\Config::create()
8+
->registerCustomFixers(new PhpCsFixerCustomFixers\Fixers())
9+
->registerCustomFixers(new PhpCsFixerCustomFixersDev\Fixers())
610
->setFinder(
711
PhpCsFixer\Finder::create()
812
->files()
@@ -16,7 +20,6 @@ return PhpCsFixer\Config::create()
1620
])
1721
)
1822
->setRiskyAllowed(true)
19-
->registerCustomFixers(new PhpCsFixerCustomFixers\Fixers())
2023
->setRules([
2124
'@PHP71Migration' => true,
2225
'@PHP71Migration:risky' => true,
@@ -94,7 +97,6 @@ return PhpCsFixer\Config::create()
9497
'no_unset_on_property' => true,
9598
'no_useless_else' => true,
9699
'no_useless_return' => true,
97-
'ordered_class_elements' => true,
98100
'ordered_imports' => [
99101
'sortAlgorithm' => 'alpha',
100102
],
@@ -129,6 +131,10 @@ return PhpCsFixer\Config::create()
129131
] + \array_reduce(
130132
\iterator_to_array(new PhpCsFixerCustomFixers\Fixers()),
131133
static function (array $carry, PhpCsFixer\Fixer\DefinedFixerInterface $fixer): array {
134+
if ($fixer instanceof PhpCsFixerCustomFixers\Fixer\NoReferenceInFunctionDefinitionFixer) {
135+
return $carry;
136+
}
137+
132138
if (!$fixer instanceof PhpCsFixer\Fixer\DeprecatedFixerInterface) {
133139
$carry[$fixer->getName()] = true;
134140
}
@@ -148,4 +154,12 @@ return PhpCsFixer\Config::create()
148154
return $carry;
149155
},
150156
[]
157+
) + \array_reduce(
158+
\iterator_to_array(new PhpCsFixerCustomFixersDev\Fixers()),
159+
static function (array $carry, PhpCsFixer\Fixer\FixerInterface $fixer): array {
160+
$carry[$fixer->getName()] = true;
161+
162+
return $carry;
163+
},
164+
[]
151165
));

composer.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
"./dev-tools/vendor/bin/phpcs --exclude=Generic.Files.LineLength --report-full --standard=PSR2 ./src ./dev-tools/src ./tests",
3030
"./dev-tools/vendor/bin/types-checker ./src ./dev-tools/src ./tests",
3131
"PHP_CS_FIXER_FUTURE_MODE=1 ./vendor/bin/php-cs-fixer fix --ansi --diff --dry-run --verbose",
32-
"./dev-tools/vendor/bin/phpcpd ./src",
3332
"./dev-tools/vendor/bin/phpmd ./src text ./phpmd.xml",
3433
"./dev-tools/vendor/bin/phpstan analyse --ansi",
3534
"./dev-tools/vendor/bin/psalm --find-dead-code --shepherd"

dev-tools/composer.json

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,19 @@
11
{
22
"require-dev": {
3-
"infection/infection": "^0.13.6 || 0.14.1",
3+
"infection/infection": "^0.13.6 || ^0.14.2",
44
"johnkary/phpunit-speedtrap": "^3.1",
55
"kubawerlos/types-checker": "^1.1",
66
"localheinz/composer-normalize": "^1.3",
77
"maglnet/composer-require-checker": "^2.0",
88
"mi-schi/phpmd-extension": "^4.3",
99
"phpmd/phpmd": "^2.7",
10-
"phpstan/phpstan": "^0.11.16",
10+
"phpstan/phpstan": "^0.11.19",
1111
"phpstan/phpstan-strict-rules": "^0.11.1",
12-
"phpunit/phpunit": "^7.4 || ^8.3",
12+
"phpunit/phpunit": "^7.4 || ^8.4",
1313
"sebastian/diff": "^3.0",
14-
"sebastian/phpcpd": "^4.1",
1514
"squizlabs/php_codesniffer": "^3.5",
1615
"symfony/console": "^4.3",
17-
"vimeo/psalm": "^3.5",
16+
"vimeo/psalm": "^3.6",
1817
"wikimedia/composer-merge-plugin": "^1.4"
1918
},
2019
"extra": {
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
<?php
2+
3+
declare(strict_types = 1);
4+
5+
namespace PhpCsFixerCustomFixersDev\Fixer {
6+
use PhpCsFixer\Fixer\ClassNotation\OrderedClassElementsFixer;
7+
use PhpCsFixer\Fixer\FixerInterface;
8+
use PhpCsFixer\Tokenizer\Tokens;
9+
10+
/**
11+
* @internal
12+
*/
13+
final class OrderedClassElementsInternalFixer implements FixerInterface
14+
{
15+
public const PUBLIC_METHODS_ORDER = [
16+
'getDefinition',
17+
'getConfigurationDefinition',
18+
'configure',
19+
'getName',
20+
'getPriority',
21+
'getPullRequestId',
22+
'supports',
23+
'isCandidate',
24+
'isRisky',
25+
'fix',
26+
'getSuccessorsNames',
27+
];
28+
29+
/** @var OrderedClassElementsFixer */
30+
private $orderedClassElementsFixer;
31+
32+
public function __construct()
33+
{
34+
$this->orderedClassElementsFixer = new OrderedClassElementsFixer();
35+
}
36+
37+
public function getName(): string
38+
{
39+
return 'Internal/' . $this->orderedClassElementsFixer->getName();
40+
}
41+
42+
public function getPriority(): int
43+
{
44+
return $this->orderedClassElementsFixer->getPriority();
45+
}
46+
47+
public function supports(\SplFileInfo $file): bool
48+
{
49+
return $this->orderedClassElementsFixer->supports($file);
50+
}
51+
52+
public function isCandidate(Tokens $tokens): bool
53+
{
54+
return $tokens->findSequence([[T_EXTENDS], [T_STRING, 'AbstractFixer']]) !== null;
55+
}
56+
57+
public function isRisky(): bool
58+
{
59+
return $this->orderedClassElementsFixer->isRisky();
60+
}
61+
62+
public function fix(\SplFileInfo $file, Tokens $tokens): void
63+
{
64+
$this->orderedClassElementsFixer->fix($file, $tokens);
65+
}
66+
}
67+
}
68+
69+
namespace PhpCsFixer\Fixer\ClassNotation {
70+
use PhpCsFixerCustomFixersDev\Fixer\OrderedClassElementsInternalFixer;
71+
72+
/**
73+
* @internal
74+
*/
75+
function usort(array &$elements): void
76+
{
77+
\usort($elements, static function (array $a, array $b) {
78+
if ($a['type'] === 'method' && $a['visibility'] === 'public'
79+
&& $b['type'] === 'method' && $b['visibility'] === 'public'
80+
&& isset($a['name'], $b['name'])) {
81+
if (!\in_array($a['name'], OrderedClassElementsInternalFixer::PUBLIC_METHODS_ORDER, true)) {
82+
throw new \Exception(\sprintf('Method %s not in order list', $a['name']));
83+
}
84+
if (!\in_array($b['name'], OrderedClassElementsInternalFixer::PUBLIC_METHODS_ORDER, true)) {
85+
throw new \Exception(\sprintf('Method %s not in order list', $b['name']));
86+
}
87+
foreach (OrderedClassElementsInternalFixer::PUBLIC_METHODS_ORDER as $name) {
88+
if ($a['name'] === $name) {
89+
return -1;
90+
}
91+
if ($b['name'] === $name) {
92+
return 1;
93+
}
94+
}
95+
}
96+
97+
if ($a['position'] === $b['position']) {
98+
return $a['start'] <=> $b['start'];
99+
}
100+
101+
return $a['position'] <=> $b['position'];
102+
});
103+
}
104+
}

dev-tools/src/Fixers.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
3+
declare(strict_types = 1);
4+
5+
namespace PhpCsFixerCustomFixersDev;
6+
7+
use Symfony\Component\Finder\Finder;
8+
9+
/**
10+
* @internal
11+
*/
12+
final class Fixers implements \IteratorAggregate
13+
{
14+
public function getIterator(): \Generator
15+
{
16+
$finder = Finder::create()
17+
->files()
18+
->in(__DIR__ . '/Fixer/')
19+
->sortByName();
20+
21+
foreach ($finder as $fileInfo) {
22+
$className = __NAMESPACE__ . '\\Fixer\\' . $fileInfo->getBasename('.php');
23+
yield new $className();
24+
}
25+
}
26+
}

dev-tools/src/Readme/ReadmeCommand.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@
2020
use Symfony\Component\Console\Output\OutputInterface;
2121
use Symfony\Component\Process\Process;
2222

23+
/**
24+
* @internal
25+
*/
2326
final class ReadmeCommand extends BaseCommand
2427
{
2528
private const NAME = 'PHP CS Fixer: custom fixers';

phpunit.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838

3939
<filter>
4040
<whitelist>
41+
<directory>./dev-tools/src/Readme</directory>
4142
<directory>./src</directory>
4243
<exclude>
4344
<file>./dev-tools/src/Readme/php-cs-fixer.config.after.php</file>

psalm.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
<InvalidArgument errorLevel='suppress' />
2121
<InvalidStringClass>
2222
<errorLevel type='suppress'>
23+
<file name='./dev-tools/src/Fixers.php' />
2324
<file name='./src/Fixers.php' />
2425
</errorLevel>
2526
</InvalidStringClass>
@@ -29,6 +30,7 @@
2930
<PossiblyNullOperand errorLevel='suppress' />
3031
<PossiblyUnusedMethod>
3132
<errorLevel type='suppress'>
33+
<file name='./dev-tools/src/Fixer/OrderedClassElementsInternalFixer.php' />
3234
<file name='./src/Analyzer/Analysis/SwitchAnalysis.php' />
3335
</errorLevel>
3436
</PossiblyUnusedMethod>

src/Fixer/CommentSurroundedBySpacesFixer.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,12 @@ public function getDefinition(): FixerDefinitionInterface
2323
);
2424
}
2525

26+
public function getPriority(): int
27+
{
28+
// Must be run after MultilineCommentOpeningClosingFixer
29+
return -1;
30+
}
31+
2632
public function isCandidate(Tokens $tokens): bool
2733
{
2834
return $tokens->isAnyTokenKindsFound([T_COMMENT, T_DOC_COMMENT]);
@@ -57,10 +63,4 @@ public function fix(\SplFileInfo $file, Tokens $tokens): void
5763
$tokens[$index] = new Token([\strpos($newContent, '/** ') === 0 ? T_DOC_COMMENT : T_COMMENT, $newContent]);
5864
}
5965
}
60-
61-
public function getPriority(): int
62-
{
63-
// Must be run after MultilineCommentOpeningClosingFixer
64-
return -1;
65-
}
6666
}

src/Fixer/DataProviderNameFixer.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,14 +39,14 @@ function dataProvider() {}
3939
);
4040
}
4141

42-
public function isCandidate(Tokens $tokens): bool
42+
public function getPriority(): int
4343
{
44-
return $tokens->isTokenKindFound(T_DOC_COMMENT);
44+
return 0;
4545
}
4646

47-
public function getPriority(): int
47+
public function isCandidate(Tokens $tokens): bool
4848
{
49-
return 0;
49+
return $tokens->isTokenKindFound(T_DOC_COMMENT);
5050
}
5151

5252
public function isRisky(): bool

0 commit comments

Comments
 (0)