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

Use normal Collection<ClassName> when property has indexBy #359

Merged
merged 3 commits into from
Dec 20, 2024

Conversation

samsonasik
Copy link
Member

Avoid using <int> index when property has indexBy.

Fixes rectorphp/rector#8791
Fixes #357

@samsonasik
Copy link
Member Author

Fixed 🎉 /cc @AlexeyKosov @yguedidi

@samsonasik samsonasik changed the title Use normal array<Collection> when property has indexBy Use normal Collection<Object> when property has indexBy Dec 20, 2024
@samsonasik samsonasik changed the title Use normal Collection<Object> when property has indexBy Use normal Collection<ClassName> when property has indexBy Dec 20, 2024
@samsonasik
Copy link
Member Author

All checks have passed 🎉 @TomasVotruba I am merging it ;)

@samsonasik samsonasik merged commit 22bc264 into main Dec 20, 2024
6 checks passed
@samsonasik samsonasik deleted the fix-indexby branch December 20, 2024 15:27
@yguedidi
Copy link
Contributor

Thanks @samsonasik !!
Maybe better to detect the type of the indexed by referenced property, and put either int or string as collection key type?

@samsonasik
Copy link
Member Author

@yguedidi that's will be too much lookup :), using Collection<ClassName> is just fine for it

@yguedidi
Copy link
Contributor

Then maybe at least skip changing if there is already an index in the type?

@samsonasik
Copy link
Member Author

that will be too much for that :)

@yguedidi
Copy link
Contributor

@samsonasik the thing is that I don't want Rector to change my Collection<string, ClassName> to Collection<ClassName> 😅

@samsonasik
Copy link
Member Author

Feel free to skip the rule.

private $trainings = [];

/**
* @return \Doctrine\Common\Collections\Collection<\Rector\Doctrine\Tests\CodeQuality\Rector\Class_\AddReturnDocBlockToCollectionPropertyGetterByToManyAnnotationRector\Source\Training>
Copy link
Member

Choose a reason for hiding this comment

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

Both values have to filled Collection<key, value>, as first is key, next is value, see:

https://github.com/doctrine/collections/blob/2790cb57e6510e4404873bdca6688e447550d720/src/Collection.php#L29-L30

Copy link
Member Author

Choose a reason for hiding this comment

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

per @AlexeyKosov at issue rectorphp/rector#8791 (comment)

the key is not necessarily need to be defined, we use \Doctrine\Common\Collections\Collection<ClassName> too in our project, and working well.

Copy link
Member

Choose a reason for hiding this comment

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

That doesn't respect the parent interface contract:

should have the Collection<string, Training> type rather than Collection<int, Training>.

Screenshot from 2024-12-21 09-49-00

Both key and value should be included.

Copy link
Member Author

@samsonasik samsonasik Dec 21, 2024

Choose a reason for hiding this comment

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

I think for win win solution, skip php doc change is better if there is indexBy key, since lookup target class -> property type defined by indexBy may or may not work.

I will create new PR

Copy link
Member Author

Choose a reason for hiding this comment

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

@yguedidi
Copy link
Contributor

Feel free to skip the rule.

I know it's possible, but I find it weird that Rector will break a more precise type (the one with key type define), and in order to avoid that, we have to make our config more complex to maintain by adding a skip configuration (either full rule, either specific to few files)
I think, as a general behavior, rectors shouldn't degrade existing type definitions if they are more precise than what the rectors changes are capable of

@samsonasik
Copy link
Member Author

It only change when it has unioned type as far as I see: @var Collection|Training[] -> @var Collection<Training>

@yguedidi
Copy link
Contributor

in my case I have something like

    /**
     * @var Collection<string, Training>
     */
    #[ORM\OneToMany(targetEntity: Training::class, indexBy: "id", mappedBy: "trainer")]
    private Collection $trainings;

that got transformed to

    /**
     * @var Collection<int, Training>
     */
    #[ORM\OneToMany(targetEntity: Training::class, indexBy: "id", mappedBy: "trainer")]
    private Collection $trainings;

@samsonasik
Copy link
Member Author

@yguedidi that's correctly skipped, see PR fixture

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