-
-
Notifications
You must be signed in to change notification settings - Fork 224
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
Update getReference phpdoc #482
base: 1.7.x
Are you sure you want to change the base?
Conversation
* | ||
* @param string $name | ||
* @psalm-param class-string<T>|null $class | ||
* | ||
* @return object | ||
* @return T|object | ||
* @psalm-return ($class is null ? object : T) |
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.
Is psalm-return
taken into account by PHPStorm? I'm asking because I don't think having just the information that this method returns T
or any object
is good enough to propose auto-completion.
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.
No, PhpStorm does not take the psalm-return
annotation into account.
However, I can confirm that adding T|object
in the @return
annotation enables auto-completion.
It must certainly interprets the psalm-param
annotation, which indicates that T is an instance of a specific object.
Additionally, I think we can migrate the @psalm-param class-string<T>|null $class
annotation to the native @param class-string<T>|null $class
annotation. What do you think?
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.
Ok, so let's say T in that instance is … YourClass
. Why does PHPStorm enable auto-completion on YourClass|object
? It is equivalent to just object
, isn't it?
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 I fully understand your last message.
If we just put @return object
, it refers to the primitive type Object, which can correspond to any object
.
Whereas T
refers to the type that is created by the "generics" brought with the @template
, indicating that T
is an instance of $class
, so the correct return type is T
.
However, we have to keep T|object
because the parameter $class
is not required at the moment.
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 know what T
refers to, I know what object
refers to as well, but it seems, you and Phpstorm disagree with me and Psalm/PHPStan as to what T|object
means. I don't think it means "instance of T
and instance of object
". To me, that's T&object
, which… is just T
. Likewise, T|object
can IMO be simplified to just object
.
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 don't claim to be an expert on this, but it fix the auto-completion in PHPStorm (I don't have colleagues using VSCode or other popular code editor to test this fix).
Here are some resources:
- https://phpstan.org/blog/generics-in-php-using-phpdocs#class-names
- https://phpstan.org/blog/generics-by-examples#accept-a-class-string-and-return-the-object-of-that-type
- https://psalm.dev/docs/annotating_code/templated_annotations/
We have a very large project (around 6000 getReferences to migrate) and I think it's a shame to have to add the $class
parameter (which, by the way, is a very good idea) without having a type-hint in return.
IMO when $class
becomes required, the return type would be @return T
.
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 an expert on PHPStorm either, I don't use it, that's why I'm asking why it behaves like that, I don't know. I recall in the distant past, Collection|User[]
was used at some point to mean Collection<User>
because IDEs only understood |
and not &
, but would expect this to be fixed by now. So IMO you should file 2 PHPStorm bugs:
- It should no longer interpret
|
as&
- It should add support for
@psalm-return ($class is null ? object : T)
BTW, maybe it already understands that syntax, but ignores it because it's @psalm-return
and not return
? Can you check?
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've just tried several combinations (with only @return
or only @psalm-return
) but nothing changes 😞
However @return T&object
works very well.
Here's a new proposal for phpdoc :
/**
* Loads an object using stored reference named by $name
*
* @param class-string<T>|null $class
*
* @return T&object
* @psalm-return ($class is null ? object : T)
*
* @throws OutOfBoundsException - if repository does not exist.
*
* @template T of object
*/
Note that the @psalm-param
has been changed to @param
because I don't think it's necessarily specific to psalm.
What do you think?
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 think T&object
is completely wrong. For instance, when $class
is null
, there is no guarantee to get T
.
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.
Yes, I completely agree with you ! T&object
is wrong when $class
is null
.
I took some time to test and I realize that PHPStorm seems to have trouble interpreting the conditional return of the psalm-return
annotation, especially with generics (if I replace T
with bool
in the psalm-return
, it understands bool|object
).
I'll open an issue with PHPStorm after my vacation.
Do you think @return T|object
is acceptable or not ? This annotation is not entirely true because it lacks precision, but it is not wrong because the method return either an instance of T
or an object
for which we cannot determine the type when the $class
parameter is not provided.
Fix of the PHPDoc for the getReference method to allow code editor such as PhpStorm (and probably others) to correctly understand that the return of the method is an instance of $class and not any object.
Without this fix, PhpStorm cannot autocomplete the methods of the object retrieved by the getReference method, and with this proposal, it works.