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

[POC] Add guessTypeForFieldDescription to TypeGuesserInterface #6839

Closed

Conversation

franmomu
Copy link
Member

@franmomu franmomu commented Feb 6, 2021

Subject

For a long description: #6701

Basically, in persistence bundles, to guess the type we have a call to a nonexistent ModelManagerInterface::getParentMetadataForProperty() which fetches the mapping for a property, the field description should have all the mapping information when is created, so it should be enough for guessing the right type.

I am targeting this branch, because this is BC.

Closes #6701.

Changelog

### Added
- Added `TypeGuesserInterface::guessTypeForFieldDescription()` method.
- Added `TypeGuesserChain::guessTypeForFieldDescription()` method.
### Deprecated
- Deprecate `TypeGuesserInterface::guessType()` method in favor of `TypeGuesserInterface::guessTypeForFieldDescription()`.
- Deprecate `TypeGuesserChain::guessType()` method in favor of `TypeGuesserInterface::guessTypeForFieldDescription()`.

To be honest I don't like the name, but I think there is no way to reuse guessType without breaking BC, any other idea is welcome.

The field description should have all the mapping information when
is created, so it should be enough for guessing the right type.
@franmomu franmomu added the minor label Feb 6, 2021
@VincentLanglet
Copy link
Member

GuessType($classOrFieldDescription, $property = null, $modelManager = null)

Couldnt this be a way to change from a signature to another with BC ?

@franmomu
Copy link
Member Author

franmomu commented Feb 7, 2021

GuessType($classOrFieldDescription, $property = null, $modelManager = null)

Couldnt this be a way to change from a signature to another with BC ?

Nope, It is not BC: https://3v4l.org/KZBXZ

Method parameter types are contravariant (only allow a more general argument).

@VincentLanglet
Copy link
Member

WDYT of GuessFieldDescriptionType ?

Or we can keep guessType if we make the Pr directly on master and document the BC break...

@SonataCI
Copy link
Collaborator

SonataCI commented Feb 9, 2021

Could you please rebase your PR and fix merge conflicts?

@wbloszyk
Copy link
Member

wbloszyk commented Feb 9, 2021

@VincentLanglet on line 43, Is it wrong - $guesser->guessers ?

public function __construct(array $guessers)
{
foreach ($guessers as $guesser) {
if (!$guesser instanceof TypeGuesserInterface) {
throw new UnexpectedTypeException($guesser, TypeGuesserInterface::class);
}
if ($guesser instanceof self) {
$this->guessers = array_merge($this->guessers, $guesser->guessers);

@VincentLanglet
Copy link
Member

@VincentLanglet on line 43, Is it wrong - $guesser->guessers ?

public function __construct(array $guessers)
{
foreach ($guessers as $guesser) {
if (!$guesser instanceof TypeGuesserInterface) {
throw new UnexpectedTypeException($guesser, TypeGuesserInterface::class);
}
if ($guesser instanceof self) {
$this->guessers = array_merge($this->guessers, $guesser->guessers);

If I understand correctly the guessers property is protected so it shouldn't work.
We should add a getGuessers() method instead. But it's not related to this PR.

@wbloszyk
Copy link
Member

wbloszyk commented Feb 9, 2021

If we wanna guess type only by one method then we should keep guessType() naming. Having guessTypeForFieldDescription() when you havent guessType() is not respecting KISS.
So can you do something like this:

public function guessType($fieldDescriptionOrDeprecaedClass, $deprecatedProperty, ModelManagerInterface $deprecatedModelManager)

@VincentLanglet
Copy link
Member

So can you do something like this:

public function guessType($fieldDescriptionOrDeprecaedClass, $deprecatedProperty, ModelManagerInterface $deprecatedModelManager)

It will still lead to BC break in 4.0.
User will have to change from guessType($fieldDescription, '', $modelManager) to guessType($fieldDescription).

If we want to avoid BC break we have to use a new method like guessFieldDescriptionType and deprecate the other.
If not, I think we could do this directly on master.

@wbloszyk
Copy link
Member

wbloszyk commented Feb 9, 2021

So can you do something like this:

public function guessType($fieldDescriptionOrDeprecaedClass, $deprecatedProperty, ModelManagerInterface $deprecatedModelManager)

It will still lead to BC break in 4.0.
User will have to change from guessType($fieldDescription, '', $modelManager) to guessType($fieldDescription).

If we want to avoid BC break we have to use a new method like guessFieldDescriptionType and deprecate the other.
If not, I think we could do this directly on master.

What is diffrence beetween?:

public function guessType($fieldDescriptionOrDeprecaedClass, $deprecatedProperty, ModelManagerInterface 
        $deprecatedModelManager) 
{
    if ($fieldDescriptionOrDeprecaedClass instaneof FieldDescription) {
        // call guessTypeForFieldDescription() which will be merge in master or write code diretly here 
        return $this->guessTypeForFieldDescription($fieldDescriptionOrDeprecaedClass);
    } // old code + trigger_errors
}

protected function guessTypeForFieldDescription(FieldDescription $fieldDescription) {}

and

public function guessType($class, $property, ModelManagerInterface $ModelManager) {}
public function guessTypeForFieldDescription(FieldDescription $fieldDescription) {}

@VincentLanglet
Copy link
Member

It's not about our implementation, it's about the developer who implement the interface and the developer who use the method.

When we're introducing a deprecation, the developer can update his code in order to fix the deprecation AND avoiding a BC break in 4.0.
Here you don't avoid the BC break.

If I need to use guessType, I'll do

guessType($fieldDescription, $deprecatedProperty, $deprecatedModelManager)

But in next major, I'll have to change my code to

guessType($fieldDescription)

And I cant do the change when using the 3.x branch.
Same if you implement the guessType method.

If the new signature was

guessType($classOrFieldDescription, $property = null, $modelManager = null)

I could do

guessType($fieldDescription)

in 3.x directly. But as explained by @franmomu this is a BC break.

Copy link
Member

@VincentLanglet VincentLanglet left a comment

Choose a reason for hiding this comment

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

Do you have some time to rebase @franmomu ?

And Wdyt of guessFieldDescriptionType instead ?

Maybe one day we will guess another Type, like a guessExportFieldType

@franmomu
Copy link
Member Author

Hey, sorry, I've been busy these days, I think I can continue this weekend.

And Wdyt of guessFieldDescriptionType instead ?

For #6761 I had something done and created a FieldDescription folder where all the FieldDescription* could eventually end up there, so creating something new could be a solution.

@VincentLanglet
Copy link
Member

For #6761 I had something done and created a FieldDescription folder where all the FieldDescription* could eventually end up there, so creating something new could be a solution.

I like this solution. And a field description folder is a nice idea.

@VincentLanglet
Copy link
Member

Closing in favor of #6854

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

Successfully merging this pull request may close these issues.

Guess type based on FieldDescriptionInterface
4 participants