Problem/Motivation
This is a followup to #3238192: Allow omitting @var for strictly typed class properties. That has this code snippet:
/**
* Where one can order a soda.
*/
protected Bar $baz;
That's not , however , how real world code looks like. For example, in EntityFormInterface you can find:
/**
* Sets the entity type manager for this form.
*
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* The entity type manager.
*
* @return $this
*/
public function setEntityTypeManager(EntityTypeManagerInterface $entity_type_manager);
The entire comment is completely superfluous, although the proposal would only drop @param. We should strive dropping it in its entirety by typing the return then dropping the return and then finally the text.
Or in Drupal\block_content\Routing\RouteSubscriber::childRoutes you can find
* @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
* The entity type.
This is a waste, completely pointless and it is actually harder to read. Because
EntityTypeInterface $entity_type
already totally tells you everything there is.
Benefits
If we adopted this change, the Drupal Project would benefit by ...
Replace 99% of the current method an parameter comments with typing the properties. Rejoice as the amount of boilerplate collapses to a fifth.
Three supporters required
Proposed changes
Drupal API documentation standards for functions
Current text
- Each parameter of a function must be documented with a
@paramtag (see exceptions below).- If a function has a return value, it must be documented with a
@returntag (see exceptions below).- If there is no return value for a function, there must not be a
@returntag.- For most functions (see exceptions below), summary lines must start with a third person singular present tense verb, and they must explain what the function does. Example: "Calculates the maximum weight for a list."
- Functions that are easily described in one line may be documented by providing the function summary line only (omitting all parameters and return value).
Proposed text
- Each parameter of a function must be documented with a
@paramtag (see exceptions below).- A
@paramtag must have a description, unless all of the following are true:
- The parameter is type-hinted.
- The parameter type is a single class, interface, or scalar and does not allow null.
- For a class or interface, the parameter name is derived directly from the type name. For example,
QueueWorkerManagerInterface $queueWorkerManager.- For a scalar, the parameter name is self-documenting.
- A description would not add useful information.
- The type in the
@paramtag is identical to the parameter type in the PHP function signature.- If a function has a return value, it must be documented with a
@returntag (see exceptions below).- If there is no return value for a function, there must not be a
@returntag.- A
@returntag must have a description, unless all of the following are true:
- The return is type-hinted.
- The return type is a single class or interface and does not allow null.
- A description would not add useful information.
- For most functions (see exceptions below), summary lines must start with a third person singular present tense verb, and they must explain what the function does. Example: "Calculates the maximum weight for a list."
- Functions that are easily described in one line may be documented by providing the function summary line only (omitting all parameters and return value).
@var: Class property data types
Current text
Typed class properties may omit the
@vardeclaration. It is recommended to use typed properties whenever possible.
Proposed text
Typed class properties may omit the
@vardeclaration. It is recommended to use typed properties whenever possible. The comment may be omitted if the name of the variable matches the type, or the type with "Interface" appended.
Remaining tasks
Create this issue in the Coding Standards queue, using the defined template~~List three supporters~~</li>~~Create a Change Record~~Review by the Coding Standards CommitteeCoding Standards Committee takes action as requiredTagged with 'Needs documentation edits' if Core is not affectedDiscussed by the Core Committer Committee, if it impacts Drupal Core.This went to the June 3rd meeting and there were no objection.Documentation updates- Edit all pages
- Publish change record
- Remove 'Needs documentation edits' tag
- If applicable, create follow-up issues for PHPCS rules/sniffs changes #3572690: Limit when @var, @param and @return or their description is required
For a fuller explanation of these steps see the Coding Standards project page
Issue fork coding_standards-3376518
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
- 3376518-Allow-omitting
changes, plain diff MR !8
Comments
Comment #2
ghost of drupal pastComment #3
ghost of drupal pastComment #4
borisson_I agree, this would be a huge improvement. I wonder if we can extract the information from the type on the generation of the api pages (for example: https://api.drupal.org/api/drupal/core%21modules%21user%21src%21AccountS...), so that we can still fill in some description there.
Comment #5
claudiu.cristeaYes, please. It's not only a core+contrib issue. Probably, most of the projects are just applying Drupal coding standards and they spend quite a lot of time to fix these kind of CS issues. When a var is correctly typed and named what's the point to add a description saying the same? It only adds noise to the code.
Comment #6
chi commentedWhy is this limited to class properties? Methods suffer from the same problem.
Comment #7
chi commentedOne thing that stopped me from doing this is inconsistency. Docblocks are used not only for the purpose of documentation but also for visual separation of properties and methods. Consider the following example.
The code style looks a bit ugly. The vertical rhythm is broken which brings some visual dissonance.
In custom projects I ended up adding
selfdoctag to code that has no need for any documentation.Comment #8
borisson_@Chi, this issue will probably already not be super easy to land, let's not try to increase scope here. Can you open a new issue for methods please?
Comment #9
chi commented@borisson_ I think that can wait till this issue is resolved.
Comment #10
kingdutchI'm against this in its current form, because I think the text is slightly too vague and open for discussions. I feel that most discussion about the duplication of these docblocks is held by very experienced Drupal developers who are easily able to see the patterns and duplications. If I had to explain this rule to someone new to Drupal they would not be able to determine whether "that variable/property/method is not specific to the instance."
I also think that the current phrasing of the proposal is very hard to test with automatic tools. That means that either the rule will exist, but anyone using coder must type out a comment anyway; or coder must stop enforcing comments altogether which leads to worse documentation.
If people really want this then my proposal would be to scope this to "Docblocks may be omitted for class properties that hold references to Drupal services" since the documentation for those services is expected to be on the service implementation. I could conceive of a way of testing that with PHPStan, but I'm not sure if coder can be so smart.
My personal preference would be to focus more on adopting constructor promotion which i think makes the discussion in this issue moot and shifts it to "Should we document the constructor" (I'll reserve my answer for an issue focused on that).
Comment #11
catchThis is at least a hint that the developer has explicitly chosen not to provide documentation, as opposed to just 'forgetting' it, so it might help @Kingdutch's objection. I also like the idea of the API module trying to backfill these - just parsing out the classes that are referenced and linking to them would help maybe? It's always slightly annoying to me that the use statements get removed from the method declarations, so that when you view a method on its own you can't see what it's referencing - I don't use an IDE so I end up on api.drupal.org a fair amount still.
Comment #12
ghost of drupal pastBoth for automated tools and unambiguous wording:
Take the name of a property or function parameter. Convert it to CamelCase and append Interface after. If this is the type of the property or function parameter then the doxygen is optional.
This rule is narrower than the issue summary, however it covers most cases. I think adding selfdoc beats the readability purpose.
Comment #13
acbramley commentedThis seems hard, if not impossible to perfectly automate with a standard.
I'm in support of removing the requirement for doc blocks entirely for these vars (and other things but not for this issue) and leaving it up to the review process to determine whether things need extra documentation. This is just like we do for inline code comments.
Comment #14
ghost of drupal pastCould you clarify why do you think this is hard to automate? One part is creating the desired type from the variable name with
str_replace('_', '', ucwords($string, '_')) . 'Interface'and then adding skipping rules to the relevant sniffs. As far as I can see coder already picks up and compares real types of function parameters to the doxygen at https://git.drupalcode.org/project/coder/-/blob/8.3.x/coder_sniffer/Drup... and so adding a skip shouldn't be terribly difficult? While I do not see similar in member vars https://git.drupalcode.org/project/coder/-/blob/8.3.x/coder_sniffer/Drup... phpcs does have the required getMemberProperties method available so an analogue once again looks very doable.What am I missing?
Comment #15
donquixote commentedWhat if we base this on whether a property has a (trivial) object (class/interface) type declaration?
This is actually an array. So yes, I want it documented.
This is actually an object, so I don't need it documented, _if_ instead we insert the proper native type declaration.
Interestingly, this is currently wrong:
There is no reason why this should be initialized as empty array.
I like it, as a way to avoid the visual inconsistency.
Comment #16
donquixote commentedSomething like this:
@phpstan-varinstead of@var(or is it phpstan-type?), if phpcs gets confused. In the latter case,@varbecomes optional.@phpstan-varinstead of@var(or is it phpstan-type?), if phpcs gets confused. In the latter case,@varbecomes optional.@selfdoc(TBD).Comment #17
ghost of drupal past> then the entire doc comment can be omitted
That's the entire point. There's no point if we are going through all this to end with another form of pointless clutter.
Comment #18
acbramley commentedBecause I don't think your suggestion covers all bases, it'll still lead to having to document some things with useless doc blocks, no? You even said that it's narrower in scope than the IS.
Take the name of a property or function parameter. Convert it to CamelCase and append Interface after. If this is the type of the property or function parameter then the doxygen is optional.Comment #19
ghost of drupal pastmy proposal does not cover all bases no but it is a step forward. Do not let perfect be an enemy of good. This would lead to a removal of a lot of pointless doxygen. There might be some odd cases like
AccountProxyInterface $currentUserorImageToolkitInterface $toolkitstill having pointless doxygen but that's fine. We can tackle that in the next issue. This particular proposal isso it should be easier to accept than a complete overhaul of our doxygen rules.
Comment #20
donquixote commentedMaybe I misunderstand, but here is where I see the problem:
It can be easy to code to detect whether an existing doc comment is pointless. E.g. "Current user" for a $currentUser parameter.
However, we also need to detect whether a doc comment is required if it is currently missing.
E.g. if we have "AccountProxyInterface $currentUser" without doc comment, how can we detect whether a doc comment must be added?
Also, the proposed check, as I understand it, cannot distinguish between a lazy doc comment that should be improved vs a redundant doc comment that can be dropped.
But maybe I completely misunderstand the proposal.
(and I want to refer to #16 again which _can_ be formalized)
Comment #21
quietone commentedAdding related that may be a duplicate, I haven't checked.
Comment #22
ghost of drupal past> E.g. if we have "AccountProxyInterface $currentUser" without doc comment, how can we detect whether a doc comment must be added?
"AccountProxyInterface" !== "CurrentUserInterface" =====> needs doxygen.
Comment #23
donquixote commentedOk, I almost thought I got it.
From that comment alone, if the property name (or parameter name) is a 1:1 transformation of the class or interface name (more precisely, the short name) from the type declaration, then the doc comment can be omitted.
I assume this would only apply for properties with a single type declaration, and only for object types. E.g.
string $stringorarray $arraydoes not count.So compared to #16, it is less permissive.
In #16 I don't make any requirement for the property name.
But in the issue summary:
This contradicts my above understanding of your proposal. Here you say that for
AccountProxyInterface $currentUserthe doc comment _can_ be omitted, because it is used elsewhere.Comment #24
dww+1000 overall, but I haven’t read every detail of every proposal, yet.
@selfdocseems like a reasonable solution for ensuring we thought about it, visual rhythm, etc.Comment #25
mondrake+1 on every single word in the IS.
Mixing up properties with and without docblock is not a problem in other projects, e.g. https://github.com/doctrine/dbal/blob/3.6.x/src/Connection.php
-1 on the use of {@selfdoc} - Drupalism?
Comment #26
dwwBut the proposed resolution in the IS (as currently written) is not something we could get any of our tools to accurately enforce.
It relies on human discernment to decide what’s ” specific to the instance” or not, by way of a few annotated examples. How could any layer of our automated tools enforce this? We need something more specific than that, or our tools can’t enforce any such doc blocks, and our code will tend to degrade over time as things which actually do need docs sneak in.
You could argue that occasionally missing docs is better than the hordes of boilerplate docs we have now, and you might be right. but I’d rather adopt one of the proposals that’s enforceable by automation.
Comment #27
dwwPartial reduction in clutter and noise, if we go the Drupalism route, can we use 1 line?
Comment #28
claudiu.cristeaWe are putting a lot of effort in maintaining our coding standards. Just another drupalism. Let's get off the island (again) and adopt one the popular PSR-* standards and focus on things that really matter (even, I know, I'll miss the 2 space indent and inline opening curly brackets)
Comment #29
catchSome of the PSR standards (cache, for example) are not fit for purpose, and for me the PHP-FIG organisation itself is also not fit for purpose - most of the member organisations including Drupal and Symfony have left some time ago.
At the moment, they have a coding style standard: https://www.php-fig.org/psr/psr-12/, but the documentation standard is still in draft: https://github.com/php-fig/fig-standards/blob/master/proposed/phpdoc.md.
So we can't adopt it even if we wanted to.
Comment #30
chi commented@catch there is also a proposal for PHPDoc tags (PSR-19). I submitted a request there yesterday.
https://github.com/php-fig/fig-standards/pull/1307
Comment #31
catch@Chi as we can see from the responses to your comment they're hostile to doing anything actually useful. People are welcome to try to make the PSRs work for us, but I gave up on that a decade ago and we should not adopt them for the sake of it. The Laminas debacle has shown that when you get off the island sometimes your raft falls apart.
Seems like this would conflict with all properties needing to be documented with C-style comments. Also for me it wouldn't help the vertical rhythm issue compared to not having docs.
Comment #32
chi commentedA few notes on
@selfdoc1. I think
@selfdocshould only be used to replace:a. A short description of the docblock when it duplicates function/property name
b. Tags that describe a signature (
@pararm,@return)That means all other contents of a docblock should stay with
@selfdocExample:
This example needs to be replaced as follows.
2.
@selfdocshould not be mandatory. That means it's up to developers decide whether to use it or just omit the whole docblock. Actually, not sure about this.3. If we want to align format of this tag with
@inheritdocas it described in PSR-19, it should be in came case and have two variations — w/wo curly braces.However, currently Drupal always use inline variation of
@inheritdoc(with curly brances) and it's not camelized.Comment #33
xjmComment #34
chi commentedAnother case of duplicated docblocks is single method services and controllers.
This probably deserves own issue.
Comment #35
ghost of drupal pastThe issue has stalled so I am narrowing to my proposal in #12. It does less than the original but it is easy to automate and unambiguous.
Comment #36
catchOnce #3278431: [May 2026] Use PHP 8 constructor property promotion for existing code is done, the property creation will happen in the constructor itself and there'll be no other property definition at all (see the before/after in the issue summary), I think it would be good for the issue summary to use something less service-y as an example where we still have similar boilerplate.
Comment #37
ghost of drupal pastThe issue summary already says "property or function parameter". It should be function/method parameter, indeed. Looking at the IS of the issue linked:
Out of eight, five is covered, a sixth could be covered by a minor modification of making the Interface append match the type:
Take the name of a property or method/function parameter. Convert it to CamelCase. If the type is an interface then append
Interfaceafter. If the result is the same as the type then doxygen is optional.I added this new rule to the IS.
This also strongly suggests TranslationInterface should be called StringTranslationInterface. That's a separate issue, of course. The last one really needs doxygen because without namespace "StorageInterface" does need explanation.
Comment #38
ghost of drupal pastWhen https://www.drupal.org/project/drupal/issues/3294266 gets in, we could add here or in a separate issue: don't mandate doxygen on constructor parameters which are known to be a service. PHP 8 constructor property promotion this will also take care of properties: they'll be gone in this case anyways.
Comment #39
quietone commentedUpdated to use the new template for coding standard.
Comment #40
catchI think the proposed standard is fine, but 90% or more of what it would affect, is going to be covered by constructor property promotion and #2140961: Allow constructor methods to omit docblocks.
We still have #3278431: [May 2026] Use PHP 8 constructor property promotion for existing code open, so core is full of the current boilerplate, but it would be useful to see an example that's not covered by that issue to see what would remain in core that this would affect.
Comment #41
ghost of drupal pastSure.
In EntityFormInterface you can find:
The entire doxygen is completely superflous although the proposal would only drop @param.
In AccountSwitcherInterface you have
and also here the @return $this could be dropped in another proposal with a :static return type, same as with the previous one.
In Drupal\block_content\Routing\RouteSubscriber you can find
In FieldTypePluginManagerInterface:
this would require renaming to field_storage_definition but IMO it'd be worth it.
and so on.
Comment #50
quietone commentedClosed #2938784: Do not require descriptions in variable comments as a duplicate, adding credit.
Comment #51
pfrenssenI support this.
Comment #52
nils.destoop commentedI support this.
Comment #53
wtrv commentedI support this.
Comment #54
claudiu.cristeaI support this
Comment #55
ghost of drupal pastComment #56
catchThe current example in the issue summary looks like a property definition for something that would be constructor property promoted now and hence not need a property definition at all, this is already covered by existing coding standards.
It would be good to see examples, ideally real ones from core, where this rule would be applied that aren't about constructors.
Comment #57
chi commentedI think
\Drupal\Core\Messenger\MessengerTraitmight be a good example.Comment #58
dwwRe #56: see #41. Someone needs to update the summary to use some of those as the examples…
Totally support this, now that it’s focused on something we can automate.
Comment #59
ghost of drupal pastComment #60
dwwPerfect, thanks @chx
Comment #61
claudiu.cristeaI'm setting to NW because of "Needs followup" tag.
Comment #62
dwwThat tag was added in #9 as a request to keep the scope limited to class properties. Life moved on. The vast majority of class properties will be auto-documented via constructor property promotion. The whole scope of this issue now is for method params and any non-promoted class members. No follow up needed. Removing tag and restoring status.
Scratch that, moving to RTBC so our committee can review this at our next meeting. I don’t believe anything else is needed for that to be the next step.
Comment #63
catchSorry I have one more question/comment about this:
If a method has one, interface, parameter, then it is easy to drop the entire doxygen.
However if a method has two parameters, one that's an interface and one that's a bool, then it would be strange to leave the first parameter undocumented and only document the second.
So do we need to add explicit language that doxygen can only be dropped when every parameter is self-documenting?
It might also be easier to automate.
Comment #64
donquixote commentedI would argue that "omit the doxygen" is unclear terminology.
There is no "doxygen" in php, and even outside php, I don't think "doxygen" means a specific part of the doc comment, but rather the mechanism to generate a documentation from doc comments.
For "omit the doxygen" it is not clear whether we omit the param description, the entire `@param` tag, or the entire doc comment.
So instead we should say "omit the param description" or "omit the param tag" or "omit the entire doc comment".
Absolutely.
Something like this:
- A function doc must have either _all_ `@param` tags or none of them.
- A param doc description can be omitted if the type is a single class or interface, and the parameter name is a derivative of the type name.
- A param doc tag is "trivial" if it only replicates the native parameter type.
- If all parameters are "trivial", then all of them can be omitted.
- If all parts of the doc comment are trivial, then the entire doc comment can be omitted.
Comment #65
donquixote commented(ignore this comment)
Comment #66
donquixote commented(ignore the previous comment)
The `setEntityTypeManager()` example is interesting.
The `@param` doc and its description are redundant, because we already have the native type declaration and the first line of the doc comment.
The `@return $this` is _not_ redundant.
The method doc description looks a bit redundant, but actually, I might want more information:
This method needs to be called before the class can be used.
In fact this method reveals a design flaw, where we don't have automatic dependency injection for this class, and instead there are various places where the method is called explicitly.
Again "doxygen is optional" can be confusing. What exactly do we omit? The description, or the entire `@param` tag, or the entire doc comment?
I think the "take the name of a function parameter..." logic is a placeholder for "The parameter is a service".
Usually, if it is not a service, then we should assume the parameter to play a specific role in the class, which deserves to be described.
Comment #67
donquixote commentedBtw, to see how a lack of documentation looks like, we only need to look at the symfony codebase.
I find this painful to read :)
Comment #68
catchIt would be redundant if the method had a return type though wouldn't it?
Comment #69
donquixote commentedThe only native return type could be `*(): static`, which is less specific than `@return $this`.
E.g. `): static` would still be correct on a wither method that returns a clone. `@return $this` must not return a clone, it must return the object itself.
Comment #70
chi commentedI think it's ok to only document parameters that need clarification. That's quite typical case when parameter type is extended via psalm/phpstan.
Comment #71
donquixote commentedIt would look quite alien and unexpected in a Drupal codebase, to have param docs for 3 out of 5 parameters of a method.
Having the complete list of parameters gives a sense of symmetry and completeness.
Also it is easier for an IDE to generate the doc comment, and warn if it is incomplete.
But maybe it is just a question of familiarity.
Do you know of 3rd party code with incomplete parameter docs?
(finding such code is the first step, we might still decide that we don't like it)
Maybe we should create an MR with example doc removals.
Comment #72
chi commentedEven if all of these parameters are self documented you might want to extend documentation for just one of them. Typical use case is clarifying types for arrays. Like
Some/Type[]instead ofarray. With "all or nothing" policy you will likely just ignore this need.Example from typhoon library.
Comment #73
chi commentedThe scope of this issue is a bit unclear. Initially it was about
@vartag, but in comments mostly reference@paramtag.It think it should apply to
@returntag as well.Comment #74
catchMaybe I'm missing something but I can't see anything in https://github.com/typhoon-php/typhoon/blob/0.3.x/src/Reflection/Metadat... which only documents some and not all parameters on the same method?
edit: yes I was missing something, the constructor doesn't have @param docs for
ChangeDetector $changeDetectorbut I had to do a 'spot the difference' reading line by line to find what was missing. Don't really like that at all tbh.Comment #75
chi commented@catch all other classes in that project follow that pattern.
For example https://github.com/typhoon-php/typhoon/blob/0.3.x/src/Reflection/Metadat...
::fromFileContents()has@paramtag for$fileparameter only because it needs extra clarification for Psalm (non-empty-string). All other parameters in that class have no tags. Also note missing@returntags as the return type is clear from typehint.Comment #76
donquixote commentedInteresting example.
For the $contents parameter, the comment description should explain that, if it is provided, the actual file contents are ignored, but the $file is still passed to FileChangeDetector. Maybe in less words.
The ChangeDetector::changed() could have a doc description saying "TRUE, if the resource has changed since the detector was created.".
Also the classes could have doc descriptions.
In this example the code is actually relatively simple, so we can make sense of it without comments.
And tbh there is a risk that a poorly written description is more misleading than helpful. I am already unhappy with my proposed comment above.
Still, in general I tend towards having doc descriptions on most symbols over not having them.
Comment #77
dwwWe could have a rule that says, more of less:
If any @param statements are required, all must be documented but the descriptions are optional for self-documenting cases.
Eg
Forgive typos / formatting, I’m typing this comment on my phone while boarding a flight. But hopefully it’s “clear”. 🤓😆
Comment #78
dwwAlso, re end of #66, I think this is definitely not just about services.
for example, this is a common parameter for which this documentation would be redundant / pointless:
Or
UserInterface $user, etc.Comment #79
catch#77 looks OK to me visually, doesn't have the 'spot the difference' problem. Would be good to know if phpcs supports it via configuration. I guess it would have to be something like 'docblock is optional. If there is a docblock, all parameters must be documented, parameter description optional' in phpcs and it's up to humans to decide which need a description?
Comment #80
ghost of drupal pastHere's another prime example
What information do these 12 lines provide which
does not?
Comment #81
joachim commented> Btw, to see how a lack of documentation looks like, we only need to look at the symfony codebase.
> I find this painful to read :)
Yup. Symfony code is horrible to work with.
> What information do these 12 lines provide which
The word 'within'.
Comment #82
nicxvan commented@joachim wouldn't this then be acceptable:
Comment #83
nicxvan commented@catch's question in 63 was answered in 77 and confirmed in 79.
There is a question about phpcs but if I understand correctly that can be handled in step 9.
If I made a mistake let me know.
Comment #84
joachim commentedNo, because what's $scope? What does it represent, what are its valid values?
A variable name is not enough.
And for omitting docs based on the type, that's only good enough if the class/interface/enum of the type itself has docs that are sufficient to tell you what that parameter is doing in the context where you currently are.
Comment #85
nicxvan commentedDoesn't answer that question either.
And that parameter wouldn't be excluded from the required docs anyway.
From the proposal:
Still rtbc per the coding standard process.
Comment #86
donquixote commentedSorry, I don't think this is rtbc with the wording currently proposed.
I don't think the term "doxygen" should be part of the doc page.
And, it is not clear what "doxygen is optional" means: Is the parameter description optional, or the parameter type, or the entire `@param` tag, or the entire doc comment?
The text should explicitly say this, without using the term "doxygen".
Comment #87
nicxvan commentedGood point I'll update it
Comment #88
nicxvan commentedMoving back to RTBC, I didn't change the structure, just removed the shorthand
doxygenfor the method and parameter comments.Comment #89
nicxvan commentedComment #90
joachim commentedThe docs of the type need to be enough for the context. The docs on the type won't tell you what the type is being used FOR.
Silly example, but given this and no knowledge of Drupal patterns:
> public function access($object, ?AccountInterface $account = NULL, $return_as_object = FALSE) {
how do you know whether this is 'access FOR the account' or 'access TO the account'?
Comment #91
nicxvan commentedComment #92
donquixote commentedThe proposed text still needs to be more clear:
- What exactly can be omitted: The param tag, or just the param description? What about the type?
- If all parameter descriptions are optional, and all parameters have a native type declaration, we can drop all the param tags in phpdoc? what if we still have a return doc?
- Where in the doc page does it say that a param doc needs a description? The part being changed does not mention the description at all.
- Does this also allow to drop the entire doc comment, or is it out of scope?
Comment #93
donquixote commentedAlso it would be interesting to see a proof-of-concept patch/PR with param docs removed from core methods and functions, to see how this would look like, and to verify that we are really all on the same page.
Comment #94
nicxvan commentedComment #95
nicxvan commentedProposed text
Comment #96
donquixote commentedWhat about something like this:
I am sure this can be further improved:
- We need to find a better wording for "native php parameter type".
- The "derived from" could be more precise. The current "take the ..." looks a bit out of place though.
- For the second part, I wonder if we allow a function that has a `@return` doc but no param docs.
(PS: This is similar to nicxvan above, because both are based on the same chat message :) )
Comment #97
nicxvan commentedI moved your suggestion to the proposed text section.
I no longer see that in proposed text, I think it's clear as is.
I think you already cleaned that up too
I think so, I've added it to the proposed text as well.
Comment #98
nicxvan commentedComment #99
quietone commentedThis is at needs work. What is the work that needs to be done next?
If this changes is accepted how does it affect the existing sniffs, including the one that are not yet fully implemented in Drupal core?
Comment #100
nicxvan commentedI think needs review is the appropriate status.
I don't know what you mean by sniffs not fully implemented, but the current ones would use the logic mentioned to mark descriptions optional.
E.g. if the variable is the same as the type plus or minus interface.
Of there are none then @param is optional entirely.
I have not looked at coder for how it would change specifically.
Comment #101
quietone commented@nicxvan, I was thinking of #3477599: Fix Drupal.Commenting.VariableComment.Missing.
Comment #102
catchThe coding standards would require a full description for $object, so it would be quite possible to word that documentation so that it's obvious that this is the 'TO' access, and the $account is the FOR. But also
We can just decide to keep that documentation on the $account object, the standard does not say we have to remove it. For example we'd also want to document what happens with $account is NULL, because it results in an implicit check on the current user.
Comment #103
drunken monkey-1
To reiterate my post from the duplicate issue: I think we should generally make the rules as simple and unambiguous, and the resulting style as consistent as possible. It seems like these new rules would just lead to lots of bikeshedding in issues about which comments can or can’t be omitted, while making it harder to spot where documentation has actually been forgotten.
The very last thing I want to happen is to drift even a bit closer to most other frameworks, libraries, etc. I’ve ever used where not even the most puzzling parameters or methods are properly documented.
If you feel distracted by the doc comments it’s also usually simple to configure your IDE to collapse them by default.
Finally, in the concrete proposal currently in the IS, I don’t understand the purpose of the “parameter name is derived directly from the type name” rule. Why would that make the description more or less necessary? Unless I misunderstand, the type and variable name will still be in the doc comment anyways.
On the contrary, it seems like a more descriptive parameter name could make the description less necessary:
$reviewermakes the purpose of the object definitely a lot clearer than$accountwould.Comment #104
donquixote commented@drunken monkey
Arguably, your example could also be read in the opposite way:
The reason why you name your parameter as "$reviewer" instead of "$account" is also the reason why you want to have a doc description.
Yes you could game the system and choose a worse parameter name to be allowed to avoid the parameter description.
It's a causation vs correlation thing.
E.g. an individual will be better off if they take medicine. But statistically, people who don't take medicine are healthier.
Personally I am not really invested in the heuristic.
I see the biggest possible benefit in reducing redundant service constructor parameter descriptions.
For other methods I don't care, I think I would rather keep the parameter descriptions.
Comment #105
drunken monkeyCan’t we then just restrict the exceptions to constructors, getters and setters? From the above, it would even be possible to restrict this to services altogether, where the description should really always be pointless. (Even if the parameter name doesn’t completely match the type name, incidentally.)
If we want to cover all methods and functions, I just see potential for a lot of pointless bikeshedding in issues.
I just now see that this issue is also about property doc comments, even though the title didn’t reflect this. Changing the title to something that hopefully better reflects the current proposal in the IS.
I like the proposal for
@vareven less, though: That doesn’t even mention that the description wouldn’t add any additional value and completely relies on the name/type heuristic. Maybe we should allow omitting the description only for services? Otherwise, I would at least state that the description may only be omitted if it doesn’t add any new information – even though that seems obvious, I think it should be stated explicitly.Comment #106
nicxvan commentedConstructors are already omitted:
This really is about removing redundant documentation and condensing the doc section afaict.
Comment #107
donquixote commentedThis line is far too generic.
It means we can either omit the full phpdoc on a constructor, or we have to put a complete phpdoc.
Maybe there are some parameters that we do want to document, but others where it would be redundant.
In that case we might want to omit the parameter description on some parameters but not all.
As mentioned before, it would be useful to have a proof of concept MR that shows how this would look like in core.
Comment #108
catch#2140961: Allow constructor methods to omit docblocks was the issue for constructor documentation. This issue was spun out of that one iirc, or maybe one of the other issues that was running alongside the constructor issue.
We haven't yet gone through core to remove constructor documentation, but it's happening when individual constructors get updated to property promotion when other changes happen etc., and for new code. When you look through core it's not obvious the new standard has been adopted though.
For me this was a feature of what we came up with over there, if a method has six parameters and only one of them is documented, then I have to think through why the other five methods weren't documented. Maybe after seeing methods like that for weeks I'd get used to it, but 'comprehensive or nothing' seems like less overhead when reading. When a constructor parameter isn't property promoted, it will probably have property documentation (not always but often), and then meaning of the parameter can be documented on the property usually, so even in cases where there's a mixture of services and other params, for many cases the constructor docs can still be omitted without leaving things undocumented and without documenting them twice in two places. Description vs. not makes sense though.
@vardocs are already unnecessary when using constructor property promotion (because there's no explicit property declaration to put it on) so while there might be cases where we still have those, there's going to be very few left too.We have another case in core where we don't require (actually forbid more or less) @param documentation and it's hook implementations - more obvious now they're OOP.
I think @drunken_monkey's idea of 'any getter, setter, or similar method that only takes service type hints' might be worth looking at the same way we did constructors separately. Then we have even less to deal with here.
Something like
Drupal\block_content\Routing\RouteSubscriber::childRouteswould still be left over.I feel like the problem there is that this is a protected helper method in an event subscriber. Not only is it an event subscriber, but it's one that only exists for bc and will be removed. It could be an anonymous function in the main method, and we wouldn't document the parameter there, and the subscriber method would still be short, and you could read the logic in one (or two places depending on setUpBaseRoute) instead of three.
Comment #109
nicxvan commentedWhat do we need to move this forward?
We've proven this works for constructors and as @catch points out has been the pattern forever for hooks.
We just want to extend this to other functions and methods where a parameter doesn't need a description.
The current situation makes it harder to know if documentation is because it was necessary or because it was mandated.
I think code where every parameter has description like this:
Is much less readable than even this:
Comment #110
kristiaanvandeneyndeIn the latter example I would even consider the following:
In case we add more docs at the top of RefinableCalculatedPermissionsInterface and AccessPolicyInterface:
Reasoning
With dedicated value objects such as the ones in the access policy API it could be better to document these once on the value object (or its interface) and then omit its documentation in @return tags.
The notion of a scope is used across a few methods, so perhaps that concept should be explained atop the interface (it's currently documented on d.o) and then omitted from all @param tags.
Comment #111
nicxvan commentedCurious on next steps here, do we need to review the language again?
Comment #112
catchI think the language is OK except that it's verbose, but I don't have suggestions to make it less verbose either.
Comment #113
acbramley commentedReading the proposed text it doesn't seem like we're enforcing that a param or return doc can only be excluded if the method has strict types for either the param or return?
I.e we should not allow removing a return doc if it does not have a return type, same for params.
I'm also unclear how this is relevant:
Comment #114
nicxvan commentedThat is already covered by bullet 1:
The return type is a single class or interface name,
If there is no return type it is not a class or interface.
This is the metric:
AccountInterface $account is ok to drop, but AccountInterface $user would not.
Comment #115
catchYeah I think "the parameter name is derived directly from the type name" is designed to keep documentation when the different parameter name expresses something specific about what's being passed in.
https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Entity%21... is the only example I can think of immediately, with the complication that it's got two EntityInterface params:
In this case, it's impossible for both parameters to be $entity, so there would be no way to break the new coding standard - have to provide docs.
When it's only one parameter name, renaming a parameter in itself isn't an API change since we don't support named parameters. So the $user example could be renamed to $account if someone feels the phpdoc is redundant.
On return types, do we need to say something like 'the type hinted return type' to make it more explicit maybe?
Comment #116
catchI've added 'The x is type hinted' to the proposed text, to make this explicit on both cases. I couldn't figure out how to fit it into the existing sentences without constructions like 'the type hinted return type' which... nope.
Comment #117
acbramley commented@catch thanks, I think it's best to be explicit.
I think this is good to go now, not sure if I'm allowed to mark this RTBC or not.
Comment #118
catchI think you are but since I'm here I can also do that :)
Comment #119
quietone commentedYes, anyone can set a coding standards issue to RTBC.
Comment #120
quietone commentedWhich sniffs can no longer be applied if this is accepted? Which ones need modification?
Comment #121
quietone commentedMajor because of the impact.
Comment #122
acbramley commentedSniffs that would need changing:
For allowing the omission of
@varcomments -Drupal.Commenting.VariableComment.Missing. You are currently allowed to omit the@varif the variable is typed, but you still need a comment. It's likely this logic can be copied to the sniffs below.For allowing the omission of
@returnwhen a return type exists - Unsure, this currently does not throw an error with either or both missing, only when the@returntag exists without a type. Likely need changes inDrupal.Commenting.FunctionComment.MissingReturnTypeFor allowing the omission of
@paramwhen a param type exists - this currently does not throw an error with either or both missing, only when the@paramtag exists without a type. Likely need changes inDrupal.Commenting.FunctionComment.MissingParamTypeEDIT: we'll also need to change
Drupal.Commenting.FunctionComment.MissingComment #123
acbramley commentedUpdating the current and proposed text to show more of what we could replace in the docs.
Comment #124
quietone commentedThis was discussed at the last meeting. see #3515394: Coding Standards Meeting Wednesday 2025-04-30 0900 UTC.
Comment #125
quietone commentedThis is an important piece of information and should not be in parentheses. And I disagree that it up to the developer to decide. A reviewer has an obligation to advocate for the needs of people new to this bit of code. And as a committer, I also do not wish to be blocked from from this decision. Our community works in collaboration and that should not be limited.
I am also concerned that the length of these descriptions makes it harder to figure out what to do when one is coding. At least for me, it is not an easy read. From the meeting I am the outlier on that. One thing that can be done to help here is examples of when the docs must be added and when the docs can be omitted.
Can we add consistency so that the 'return' section has separate line like "All @param tags on a function can be dropped, if:" ?
Why is the summary line removed? That seems out of scope.
Comment #126
acbramley commentedI think "developer" is used very broadly here to include reviewers/committers (if you're reviewing code or committing it you're probably a developer too?) but we can use more generic language.
That is going to drastically increase the length of the description though?
There is only ever a single return tag so it doesn't make sense IMO.
I removed it to shorten the overall section because it's implied by the other information.
Comment #127
quietone commentedWhat do you suggest?
I don't think that is true at all. Plus, a standard should avoid relying on implication.
Even with the length of this text, examples are helpful.
Overall, with my educator hat on, the language of the change should tell people when to add the 'thing' instead this says when not to add the 'thing'. While I don't want to slow this down it does go against my training and practice.
Could it not be flipped to something like the following
Comment #128
nicxvan commentedI'm not opposed to this being a positive instruction vs a negative.
Comment #129
acbramley commentedReversing the terminology and adding the summary line back as well as changing the "developer" wording. Still need to add examples but I'm not sure where they should live (probably under all of the text?) and how detailed we want to be.
Comment #130
quietone commented@acbramley, thanks for re-wording the proposed text. Very helpful.
Yes, examples can be added later.
There is at least a point in #125 that should be resolved, that is, the use of parentheses. Parentheses are for non-essential information. I think that "This last condition won't be checked by any code quality tools, and is up to the contributor or reviewer to decide" is essential.
What about moving that item up to the item it affects. I also this we can remove the bit about linting. For example,
"A description will add new information. The addition of a description is decided by contributors."
Comment #131
acbramley commentedDone.
Comment #132
quietone commentedI would still like to know more about the sniffs that need to be changed. They are likely in Drupal.Commenting.DocComment and Drupal.Commenting.FunctionComment. What issues need to be made in Coder?
Also, core is not compliant with the existing coding standards. That means, there are functions, parameters and return values not documented. We have no idea how many of those should be documented with these new rules. If this is accepted and sniffs change to ignore these cases, there is little chance these places will be found. As painful the existing rules are to many of us, they do find and improve the existing code base.
Comment #133
quietone commentedChanged style of
"It is also permissible to completely omit the comment if the name of the variable matches the type or type with Interface appended."
to
"The comment may be omitted if the name of the variable matches the type, or the type with "Interface" appended."
for consistency with style in same heading.
Comment #134
acbramley commentedRe #132 and some chats in slack, there is some hesitancy here based on the fact core is only applying some of these sniffs to a subset of the codebase. The concern is that by relaxing the sniffs we won't find things that need documentation in the future.
Let's step through that, based on the sniffs identified in #122 that need changing:
1.
Drupal.Commenting.VariableComment- core includes this sniff on the entire codebase. No loss here2.
Drupal.Commenting.FunctionComment.MissingReturnType- this is part of the FunctionComment sniff which core includes on the entire codebase.3.
Drupal.Commenting.FunctionComment.MissingParamType- same as above, but is also for some reason explicitly included again4.
Drupal.Commenting.FunctionComment.Missing-Drupal.Commenting.FunctionCommentis included on the whole codebase, butDrupal.Commenting.FunctionComment.Missingis only applied to Plugins, the Database namespace, and tests. Tested this manually and you can indeed omit a function comment, however when manually adding the node module to the include patterns and removing a function comment inside NodeController no errors were produced. I even tried debugging through the sniff and it was correctly scanning the file but not throwing an error. I'm not sure if this is a bug in coder or not.In any case, 4 is the only sniff where these concerns may apply. If I understand correctly, the concern is that since we're not currently scanning the full codebase for missing function comments, there may be functions without comments that do need documenting. If we relax the sniffs, then when the sniff is eventually applied to the whole codebase we won't "find" these functions with missing comments that do need documenting.
But that would only happen if those functions were also missing @param and @return docs (since we only allow omitting the description if those are also missing). But since we apply the missing return/param type sniffs to the whole codebase, I think this is overall a non-issue. And even if it were, it's likely only to affect a very small amount of code.
One thing I'm unclear on is core's process of updating drupal/coder versions. I'm assuming how this will work is we'll have 1 or more issues in coder to make these changes, a new version will then be released, and then we'll have an issue for core to update to that and fix the violations?
I also noticed as part of the return docs we don't suggest return types declarations, should we? I.e you must include either @return OR a return type declarations
Comment #135
acbramley commentedAfter further testing #134.4 the sniff only detects completely missing function comments, it does not enforce the short description at all.
Comment #136
xjm(IS changes are just punctuation fixes).
Overall, a +1 from me. We can finally do this now that PHP is fully type-hinted. However, PHPCS enforcement of the if/thens above would be helpful. (I believe this is an additional consideration on top of everything in #134.) Actually implementing it would go to the separate PHPCS issue for this standard, but I would love it if PHPCS could always flag missing
@param/@returndescriptions whenever the type is missing or not an exact match.Is it worth discussing any specifics about arrays? The text typehint for an
@paramarray is almost always more informative than the PHP type. (E.g.,string[],string[][],mixed[], whatever.) Arrays also usually need explanation, except in the case where it's a "special" ArrayPI array being passed around (render arrays and such), or things like unit test arrays. (Edit: And in the former case, half the time, it needs a docs link because it's not a properly injected object.)I do have one issue with the text:
This doesn't fit with anything else in the document. This is a policy document, not a governance document. Also, I think it's not accurate; the committers would ultimately make the decision, with input from subsystem maintainers and other contributors. We could either omit the sentence or rephrase it.
Comment #137
catchon arrays we have "The parameter type is not a single class, interface, or scalar type." which means all arrays would need @param docs still.
This was changed from 'developers' from around #127 downwards, I don't think we can word this so it's only about core - it includes contrib modules too.
Comment #138
xjmMy point is, can we just omit the sentence? The meaning seems to be the same without it.
Comment #139
xjmI... do not understand the sentence I guess.
Comment #140
xjmOkay, I think what I am struggling with is the negation:
Can we flip it around? Put the circumstances under which it may be omitted first (thus allowing all those things to omit the word "not"), and say otherwise it must be included?
Comment #141
xjmLike so:
That removes heaps of negation, and reduces it from two sections to one. We could do likewise with the return section.
I read the current IS proposal like 5 times and never understood what it meant before @catch's comment, which is why I think an edit is needed.
Comment #142
xjmThough I do still have a question about:
What is the "type name"? I don't know what that means in context.
Comment #143
xjmNR because the more I read it, the more I think it actually really does need an overhaul for clarity.
Comment #144
donquixote commented@xjm
Yes the way I understand it, this would only require description on arrays.
I would disagree. I would argue that on most scalar types there is something to document:
- For arrays we want to know the structure, and what the keys and values represent.
- For strings, we may want to know if it is a machine name or a human-readable label, whether it is raw input or has been sanitized already, etc.
- For boolean, we want to know what is the meaning of true or false.
- For integer, we want to know whether it is seconds or milliseconds.
See what I said in #16.
The idea here was this, if that is still valid:
"DuckInterface $duck" -> does not need a description.
"DuckInterface $animal" -> needs a description.
"QueueWorkerManagerInterface $queueManager" -> needs a description
"QueueWorkerManagerInterface $queueWorkerManager" -> does not need a description
"UnroutedUrlAssemblerInterface $url_assembler" -> needs a description
"UnroutedUrlAssemblerInterface $unrouted_url_assembler" -> does not need a description
Now up to you what you think about it :)
Comment #145
donquixote commented@xjm
I like reducing the negation.
We could also drop the last line of "otherwise, ..." if we use "unless".
Comment #146
xjmThanks @donquixote, I like your improvement!
When I asked what the "type name" meant in context, I meant that the documentation should make it clear without needing to refer to a comment on a policy issue. :) In your example, it's specifically parameters named for classes and interfaces, so I think we should replace "type name" with "class or interface name". However, that doesn't cover the scalars, and we're certainly not going to allow parameters named
$intor$string. (Which I think is related to what you are getting at in the beginning of #144.) So that means there's missing logic around what we expect for scalars' names.Comment #147
donquixote commentedI see the "scalar types" was added in #129, and I don't see why.
https://www.drupal.org/node/3376518/revisions/view/13999604/13999612
For my taste, we should simply drop that part:
For the first condition, "The parameter is type-hinted.", how could we make it more clear that this is about the php signature and not the phpdoc type?
Comment #148
xjm@donquixote, I don't understand. I didn't think we were talking about phpdoc; why did you think I did? Scalars can be typehinted at the language level in PHP 8 and we do it all over the place. For a year or two there, one of the most common reasons I would NW an issue was to add scalar typehints to parameters, properties, etc.
Comment #149
donquixote commentedThis was not about you, it was about others who may read these rules and think that "type-hinted" could refer to the param doc type.
But maybe saying "type-hinted" is clear enough.
Comment #150
xjm@donquixote, I really think saying "class or interface name" is a lot clearer than "type name", even with your example with ducks.
I think we do want to include scalars in the proposal; one of the biggest usecases for this is for constructor property promotion I think. Maybe we have a separate issue coding standards about that, but I thought this was part of a list of related policy changes for it.
Scalars can also be specific external values, or be special properties of an injected object like the entity type, and so on. Boolean flags can have a descriptive name that very clearly explains the meaning. Things that aren't things needing definition in milliseconds or whatever.
Comment #151
xjmHowever, since it is easy for me to explain what the names should be for classes and interfaces, but more difficult to explain it for scalars, maybe we should split the policy proposal into two steps?
Comment #152
catchYeah scalar arguments can be self documenting with the right variable name.
There are plenty of examples in core where we have something like:
And the phdoc just does not add anything over
function foo(string $the_thing)Not sure we need a whole separate issue for that, it should just be something like 'if the parameter is a class or interface it should be named the same as the class or interface, if it's a scalar it should be sufficiently self documenting that phdoc would not add any additional information.'
Comment #153
quietone commentedA bit late on the update on this for personal reasons. This went to the committer meeting of 3 June and there were no objections stated in that meeting. I added that to the steps in the issue summary.
Since this is no longer RTBC I have updated the steps to show that this is still under discussion.
Comment #154
quietone commentedI made an attempt to understand the new proposal, as follows. This changes the @return section to be in the same style. And I removed the hyphen in type-hint because the PHP manual does not use it. Is this the current idea?
Proposed text
@var: Class property data types
Comment #155
mstrelan commented@quietone does the php.net manual use the word typehint? I've only seen it use "type declaration". From my understanding a type hint is an annotation whereas a type declaration is native.
Comment #156
quietone commentedI was mistaken, it is in the wiki, not the manual, https://wiki.php.net/rfc/scalar_type_hints
Comment #157
acbramley commentedRe #140 I swapped the negation because it was requested back in #127
The issue summary has been mangled and now contains only the proposed text.
Comment #158
quietone commented@acbramley. thanks. I have restored the issue summary.
I did ask for the negation to be swapped in #127 and that was done. Thanks. And now a core committer has asked for that to be put back. @donquixote did that and added some further refinements which I put into comment #154. That brings this back to the original style here. Given that, and although I still stand by my view, I do not want that to prevent progress here. And even more so since this was as Step 8 before the change. From now on, I'll facilitate on this issue.
So is #154 correct and should be in the issue summary?
Comment #159
acbramley commentedThanks @quietone, #154 is looking better than what's in the IS.
I would change "does not allow null" to "is not nullable".
However, I'm hesitant to support needing a description just on the basis that something is nullable, especially for returns.
For example, if we have:
public function getTitle(): ?stringIf would be nice to be able to omit a (IMO useless) return doc like this:
Comment #160
catchYeah I think nullable arguments (probably) always need documentation. E.g. the optional $account argument on access methods should say it defaults to the current user if not set etc.
But for return types there's not a lot else to say.
Comment #161
donquixote commented(I was going to post the below yesterday but forgot to submit)
I assume it would apply to this part:
"The parameter name is derived directly from the type name." -> "The parameter name is derived directly from the class or interface name."
In that case, +1.
When I search `@param int \$\w+` in Drupal core and in vendor/symfony, I see many places where I either want to keep the existing description or see it improved. And when just looking for `int \$\w` in vendor/symfony, to find undocumented parameters, in many cases I would like to see a description.
Of course there are cases when the parameter name is clear enough, or when a description would be redundant with the description on the method itself (e.g. for a setter method).
Having a general rule to always require a description is annoying, but if we leave it to the developer, it cannot be enforced by automatic tools. A rule at least forces the developer to think, and it gives the reviewer some leverage.
Also keep in mind that, with named argument calls, it is harder than before to rename an existing parameter that is considered part of a public API. As a consequence, we will have parameters names that are not ideal.
I think this would be a good idea, yes.
The rule proposed here when this issue was started to determine when to omit the description does not really work for scalar types.
The newly proposed rule "the parameter name is self documenting" would work but is not enforceable.
So I would prefer to handle this in a separate issue.
Comment #162
donquixote commentedI don't think it is useless.
In many cases, the NULL case is actually more interesting.
E.g. "The entity identifier, or NULL if the object does not yet have an identifier.".
For entities, this generally means that the object is a "stub" and has not been saved in the database yet.
"The title, or null if there's not one."
This could mean the specific entity does not have a title, or that entities of this type never have a title.
Given that this description will be in an interface method, it is worthwhile to have a description.
I think it is best to move piecemeal on relaxing the doc requirements, and for each step we can look at specific examples.
Comment #163
catchThis isn't the case with Drupal core because we've explicitly excluded named arguments from the bc policy (with one exception for attributes), so we can and will rename method arguments to improve them. And contrib can also do this if it wants too.
Comment #164
quietone commentedI have updated the IS with the proposed text in #154 and the suggestion in #159.
#151 and #161 support a new issue for discussing the details of for scalars.
Comment #165
nicxvan commentedMaybe 2 should be
That covers is not nullable, classes and scalars right?
Comment #166
donquixote commentedIt should, but I can see how some people might find it ambiguous when looking at `?MyClass` types.
I always prefer the explicit "don't make me think" style, even at the cost of having some perceived redundancy.
It is like in Monopoly go to jail card, which says "Do not pass go" and then "Do not collect $200".
The current version is contradictory.
We first talk about "class or interface", then later we talk about scalars.
Either we omit scalars from the proposal (which I prefer), or we have to include them in condition 2.
-----
Another problem with the current proposal is what is being replaced.
If we truly replace the entire section in "Current text", then we start with "An @param tag must have a description, unless ...", without having specified when a "@param" tag is needed.
The "Current text" says "Each parameter of a function must be documented with a @param tag (see exceptions below).". We seem to drop this completely.
Even if we do want to relax this requirement (which I would consider wrong for the scope of this issue), there should at least be something before we start talking about the description for a @param tag.
Comment #167
donquixote commentedIn fact, the "Current text" says nothing about parameter description or return description.
Further below we have separate sections about "@param" and "@return":
Even here it is not fully clear to me that the param description is required.
It says "The following paragraph is considered by the API module to be documentation.", but does this mean it is required?
Perhaps some of the changes can move here. But I am not really sure.
Comment #168
quietone commentedformatting fix only
Comment #169
quietone commentedRestore sentence missed in a copy/paste action. Addresses the last point in #166
Comment #170
quietone commented@donquixote, it would help me if you could add proposed text to go along with your comments.
#167 points out the @param and @return sections that are later on the page are not discussed here. These are in the "Tag reference" section which, as I read it, is about syntax and not about the conditions needed to use a tag, or in this case a description as well.
#166, first part. Since scalar was in the version that was approved here and in a core committer meeting, I have put that back in the proposed text and added some indentation. That should make the cases clearer. And that still leaves the option to open another issue to adjust that as needed.
Comment #171
nicxvan commentedThat looks great now!
Comment #172
xjmRe: "type hint" versus "type-hint", this is an American English grammar standard thing. It depends on where it's used in the sentence and what part of speech it is. I will just correct the final proposal according to the Chicago Manual of Style rather than taking up community time on it. 😅
A small inconsistency between the two sections: Do we want to say "does not allow null" or "is not nullable"? The former is more clear and more standard English, I think, even though the latter is what I probably use more often in everyday speech. Edit: Although it appears @acbramley suggested the opposite in #159. 🤷♀️
Comment #173
xjmThis sort of reminds me of a very good point @msonnabaum made to me many many years ago that I still keep in my head when I do committer reviews, which is that our reliance on API documentation sometimes leads to us using parameter and method names that are not as self-documenting as they should be. What we want is definitely to focus this policy on 1:1 things where it's like
string $entity_type The entity type.and such. I think we will learn a lot from actually implementing our policy once it's adopted, and the meta issues where we actually implement this will probably prompt corresponding issues to improve the names of some parameters to be more self-documenting.This is part of why I resisted proposals like this for so long. I think it's only become tenable now that PHP and core have both evolved toward a more strictly typed API.
Also standardizing "a
@paramversus "an@param" in the proposed text. I actually say "an a' param" aloud (with a glottal stop for some reason apparently), but the current node/1354 text seems to use "a" as the standard article, as if it were just pronounced "param" (no "at").Or vice versa?
Comment #174
donquixote commentedWe are still losing parts of the existing text, without an explicit intention to do so.
Especially the points about
@returntag being required.Let's try again.
Current text
Proposed text
EDIT: I am not sure if we need the bit about the "fully-qualified name", I think this is already covered elsewhere, or not?
And for the bullet list, we could break this up.
Comment #175
acbramley commentedI suggested that "is not nullable" is better from my pov as a developer. It sounds like that's what you'd prefer too so I don't know what the opposite is? I don't really care that much though.
Comment #176
quietone commented#174. This is suggesting is adding back some lines from the current text. That does add clarification so I have updated the proposed text in the issue summary with this version. The "fully-qualified type" has been kept because that was agreed to earlier in the issue and by a committer meeting. There are other issues about when to use the FQN so I suggest those issues are used to thoroughly define when to fully qualify something.
#172
1) Thanks @xjm, your English grammar knowledge is better than mine.
2) #172. Re the choice of "does not allow null" or "is not nullable". Since there is agreement on the idea here the actual text chosen can be left to the Committee to make a final decision. Part of the responsibility of the Committee is to keep the tone and style of the standards consistent.
So, what I did is search the standards for the use of 'null' and didn't find an existing case similar to this one. That means we are making a new decision here. In that case, I would use what xmj says is "more standard English", which is "does not allow null". That phrase is now used in both cases in the proposed text.
Comment #177
donquixote commentedMy problem with this "fully-qualified" is that this can only apply to classes/interfaces.
E.g. if you have this:
Here some parts of these
@paramdocs have fully-qualified names, for other parts this term does not apply.To recap from https://www.php.net/manual/en/language.namespaces.rules.php:
As such, it does not really make sense to ask for the entire type to be "fully qualified", only specific namespace-aware symbols within the type can be fully-qualified.
And here I thought it is preferable to just define in one place that all namespace-aware symbols in any doc type must be fully-qualified, instead of repeating this everywhere.
(Of course we might at some point relax this requirement, but this is out of scope for this issue.)
(I think the main argument to use FQN is to not have imports only for doc types.)
Comment #178
acbramley commentedI think we're getting far too nit picky with this, I'm fine with leaving fully-qualified how it is.
However, I think where we've landed in the IS is a bit more ambiguous than we had in earlier iterations. This line doesn't make sense to me:
We wouldn't have a @param tag without a description, and we wouldn't have a @param tag with a type that's different to the signature.
It's also not clear that if there is at least 1 @param tag, all params must be documented (afaik that is a requirement)
Comment #179
quietone commentedAt the last meeting @acbramley and @borisson_ agreed that restoring the line "Each parameter of a function must be documented with a @param tag (see exceptions below"). I have made that change to the issue summary
#3527210: Coding Standards Meeting Wednesday 2025-06-25 0900 UTC
Comment #180
catchI think this is ready to go. We can make very minor tweaks to the wording once the policy is in place if we need to, but I don't really think we're discussing the policy itself any more.
Comment #181
nicxvan commentedUpdating steps based on @borisson_'s feedback in slack.
Comment #183
quietone commentedConverted the change to an MR
Comment #184
mstrelan commentedWhat is the next step? The docs say it should have the "Needs announcement for final discussion" tag added once it's been approved by the committee. That appears to have happened in June: #3527210: Coding Standards Meeting Wednesday 2025-06-25 0900 UTC.
Comment #185
quietone commentedI think the next things are
1. Check the MR is correct
2. Make issues for Coder. I tested with the following examples.
Examples:
1. Original
Allowed
and
Error: Drupal.Commenting.VariableComment.MissingVar
Original
Allowed
Error: Drupal.Commenting.FunctionComment.MissingParamComment
Original
Allowed
* @return \Drupal\Core\DrupalKernelInterfaceError: Drupal.Commenting.FunctionComment.MissingReturnComment
So, this means that these sniffs are stricter than desired. Devs will still need to comply with the stricter rules until the sniffs are changed.
Comment #186
quietone commentedforgot to add tag
Comment #187
quietone commentedCan someone confirm the MR matches the changes in the issue summary?
Comment #188
quietone commentedOops, sorry. @borisson_ confirmed the MR is correct in the last meeting, #3549265: Coding Standards Meeting Wednesday 2025-10-29 0900 UTC
Comment #189
quietone commentedNeeds issues for Coder, refer to comment 185
Comment #190
geek-merlinForst of all, +1000 for updating code style that was created when php had no types.
The current MR does not make sense though:
(Omit the description if ... parameter name ...???)
What would make sense:
At least this is my best effort to match the words of the MR w/ the points made in the discussion (which i did my best to read most, but tbh not completely all).
Original MR for reference:
Comment #191
geek-merlinIn the next step let me challenge the name-derived-from-type condition. What is it meeded for? If a parameter name is not derived from a type, what is won from duplicating it in a phpdoc.
I.e., what is won from
over
(If i missed the reasoning, let's at least add it to the IS.)
Comment #192
geek-merlinAlso when i cross-checked the above in the IS, the reasoning does not match the proposal anymore.
Comment #193
catchI can understand the example in the issue summary but not the suggestion in #191. Suggest we get the coding standards change in, wording changes to the documentation that don't conflict with the meaning of the coding standard itself can happen later.
Comment #194
quietone commentedThanks to ghost of drupal past there is now a Coder issue and one they have agreed to work on. Yah!
Comment #195
ghost of drupal pastI note coder already does not enforce @param and @return tags at all.
I have submitted a PR which allows omitting the @var comment when appropriate:
Comment #196
quietone commentedThanks to @ghost of drupal past for continuing to push this along. I had hoped to commit this about 5 days ago but busy family life and a major storm here has interrupted my plans for many things.
I now see that there has been no review of the change record. I have done that now and expanded it a bit, linking to the docs. I think that is needed so that the criteria that must be met stays in one place.
With that done, I see nothing to prevent commit of this issue. In this case, Coder will be enforcing stricter rules and that is better than Coder having looser rules which brings in the potential for delays on issues.
Comment #198
quietone commentedCommitted!
Thanks everyone!