Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion rules/CodingStyle/Node/NameImporter.php
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ private function addUseImport(
FullyQualified $fullyQualified,
FullyQualifiedObjectType $fullyQualifiedObjectType
): void {
if ($this->useNodesToAddCollector->hasImport($file, $fullyQualified, $fullyQualifiedObjectType)) {
if ($this->useNodesToAddCollector->hasImport($file, $fullyQualifiedObjectType)) {
return;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ private function processFqnNameImport(
return null;
}

if ($this->shouldImport($newNode, $identifierTypeNode, $fullyQualifiedObjectType)) {
if ($this->shouldImport($file, $newNode, $identifierTypeNode, $fullyQualifiedObjectType)) {
$this->useNodesToAddCollector->addUseImport($fullyQualifiedObjectType);
$this->hasChanged = true;

Expand All @@ -157,6 +157,7 @@ private function processFqnNameImport(
}

private function shouldImport(
File $file,
IdentifierTypeNode $newNode,
IdentifierTypeNode $identifierTypeNode,
FullyQualifiedObjectType $fullyQualifiedObjectType
Expand All @@ -181,7 +182,7 @@ private function shouldImport(

$firstPath = Strings::before($identifierTypeNode->name, '\\' . $newNode->name);
if ($firstPath === null) {
return true;
return ! $this->useNodesToAddCollector->hasImport($file, $fullyQualifiedObjectType);
}

if ($firstPath === '') {
Expand Down
2 changes: 0 additions & 2 deletions src/PostRector/Collector/UseNodesToAddCollector.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
namespace Rector\PostRector\Collector;

use PhpParser\Node\Identifier;
use PhpParser\Node\Name\FullyQualified;
use Rector\Application\Provider\CurrentFileProvider;
use Rector\Naming\Naming\UseImportsResolver;
use Rector\StaticTypeMapper\ValueObject\Type\AliasedObjectType;
Expand Down Expand Up @@ -86,7 +85,6 @@ public function getUseImportTypesByNode(File $file): array

public function hasImport(
File $file,
FullyQualified $fullyQualified,
FullyQualifiedObjectType $fullyQualifiedObjectType
): bool {
$useImports = $this->getUseImportTypesByNode($file);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,7 @@ public function mapIdentifierTypeNode(IdentifierTypeNode $identifierTypeNode, No
return new UnionType($scalarTypes);
}

$identifierTypeNode->name = ltrim($identifierTypeNode->name, '@');
$objectType = new ObjectType($identifierTypeNode->name);
$objectType = new ObjectType(ltrim($identifierTypeNode->name, '@'));
}

$scope = $node->getAttribute(AttributeKey::SCOPE);
Expand Down
33 changes: 33 additions & 0 deletions tests/Issues/Issue9388/Fixture/fixture.php.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

namespace Rector\Tests\Issues\Issue9388\Fixture;

final class MyClass
{
/**
* @var string
* @TYPO3\CMS\Extbase\Annotation\Validate("NotEmpty")
*/
protected $name = '';

/**
* @TYPO3\CMS\Extbase\Annotation\Validate("NotEmpty")
*/
protected $thisWorks = '';
}
-----
<?php

namespace Rector\Tests\Issues\Issue9388\Fixture;

final class MyClass
{
/**
* @var string
*/
#[\TYPO3\CMS\Extbase\Annotation\Validate(['validator' => 'NotEmpty'])]
protected $name = '';

#[\TYPO3\CMS\Extbase\Annotation\Validate(['validator' => 'NotEmpty'])]
protected $thisWorks = '';
}
31 changes: 31 additions & 0 deletions tests/Issues/Issue9388/Issue9388Test.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

declare(strict_types=1);

namespace Rector\Tests\Issues\Issue9388;

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

/**
* @see https://github.com/rectorphp/rector/issues/9388
*/
final class Issue9388Test 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,26 @@
<?php

declare(strict_types=1);

namespace Rector\Tests\Issues\Issue9388\Source\AnnotationToAttribute;

use PhpParser\Node\Attribute;

final readonly class AttributeDecorator
{
/**
* @param AttributeDecoratorInterface[] $decorators
*/
public function __construct(private array $decorators)
{
}

public function decorate(string $phpAttributeName, Attribute $attribute): void
{
foreach ($this->decorators as $decorator) {
if ($decorator->supports($phpAttributeName)) {
$decorator->decorate($attribute);
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

declare(strict_types=1);

namespace Rector\Tests\Issues\Issue9388\Source\AnnotationToAttribute;

use PhpParser\Node\Attribute;

interface AttributeDecoratorInterface
{
public function supports(string $phpAttributeName): bool;

public function decorate(Attribute $attribute): void;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?php

declare(strict_types=1);

namespace Rector\Tests\Issues\Issue9388\Source\AnnotationToAttribute;

use PhpParser\Node\Arg;
use PhpParser\Node\ArrayItem;
use PhpParser\Node\Attribute;
use PhpParser\Node\Expr\Array_;
use PhpParser\Node\Expr\ClassConstFetch;
use PhpParser\Node\Identifier;
use PhpParser\Node\Scalar\String_;
use Rector\Php55\Rector\String_\StringClassNameToClassConstantRector;
use Rector\PhpParser\Node\Value\ValueResolver;

final readonly class ValidateAttributeDecorator implements AttributeDecoratorInterface
{
public function __construct(private ValueResolver $valueResolver, private StringClassNameToClassConstantRector $stringClassNameToClassConstantRector)
{
}

public function supports(string $phpAttributeName): bool
{
return $phpAttributeName === 'TYPO3\CMS\Extbase\Annotation\Validate';
}

public function decorate(Attribute $attribute): void
{
$array = new Array_();

foreach ($attribute->args as $arg) {
$key = $arg->name instanceof Identifier ? new String_($arg->name->toString()) : new String_('validator');

if ($this->valueResolver->isValue($key, 'validator')) {
$classNameString = $this->valueResolver->getValue($arg->value);
if (! is_string($classNameString)) {
continue;
}

$className = ltrim($classNameString, '\\');
$classConstant = $this->stringClassNameToClassConstantRector->refactor(new String_($className));
$value = $classConstant instanceof ClassConstFetch ? $classConstant : $arg->value;
} else {
$value = $arg->value;
}

$array->items[] = new ArrayItem($value, $key);
}

$attribute->args = [new Arg($array)];
}
}
Loading
Loading