Skip to content

Commit

Permalink
Add known type casting to AnnotationToAttributeRector
Browse files Browse the repository at this point in the history
  • Loading branch information
TomasVotruba committed Aug 6, 2024
1 parent b36e264 commit 1258558
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ use Symfony\Component\Validator\Constraints as Assert;

final class ValidationIntegerParameter
{
#[Assert\Length(min: '100', max: '255', maxMessage: 'some Message', allowed: 'true')]
#[Assert\Length(min: 100, max: 255, maxMessage: 'some Message', allowed: 'true')]
public function action()
{
}
Expand Down
13 changes: 13 additions & 0 deletions src/PhpAttribute/Enum/AnnotationClassName.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

declare(strict_types=1);

namespace Rector\PhpAttribute\Enum;

final class AnnotationClassName
{
/**
* @var string
*/
public const LENGTH = 'Symfony\Component\Validator\Constraints\Length';
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?php

declare(strict_types=1);

namespace Rector\PhpAttribute\NodeFactory;

use PhpParser\Node\Arg;
use PhpParser\Node\Expr\ArrayItem;
use PhpParser\Node\Scalar\LNumber;
use PhpParser\Node\Scalar\String_;
use Rector\Php80\ValueObject\AnnotationToAttribute;
use Rector\PhpAttribute\Enum\AnnotationClassName;

final class AnnotationToAttributeKeyTypeCaster
{
/**
* @var array<string, string[]>
*/
private const INTEGER_KEYS_BY_CLASS = [
AnnotationClassName::LENGTH => ['min', 'max'],
];

/**
* @param Arg[] $args
*/
public function castAttributeTypes(AnnotationToAttribute $annotationToAttribute, array $args): void
{
// known type casting
foreach (self::INTEGER_KEYS_BY_CLASS as $annotationClass => $integerKeys) {
if ($annotationToAttribute->getAttributeClass() !== $annotationClass) {
continue;
}

foreach ($integerKeys as $integerKey) {
foreach ($args as $arg) {
if (! $arg->value instanceof ArrayItem) {
continue;
}

$arrayItem = $arg->value;
if (! $arrayItem->key instanceof String_) {
continue;
}

if ($arrayItem->key->value !== $integerKey) {
continue;
}

// ensure type is casted to integer
if ($arrayItem->value instanceof String_) {
$arrayItem->value = new LNumber((int) $arrayItem->value->value);
}
}
}
}
}

}
7 changes: 6 additions & 1 deletion src/PhpAttribute/NodeFactory/PhpAttributeGroupFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use PhpParser\Node\Expr\ArrayItem;
use PhpParser\Node\Expr\ClassConstFetch;
use PhpParser\Node\Name\FullyQualified;
use PhpParser\Node\Scalar\LNumber;
use PhpParser\Node\Scalar\String_;
use PhpParser\Node\Stmt\Use_;
use Rector\BetterPhpDocParser\PhpDoc\ArrayItemNode;
Expand All @@ -21,6 +22,7 @@
use Rector\Php81\Enum\AttributeName;
use Rector\PhpAttribute\AnnotationToAttributeMapper;
use Rector\PhpAttribute\AttributeArrayNameInliner;
use Rector\PhpAttribute\Enum\AnnotationClassName;

/**
* @see \Rector\Tests\PhpAttribute\Printer\PhpAttributeGroupFactoryTest
Expand All @@ -31,7 +33,8 @@ public function __construct(
private AnnotationToAttributeMapper $annotationToAttributeMapper,
private AttributeNameFactory $attributeNameFactory,
private NamedArgsFactory $namedArgsFactory,
private AttributeArrayNameInliner $attributeArrayNameInliner
private AttributeArrayNameInliner $attributeArrayNameInliner,
private \Rector\PhpAttribute\NodeFactory\AnnotationToAttributeKeyTypeCaster $annotationToAttributeKeyTypeCaster,
) {
}

Expand Down Expand Up @@ -79,6 +82,8 @@ public function create(
$annotationToAttribute->getClassReferenceFields()
);

$this->annotationToAttributeKeyTypeCaster->castAttributeTypes($annotationToAttribute, $args);

$args = $this->attributeArrayNameInliner->inlineArrayToArgs($args);

$attributeName = $this->attributeNameFactory->create(
Expand Down
11 changes: 11 additions & 0 deletions stubs/Symfony/Component/Validator/Constraints/Length.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

namespace Symfony\Component\Validator\Constraints;

if (class_exists('Symfony\Component\Validator\Constraints\Length')) {
return;
}

class Length
{
}

0 comments on commit 1258558

Please sign in to comment.