-
Notifications
You must be signed in to change notification settings - Fork 74
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
WIP: Rule to convert action to attributes #257
Conversation
1 file with changes
===================
1) modules_/examples/modules/action_example/src/Plugin/Action/BasicExample.php:1
---------- begin diff ----------
@@ @@
namespace Drupal\action_example\Plugin\Action;
+use Drupal\Core\Action\Attribute\Action;
+use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Action\ActionBase;
use Drupal\Core\Messenger\MessengerInterface;
@@ @@
/**
* A basic example action that does nothing.
- *
- * @Action(
- * id = "action_example_basic_action",
- * label = @Translation("Action Example: A basic example action that does nothing"),
- * type = "system"
- * )
*/
+#[Action(id: 'action_example_basic_action', label: new TranslatableMarkup('Action Example: A basic example action that does nothing'), type: 'system')]
class BasicExample extends ActionBase implements ContainerFactoryPluginInterface {
/**
----------- end diff -----------
Applied rules:
* ActionAnnotationToAttributeRector (https://docs.phpunit.de/en/10.0/annotations.html#ticket) |
714f6bb
to
5f4a4e8
Compare
Good start ❤️, thank you for working on this. I'd probably make it a Then it could work like a backwards compatible rule, where we pass the version it was introduced in (as FunctionToStaticRector). But it also means it needs new handling in the AbstractDrupalCoreRector since the BC call is not really a call (which can be called using DeprecationHelper), but the fact it does not remove the docblock annotatation. Thinking about that, it might need some refactoring to handle this case of it being a docblock, or we need to handle that in the rector itself in this case. But i need to be more awake to think about that one. Random thought, what if we make the removal bases on a property of ActionAnnotationToAttributeRector which we can set with a setter? Then we can toggle it easily. By default remove the docblock, but allow The end result would be:
When looking at the core change record i did also notice the following: /*
* @Block(
* id = "test_block_instantiation",
* admin_label = @Translation("Display message")
* )
*/
#[Block(
id: "test_block_instantiation",
admin_label: new TranslatableMarkup("Display message")
)] This does mean there is nested tags going on? Do we know what those are? Is that a fixed set? |
There's issue about formatting as miltiline rectorphp/rector#8239 |
The set keys of annotation is defined by class https://git.drupalcode.org/project/drupal/-/blob/11.x/core/lib/Drupal/Core/Block/Annotation/Block.php Technically the annotation could be parsed, child nodes could be picked from properties' doc-blocks and mapped
|
$args = []; | ||
foreach ($parsedArgs as $value) { | ||
if ($value->key === 'label') { | ||
$arg = new Node\Expr\New_(new Node\Name(TranslatableMarkup::class), [new Arg(new String_($value->value->values[0]->value->value))]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it could be a helper method
I don't think that's related. That's not about generating multiline attributes, it's about parsing annotations with multiline strings. |
To apply coding standards, according to https://github.com/rectorphp/rector/blob/main/README.md#how-to-apply-coding-standards https://github.com/rectorphp/rector-src/blob/main/ecs.php |
$arg = new Node\Expr\New_(new Node\Name(TranslatableMarkup::class), [new Arg(new String_($value->value->values[0]->value->value))]); | ||
} | ||
else { | ||
$arg = new String_($value->value->value); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In our internal projects we tend to use a const PLUGIN_ID = 'foo'
pattern and reference these in our annotations. I've been playing around with a custom annotation to attribute rector rule based on this one and noticed it fails on these constants. The following seems to work, although I'm wondering if there is a better way to detect the use of a constant in the annotation.
$arg = new String_($value->value instanceof StringNode ? new String_($value->value->value) : new ConstFetch(new Node\Name($value->value)));
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See root comment.
676af5b
to
dcffdd9
Compare
What changed yesterday (AI generated):
These changes seem to streamline the annotation handling in Drupal and improve compatibility with earlier versions. Note: |
5b5bc68
to
401e127
Compare
New conversions |
Added the rest of conversion https://www.drupal.org/node/3229001 |
…return types match the method names).
… ActionAnnotationToAttributeRector to use AbstractDrupalCoreRector (mostly)
…y taking the actual annotation instead of its container.
401e127
to
773255a
Compare
…e configuration to more targetted.
src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector.php
Outdated
Show resolved
Hide resolved
if ($hasAttribute === false) { | ||
$stringValue = $valueNode->value->value; | ||
$stringValue = '{'.trim($stringValue, '()').'}'; | ||
$tokenIterator = $this->tokenIteratorFactory->create($stringValue); | ||
$data = $this->arrayParser->parseCurlyArray($tokenIterator, $node); | ||
$attribute = $this->createAttribute($configuration->getAttributeClass(), $data); | ||
$node->attrGroups[] = new AttributeGroup([$attribute]); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can this do a better check that the annotation matching the ending class name?
Wouldn't this cause @foo
to become #Foo
attribute because its a generic string?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you mean here; you get to this code after checking a tag is present as configured. Then we move on to check if there is already an attribute. If that is present, then we loopt through the tagnames and if there was no attribute matching the relevant attribute class from the configuration we start building the attribute based on the class passed into the rector by the configuration.
Don't really see how you could break this, unless user error using their own config?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
More so just:
$blah = explode('\', $configuration->getAttributeClass());
$className = end($blah);
if ($blah === substr($stringValue, 1)) {
Not entirely configured. Just that the tag matches the attribute's class name. I'm going to bet there is a "malformed" phpdoc somewhere with what the phpdoc parser considers generic tags
…ter validation on these.
Perhaps we could do more with this one by rector itself:
This class (which allowd extending classes by interface) does smart things with values. It also does stuff like mapping consts and such. Kinda worth exploring if we can maybe just hook into that for converting some. The code looked very interesting to structure the mapping. Those classes were made for doctrine itself. |
BTW want to mention, these three would've been automatable with this MR without any problem. All known properties. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Approving. The rule isn't configured and this allows using it for Drupal core improvements.
Description
Rule to convert Action annotation to Attribute https://www.drupal.org/node/3395575
To-do https://www.drupal.org/node/3229001
To Test
using with core and examples module
vendor/bin/rector --xdebug -c rector.php -n process modules_/examples/modules/action_example
Drupal.org issue
https://www.drupal.org/project/rector/issues/3265946