Skip to content
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

[TypeDeclaration] Add param type to array map closure #6377

Conversation

peterfox
Copy link
Contributor

Changes

  • Adds a new rule for type hinting closures used with array_map.
  • Adds tests.

Why

Another rule from me which will deal with the difficulties of type hinting closures. It takes the key and value types of all the arrays provided and then type hints them. If more than one array is provide and the value/key types are different it will work out the union type.

-array_map(function ($value, $key): string {
+array_map(function (string $value, int $key): string {
    return $value . $key;
}, $strings);

@peterfox peterfox requested a review from samsonasik October 12, 2024 04:02
@staabm
Copy link
Contributor

staabm commented Oct 12, 2024

Since this rule works on phpdoc types and most other rules only work on native types, do we need some special documentation or rule-set for it?

@peterfox
Copy link
Contributor Author

Since this rule works on phpdoc types and most other rules only work on native types, do we need some special documentation or rule-set for it?

@staabm

I've just recently merged a rule that also interacts with the phpdoc information #6345

There are also rules that generate PHPDoc tags https://getrector.com/rule-detail/add-return-type-declaration-from-yields-rector

@TomasVotruba
Copy link
Member

I think we should be safe here, despite risk of docblocks. Typed closures could have a standalone set, as quite nich area.
How many other closure rules that help with native array_ () cases we have here?

@peterfox
Copy link
Contributor Author

There's a number of functions off the top of my head that are in core PHP.

  • array_walk
  • array_filter
  • array_reduce
  • array_diff_uassoc

@staabm
Copy link
Contributor

staabm commented Oct 12, 2024

my point is, that inferring types based on phpdocs has a big risk of beeing wrong. I don't say that I don't like these new rules, but these make only sense if you apply them in a codebase which already has decent correct native type coverage.

thats why I think these phpdoc based rules should be somehow identifiable by the rector-user

@peterfox
Copy link
Contributor Author

I can see what you mean but technically all rules can be informed by incorrect hinting. PHPStan is informed by both native types and phpdocs. Checking an ObjectType might be only established by a PHPDoc for a parameter etc.

Comment on lines +64 to +90
/**
* @param array<int, string> $array
* @param array<int, Foo> $arrayTwo
*/
public function runTwo(array $array, array $arrayTwo)
Copy link
Member

Choose a reason for hiding this comment

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

Could you add a test fixture for following:

* @param array<int> $array

I think these should be skipped, right?

Copy link
Contributor Author

@peterfox peterfox Nov 24, 2024

Choose a reason for hiding this comment

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

I've added these to fixtures. It comes about it two different ways.

   /**
     * @param array<int, string> $array
     * @param array<string> $arrayTwo // translates to the key is either int or string and the value is string
     * @param list<string> $arrayTwo // translates to the key is either int and the value is string
     */

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've added another fixture for tuples and array spread. I'd love to make that work but it's just too complicated. I've had a dig into PHPStan and how it gets the types but it's not overly straight forward to understand how its own classes work out the types.

@TomasVotruba
Copy link
Member

My appologies for delays, we got lot of upgrade work recently.

I'll make sure this is merged 👍

@samsonasik
Copy link
Member

@peterfox rebase is needed, ensure it works with the way phpstan 2 and phpdoc-parser 2 detect it on latest main.

@peterfox peterfox force-pushed the feature/add-param-type-to-array-map-closure branch from 034af62 to 8daf5aa Compare November 24, 2024 13:51
@peterfox
Copy link
Contributor Author

@samsonasik I have now rebased the rules. No changes required.

@TomasVotruba TomasVotruba merged commit 1013a5a into rectorphp:main Dec 14, 2024
36 checks passed
@TomasVotruba
Copy link
Member

Thank you Peter!
Let's ship it 👌

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants