Skip to content

Commit c060132

Browse files
committed
Extend PhpDocPropertySorterFixer to support @property-read and @property-write
1 parent be3ff0d commit c060132

File tree

5 files changed

+395
-260
lines changed

5 files changed

+395
-260
lines changed

composer.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,15 +50,15 @@
5050
],
5151
"infection": [
5252
"@prepare-dev-tools",
53-
"@composer --working-dir=.dev-tools infection"
53+
"@composer --working-dir=.dev-tools infection -- --coverage=build --skip-initial-tests"
5454
],
5555
"prepare-dev-tools": [
5656
"@putenv PHP_CS_FIXER_IGNORE_ENV=1",
5757
"@composer --working-dir=.dev-tools --quiet install --classmap-authoritative"
5858
],
5959
"test": [
6060
"phpunit --check-php-configuration",
61-
"phpunit"
61+
"phpunit --coverage-xml=.dev-tools/build/coverage-xml --log-junit=.dev-tools/build/junit.xml --coverage-text"
6262
],
6363
"verify": [
6464
"@analyse",

src/Fixer/PhpDocPropertySorterFixer.php

Lines changed: 19 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -11,127 +11,54 @@
1111

1212
namespace PhpCsFixerCustomFixers\Fixer;
1313

14-
use PhpCsFixer\FixerDefinition\CodeSample;
15-
use PhpCsFixer\FixerDefinition\FixerDefinition;
14+
use PhpCsFixer\Fixer\DeprecatedFixerInterface;
1615
use PhpCsFixer\FixerDefinition\FixerDefinitionInterface;
17-
use PhpCsFixer\Preg;
18-
use PhpCsFixer\Tokenizer\Token;
1916
use PhpCsFixer\Tokenizer\Tokens;
2017

2118
/**
19+
* @deprecated
20+
*
2221
* @no-named-arguments
2322
*/
24-
final class PhpDocPropertySorterFixer extends AbstractFixer
23+
final class PhpDocPropertySorterFixer extends AbstractFixer implements DeprecatedFixerInterface
2524
{
25+
private PhpdocPropertySortedFixer $phpdocPropertySortedFixer;
26+
27+
public function __construct()
28+
{
29+
$this->phpdocPropertySortedFixer = new PhpdocPropertySortedFixer();
30+
}
31+
2632
public function getDefinition(): FixerDefinitionInterface
2733
{
28-
return new FixerDefinition(
29-
'Sorts @property annotations in PHPDoc blocks alphabetically within groups separated by empty lines.',
30-
[new CodeSample('<?php
31-
/**
32-
* @property string $zzz
33-
* @property int $aaa
34-
* @property bool $mmm
35-
*/
36-
class Foo {}
37-
')],
38-
'',
39-
);
34+
return $this->phpdocPropertySortedFixer->getDefinition();
4035
}
4136

4237
public function getPriority(): int
4338
{
44-
return 0;
39+
return $this->phpdocPropertySortedFixer->getPriority();
4540
}
4641

4742
public function isCandidate(Tokens $tokens): bool
4843
{
49-
return $tokens->isTokenKindFound(\T_DOC_COMMENT);
44+
return $this->phpdocPropertySortedFixer->isCandidate($tokens);
5045
}
5146

5247
public function isRisky(): bool
5348
{
54-
return false;
49+
return $this->phpdocPropertySortedFixer->isRisky();
5550
}
5651

5752
public function fix(\SplFileInfo $file, Tokens $tokens): void
5853
{
59-
foreach ($tokens as $index => $token) {
60-
if (!$token->isGivenKind(\T_DOC_COMMENT)) {
61-
continue;
62-
}
63-
64-
$originalDocContent = $token->getContent();
65-
$sortedDocContent = self::sortPropertiesInDocBlock($originalDocContent);
66-
67-
if ($originalDocContent !== $sortedDocContent) {
68-
$tokens[$index] = new Token([\T_DOC_COMMENT, $sortedDocContent]);
69-
}
70-
}
71-
}
72-
73-
private static function sortPropertiesInDocBlock(string $docContent): string
74-
{
75-
$docLines = \explode("\n", $docContent);
76-
$processedLines = [];
77-
$currentPropertyGroup = [];
78-
79-
foreach ($docLines as $line) {
80-
if (self::isPropertyAnnotation($line)) {
81-
$currentPropertyGroup[] = $line;
82-
} else {
83-
self::flushPropertyGroup($currentPropertyGroup, $processedLines);
84-
$processedLines[] = $line;
85-
}
86-
}
87-
88-
return \implode("\n", $processedLines);
89-
}
90-
91-
private static function isPropertyAnnotation(string $line): bool
92-
{
93-
return Preg::match('/@property/', $line);
94-
}
95-
96-
/**
97-
* Sorts and adds a property group to the processed lines.
98-
*
99-
* @param list<string> $propertyGroup
100-
* @param list<string> $processedLines
101-
*/
102-
private static function flushPropertyGroup(array &$propertyGroup, array &$processedLines): void
103-
{
104-
if (\count($propertyGroup) === 0) {
105-
return;
106-
}
107-
108-
self::sortPropertiesByName($propertyGroup);
109-
$processedLines = \array_merge($processedLines, $propertyGroup);
110-
$propertyGroup = [];
54+
$this->phpdocPropertySortedFixer->fix($file, $tokens);
11155
}
11256

11357
/**
114-
* @param list<string> $properties
58+
* @return list<string>
11559
*/
116-
private static function sortPropertiesByName(array &$properties): void
60+
public function getSuccessorsNames(): array
11761
{
118-
\usort($properties, static function (string $propertyA, string $propertyB): int {
119-
$nameA = self::extractPropertyName($propertyA);
120-
$nameB = self::extractPropertyName($propertyB);
121-
122-
return \strcmp($nameA ?? '', $nameB ?? '');
123-
});
124-
}
125-
126-
private static function extractPropertyName(string $propertyLine): ?string
127-
{
128-
$matches = [];
129-
Preg::match('/@property(?:-read|-write)?\\s+[^\\s]+\\s+\\$(\\w+)/', $propertyLine, $matches);
130-
/** @var array<array-key, string> $matches */
131-
if (\count($matches) > 1) {
132-
return $matches[1];
133-
}
134-
135-
return null;
62+
return [$this->phpdocPropertySortedFixer->getName()];
13663
}
13764
}
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
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\Preg;
18+
use PhpCsFixer\Tokenizer\Token;
19+
use PhpCsFixer\Tokenizer\Tokens;
20+
21+
/**
22+
* @no-named-arguments
23+
*/
24+
final class PhpdocPropertySortedFixer extends AbstractFixer
25+
{
26+
public function getDefinition(): FixerDefinitionInterface
27+
{
28+
return new FixerDefinition(
29+
'Sorts @property annotations in PHPDoc blocks alphabetically within groups separated by empty lines.',
30+
[new CodeSample('<?php
31+
/**
32+
* @property string $zzz
33+
* @property int $aaa
34+
* @property bool $mmm
35+
*/
36+
class Foo {}
37+
')],
38+
'',
39+
);
40+
}
41+
42+
public function getPriority(): int
43+
{
44+
return 0;
45+
}
46+
47+
public function isCandidate(Tokens $tokens): bool
48+
{
49+
return $tokens->isTokenKindFound(\T_DOC_COMMENT);
50+
}
51+
52+
public function isRisky(): bool
53+
{
54+
return false;
55+
}
56+
57+
public function fix(\SplFileInfo $file, Tokens $tokens): void
58+
{
59+
foreach ($tokens as $index => $token) {
60+
if (!$token->isGivenKind(\T_DOC_COMMENT)) {
61+
continue;
62+
}
63+
64+
$originalDocContent = $token->getContent();
65+
$sortedDocContent = self::sortPropertiesInDocBlock($originalDocContent);
66+
67+
if ($originalDocContent !== $sortedDocContent) {
68+
$tokens[$index] = new Token([\T_DOC_COMMENT, $sortedDocContent]);
69+
}
70+
}
71+
}
72+
73+
private static function sortPropertiesInDocBlock(string $docContent): string
74+
{
75+
$docLines = \explode("\n", $docContent);
76+
$processedLines = [];
77+
$currentPropertyGroup = [];
78+
79+
foreach ($docLines as $line) {
80+
if (self::isPropertyAnnotation($line)) {
81+
$currentPropertyGroup[] = $line;
82+
} else {
83+
self::flushPropertyGroup($currentPropertyGroup, $processedLines);
84+
$processedLines[] = $line;
85+
}
86+
}
87+
88+
return \implode("\n", $processedLines);
89+
}
90+
91+
private static function isPropertyAnnotation(string $line): bool
92+
{
93+
return Preg::match('/@property/', $line);
94+
}
95+
96+
/**
97+
* Sorts and adds a property group to the processed lines.
98+
*
99+
* @param list<string> $propertyGroup
100+
* @param list<string> $processedLines
101+
*/
102+
private static function flushPropertyGroup(array &$propertyGroup, array &$processedLines): void
103+
{
104+
if (\count($propertyGroup) === 0) {
105+
return;
106+
}
107+
108+
self::sortPropertiesByName($propertyGroup);
109+
$processedLines = \array_merge($processedLines, $propertyGroup);
110+
$propertyGroup = [];
111+
}
112+
113+
/**
114+
* @param list<string> $properties
115+
*/
116+
private static function sortPropertiesByName(array &$properties): void
117+
{
118+
\usort($properties, static function (string $propertyA, string $propertyB): int {
119+
$nameA = self::extractPropertyName($propertyA);
120+
$nameB = self::extractPropertyName($propertyB);
121+
122+
return \strcmp($nameA ?? '', $nameB ?? '');
123+
});
124+
}
125+
126+
private static function extractPropertyName(string $propertyLine): ?string
127+
{
128+
$matches = [];
129+
Preg::match('/@property(?:-read|-write)?\\s+[^\\s]+\\s+\\$(\\w+)/', $propertyLine, $matches);
130+
/** @var array<array-key, string> $matches */
131+
if (\count($matches) > 1) {
132+
return $matches[1];
133+
}
134+
135+
return null;
136+
}
137+
}

0 commit comments

Comments
 (0)