[Downgrade] Fix parameter type widening issue, when method lives on the ancestor's interface (#4877)

Co-authored-by: rector-bot <tomas@getrector.org>
This commit is contained in:
Leonardo Losoviz 2020-12-14 19:41:36 +08:00 committed by GitHub
parent 78c619be8c
commit c5a15d559a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 62 additions and 1 deletions

View File

@ -150,8 +150,21 @@ CODE_SAMPLE
foreach ($ancestorAndInterfaceClassNames as $ancestorClassOrInterface) {
/** @var string */
$parentClassName = $ancestorClassOrInterface->getAttribute(AttributeKey::CLASS_NAME);
/** @var ClassMethod */
$classMethod = $this->nodeRepository->findClassMethod($parentClassName, $methodName);
/**
* If it doesn't find the method, it's because the method
* lives somewhere else.
* For instance, in test "interface_on_parent_class.php.inc",
* the ancestor abstract class is also retrieved
* as containing the method, but it does not: it is
* in its implemented interface. That happens because
* `ReflectionMethod` doesn't allow to do do the distinction.
* The interface is also retrieve though, so that method
* will eventually be refactored.
*/
if ($classMethod === null) {
continue;
}
$this->removeParamTypeFromMethod($ancestorClassOrInterface, $position, $classMethod);
$this->removeParamTypeFromMethodForChildren($parentClassName, $methodName, $position);
}

View File

@ -0,0 +1,48 @@
<?php
namespace Rector\DowngradePhp72\Tests\Rector\ClassMethod\DowngradeParameterTypeWideningRector\Fixture;
interface SomeInterface
{
public function test(string $input);
}
abstract class AbstractSomeAncestorClass implements SomeInterface
{
}
class SomeChildClass extends AbstractSomeAncestorClass
{
public function test($input) // type omitted for $input
{
/* ... */
}
}
?>
-----
<?php
namespace Rector\DowngradePhp72\Tests\Rector\ClassMethod\DowngradeParameterTypeWideningRector\Fixture;
interface SomeInterface
{
/**
* @param string $input
*/
public function test($input);
}
abstract class AbstractSomeAncestorClass implements SomeInterface
{
}
class SomeChildClass extends AbstractSomeAncestorClass
{
public function test($input) // type omitted for $input
{
/* ... */
}
}
?>