Problem/Motivation

We can improve the typing of the return values of methods of MenuLinkManagerInterface so PHPStan on higher levels doesn't complain so much. This is primarily useful for consumers of MenuLinkManager, as core is currently at a lower level with a large baseline.

Note that the menu definitions returned by MenuLinkInterface and descendants (MenuLinkBase, MenuLinkDefault, etc), and MenuTreeStorage/MenuTreeStorageInterface are distinctly different, so they do not share the same type.

MenuLink definitions can have arbitrary keys, and MenuTreeStorage also has level (P*) columns.

I think MenuLinkItemInterface etc will need to use a generic, anyway.

Steps to reproduce

Make calls to MenuLinkManagerInterface methods in a private project with a high PHPSTan level.

Run \PHPStan\dumpType() on the result of the methods.

See the results do not have any keys or typing.

Proposed resolution

Introduce two PHPStan types, which have array shapes of menu link definitions.

One is a fully hydrated definition, the other is a partial, which includes the same typing, except all keys are optional.

Update calls and usages where definitions are passed around, making the calls more strict. Where getDefinition is used to determine existence, switch to hasDefinition instead.

Remaining tasks

Improve docs.

User interface changes

Nil.

Introduced terminology

Nil.

API changes

PHPDocs

Data model changes

Nil.

Release notes snippet

Nil.

Issue fork drupal-3523800

Command icon 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:

Comments

dpi created an issue. See original summary.

dpi’s picture

Issue summary: View changes

dpi’s picture

Issue summary: View changes
dpi’s picture

Assigned: dpi » Unassigned
Status: Active » Needs review
borisson_’s picture

I'm unsure about this, while we do allow phpstan types to be added in code since a recent coding standards update, this would be the first time we'd be adding a type like this as far as I know.

I'm not sure it was the intention of the coding standards committee to allow us to introduce a typing as complex as this one.

How do we make sure we keep the type compatible with the actual array structure, can phpstan help us with this or is that something we'd need to define in a test?
Should we not bother?

I do see the value in doing this though, it makes IDE's so much happier.

dpi’s picture

How do we make sure we keep the type compatible with the actual array structure, can phpstan help us with this or is that something we'd need to define in a test?
Should we not bother?

When our internal usage changes, either regular runtime or tests, PHPStan will display errors.

For example if we add a new array key to the structure, and a test makes use of that new key, PHPStan will complain the key does not exist.

The same applies to removals, type changes, restructures, etc.

mondrake’s picture

This would be very very nice, but aside from @borisson_ comment above, I wonder whether we are ready for it.

If I am not mistaken, https://phpstan.org/user-guide/rule-levels, the actual checking of the array shapes' contents will start from PHPStan level 5 above; we are currently struggling with level 1...

So we may be introducing non-validated typing that could become later a barrier rather than a facilitation to move to upper levels. Happy to be mistaken though.

borisson_’s picture

If I am not mistaken, https://phpstan.org/user-guide/rule-levels, the actual checking of the array shapes' contents will start from PHPStan level 5 above; we are currently struggling with level 1...

This is already noted in the Issue Summary as well. I agree - I don't think we can start doing this without us being on level 5 as well, because the arguments in #7 need level 5 to be valid.

dpi’s picture

the actual checking of the array shapes' contents will start from PHPStan level 5 above; we are currently struggling with level 1...

- I don't think we can start doing this without us being on level 5 as well,

Level 2, not 5, by the looks: https://phpstan.org/r/63bdb4f4-ca81-4423-8828-9da62ef4a5c9

According to that try page, perhaps it is enforcable with just enabling reportPossiblyNonexistentGeneralArrayOffset, and we could baseline on that.

Stan and typing doesnt start and end with core. This change benefits, and is driven by, contrib and custom code.

As a project using PHPStan Lvl 9 + Strict I can immediately benefit from this.

Whether we enforce this in core now or later shouldn't matter too much, if non-core is consuming it, then it can also be responsible for reporting back to core. Just like we have to right now with the multitude of unenforced defective PHPDocs. When it comes time to core enforcing it, the amount of code is drastically reduced to simple bulk fixups, just like we would with existing PHPStan bulk changes.

smustgrave’s picture

Trying to follow but if this can't be checked in core till a different level then shouldn't it be postponed. Not sure I see many issues land that are only for contrib and not useable by core.

borisson_’s picture

Not sure I see many issues land that are only for contrib and not useable by core.

That's true, there's usually the rule that there needs to be at least one usecase in core. But I think that's mostly about code-implementations.
This will help for core development as well, since it will help everyone working with this that is using an IDE with code completion.

In hopes not to derail this issue too much, I wonder if it's a good plan to start with one random thing that returns an array as we're doing here or if we should form a plan first.

smustgrave’s picture

Not going to pretend I can speak on this one. But seems like from the comments it would be better to first formulate a plan to start implementing these kind of changes no?

borisson_’s picture

I talked about this with Matt Glaman at drupalcon last week. I'm hoping he can find a good solution for this, while a plan would be nice, I think we can start small and start adding it in places where we can add value.

I just really don't want to add this without it being validated, but it sounded like Matt had a good solution for that.

smustgrave’s picture

Status: Needs review » Needs work

So would this be the best status? Can change back if I'm wrong.

smustgrave’s picture

Thanks for sparking that conversation too!

Version: 11.x-dev » main

Drupal core is now using the main branch as the primary development branch. New developments and disruptive changes should now be targeted to the main branch.

Read more in the announcement.