Skip to content

Commit

Permalink
[NodeTypeResolver] Handle nullable extended class on ->isObjectType()…
Browse files Browse the repository at this point in the history
… on DowngradeReflectionGetAttributesRector (#5224)

* [NodeTypeResolver] Handle nullable extended class on ->isObjectType() on DowngradeReflectionGetAttributesRector

* [ci-review] Rector Rectify

* [ci-review] Rector Rectify

* Fixed 🎉

* fix

---------

Co-authored-by: GitHub Action <actions@github.com>
  • Loading branch information
samsonasik and actions-user committed Nov 5, 2023
1 parent 2ad03db commit 8615d40
Show file tree
Hide file tree
Showing 7 changed files with 93 additions and 18 deletions.
2 changes: 1 addition & 1 deletion packages/NodeTypeResolver/NodeTypeResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -438,7 +438,7 @@ private function isMatchingUnionType(Type $resolvedType, ObjectType $requiredObj
return $this->isMatchObjectWithoutClassType($type, $requiredObjectType);
}

return $type->isSuperTypeOf($requiredObjectType)
return $requiredObjectType->isSuperTypeOf($type)
->yes();
}

Expand Down
16 changes: 7 additions & 9 deletions packages/Testing/PHPUnit/AbstractRectorTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -94,12 +94,10 @@ protected function setUp(): void
$this->bootFromConfigFiles([$configFile]);

$rectorsGenerator = $rectorConfig->tagged(RectorInterface::class);
if ($rectorsGenerator instanceof RewindableGenerator) {
$rectors = iterator_to_array($rectorsGenerator->getIterator());
} else {
$rectors = $rectorsGenerator instanceof RewindableGenerator
? iterator_to_array($rectorsGenerator->getIterator())
// no rules at all, e.g. in case of only post rector run
$rectors = [];
}
: [];

/** @var RectorNodeTraverser $rectorNodeTraverser */
$rectorNodeTraverser = $rectorConfig->make(RectorNodeTraverser::class);
Expand Down Expand Up @@ -231,7 +229,7 @@ private function doTestFileMatchesExpectedContent(
// the file is now changed (if any rule matches)
$rectorTestResult = $this->processFilePath($originalFilePath);

$changedContent = $rectorTestResult->getChangedContents();
$changedContents = $rectorTestResult->getChangedContents();

$fixtureFilename = basename($fixtureFilePath);
$failureMessage = sprintf('Failed on fixture file "%s"', $fixtureFilename);
Expand All @@ -247,12 +245,12 @@ private function doTestFileMatchesExpectedContent(
}

try {
$this->assertSame($expectedFileContents, $changedContent, $failureMessage);
$this->assertSame($expectedFileContents, $changedContents, $failureMessage);
} catch (ExpectationFailedException) {
FixtureFileUpdater::updateFixtureContent($originalFileContent, $changedContent, $fixtureFilePath);
FixtureFileUpdater::updateFixtureContent($originalFileContent, $changedContents, $fixtureFilePath);

// if not exact match, check the regex version (useful for generated hashes/uuids in the code)
$this->assertStringMatchesFormat($expectedFileContents, $changedContent, $failureMessage);
$this->assertStringMatchesFormat($expectedFileContents, $changedContents, $failureMessage);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
new MethodCallRename(DifferentInterface::class, 'renameMe', 'toNewVersion'),

// reflection method name
new MethodCallRename(ReflectionMethod::class, 'getTentativeReturnType', 'getReturnType'),
new MethodCallRename(ReflectionFunctionAbstract::class, 'getTentativeReturnType', 'getReturnType'),

// with array key
new MethodCallRenameWithArrayKey('Nette\Utils\Html', 'addToArray', 'addToHtmlArray', 'hey'),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
* @see https://wiki.php.net/rfc/marking_overriden_methods
* @see \Rector\Tests\Php83\Rector\ClassMethod\AddOverrideAttributeToOverriddenMethodsRector\AddOverrideAttributeToOverriddenMethodsRectorTest
*/
class AddOverrideAttributeToOverriddenMethodsRector extends AbstractRector implements MinPhpVersionInterface
final class AddOverrideAttributeToOverriddenMethodsRector extends AbstractRector implements MinPhpVersionInterface
{
public function __construct(
private readonly ReflectionProvider $reflectionProvider,
Expand Down Expand Up @@ -97,22 +97,25 @@ public function refactor(Node $node): ?Node

$hasChanged = false;

foreach ($node->getMethods() as $method) {
if ($method->name->toString() === '__construct') {
foreach ($node->getMethods() as $classMethod) {
if ($classMethod->name->toString() === '__construct') {
continue;
}

// Private methods should be ignored
if ($parentClassReflection->hasNativeMethod($method->name->toString())) {
if ($parentClassReflection->hasNativeMethod($classMethod->name->toString())) {
// ignore if it is a private method on the parent
$parentMethod = $parentClassReflection->getNativeMethod($method->name->toString());
$parentMethod = $parentClassReflection->getNativeMethod($classMethod->name->toString());
if ($parentMethod->isPrivate()) {
continue;
}

// ignore if it already uses the attribute
if ($this->phpAttributeAnalyzer->hasPhpAttribute($method, 'Override')) {
if ($this->phpAttributeAnalyzer->hasPhpAttribute($classMethod, 'Override')) {
continue;
}
$method->attrGroups[] = new AttributeGroup([new Attribute(new FullyQualified('Override'))]);

$classMethod->attrGroups[] = new AttributeGroup([new Attribute(new FullyQualified('Override'))]);
$hasChanged = true;
}
}
Expand All @@ -134,6 +137,7 @@ private function shouldSkipClass(Class_ $class): bool
if ($this->classAnalyzer->isAnonymousClass($class)) {
return true;
}

if (! $class->extends instanceof FullyQualified) {
return true;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

declare(strict_types=1);

namespace Rector\Core\Tests\Issues\DowngradeNullableReflectionProperty;

use Iterator;
use PHPUnit\Framework\Attributes\DataProvider;
use Rector\Testing\PHPUnit\AbstractRectorTestCase;

final class DowngradeNullableReflectionPropertyTest extends AbstractRectorTestCase
{
#[DataProvider('provideData')]
public function test(string $filePath): void
{
$this->doTestFile($filePath);
}

public static function provideData(): Iterator
{
return self::yieldFilesFromDirectory(__DIR__ . '/Fixture');
}

public function provideConfigFilePath(): string
{
return __DIR__ . '/config/configured_rule.php';
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

namespace Rector\Core\Tests\Issues\DowngradeNullableReflectionProperty\Fixture;

class UseNullableReflectionProperty
{
public function run(?\ReflectionProperty $reflectionProperty)
{
if ($reflectionProperty->getAttributes('SomeAttribute')[0] ?? null) {
return true;
}

return false;
}
}

?>
-----
<?php

namespace Rector\Core\Tests\Issues\DowngradeNullableReflectionProperty\Fixture;

class UseNullableReflectionProperty
{
public function run(?\ReflectionProperty $reflectionProperty)
{
if ((method_exists($reflectionProperty, 'getAttributes') ? $reflectionProperty->getAttributes('SomeAttribute') : [])[0] ?? null) {
return true;
}

return false;
}
}

?>
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

declare(strict_types=1);

use Rector\Config\RectorConfig;
use Rector\DowngradePhp80\Rector\MethodCall\DowngradeReflectionGetAttributesRector;

return static function (RectorConfig $rectorConfig): void {
$rectorConfig->rule(DowngradeReflectionGetAttributesRector::class);
};

0 comments on commit 8615d40

Please sign in to comment.