Skip to content
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

PHP 8.1 attributes #982

Merged
merged 13 commits into from
Nov 28, 2021
Merged

PHP 8.1 attributes #982

merged 13 commits into from
Nov 28, 2021

Conversation

DerManoMann
Copy link
Collaborator

@DerManoMann DerManoMann commented Aug 26, 2021

Sneak preview on attributes (requires PHP 8.1).

In fact, this is now the branch for swagger-php v4!

Feedback welcome!

So far:

  • bumps major version to 4.x
  • moved/renamed TokenAnalyserand Analyser
  • introduced a new ReflectionAnalyser and AnnotationFactoryInterface
  • introduced new AnalyserInterface implemented by both TokenAnalyser and ReflectionAnalyser
  • new annotation factories added: DocBlockAnnotationFactory and AttributeAnnotationFactory; ReflectionAnalyser can use either (or possibly both at the same time...)
  • updated all examples to pass with both token analyser and reflection analyser (using DocBlockAnnotationFactory)
    • this required adding classes to lots of stand-alone docblocks....
  • Updated some annotation classes to also work as \Attribute
  • Attribute based fixture intests/Fixtured/Apis/Attributes - this is on parity with the corresponding DocBlock example
  • Allow to mix attributes and annotations
  • Add PHP 8.1 to build matrix (latest deps only)

TODO:

  • add all supported properties as named ctor parameters to PHP 8.1 constructors
  • add more attribute based tests
  • things I've missed to far :)

@DerManoMann DerManoMann marked this pull request as draft August 26, 2021 23:32
@DerManoMann DerManoMann force-pushed the php81-attributes branch 2 times, most recently from c2d3782 to 65fde13 Compare August 26, 2021 23:43
@DerManoMann DerManoMann changed the title Php81 attributes PHP 8.1 attributes Aug 27, 2021
@DerManoMann
Copy link
Collaborator Author

Progress: The openapi-spec example now passed with all analysers!
https://github.com/DerManoMann/swagger-php/tree/php81-attributes/Examples/openapi-spec

Unfortunately the nested attributes have to be wrapped into a single line to be BC.

@Tobion
Copy link
Contributor

Tobion commented Sep 15, 2021

From what I see, you want to support both attributes and annotations? Wouldn't it be easier and better to just support attributes in the next major version?
To me, either you try to make attributes and annotations interchanable without bc break. Then there is no reason for a new major version. Or you create a new major version and then there is not need to support legacy annotations anymore.

@DerManoMann
Copy link
Collaborator Author

To me, either you try to make attributes and annotations interchanable without bc break. Then there is no reason for a new major version. Or you create a new major version and then there is not need to support legacy annotations anymore.

I think we do have a different understanding of semantic versioning. To me the version bump is justified by the big refactor of existing classes. I doubt that any downstream project using swaggger-php could update to this new code without some work.

Having a new major version doesn't mean we do have to abandon all annotation support. Considering that apparently people still use version 2 ;) I would expect lots of projects will have other priorities than updating annotations.
It also means regular users should be able to upgrade without issues and we do not have to maintain three main versions at the same time.

The way I see it anyone just using swagger-php via CL should be able to upgrade without pressure of migrating to attributes (which would require updating the project to PHP 8.1, no less).
Anyone using something like https://github.com/nelmio/NelmioApiDocBundle will be stuck with whatever that project does anyway and I do not expect those to drop annotation support quickly either.

Finally, being able to run both side by side (or mixed, which I think is possible) helps immensly with testing. There are a lot of tests that would not work using the new ReflectionAnalyser and migrating those will take some time. Right now I do not expect that to be fully done before this new version is released.

Beside all that I'd be still interested in actual feedback (testing, things missing, etc...)

@BusterNeece
Copy link
Contributor

Hey everyone! We're using this library in our main project and we're eager to get everything moved over to annotations, so I've started playing with this branch locally.

One problem I've found is that my IDE isn't type-hinting the attribute the way it does with the older annotation. I suspect that's because of the conditional class definitions for the parent classes, where they're only defined as attributes if the PHP version is >= 8.0.

I'm not sure that there's really any simple workaround for this besides just making a version of the library that requires PHP 8.0 or greater and that leans fully into the attribute support, leaving the annotations for older versions of the library. I'm personally not opposed to that idea at all.

@DerManoMann
Copy link
Collaborator Author

Hey everyone! We're using this library in our main project and we're eager to get everything moved over to annotations, so I've started playing with this branch locally.

One problem I've found is that my IDE isn't type-hinting the attribute the way it does with the older annotation. I suspect that's because of the conditional class definitions for the parent classes, where they're only defined as attributes if the PHP version is >= 8.0.

