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

Resolve collections from DocBlock #1214

Merged

Conversation

dgafka
Copy link
Contributor

@dgafka dgafka commented Jun 14, 2020

Q A
Bug fix? no
New feature? yes
Doc updated no
BC breaks? no
Deprecations? no
Tests pass? yes
Fixed tickets #1208
License MIT

There are few things worth discussion:

  1. What should happen, when incorrect DocBlock type is given?

    /**
    * @var \stdClass
    */
    public array $productIds;
    

Current implementation will throw exception, as above has no sense

  1. What should happen, when union type is given?

     /**
     * @var ProductName[]|ProductDescription[]
     */
    public array $productIds;
    

Current implementation will throw exception, as we will not know, which class should be used for deserialization.

  1. What should happen, when class does not exists?

     /**
     * @var NotExistingClass[]
     */
    public array $productIds;
    

Current implementation will throw exception as, this class will not be deserializable.

  1. If exception is thrown in any case of 1) and 2) 3) what exception type it should be?

Current implementation will throw \InvalidArgumentException

@dgafka dgafka changed the title resolve collections from doc block resolve collections from DocBlock Jun 14, 2020
@dgafka dgafka changed the title resolve collections from DocBlock Resolve collections from DocBlock Jun 14, 2020
@dragosprotung
Copy link
Contributor

Any chance to support also this format:

/**
 * @var array<ProductName>
 */
public array $productIds;

@dgafka
Copy link
Contributor Author

dgafka commented Jun 23, 2020

@dragosprotung yes, I can add it :)

@goetas can you deliver feedback about current implementation and answer above questions?
So I can know, if current behaviour is expected and continue with possible fixes. :)

Copy link
Collaborator

@goetas goetas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really like how this feature is progressing.

I did not review possible edge cases in the comment parsing, that would be done when we agree on the architecture of this feature.

In particular im interested in the feedback about implementing this feature as a new driver and implementing DriverInterface

phpcs.xml.dist Show resolved Hide resolved
src/Metadata/Driver/TypedPropertiesDriver.php Outdated Show resolved Hide resolved
src/Metadata/Driver/TypedPropertiesDriver.php Outdated Show resolved Hide resolved
@dgafka
Copy link
Contributor Author

dgafka commented Jul 10, 2020

@goetas Proposal of @dragosprotung is implemented.
This will be possible:

 /**
 * @var array<Product>
 */
private array $products;

To keep this compatible with JMS Serializer documentation this will also be possible:

 /**
 * @var array<string, Product>
 */
private array $products;

@dgafka
Copy link
Contributor Author

dgafka commented Jul 10, 2020

@goetas I would like to ask for review now.
There are 4 failing tests left, I am not able to fix them, as I don't understand why they fail. Can you check them out?

@dgafka dgafka requested a review from goetas July 10, 2020 17:32
@goetas
Copy link
Collaborator

goetas commented Jul 12, 2020

This looks great so far! I will try it in the next days/weeks and see if I can help with the failing tests

@dgafka
Copy link
Contributor Author

dgafka commented Aug 17, 2020

@goetas will you find time to check the tests? :)

@dgafka
Copy link
Contributor Author

dgafka commented Sep 4, 2020

@goetas can you tell, if you will find time for verifying tests?

I understand that you may have not enough time for it.
So please tell me, if you will not find the time, then I will try to fix it on my own :)

@goetas
Copy link
Collaborator

goetas commented Sep 17, 2020

I have tested this and looks great, but is seems that needs to be targeting a 4.0 release...

the issue is the following code that works as expected now, and is broken if we were going to merge this PR.

class User {
     /**
     * @var Country
     */
     private $country;

     public function __construct($country) 
     {
         $this->country = $country;
     }
}

$user = new User(new Car()); // yes we are passing a "car", not a country, it is not a typo

Even if the following code is "wrong", it works. A user will be serialized and in the "country" there will be serialized the car object.

If this PR gets merged, the serializer will try to traverse the "car" by using the props defined for "country".

This is not an uncommon scenario... immagine just how many docblocks might be not up to date in a project.... and now suddenly applications will start crashing.

With typed props this was not an issue is since PHP will do the check for us and tell the user that the code was wrong... but in our case there is no such check.

@goetas goetas added this to the v4.0 milestone Sep 17, 2020
@dgafka
Copy link
Contributor Author

dgafka commented Sep 21, 2020

This is understandable, you would like to avoid breaking change for current major release.

Should I leave the MR to you now and wait for 4.0 release? :)

@goetas
Copy link
Collaborator

goetas commented Sep 21, 2020

Should I leave the MR to you now and wait for 4.0 release? :)

@dgafka Sadly I have to say yes. The 4.0 is not yet planned but there are a couple of things I would like to place into it (but have no time to work on it....).

The only option I can see to have it in 3.x to make it opt-in, so who is interested can enable it and deal with potential bc breaks? What do you think? (i think it could be possible just by removing the instantiation of it from https://github.com/schmittjoh/serializer/pull/1214/files#diff-31d5d899bd07e7ac0794ccc1b0facdeaR64 and move it to the serializer builder).

Thanks a lot again for your great work!

@dgafka
Copy link
Contributor Author

dgafka commented Sep 21, 2020

@goetas I have added DocBlock Type Resolver as opt in feature, which by default is disabled. :)

You can enable it by using method setDocBlockTypeResolver on SerializerBuilder

builder->setDocBlockTypeResolver(true)

@dgafka
Copy link
Contributor Author

dgafka commented Oct 15, 2020

@goetas will we make it to 3.x after recent change? :)

@goetas
Copy link
Collaborator

goetas commented Oct 15, 2020

hi! sorry if it took that long, but I think that this is ready!

I was trying to use https://github.com/phpstan/phpdoc-parser to parse the docblocks, but I did not make it, will try again!

Thanks a lot for your work!

@goetas goetas merged commit 8d7113e into schmittjoh:master Oct 15, 2020
@dgafka
Copy link
Contributor Author

dgafka commented Oct 16, 2020

If I understand you were trying to replace the part which resolves the docblock types for an external library.
Plus of the current solution is less dependencies on the JMS\Serializer :)

Thank you for merging it :)

I am looking forward for next MR, in order to optimize deserializing process. I feel like version 3, had big impact on that as the times increased.
However that's a plan for a future, as I will need to understand the library deeper :)

@goetas
Copy link
Collaborator

goetas commented Oct 18, 2020

If I understand you were trying to replace the part which resolves the docblock types for an external library.
Plus of the current solution is less dependencies on the JMS\Serializer :)

yeah. the advantage of the other lib is that is fully tested and support very exotic syntaxes to express types (see PHPStan)...

I am looking forward for next MR, in order to optimize deserializing process.

Looking forward to it.

I feel like version 3, had big impact on that as the times increased.

did not know that... IMO should be faster than 1.x... but I might be wrong.

@goetas
Copy link
Collaborator

goetas commented Oct 18, 2020

However that's a plan for a future, as I will need to understand the library deeper :)

thanks again for this contribution

@simPod
Copy link
Contributor

simPod commented Nov 30, 2020

@dgafka how to enable DocBlockDriver?

@dgafka
Copy link
Contributor Author

dgafka commented Nov 30, 2020

@simPod
Copy link
Contributor

simPod commented Nov 30, 2020

I see. I'll have to do it differently if I use the sf bundle. Thanks.

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.

4 participants