-
-
Notifications
You must be signed in to change notification settings - Fork 431
[PHP 8.4] Add PropertyHookRector (optional) #7498
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
Conversation
02658a0 to
aa9c9a6
Compare
c8dd7ee to
2213fbc
Compare
2213fbc to
8232722
Compare
703e077 to
e34e37a
Compare
...ests/Php84/Rector/Class_/DeprecatedAnnotationToDeprecatedAttributeRector/Fixture/fixture.php
Outdated
Show resolved
Hide resolved
d52a9ef to
8b1ace2
Compare
samsonasik
left a comment
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.
This need test for readonly property which should be skipped.
property hook seems remove readonly flag based on the transformation.
c06c135 to
d42b9d5
Compare
👍 |
samsonasik
left a comment
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.
If class->isReadonly(), all properties become readonly, so seems should be skipped as well.
|
@samsonasik What if there is only getter property hook? |
|
@TomasVotruba that will error, see https://3v4l.org/aQhYo#v8.4.12 |
|
@samsonasik I see 👍 |
| if ($node->getProperties() === []) { | ||
| return null; | ||
| } | ||
|
|
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.
this should check if there is promoted property that is readonly, eg:
$constructClassMethod = $node->getMethod('__construct');
if ($constructClassMethod instanceof ClassMethod) {
foreach ($constructClassMethod->params as $param) {
// readonly param must be promoted property already, and can't have property hook
if ($param->isReadonly()) {
return null;
}
}
}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.
I'm not sure if promoted properties should be covered, as those are usually set in the constructor.
If we change it to property hook, it will start look rather messy. Property will become non-promoted and constructor full of assings. I want to skip these.
Before:
final class SomeClass
{
public function __construct(
private int $value,
)
{
}
public function getValue()
{
return $this->value;
}
}After:
final class SomeClass
{
public int $value {
get => $this->value;
}
public function __construct(int $value)
{
$this->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.
What I mean if there is another readonly promoted property, it should be skipped as well, same behaviour with normal readonly property.
I will create PR to skip mixed existing property with readonly promoted property.
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.
@TomasVotruba I created new PR to skip if class has:
-
normal property
-
readonly promoted property
0366b86 to
448163f
Compare
|
Let's kick of first version, to try and iterate 👍 |
Closes rectorphp/rector#9152
final class Product { - private string $name; + public string $name { + get { return $this->name; } + set { $this->name = ucfirst($value); } + } - - public function getName(): string { - return $this->name; - } - - public function setName(string $name): void { - $this->name = ucfirst($name); - } }Changing getters/setters to property hooks may have alter behavior, if the class is extended and uses getter, see https://3v4l.org/HIHXs
That's why it runs safely on
finalclasses only.If you're confident there is close to zero of such cases, you can enable option to run on non-final classes too: