Problem/Motivation
We are encouraged to use the DrupalDateTime and DrupalDateTime classes as best practice. Those class implements rely on magic methods to access the DateTime methods via a proxy pattern. IDE's are not very good inspecting and code completion in this situation.
Proposed resolution
Add a PhpDoc section to the class with @method statements to reflect the proper type signature for magic methods proxied to the protected \DateTime object.
Remaining tasks
Finish it.
User interface changes
None.
API changes
None.
Data model changes
None.
| Comment | File | Size | Author |
|---|---|---|---|
| #23 | document_magic_methods-2902707-23.patch | 1.08 KB | gambry |
| #22 | Screen Shot 2017-10-30 at 5.41.23 PM.png | 163.06 KB | mpdonadio |
| #20 | interdiff-13-20.txt | 2.7 KB | mpdonadio |
| #20 | 2902707-20.patch | 2.25 KB | mpdonadio |
| #13 | 2902707-13.patch | 1.19 KB | jofitz |
Comments
Comment #2
mpdonadioI'm in favor of this; I find magic methods very annoying in an PhpStorm. Do we do this anywhere else in core? Unfortunately \DateTime doesn't implement an interface, so we would be duplicating that and have the potential for getting out of sync.
Comment #3
jaykandariPicking
Comment #4
mpdonadioEr, just re-read #2. \DateTime implements \DateTimeInterface, but only really as a way to have interoperability with the \DateTimeImmutable version. Many of the common functions used aren't on the interface.
Comment #5
jaykandariDocumented all methods of
DateTime.Refernce: http://php.net/manual/en/class.datetime.php
Kindly review. Thanks !
Comment #6
gambryAlthough the @method tag is new to the Drupal standars for code comments I think we should still follow the consistent syntax for declaring/calling functions. From the documentation for Function Calls:
Comment #7
gambryHaving a closer look at #5 patch and most
@methodhave errors, i.e.:Undefined class DateInterval. Should that be\DateInterval?Declaration should be compatible with DateTimePlus::createFromFormat().
Etc.
Comment #8
ada hernandez commented@gambry I tried fixed but I found with createFromFormat and I don't know if I could do with this way, -> with parameters
Comment #9
jhedstromNot sure I understand this comment. The method declaration now looks to be compatible with
DateTimePlus::createFromFormat.Comment #10
mpdonadioI think what #7 was getting at is that all of these should be declared to return DateTimePlus and be added to that class and not DrupalDateTime. Yes, these operate on the protected object, but this should not "downgrade" the class of the object being acted on.
Comment #11
jofitz@ methods now return DateTimePlus rather than \DateTime.
Comment #12
gambryWhat I meant on #7 was most methods definitions on #6 were flagged as wrong by my IDE, due coding standard issues and incompatibility with DateTimePlus definitions, i.e. createFromFormat().
I don't think that's correct. Magic
__call()returned items are actually still DateTime objects, aren't they?In this case we don't want to let IDEs and developers think those are DateTimePlus when they are actually not.
What I think we should do in here is:
These shouldn't be in the class docblock. The __constructor already takes care of them.
These should return \DateTime.
This can be removed. DateTimePlus has its own definition for this, without relying on the DateTime one through the __call() magic method.
Then we can refactor
DateTimePlus::__call()method to actually return DateTimePlus object instead of DateTime and updating affected phpDoc@methods defined in here. In alternative we can postpone this until the refactoring is done.Thoughts?
Comment #13
jofitz@params.Can you explain what you mean about refactoring DateTimePlus::__call(), please?
Comment #14
gambryHey @Jo Fitzgerald , thank for the changes. I haven't moved the issue status to Needs work as #12 was more a question for @mpdonadio and @jhedstrom than a real request.
At the moment methods listed in #12.2 return a DateTime object. IMHO if we want to do what #10 suggests then those method should return DateTimePlus, so a bit of refactoring is needed.
I think we are good with your work on #13. I'd leave the final decision about which is the right Class to suggest through @method(s) and about refactoring to the datetime maintainers.
Comment #15
mpdonadioI'm not going to have time to play with this for few days. I'm worried about BC if we refactor these, but I don't think I put 2-and-2 together about the return types and this could explain some weirdness I have seen chaining calls. Have to think on this...
Comment #16
mpdonadio`diff` is already implemented as DateTimePlus::diff(), so this can go.
The conundrum is if you look at the docs, eg http://php.net/manual/en/datetime.settimestamp.php
So, these are supposed to be chainable, but the implementation doesn't allow it; the wrapped object gets returned. Blerg.
Just made #2910081: DateTimePlus calls should be chainable, but I think this may worse than I thought...
Comment #17
mpdonadioPostponing on #2910081: DateTimePlus calls should be chainable.
Comment #18
mpdonadioUnpostponing since #2910081: DateTimePlus calls should be chainable is in both 8.5.x and backported to 8.4.x.
Keeping this at 8.5.x, but should be 8.4.x eligible as an "API documentation improvements".
So, lets wrap this up.
Feedback in #16 needs to be addressed, and we should update both DateTimePlus and DrupalDateTime to reflect that the proper object type is returned, and not \DateTime now.
Comment #19
mpdonadioComment #20
mpdonadioDecided to remove __set_state(), since that is really just used by var_dump().
PhpStorm complains about the changes to DrupalDateTime, but looks like everything works as expected.
Comment #21
jhedstromI manually tested with these, and as expected, method autocompletion works with this patch, and doesn't without it.
It seemed to work fine. What was the complaint?
This is RTBC assuming that isn't an issue.
Comment #22
mpdonadioPhpStorm 2017.2.4 says this:
I don't see it as a show stopper, just that the inspection isn't smart enough to fully understand the magic __call w/o us redeclaring it.
Comment #23
gambryI get the same errors as @mpdonadio and the reason is clearly those methods are actually already part of DrupalDateTime and PHPStorm doesn't understand why we are trying to override their return types.
But if we remove the @method tags from DrupalDateTime then the IDE thinks returned values are
DateTimePlus, which is not the end of the world but still technically wrong.A solution seems to be using
$this, as explained here. It works on PHPStorm but I can't understand if it's part of the tag definition or it-just-magically-works.Attached a patch using
$thisas returned type.Comment #24
gambryThere is a PHP Standards Recommendation (PSR-5) currently in draft proposing
$thisas return type.The most popular IDE already uses it.
Comment #25
jhedstromThe patch in #23 is missing the changes to
DrupalDateTime, but locally changing those to also use$thisresolves the php storm complaint.Comment #26
gambry@jhedstrom as
DrupalDateTimeextendsDateTimePlus, if we use$thisas @method return type inDateTimePluswe don't need to patchDrupalDateTime.Comment #27
jhedstrom@gambry ah yes, I missed that bit. It does indeed work with the patch in #23.
So regarding #24, can we use
$thisbefore it's 'official'?Comment #28
mpdonadio`@return $this` is used in core already for chainable things, so this (ha!) should be OK for `@method`. See EntityPublishedInterface for an example.
Comment #29
jhedstromI think this is good to go then.
Comment #30
xjmHuh interesting. This isn't a phpdoc pattern we have yet anywhere in core:
grep -r "* @method" * | grep "php" | grep -v "vendor"I found the canonical reference here: https://docs.phpdoc.org/references/phpdoc/tags/method.html
It is used in a few vendor libraries:
I think what's in the patch looks in line with what we already have for other tags like
@param,@return,@throws, etc.: Tag, followed by datatype, followed by thing; no blank lines between the items; blank lines between the section containing that doc tag and other tag sections.Before we commit this as a one-off, let's file a followup issue in the coding standards queue: https://www.drupal.org/project/coding_standards
I don't think we need to block committing this on that being fully adopted, but since this is the first example for core, let's at least get the issue filed so any! followup discussion can go in that standards issue. Once it's filed this can probably be RTBC again.
Thanks!
Comment #31
mpdonadioCreated #2920333: Allow PHPDoc @method annotations in class headers..
Comment #33
xjmThanks @mpdonadio.
Committed to 8.5.x. We're in commit freeze right now since 8.4.1 just landed a couple hours ago, so leaving this RTBC against 8.4.x for backport.
Comment #35
xjmBackported to 8.4.x as well now. Thanks everyone.