I'm not sure that there's really any simple workaround for this besides just making a version of the library that requires PHP 8.0 or greater and that leans fully into the attribute support, leaving the annotations for older versions of the library. I'm personally not opposed to that idea at all.

Thanks for doing some testing - that is much appreciated.

What kind of type hinting are you missing exactly?
If I set language support to PHP 8.1 in PHPStorm I do get support for the available named parameters.

What I do not get (but that is not related to the PHP version) is type hints for the values unless they are strings due to how the library uses Generator::UNDEFINED see #931.
I am sure we'll get there at some point...

@DerManoMann DerManoMann force-pushed the php81-attributes branch 4 times, most recently from c0a8354 to 1c7334f Compare October 31, 2021 22:43
@DerManoMann
Copy link
Collaborator Author

@SlvrEagle23 I've added some more type hints to the 8.1 named attributes - could you guy have a look and see if that helped things?

Also, those are only enabled with PHP 8.1, not 8.0 as some attributes really require nesting...

Anything else, just let me know; I know there are some named properties in the attribute constructors still missing - if you find any please let me know ( or any other issues, for that matter)

@BusterNeece
Copy link
Contributor

So, I keep a pretty close eye on the PHP internals and I haven't actually seen anything at all about allowing nested attributes in PHP 8.1, and I looked through the approved RFCs and found nothing of the sort either.

It's entirely possible I'm missing something, though. I'd certainly love to see it implemented in 8.1 but I'm not seeing any evidence at the moment that it's coming down the line.

@DerManoMann DerManoMann force-pushed the php81-attributes branch 2 times, most recently from 186a20b to 0defe59 Compare November 14, 2021 20:44
@DerManoMann DerManoMann force-pushed the php81-attributes branch 4 times, most recently from 2abc08b to 780a65a Compare November 22, 2021 21:28
@DerManoMann DerManoMann marked this pull request as ready for review November 24, 2021 03:50
Also prepare for usikng the `Generator` in place of the current static config properties
This makes the `Generator` class the authority about whitelisted annotation
namespaces. A value of `null` is interpreted as wildcard.

Registers a new loader for each `Generator` instance. A new method
`withContext()` was also added to allow to run custom code in the context
of a configured `Generator`.
Shortcut version of `Parameter(in='path', required: true)`.

In addition to that it can be used as method parameter attribute. In that case the name
and (optiona) type-hint are automatically configured.

Example:
```
public function getProduct(#[OA\PathParameter] string $product_id) {
   // ...
}
```

Same as:
```
/**
 *   @OA\PathParameter(
 *     name="product_id",
 *     @OA\Schema(type="string")
 *   )
 */
```
The legacy `TokenAnalyser` can be used by specifying the `--legacy` (`-l`) option.
@DerManoMann DerManoMann merged commit dd5f1b7 into zircote:master Nov 28, 2021
@DerManoMann DerManoMann deleted the php81-attributes branch November 28, 2021 00:58
@itsjavi
Copy link

itsjavi commented Dec 11, 2021

@DerManoMann as reported here, due to the duplication of classes, PHPStorm 2021.2.3 is not able to find the attribute ones

Screenshot 2021-12-11 at 01 26 40

If I comment out the Annotation class and leave the Attribute one, all it's fine:

Screenshot 2021-12-11 at 01 27 12

Wouldn't it be better to define the attributes in a new namespace, for better IDE compat.?

@DerManoMann
Copy link
Collaborator Author

Honestly, I do not know why that would be. I have a project using 4.0.4 attributes and that is fine.

I do get a message about multiple implementations but that is it. Again, the configured language level might make a difference.

I do agree that a separate namespace would be nice. In fact, that is how I started. Unfortunately, some fo the internals do check for explicit class names to verify allowed parent/child relationships and that would have been a major pain.

@itsjavi
Copy link

itsjavi commented Dec 11, 2021

@DerManoMann I have the target language as php 8.1. It might be just a phpstorm issue, but anyway having duplicated class names is always tricky because it may get other analysis tools "confused" as well.

thanks for the effort in this PR anyway

@DerManoMann
Copy link
Collaborator Author

Thanks @itsjavi; also apologies for avoiding more work :)

Happy to say that in light of #1021 I've started looking into a potential split... Turns out some very early iteration had some code to deal with different namespaces for attributes/annotations already - I just thought that never made it into the real PR but it seems I was wrong :)

So, chances are the change might not be too bad after all.

@rustamwin
Copy link

Why not 8.0?

@DerManoMann
Copy link
Collaborator Author

Why not 8.0?

Except for simple attributes there is some nesting required with using new ... and that is only available in 8.1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants