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
Improving support for anonymous classes #2613
base: master
Are you sure you want to change the base?
Conversation
lib/WorseReflection/Core/Inference/Resolver/ObjectCreationExpressionResolver.php
Show resolved
Hide resolved
} | ||
|
||
if ($child instanceof ObjectCreationExpression) { | ||
// TODO: come up with a good way to generate a class name |
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.
We need a better way to generate class names as the code is currently duplicated everywhere.
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.
PHPStan does it like this: https://github.com/dantleech/phpstan-src/blob/f7b89d47cfa1fa636fb571b4315841a9af0e976f/src/Broker/AnonymousClassNameHelper.php#L22-L25
but I don't think this is the correct place to do it.
We can create the reflection class in the resolver?
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.
Yeah, technically using the line number is not 100% garanteed to be unique but who has two anon classes on the same line. :D
But what you mean with "creating the reflection class in the resolver"? I wanted to try to avoid making a ReflectionAnonymousClass
class as anon classes should be the same except for their weird name.
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 you are right. A different approach for this would probably make more sense but that would require a lot of refactoring as the fromNode
function is used quite a lot.
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 think it needs refactoring and would also fix the issue Thomas raised below, but would need to show an example.
lib/WorseReflection/Core/Inference/Resolver/ObjectCreationExpressionResolver.php
Outdated
Show resolved
Hide resolved
lib/WorseReflection/Core/Reflection/Collection/ClassLikeReflectionMemberCollection.php
Outdated
Show resolved
Hide resolved
lib/WorseReflection/Core/Inference/Resolver/ObjectCreationExpressionResolver.php
Outdated
Show resolved
Hide resolved
f8c99ee
to
8e24b48
Compare
4235fc4
to
f32ad1b
Compare
From #2612 perspective this seems to be one step ahead but: |
What were you trying to do? Generate a class? |
"Implement contracts" like in #2612 |
Now it should work (at least the test for it is green) and it looks like the rest broke. |
681f9c8
to
7a53a6b
Compare
lib/WorseReflection/Core/Reflection/Collection/ClassLikeReflectionMemberCollection.php
Outdated
Show resolved
Hide resolved
continue; | ||
} | ||
|
||
if ($child instanceof ObjectCreationExpression && !($child->classTypeDesignator instanceof Node)) { |
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 may cause unexpected issues. "reflect classes in" reflects locatable symbols and also it should not need to deeply traverse the AST.
we could consider removing this and instead adding support to $reflector->reflect{Node,AnnonymousClass,Object}($node)
for example.
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.
The problem is this approach won't find all classes anyways. Because we actually have to traverse into class definitions as well. Otherwise we would miss anonymous classes inside other classes. But I don't have an idea how to do improve performance here.
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, they need probably to be interpreted inline as types as with the above comment. doing this will mean that "implement contracts" will not automatically work, but at the same time it's only working because of the cache effect in this PR
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 just saw that reflectClassesIn
should probably better be named reflectClassLikeIn
'cause it also returns interfaces enums etc. which are completely irrelevant for the "Implement contracts". But that's not a problem of this PR.
However I get what you're saying, I'm not sure if its based on cache in this situation because the source code builder reflects the same structure again and should also build the same list of ClassLike
nodes. On the other hand I'm quite familiar with the concept of inline types and how I would go about and implement this. Do we already have an example for this?
b7acb99
to
da577f9
Compare
At the moment I have no occasion to work with anonymous classes, but have merged the recent version of this PR into my experimental branch and can report possible side effects. |
just to be clear, it's unlikely to be merged with it's current implementation. but hopefully I can find some time to look more into it. |
Things that have been done
Limitations: