-
-
Notifications
You must be signed in to change notification settings - Fork 336
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[DowngradePhp72] Handle anonymous class override class method on Down…
…gradeParameterTypeWideningRector (#777) * Another failing test case for DowngradeParameterTypeWideningRector. * Fixes test. * Closes #762 Fixes rectorphp/rector#6664 * move skip method * rectify * [ci-review] Rector Rectify * move Sealed Class check to SealedClassAnalyzer * final touch * final touch Co-authored-by: Bobab12 <bobab12@users.noreply.github.com> Co-authored-by: GitHub Action <action@github.com>
- Loading branch information
1 parent
646b207
commit b2c44bf
Showing
5 changed files
with
212 additions
and
36 deletions.
There are no files selected for viewing
55 changes: 55 additions & 0 deletions
55
...2/Rector/ClassMethod/DowngradeParameterTypeWideningRector/Fixture/anonymous_class.php.inc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
<?php | ||
|
||
namespace Rector\Tests\DowngradePhp72\Rector\ClassMethod\DowngradeParameterTypeWideningRector\Fixture; | ||
|
||
class SomeClass | ||
{ | ||
public function hello(string $world = 'world') { | ||
printf('Hello %s', $world); | ||
} | ||
} | ||
|
||
class SomeOtherClassUsingAnAnonymousClass | ||
{ | ||
public function doSomething(): void | ||
{ | ||
$class = new class () extends SomeClass { | ||
public function hello(string $world = 'world') { | ||
printf('Hi %s', $world); | ||
} | ||
}; | ||
} | ||
} | ||
|
||
?> | ||
----- | ||
<?php | ||
|
||
namespace Rector\Tests\DowngradePhp72\Rector\ClassMethod\DowngradeParameterTypeWideningRector\Fixture; | ||
|
||
class SomeClass | ||
{ | ||
/** | ||
* @param string $world | ||
*/ | ||
public function hello($world = 'world') { | ||
printf('Hello %s', $world); | ||
} | ||
} | ||
|
||
class SomeOtherClassUsingAnAnonymousClass | ||
{ | ||
public function doSomething(): void | ||
{ | ||
$class = new class () extends SomeClass { | ||
/** | ||
* @param string $world | ||
*/ | ||
public function hello($world = 'world') { | ||
printf('Hi %s', $world); | ||
} | ||
}; | ||
} | ||
} | ||
|
||
?> |
24 changes: 24 additions & 0 deletions
24
.../DowngradeParameterTypeWideningRector/Fixture/skip_anonymous_class_private_method.php.inc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
<?php | ||
|
||
namespace Rector\Tests\DowngradePhp72\Rector\ClassMethod\DowngradeParameterTypeWideningRector\Fixture; | ||
|
||
class SomeClass2 | ||
{ | ||
private function hello(string $world = 'world') { | ||
printf('Hello %s', $world); | ||
} | ||
} | ||
|
||
class SkipAnonymousClassPrivateMethod | ||
{ | ||
public function doSomething(): void | ||
{ | ||
$class = new class () extends SomeClass2 { | ||
private function hello(string $world = 'world') { | ||
printf('Hi %s', $world); | ||
} | ||
}; | ||
} | ||
} | ||
|
||
?> |
58 changes: 58 additions & 0 deletions
58
rules/DowngradePhp72/NodeAnalyzer/OverrideFromAnonymousClassMethodAnalyzer.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Rector\DowngradePhp72\NodeAnalyzer; | ||
|
||
use PhpParser\Node\Name\FullyQualified; | ||
use PhpParser\Node\Stmt\Class_; | ||
use PhpParser\Node\Stmt\ClassLike; | ||
use PhpParser\Node\Stmt\ClassMethod; | ||
use PHPStan\Reflection\Php\PhpMethodReflection; | ||
use PHPStan\Reflection\ReflectionProvider; | ||
use Rector\Core\NodeAnalyzer\ClassAnalyzer; | ||
use Rector\NodeNameResolver\NodeNameResolver; | ||
use Rector\NodeTypeResolver\Node\AttributeKey; | ||
|
||
final class OverrideFromAnonymousClassMethodAnalyzer | ||
{ | ||
public function __construct( | ||
private ClassAnalyzer $classAnalyzer, | ||
private NodeNameResolver $nodeNameResolver, | ||
private ReflectionProvider $reflectionProvider | ||
) { | ||
} | ||
|
||
public function isOverrideParentMethod(ClassLike $classLike, ClassMethod $classMethod): bool | ||
{ | ||
if (! $this->classAnalyzer->isAnonymousClass($classLike)) { | ||
return false; | ||
} | ||
|
||
/** @var Class_ $classLike */ | ||
if (! $classLike->extends instanceof FullyQualified) { | ||
return false; | ||
} | ||
|
||
$extendsClass = $classLike->extends->toString(); | ||
if (! $this->reflectionProvider->hasClass($extendsClass)) { | ||
return false; | ||
} | ||
|
||
$classReflection = $this->reflectionProvider->getClass($extendsClass); | ||
$methodName = $this->nodeNameResolver->getName($classMethod); | ||
|
||
if (! $classReflection->hasMethod($methodName)) { | ||
return false; | ||
} | ||
|
||
$scope = $classMethod->getAttribute(AttributeKey::SCOPE); | ||
$method = $classReflection->getMethod($methodName, $scope); | ||
|
||
if (! $method instanceof PhpMethodReflection) { | ||
return false; | ||
} | ||
|
||
return ! $method->isPrivate(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Rector\DowngradePhp72\NodeAnalyzer; | ||
|
||
use PHPStan\Reflection\ClassReflection; | ||
|
||
final class SealedClassAnalyzer | ||
{ | ||
/** | ||
* This method is perfectly sealed, nothing to downgrade here | ||
*/ | ||
public function isSealedClass(ClassReflection $classReflection): bool | ||
{ | ||
if (! $classReflection->isClass()) { | ||
return false; | ||
} | ||
|
||
if (! $classReflection->isFinal()) { | ||
return false; | ||
} | ||
|
||
return count($classReflection->getAncestors()) === 1; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters