-
Notifications
You must be signed in to change notification settings - Fork 938
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] Implement reader using reflection #214
Conversation
Swagger-PHP used to work based on reflection. It was actually my 3rd pull request that switched it to static analyses :) But the PHP landscape has changed a lot since then, so maybe its time to revisit the reflection strategy. Option 1: new libI'd like you to work on swagger-php directly, but a separate library is certainly an option. Option 2: both
Option 3: reflection onlyI'd could be Loss aversion, but i'm not ready to ditch the parser just yet. Option 4: processorBuilding a ReflectionProcessor that uses ReflectionClass to determine inheritance and traits. Option 5: no reflectionFor traits and inheritance using purly static analysis swagger-php needs to create a worldview object that contains all annotations, all classes and traits and their relationships. I think the processors should then operate on this worldview object instead of an Swagger object. Closing thoughts.One of the swagger-php 2.x goals is to simplify the architecture/api/codebase. |
Split Parser in Analyser & StaticAnalyser see #214 Extracted logic from Swagger->crawl() into factory method `Swagger\buildFinder()`
Thanks for the comments. I'm not sure what "Needs complex logic to figure out traits and inheritance" means in the reflection cons list -- since there's actually no extra logic. The earlier issues the "Needs to executes arbitrary php code." comment refers to look nasty indeed. Though it seems they are related to buggy autoloader implementations rather than reflection directly. Composer has also been developed significantly since then. I've tested the annotation reader with a couple of large projects and noticed no problems (still anecdotal of course). In any case I'll refactor this PR to follow the |
a1c3536
to
d44d110
Compare
40008c5
to
3573667
Compare
- Add targets to all annotations - Allow autoloading - Fix test compatibility
3573667
to
debfbab
Compare
Basic refactoring is now done:
|
@@ -23,6 +23,7 @@ public function __invoke(Swagger $swagger) | |||
$definitions = $annotation->definitions; | |||
unset($annotation->paths); | |||
unset($annotation->definitions); | |||
$unmerged = array_merge($unmerged, $annotation->_unmerged); |
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.
There was a problem here: If the Swagger
annotation being merged also contained unmerged annotations, those annotations were lost. This is the quick single line fix.
The whole merging process seems quite brittle and may be going away anyway with the world view objects and what not, so I'm not sure if any additional effort should be spent here. I can at least add a test for this case though.
Allows a ReflectionAnalyser #214
Do you need help to finalize this or isn't this planned at all? I'd like to extend Swagger-php with custom annotations/processors to integrate it in Symfony but I currently can't without using my annotation's fqcn everytime as custom imports aren't detected. |
@GuilhemN A reflection based analyser is not going to help with custom annotations or processors. In the mean time you don't have to use the fqcn for every annotation, swagger tricks doctrine as if the file contains: You can for example add |
@bfanger sure that would help, even if the best would be to support the user imports (as everyone has his own habits).
Yes, I meant only when using custom annotations but that's already anoying. |
Looking forward to this "user imports" as a pull request 😉 |
@bfanger in fact it is already supported, I just had to add my namespace to |
This was kind of left in a limbo. For a while I tried keeping it compatible with other changes, but that was somewhat tricky. Then we pretty much stopped using Swagger-php, for the most part it was replaced with a library similar to the Symfony PropertyInfo component) + a custom writer, so I lost interest in this PR as well. I also wasn't quite sure how to proceed and what (if any) implementation might be an acceptable PR, and didn't bother to ask for clarification. In case there's interest for reviving this -- say, to help with #360 -- go for it. I might be able to contribute something to finish this as well, but can't promise anything. |
Intro
I have a use case where I'd like to use Swagger annotations in traits and I noticed that the parsing mechanism didn't support this. I thought using reflection to read the annotations would be easier anyway and this is what I came up with.
This PR contains an alternative, work in progress implementation of using reflection and Doctrine
AnnotationReader
to read the annotations instead of a token parser. It's not meant to be merged as is, but I wanted to get some feedback to decide how to proceed from here.How it works
To the user reading the annotations works pretty much the same as currently. With default options, it'd look something like this:
The new
Builder
andReader
classes can be customized with dependency injection as needed.Internally the build process works as follows:
Finder
.TokenParser
.AnnotationReader
to read class, method and property annotations from these files.AbstractAnnotation
object.Swagger
object.Swagger
object.Swagger
object.Steps 2 - 5 are mostly new, the rest are basically the same as using the current version.
Notes
FinderFactory
class was extracted fromSwagger
and is used by both build processes.Parser
class.Context
class, the annotations are wrapped inAnnotationContainer
objects that also contain the matching reflection object. The class reflection could also be accessed when processing method and property annotations if needed.AnnotationContainer
objects since token parsing is not needed in this case.The new reader has basic functionality, and produces correct results for the included examples (with some additions, included). There are currently incompatibilities between the reader implementations, but at least some of them can be solved with some additional development:
Context
class is effectively not used, the output from validation is not very useful.How to proceed
There's probably more to consider, but overall I think that there are three options:
AnnotationReader
could replace the current reader implementation entirely with some additional development. The immediate benefit would be trait support, but not having the ownParser
implementation would also mean a lot less code to maintain in the long run.In any case, I'm just looking for some overall thoughts at this point.