Skip to content

Commit cb73a3a

Browse files
authored
[PHP 8.3] Apply rest of ugprade set (#7840)
* early return * [php 8.3] exclude test case setup from override attribute, as not helpful * make use of Override attribute
1 parent bc675f0 commit cb73a3a

27 files changed

+172
-7
lines changed

phpunit.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
<directory>tests</directory>
1515
<directory>rules-tests</directory>
1616
<directory>utils-tests</directory>
17+
<exclude>rules-tests/Php83/Rector/ClassMethod/AddOverrideAttributeToOverriddenMethodsRector/Source/SomeAbstractTest.php</exclude>
1718
</testsuite>
1819
</testsuites>
1920

rector.php

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
use Rector\Config\RectorConfig;
77
use Rector\DeadCode\Rector\ConstFetch\RemovePhpVersionIdCheckRector;
88
use Rector\Php55\Rector\String_\StringClassNameToClassConstantRector;
9-
use Rector\Php83\Rector\ClassConst\AddTypeToConstRector;
109
use Rector\PHPUnit\CodeQuality\Rector\Class_\AddSeeTestAnnotationRector;
1110
use Rector\Utils\Rector\RemoveRefactorDuplicatedNodeInstanceCheckRector;
1211

@@ -26,7 +25,7 @@
2625
)
2726
->withAttributesSets()
2827
->withComposerBased(phpunit: true)
29-
->withPhpSets(php82: true)
28+
->withPhpSets()
3029
->withPaths([
3130
__DIR__ . '/bin',
3231
__DIR__ . '/config',
@@ -40,10 +39,7 @@
4039
])
4140
->withRootFiles()
4241
->withImportNames(removeUnusedImports: true)
43-
->withRules([
44-
RemoveRefactorDuplicatedNodeInstanceCheckRector::class, AddSeeTestAnnotationRector::class,
45-
AddTypeToConstRector::class,
46-
])
42+
->withRules([RemoveRefactorDuplicatedNodeInstanceCheckRector::class, AddSeeTestAnnotationRector::class])
4743
->withSkip([
4844
StringClassNameToClassConstantRector::class,
4945
// tests
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
namespace Rector\Tests\Php83\Rector\ClassMethod\AddOverrideAttributeToOverriddenMethodsRector\Fixture;
4+
5+
use Rector\Tests\Php83\Rector\ClassMethod\AddOverrideAttributeToOverriddenMethodsRector\Source\SomeAbstractTest;
6+
7+
final class SkipSetupPHPUnitAsClutter extends SomeAbstractTest
8+
{
9+
protected function setUp(): void
10+
{
11+
parent::setUp();
12+
13+
$someValue = 1;
14+
}
15+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
namespace Rector\Tests\Php83\Rector\ClassMethod\AddOverrideAttributeToOverriddenMethodsRector\Source;
4+
5+
use PHPUnit\Framework\TestCase;
6+
7+
abstract class SomeAbstractTest extends TestCase
8+
{
9+
protected function setUp(): void
10+
{
11+
$value = 1000;
12+
}
13+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Rector\DeadCode\NodeAnalyzer;
6+
7+
use PhpParser\Node\Expr\StaticCall;
8+
use PhpParser\Node\Stmt\ClassMethod;
9+
use PhpParser\Node\Stmt\Expression;
10+
use Rector\NodeNameResolver\NodeNameResolver;
11+
12+
final readonly class ParentClassAnalyzer
13+
{
14+
public function __construct(
15+
private NodeNameResolver $nodeNameResolver,
16+
) {
17+
18+
}
19+
20+
public function hasParentCall(ClassMethod $classMethod): bool
21+
{
22+
if ($classMethod->isAbstract()) {
23+
return false;
24+
}
25+
26+
if ($classMethod->isPrivate()) {
27+
return false;
28+
}
29+
30+
$classMethodName = $classMethod->name->name;
31+
32+
foreach ((array) $classMethod->stmts as $stmt) {
33+
if (! $stmt instanceof Expression) {
34+
continue;
35+
}
36+
37+
$expr = $stmt->expr;
38+
if (! $expr instanceof StaticCall) {
39+
continue;
40+
}
41+
42+
if (! $this->nodeNameResolver->isName($expr->class, 'parent')) {
43+
continue;
44+
}
45+
46+
if ($this->nodeNameResolver->isName($expr->name, $classMethodName)) {
47+
return true;
48+
}
49+
}
50+
51+
return false;
52+
}
53+
}

rules/Php81/Rector/Array_/FirstClassCallableRector.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
namespace Rector\Php81\Rector\Array_;
66

7+
use Override;
78
use PhpParser\Node;
89
use PhpParser\Node\Expr\MethodCall;
910
use PhpParser\Node\Expr\StaticCall;
@@ -15,6 +16,7 @@
1516
*/
1617
final class FirstClassCallableRector extends ArrayToFirstClassCallableRector implements DeprecatedInterface
1718
{
19+
#[Override]
1820
public function refactor(Node $node): StaticCall|MethodCall|null
1921
{
2022
throw new ShouldNotHappenException(sprintf(

rules/Php83/Rector/ClassMethod/AddOverrideAttributeToOverriddenMethodsRector.php

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
use PHPStan\Reflection\ClassReflection;
2020
use PHPStan\Reflection\ReflectionProvider;
2121
use Rector\Contract\Rector\ConfigurableRectorInterface;
22+
use Rector\DeadCode\NodeAnalyzer\ParentClassAnalyzer;
2223
use Rector\NodeAnalyzer\ClassAnalyzer;
2324
use Rector\Php80\NodeAnalyzer\PhpAttributeAnalyzer;
2425
use Rector\PhpParser\AstResolver;
@@ -54,6 +55,7 @@ public function __construct(
5455
private readonly PhpAttributeAnalyzer $phpAttributeAnalyzer,
5556
private readonly AstResolver $astResolver,
5657
private readonly ValueResolver $valueResolver,
58+
private readonly ParentClassAnalyzer $parentClassAnalyzer,
5759
) {
5860
}
5961

@@ -135,6 +137,11 @@ public function refactor(Node $node): ?Node
135137
return null;
136138
}
137139

140+
// skip if no parents, nor traits, nor strinables are involved
141+
if ($node->extends === null && $node->getTraitUses() === [] && ! $this->implementsStringable($node)) {
142+
return null;
143+
}
144+
138145
$className = (string) $this->getName($node);
139146
if (! $this->reflectionProvider->hasClass($className)) {
140147
return null;
@@ -227,12 +234,18 @@ private function shouldSkipClassMethod(ClassMethod $classMethod): bool
227234
return true;
228235
}
229236

237+
// nothing to override
230238
if ($classMethod->isPrivate()) {
231239
return true;
232240
}
233241

234242
// ignore if it already uses the attribute
235-
return $this->phpAttributeAnalyzer->hasPhpAttribute($classMethod, self::OVERRIDE_CLASS);
243+
if ($this->phpAttributeAnalyzer->hasPhpAttribute($classMethod, self::OVERRIDE_CLASS)) {
244+
return true;
245+
}
246+
247+
// skip test setup method override, as rather clutters the code than helps
248+
return $this->isName($classMethod, 'setUp') && $this->parentClassAnalyzer->hasParentCall($classMethod);
236249
}
237250

238251
private function shouldSkipParentClassMethod(ClassReflection $parentClassReflection, ClassMethod $classMethod): bool
@@ -284,4 +297,15 @@ private function shouldSkipParentClassMethod(ClassReflection $parentClassReflect
284297

285298
return false;
286299
}
300+
301+
private function implementsStringable(Class_ $class): bool
302+
{
303+
foreach ($class->implements as $implement) {
304+
if ($this->isName($implement, 'Stringable')) {
305+
return true;
306+
}
307+
}
308+
309+
return false;
310+
}
287311
}

src/BetterPhpDocParser/PhpDoc/SpacelessPhpDocTagNode.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
namespace Rector\BetterPhpDocParser\PhpDoc;
66

7+
use Override;
78
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode;
89
use Stringable;
910

@@ -13,6 +14,7 @@
1314
*/
1415
final class SpacelessPhpDocTagNode extends PhpDocTagNode implements Stringable
1516
{
17+
#[Override]
1618
public function __toString(): string
1719
{
1820
return $this->name . $this->value;

src/BetterPhpDocParser/PhpDocParser/BetterPhpDocParser.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
namespace Rector\BetterPhpDocParser\PhpDocParser;
66

77
use Nette\Utils\Strings;
8+
use Override;
89
use PhpParser\Node;
910
use PHPStan\PhpDocParser\Ast\PhpDoc\GenericTagValueNode;
1011
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocChildNode;
@@ -90,6 +91,7 @@ public function parseWithNode(BetterTokenIterator $betterTokenIterator, Node $no
9091
return $phpDocNode;
9192
}
9293

94+
#[Override]
9395
public function parseTag(TokenIterator $tokenIterator): PhpDocTagNode
9496
{
9597
// replace generic nodes with DoctrineAnnotations
@@ -106,6 +108,7 @@ public function parseTag(TokenIterator $tokenIterator): PhpDocTagNode
106108
/**
107109
* @param BetterTokenIterator $tokenIterator
108110
*/
111+
#[Override]
109112
public function parseTagValue(TokenIterator $tokenIterator, string $tag): PhpDocTagValueNode
110113
{
111114
$isPrecededByHorizontalWhitespace = $tokenIterator->isPrecededByHorizontalWhitespace();

src/BetterPhpDocParser/ValueObject/PhpDoc/SpacingAwareTemplateTagValueNode.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
namespace Rector\BetterPhpDocParser\ValueObject\PhpDoc;
66

7+
use Override;
78
use PHPStan\PhpDocParser\Ast\PhpDoc\TemplateTagValueNode;
89
use PHPStan\PhpDocParser\Ast\Type\TypeNode;
910
use Stringable;
@@ -19,6 +20,7 @@ public function __construct(
1920
parent::__construct($name, $typeNode, $description);
2021
}
2122

23+
#[Override]
2224
public function __toString(): string
2325
{
2426
// @see https://github.com/rectorphp/rector/issues/3438

0 commit comments

Comments
 (0)