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

Require value types for iterables #70

Closed
wants to merge 10 commits into from

Conversation

thewilkybarkid
Copy link

This is a PR to require that the value types of iterables are defined (eg array<string> rather than just array).

I've implemented return types, but will hold for feedback. The only concern I can see is that it's not possible to allow defining @return array<mixed> (which is defining a value type; can't see how to reliably distinguish between implicit and explicit use of mixed).

(Refs libero/php-coding-standard#40.)

@ondrejmirtes
Copy link
Member

Hi,
I think you'd be reliably able to add this feature to existing rules, e.g. MissingFunctionParameterTypehintRule, MissingFunctionReturnTypehintRule, MissingMethodParameterTypehintRule, MissingMethodReturnTypehintRule.

Just ask Type::isIterable()->yes() and then Type::getIterableValueType().

The main hurdle is that it differentiates between implicit and explicit mixed, but the array is currently considered an explicit mixed. So this would be helpful only for native array typehint without any phpDoc, which is a good start.

@ondrejmirtes
Copy link
Member

You could also fix the existing rules to register them to InClassMethodNode - the correct reflection is then available in $scope->getFunction() and no exceptions for traits are needed.

@adaamz
Copy link
Contributor

adaamz commented Feb 8, 2019

btw I also tried at #35 but there were some reflection issues... is it fixed now?

@ondrejmirtes
Copy link
Member

What reflection issues?

@adaamz
Copy link
Contributor

adaamz commented Feb 8, 2019

https://travis-ci.org/phpstan/phpstan-strict-rules/jobs/490487289
on interface method parameter of type array, key/item is explicitly mixed.

image

@ondrejmirtes
Copy link
Member

I said that above:

The main hurdle is that it differentiates between implicit and explicit mixed, but the array is currently considered an explicit mixed. So this would be helpful only for native array typehint without any phpDoc, which is a good start.

So it's fine for me if the rule currently addreses native typehints without any item specification in the phpDoc.

@@ -31,7 +34,11 @@ public function processNode(Node $node, Scope $scope): array
throw new \PHPStan\ShouldNotHappenException();
}

$methodReflection = $scope->getClassReflection()->getNativeMethod($node->name->name);
if (!$scope->isInTrait()) {
Copy link
Author

Choose a reason for hiding this comment

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

I had to leave this in to get

[
'Method MissingMethodReturnTypehint\FooTrait::c1() has no return typehint specified.',
42,
],
[
'Method MissingMethodReturnTypehint\FooTrait::c2() has a return type array with no value type specified.',
46,
],
[
'Method MissingMethodReturnTypehint\FooTrait::c3() has a return type iterable with no value type specified.',
50,
],
[
'Method MissingMethodReturnTypehint\FooTrait::c4() has a return type ArrayObject with no value type specified.',
54,
],
to work. Would you not expect to check the trait directly?

Copy link
Member

Choose a reason for hiding this comment

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

Please follow my advice I gave here: #70 (comment)

Copy link
Author

Choose a reason for hiding this comment

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

I can't get that to work... I end up with the using class name but the line number from the trait (eg 42: Method MissingMethodReturnTypehint\Foo::c1() has no return typehint specified.).

Copy link
Member

Choose a reason for hiding this comment

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

Can you push this change as a new commit so I can review it?

Copy link
Author

Choose a reason for hiding this comment

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

Pushed 10eee51.

Copy link
Member

Choose a reason for hiding this comment

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

The results look fine to me, just the declaring class is wrong there - which is something we might fix in PHPStan's core, but it's not a big deal.

@thewilkybarkid
Copy link
Author

@ondrejmirtes Thanks; I've tweaked the tests slightly to remove the override, since it's now testing the class rather than the trait directly.

@thewilkybarkid thewilkybarkid changed the title [WIP] Require value types for iterables Require value types for iterables Feb 15, 2019
@thewilkybarkid
Copy link
Author

@ondrejmirtes Hopefully all done now.

@adaamz
Copy link
Contributor

adaamz commented Apr 4, 2019

@ondrejmirtes Is anything needed to merge this PR?

@ondrejmirtes
Copy link
Member

FYI I plan to move these mixed-detecting rules from strict-rules to phpstan/phpstan as a new level 6 for the new version 0.12 :) Stay tuned!

@ondrejmirtes
Copy link
Member

I just pushed an implementation of this in phpstan/phpstan: phpstan/phpstan@f58624b

Thank you!

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.

None yet

3 participants