Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(symfony-routing): replace Symfony route annotation by attribute one #557

Merged

Conversation

mcsky
Copy link
Contributor

@mcsky mcsky commented Jan 12, 2024

Integrate in Symfony upgrade the replacement of Symfony\Component\Routing\Annotation\Route by Symfony\Component\Routing\Attribute\Route

see this issue

Closes rectorphp/rector#8384

@mcsky
Copy link
Contributor Author

mcsky commented Jan 12, 2024

(i'm going to add a test for this)

@mcsky mcsky force-pushed the feat-rename-route-annotation-to-attribute branch from 845d002 to 9dcc10d Compare January 12, 2024 18:37
@mcsky mcsky force-pushed the feat-rename-route-annotation-to-attribute branch 2 times, most recently from 497bb68 to 1cba32c Compare January 12, 2024 18:39
@@ -18,4 +19,10 @@
// @see Symfony 5.2+ https://github.com/symfony/doctrine-bridge/commit/02d2cf4743331e6b69ffd1d68e09b7e2dc417201#diff-1a16e2739e51eab000116d0542bd0226cea59a6d64711740ed7ce14769f95d1b
new AnnotationToAttribute('Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity'),
]);
$rectorConfig->ruleWithConfiguration(
RenameClassRector::class,
[
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems not needed, just update the 2nd arg of AnnotationToAttribute arg to Symfony\Component\Routing\Attribute\Route above on line 18 should auto change to target attribute with new name

new AnnotationToAttribute('Symfony\Component\Routing\Annotation\Route', 'Symfony\Component\Routing\Attribute\Route'

test is needed tho

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/cc @scuben @JohJohan could you verify that "Symfony\Component\Routing\Attribute\Route" class exists in specific symfony version when upgrading from "Symfony\Component\Routing\Annotation\Route" thank you

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, rename seems still needed if it "already an attribute", but with "old name".

For other AnnotationToAttribute usage, the target and rename seems needed for this case, but need to ensure that the target attribute class already exists on specific symfony version when attribute introduced

Copy link
Contributor Author

@mcsky mcsky Jan 12, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Symfony\Component\Routing\Attribute\Route is available since symfony 6.4 AFAIK

I'm going to have a look at your feedbacks when at home.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's what I mean, if that target class introduced in later version, eg transforming annotation is start from symfony 5.2, while the new target attribute class only exists since 6.4, then that RenameClassRector need to be placed in specific setlists, the issue is, that need to be checked that rename attribute, not rename annotation

@samsonasik
Copy link
Member

samsonasik commented Jan 15, 2024

Ok, I am checking, the PHP 8 route attribute support exists since symfony 5.2, but the new class: "Symfony\Component\Routing\Attribute\Route" not yet exists, ref:

only the class: "Symfony\Component\Routing\Annotation\Route".

Then, start from symfony 6.4, the "Symfony\Component\Routing\Attribute\Route" exists,

https://github.com/symfony/symfony/blob/914c2880393fe31335e716809edfdf66beedd246/src/Symfony/Component/Routing/Attribute/Route.php#L26-L27

but the Annotation sub namespace is not deprecated, see

https://github.com/symfony/symfony/blob/914c2880393fe31335e716809edfdf66beedd246/src/Symfony/Component/Routing/Annotation/Route.php#L12-L16

so the original "Symfony\Component\Routing*Annotation*\Route" is still valid, which means the mapping is not necessarily needed.

If this is needed, to avoid invalid rename, as it only should be used in the attribute part, I think custom rule is needed which the step is:

  • create custom rule
  • verify if it is attribute in method, if match, rename
  • register the rule to symfony 6.4 setlist

https://github.com/rectorphp/rector-symfony/blob/main/config/sets/symfony/symfony64.php

which the "Symfony\Component\Routing\Attribute\Route" exists.

@mcsky
Copy link
Contributor Author

mcsky commented Jan 15, 2024

I give it a try very soon, thanks for all the details !

@mcsky mcsky force-pushed the feat-rename-route-annotation-to-attribute branch 2 times, most recently from c0fc2eb to 2407797 Compare January 20, 2024 18:31
Comment on lines 63 to 69
if ($node instanceof Attribute && $node->name !== null && (string) $node->name === self::ANNOTATION_ROUTE) {
// there I'd like to modify the UseUse node representing my current node->name
// AFAIK the node I'm returning from this method is only the Attribute node
// maybe should I retrieve the global AST from somewhere and manually get the UseUse node to edit the value
// Or maybe there is a more elegant way to do that ?

return null;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would like some help on this part. I think this if statement is enough to identify that the #[Route] attribute is used in the file.

But I'm stuck to modify the related UseUse node of this attribute. Have you any recommendations on this ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to import to use statement, that will be taken care by : $rectorConfig->importNames() when enabled.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh I see what you mean, in that case, $rectorConfig->importNames() is working on RenameClassRector, but not this custom rector, you may need to lookup of what AnnotationToAttributeRector implementation, set Name node, and add Name node to import nodes collector to be imported later

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can use Rector\PostRector\Collector\UseNodesToAddCollector service for that, eg:

$this->useNodesToAddCollector->addUseImport(new FullyQualifiedObjectType($namespacedAttrName));

see https://github.com/rectorphp/rector-src/blob/663f526966313e0f178c088ea667119490404da9/rules/Php80/Rector/Property/NestedAnnotationToAttributeRector.php#L219

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After some thinking, replace use statement directly is unnecessary on this case, if that needed, you can do:

$rectorConfig->importNames();
$rectorConfig->removeUnusedImports();

That will be safer imo, and that will be replaced.

The improvement for this case need to be verified carefully, and that need separate PR.

@mcsky
Copy link
Contributor Author

mcsky commented Jan 20, 2024

@samsonasik I started an implementation of the behaviour you described but I'm stuck. I can't figure out how to modify the use statement related to the #[Route] attribute node


public function getNodeTypes(): array
{
return [Attribute::class];
Copy link
Member

@samsonasik samsonasik Jan 21, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use ClassMethod instead, and rename its attrGroups so it only change on ClassMethod

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The #Route[] attribute can be specified on a method but also on a class in Symfony

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

then, you need to define in Class_ and ClassMethod

@mcsky mcsky force-pushed the feat-rename-route-annotation-to-attribute branch from 2407797 to 2a86bfc Compare January 21, 2024 11:15
…by attribute one

    Replace Symfony\Component\Routing\Annotation\Route by Symfony\Component\Routing\Attribute\Route
@mcsky mcsky force-pushed the feat-rename-route-annotation-to-attribute branch from 2a86bfc to 6c57a74 Compare January 21, 2024 11:18
}

?>
-----
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The second part start from ----- can be removed if equal content

Copy link
Member

@samsonasik samsonasik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, thank you

@samsonasik samsonasik changed the title chore(symfony-routing): replace Symfony route annotation use import by attribute one chore(symfony-routing): replace Symfony route annotation by attribute one Jan 22, 2024
@samsonasik samsonasik merged commit e52eac8 into rectorphp:main Jan 22, 2024
5 checks passed
@samsonasik
Copy link
Member

Thank you @mcsky

@TomasVotruba
Copy link
Member

Thanks @mcsky 🙏

@samsonasik samsonasik mentioned this pull request Jan 27, 2024
1 task
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Can't get AnnotationToAttribute to work.
3 participants