Skip to content

Annotations refactoring & PHP 8 Attributes #801

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

Merged
merged 27 commits into from
Jan 19, 2021
Merged

Annotations refactoring & PHP 8 Attributes #801

merged 27 commits into from
Jan 19, 2021

Conversation

Vincz
Copy link
Collaborator

@Vincz Vincz commented Jan 2, 2021

Q A
Bug fix? no
New feature? yes
BC breaks? no
Deprecations? yes
Tests pass? yes
Documented? partly
Fixed tickets #707

@murtukov
Copy link
Contributor

murtukov commented Jan 2, 2021

I thought we are gonna discuss it in January first

@Vincz
Copy link
Collaborator Author

Vincz commented Jan 2, 2021

I thought we are gonna discuss it in January first

@murtukov We will. I had a bit of free time and I just wanted to implement the PHP 8 attributes and try to clean the annotations code base (also based on #707). But everything is still open to discussion.

@Vincz
Copy link
Collaborator Author

Vincz commented Jan 2, 2021

@mcg-web Hey man!
I have a couple of issues with php stan as you can see here : https://github.com/overblog/GraphQLBundle/pull/801/checks?check_run_id=1637669155

I have a bunch of missing type hints but I'm not sure how to handle them when a parameter can accept multiple types (string or array for example).
Also, there is a bunch of issue related to PHP 8 (PHP stan does not know some classes or methods specifics to PHP8). Not sure how to handle this as well.
Could you help me with this?

@Vincz
Copy link
Collaborator Author

Vincz commented Jan 3, 2021

@mcg-web Another problem is with the test coverage. As the PHP 8 attribute parser tests only run with PHP8, the coverage drops when used with PHP 7.

@mcg-web
Copy link
Contributor

mcg-web commented Jan 4, 2021

Hey @Vincz !

I have a bunch of missing type hints but I'm not sure how to handle them when a parameter can accept multiple types (string or array for example).

you should use phpdoc right now since union is available only for php >= 8.0

/**
* @param string|array $myArg
*/
function ($myArg) {}

Another problem is with the test coverage. As the PHP 8 attribute parser tests only run with PHP8, the coverage drops when used with PHP 7.

we can try using php 8.0 for coverage tests

@Vincz
Copy link
Collaborator Author

Vincz commented Jan 6, 2021

Ok guys, this PR is almost ready.
I still need to update the documentation.
Trying to make a chinese panda happy, all features from #707 have been implemented (except the 'get' removal from queries).

  • The nested annotations have been deprecated in favor of a flat config.
  • We now have a type guesser based on doc block @var and @return
  • PHP8 attributes are supported.
  • We have shortcuts on annotations (ex: @Field('myfield')) - I'm not satisfied with the implementation but I'm waiting for this PR Introduced annotation NamedArgumentConstructor doctrine/annotations#391 to be merged, so I can submit another one to handle default property on annotation, so we can use more explicit configuration property instead of value.

We would need to be able to run tests in a PHP8 environment to support attributes (at the moment tests related to attributes are skipped if not in PHP8).
Some config keys have been renamed for builders so it's a BC break (is that ok if we targeting v1.0 with this new features or should I provider Backward compatibility).

Let me know what you think!

@Vincz
Copy link
Collaborator Author

Vincz commented Jan 12, 2021

Hey @murtukov! I'm trying to run the test on Github with PHP 8 (see my latest commit).
It failed because of the PHP Generator library. Do you know if it is compatible with PHP 8 and if so, would you mind to update the composer to allow it?
Thanks man!

@murtukov
Copy link
Contributor

murtukov commented Jan 12, 2021

@Vincz just released a new version of PHPCodeGenerator. Change the composer requirement to 0.1.5

@Vincz
Copy link
Collaborator Author

Vincz commented Jan 12, 2021

@Vincz just released a new version of PHPCodeGenerator. Change the composer requirement to 0.1.5

Thank you!

@Vincz
Copy link
Collaborator Author

Vincz commented Jan 12, 2021

@murtukov It break the PHP 7 tests, because:

➜  ~ $ echo '<?php new flu(); ?>' | php
PHP Fatal error:  Uncaught Error: Class 'flu' not found in Standard input code:1

but...

➜  ~ $ echo '<?php new flu(); ?>' | php8
PHP Fatal error:  Uncaught Error: Class "flu" not found in Standard input code:1

@murtukov
Copy link
Contributor

@Vincz well if both approaches use almost the 100% same codebase, then let it be a single bundle 🙂

One thing I don't understand is why removing shorthands? As I know the Symfony's Router uses both annotations and attributes with a single class and it's still possible to use shorthands. Why can't we do the same?

Here is the implementation: https://github.com/symfony/routing/blob/5.x/Annotation/Route.php

@murtukov murtukov added the wip label Jan 14, 2021
@Vincz
Copy link
Collaborator Author

Vincz commented Jan 14, 2021

@murtukov Yes, at the end it was exactly the same: Metadata stored on a PHP classes, but the exploitation of this metadata is the same. So there is just a very few differences than we can handle in the parser itself.

I removed the shorthands for now, cause I didn't like the implementation. The current route annotation use the "old" way to setup the annotation. It takes the parameters from an array in the first argument of the constructor. So there is no argument validation by the annotation system. So, they introduce the NamedArgumentConstructor to ease the migration to attribute. But the Symfony team is also planning to use the "new" way (see doctrine/annotations#391).
I'll put them back as soon as we have the ability to set a default property other than value in annotations. It should not be a problem to add it later as there will be no BC break. I also wanted to rename a bunch of properties for more explicit names, like expression instead of value in @Access or @Public for example.
To handle it, I was adding a value property to the constructor to handle the default and use it's value as the value of my default property. But I had to raise an exception if both where used and I had to mark required properties as nullable and I didn't liked it.
But the shorthand works with attributes as long as the arguments order is correct. It's just a constructor call with named arguments.

@Vincz
Copy link
Collaborator Author

Vincz commented Jan 14, 2021

@murtukov About the tests, the coverage drops because the attributes tests are skipped.
What do you think we should do about it? Should we update the coverage environment to use PHP 8?

@Vincz
Copy link
Collaborator Author

Vincz commented Jan 14, 2021

Well... The tests with coverage in PHP8 is ok, but the coverage upload to scrutinizer fails.

@murtukov
Copy link
Contributor

@Vincz seems like switching to PHP 8 environment is the only solution

@Vincz
Copy link
Collaborator Author

Vincz commented Jan 14, 2021

@mcg-web Hey man! Any idea what the coverage upload would fail? I don't want to mess with the ci tasks so I didn't try to fix it myself...

@murtukov
Copy link
Contributor

@Vincz I don’t know, I never configured GitHub workflows. Try setting the PHP version to “8.0” instead of just “8”

@Vincz
Copy link
Collaborator Author

Vincz commented Jan 15, 2021

Ok, so the problem is ocular (the binary to upload the coverage) downloaded from the scrutinizer website is an old version (see scrutinizer-ci/ocular#53).
The solution seems to install it as a composer dependency.

- name: "Install Ocular as depencies"
   run: composer req "scrutinizer/ocular" --dev --no-update

I tried, it installs fine, but I'm unable execute it, no matter the syntax I use (the binary is stored in vendor/bin/ocular)
I tried the following:

run: php vendor/bin/ocular code-coverage:upload --format=php-clover build/logs/clover.xml

run: vendor/bin/ocular code-coverage:upload --format=php-clover build/logs/clover.xml

run: ./vendor/bin/ocular code-coverage:upload --format=php-clover build/logs/clover.xml

But none of them worked and the binary is not found. Seems like a context problem.
ping @mcg-web

Fix the path to Ocular
@murtukov
Copy link
Contributor

murtukov commented Jan 15, 2021

@Vincz the path is fixed and seems to work now. Just need to add/ignore some test coverages.

P.S. Could you register in Telegram for quick contacts? Slack is too heavy and imperfect for this.

@Vincz
Copy link
Collaborator Author

Vincz commented Jan 15, 2021

@murtukov You're the best! I'll check the missing tests.
I just registered to Telegram and sent you an email with my account details.

@murtukov murtukov changed the title [WIP] Annotations refactoring & PHP 8 Attributes Annotations refactoring & PHP 8 Attributes Jan 15, 2021
@murtukov murtukov removed the wip label Jan 15, 2021
@murtukov murtukov merged commit 070b804 into overblog:master Jan 19, 2021
@murtukov murtukov linked an issue Jan 20, 2021 that may be closed by this pull request
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.

[RFC] Improve annotations
3 participants