Skip to content

Convert ClassMetadata::getFieldValue/setFieldValue from @method to real interface methods#513

Open
GromNaN wants to merge 1 commit into
doctrine:5.0.xfrom
GromNaN:make-get-set-field-value-real-methods
Open

Convert ClassMetadata::getFieldValue/setFieldValue from @method to real interface methods#513
GromNaN wants to merge 1 commit into
doctrine:5.0.xfrom
GromNaN:make-get-set-field-value-real-methods

Conversation

@GromNaN
Copy link
Copy Markdown
Member

@GromNaN GromNaN commented Apr 27, 2026

Closes #451

@param T $entity is used on both methods even though T is declared covariant. This is intentional( the methods only make sense for the mapped entity type) but it violates strict generic variance rules. PHPStan warnings are suppressed with @phpstan-ignore generics.variance.

Open question: should @template-covariant T be relaxed to @template T (invariant) to model this more accurately? That would be a breaking change for downstream type annotations.

@GromNaN GromNaN changed the base branch from 4.2.x to 5.0.x April 27, 2026 08:11
@GromNaN GromNaN added this to the 5.0.0 milestone Apr 27, 2026
Comment thread src/Mapping/ClassMetadata.php Outdated
*
* @param T $entity
*
* @phpstan-ignore generics.variance (T in parameter position is intentional: the method only makes sense for the mapped entity type)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

T in parameter position requires the generic to be invariant. So we should indeed change it.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

The parameter $object is typed as object rather than T. The interface declares @template-covariant T of object, meaning ClassMetadata<Cat> is a subtype of ClassMetadata<Animal>. Covariance requires T to appear only in return (output) positions. Using @param T $object would place T in a parameter position, violating that constraint.

I can't change to @template T, it's creating more issues with the child classes.

@GromNaN GromNaN force-pushed the make-get-set-field-value-real-methods branch 2 times, most recently from bf96d1c to 2349c76 Compare April 30, 2026 18:24
Copy link
Copy Markdown
Member Author

@GromNaN GromNaN left a comment

Choose a reason for hiding this comment

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

Now I understand how covariance works for this class.

/**
* Gets the value of the given field of the given object.
*
* @throws InvalidArgumentException if the object is not supported, or the field is not mapped.
Copy link
Copy Markdown
Member Author

@GromNaN GromNaN Apr 30, 2026

Choose a reason for hiding this comment

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

I also added @throws InvalidArgumentException to document the contract when $object is not of the expected type or $field is not mapped. Currently the ORM and ODM implementations don't throw an exception, but that would be an improvement when upgrading to persistence v5

Comment thread src/Mapping/ClassMetadata.php Outdated
*
* @param T $entity
*
* @phpstan-ignore generics.variance (T in parameter position is intentional: the method only makes sense for the mapped entity type)
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

The parameter $object is typed as object rather than T. The interface declares @template-covariant T of object, meaning ClassMetadata<Cat> is a subtype of ClassMetadata<Animal>. Covariance requires T to appear only in return (output) positions. Using @param T $object would place T in a parameter position, violating that constraint.

I can't change to @template T, it's creating more issues with the child classes.

@GromNaN GromNaN force-pushed the make-get-set-field-value-real-methods branch from 2349c76 to e67b1d6 Compare April 30, 2026 20:16
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.

3 participants