-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[PropertyInfo] Add an extractor to guess if a property is initializable #26997
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
Conversation
a95d0a8
to
1f2103e
Compare
*/ | ||
public function isInitializable(string $class, string $property, array $context = array()): ?bool | ||
{ | ||
$this->assertIsString($class); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the point of this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added this for consistency with other methods, I'm not sure of the origin intent...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here is the original intent: #19437
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right. So type hints are added now so these checks are redundant
/** | ||
* Is the property initializable? | ||
*/ | ||
public function isInitializable(string $class, string $property, array $context = array()): ?bool; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the use-case for returning null
? Also, shouldn't we explicit within the method name that we are talking about the constructor in here? isInitializableViaConstructor
or something like that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
null
means "we don't know"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@teohhanhui is right. It means "this extractor cannot guess", try the next registered in the chain. It's mandatory to keep this behavior for consistency with existing interfaces and to provide an extension point.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@sroze I prefer the current name, isInitializableViaConstructor
is too verbose and brings nothing much.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My 2cts are that I didn't understand what isInitializable
meant before reading more about your PR. I can tell you that if I saw this interface I'd think "wait. What is that about?". While the isInitializableViaConstructor
clarifies it and is not too verbose.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wouldn't, the PhpDoc that you've put is enough (to me).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"Property initializable" on its own indeed makes no sense to me. Perhaps ConstructorInitializableExtractorInterface::isPropertyInitializable
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PropertyInitializableViaConstructorExtractorInterface::isInitializable
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess we could just stick with the current names. Lol...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me
if ($property !== $parameter->name) { | ||
continue; | ||
if ($property === $parameter->name) { | ||
return array($this->extractFromReflectionType($parameter->getType())); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what's the point of this change ? I know it does the same, but with a different style, but then ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removing 2 lines and making the code more explicit, but yes it's not mandatory.
return null; | ||
} | ||
|
||
if ($constructor = $reflectionClass->getConstructor()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why don't you test if the constructor is instantiable first?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good idea, I'll update the code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
interface PropertyInitializableExtractorInterface | ||
{ | ||
/** | ||
* Is the property initializable? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not sure this is useful :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's for consistency with other interfaces.
rebase needed (and some comments to address) |
88b2286
to
17cf6a1
Compare
rebased and comments addressed |
/** | ||
* Is the property initializable? | ||
*/ | ||
public function isInitializable(string $class, string $property, array $context = array()): ?bool; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My 2cts are that I didn't understand what isInitializable
meant before reading more about your PR. I can tell you that if I saw this interface I'd think "wait. What is that about?". While the isInitializableViaConstructor
clarifies it and is not too verbose.
fced167
to
6737e71
Compare
Rebased, I suggest to keep the current name as there are no consensus on another name. |
4.2.0 | ||
----- | ||
|
||
* added `PropertyInitializableExtractorInterface` to test if a property can be initialized through the constructor and an implementation is `ReflectionExtractor` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if a property can be initialized through the constructor (implemented by ReflectionExtractor
)
|
||
if ($constructor = $reflectionClass->getConstructor()) { | ||
foreach ($constructor->getParameters() as $parameter) { | ||
if ($property === $parameter->name) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The fact that the constructor parameter name must match the property one should be documented somewhere.
interface PropertyInitializableExtractorInterface | ||
{ | ||
/** | ||
* Is the property initializable? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is probably where we need more docs about the naming convention.
@dunglas Do you have time to have a look at my comments? |
d125f25
to
4a0483d
Compare
@fabpot done |
CI errors look unrelated. |
a8fb40e
to
9d2ab9e
Compare
Thank you @dunglas. |
… is initializable (dunglas) This PR was squashed before being merged into the 4.2-dev branch (closes #26997). Discussion ---------- [PropertyInfo] Add an extractor to guess if a property is initializable | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | yes | BC breaks? | no <!-- see https://symfony.com/bc --> | Deprecations? | no <!-- don't forget to update UPGRADE-*.md and src/**/CHANGELOG.md files --> | Tests pass? | yes <!-- please add some, will be required by reviewers --> | Fixed tickets | n/a <!-- #-prefixed issue number(s), if any --> | License | MIT | Doc PR | todo When dealing with value objects, being able to detect if a property can be initialized using the constructor is a very valuable information. It's mandatory to add a proper value object support in API Platform and in the Serializer component. See api-platform/core#1749 and api-platform/core#1843 for the related discussions, extended use cases and proof of concepts. This PR adds a new interface to guess if a property can be initialized through the constructor, and an implementation using the reflection (in `ReflectionExtractor`). Commits ------- 9d2ab9e [PropertyInfo] Add an extractor to guess if a property is initializable
This PR breaks the CI by breaking BC somehow, see deps=high failures (which mean that 4.1 is broken when using PropertyInfo master) |
(fixed in 5557e38, we'll have to deal with this kind of BC breaks now that we put DI passes in components and not in bundles anymore.) |
Thanks for the fix @nicolas-grekas |
I've created symfony/symfony-docs#10272 to document this new feature. Please, don't forget to create a doc issue for every new feature. Kévin, if you don't have time to contribute the docs, we'll need some code examples of using this feature in action. Thanks! |
…s initializable (dunglas, javiereguiluz) This PR was merged into the master branch. Discussion ---------- [PropertyInfo] Add an extractor to guess if a property is initializable symfony/symfony#26997 symfony/symfony#24571 Closes #10272. Commits ------- 8415f96 Minor tweaks eebca4a RST f7ed144 [PropertyInfo] Add an extractor to guess if a property is initializable
When dealing with value objects, being able to detect if a property can be initialized using the constructor is a very valuable information. It's mandatory to add a proper value object support in API Platform and in the Serializer component.
See api-platform/core#1749 and api-platform/core#1843 for the related discussions, extended use cases and proof of concepts.
This PR adds a new interface to guess if a property can be initialized through the constructor, and an implementation using the reflection (in
ReflectionExtractor
).