Skip to content

Conversation

VincentLanglet
Copy link
Contributor

Rework of #4409
and #4415

I added a non regression of phpstan/phpstan#10215 as a proof it works.

I don't like the naming of my methods, suggestion are opened.
Also I'm not fully sure getDefaultMethodPurity shouldn't be called somewhere else too...

@VincentLanglet
Copy link
Contributor Author

I dunno which strategy you will prefer @ondrejmirtes between

The second one seems simpler to me because isPure was used multiple times like in NodeScopeResolver::getPhpDocs and it would have require more changes.


private function getClassReflection(): ?ClassReflection
{
$className = $this->nameScope?->getClassName();
Copy link
Contributor

Choose a reason for hiding this comment

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

The phpstan downgrade process does not support null-safe calls. You need regular if-null checks for php7 compat

Copy link
Member

@ondrejmirtes ondrejmirtes left a comment

Choose a reason for hiding this comment

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

I think that ResolvedPhpDocBlock should simply add isAllMethodsPure and isAllMethodsImpure.

I imagine the new tags should be handled similarly to isImmutable / isReadOnly.

Above class there can be @phpstan-immutable tag which marks all properties as readonly. And above properties you can have @phpstan-readonly.

Having @phpstan-immutable above class does not change what ResolvedPhpDocBlock says about isReadOnly.

Instead, PhpClassReflectionExtension handles this when creating properties by asking about both tags:

$isReadOnlyByPhpDoc = $isReadOnlyByPhpDoc || $resolvedPhpDoc->isReadOnly();

So handling these new tags should be equivalent.

Please do not forget to test that PureMethodRule still correctly reports errors with all possible combinations. This means that these new tags also have to be read in NodeScopeResolver::getPhpDocs() so that they're available in PhpMethodFromParserNodeReflection (which is the object used when analysing method body itself).

@VincentLanglet VincentLanglet marked this pull request as draft October 9, 2025 07:12
@VincentLanglet VincentLanglet force-pushed the allMethodsAre branch 2 times, most recently from 908d9ff to 6723fac Compare October 9, 2025 08:26
@VincentLanglet VincentLanglet marked this pull request as ready for review October 9, 2025 18:50
@phpstan-bot
Copy link
Collaborator

This pull request has been marked as ready for review.

@VincentLanglet
Copy link
Contributor Author

I think it's ready for a new review :)

Copy link
Member

@ondrejmirtes ondrejmirtes left a comment

Choose a reason for hiding this comment

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

Also I'd like some more tests:

  1. Calling all-methods-pure + nothing method from impure method (should report that impure method has no side effects)

  2. Calling all-methods-pure + 'impure' method from impure method (no errors)

  3. Calling all-methods-pure + nothing method from pure method (no errors)

  4. Calling all-methods-pure + 'impure' method from pure method (should report a side effect in a pure method)

  5. Calling all-methods-impure + nothing method from pure method (should report a side effect in a pure method)

  6. Calling all-methods-impure + 'pure' method from pure method (no errors)

  7. Calling all-methods-impure + nothing method from impure method (no errors)

  8. Calling all-methods-impure + 'pure' method from impure method (should report that impure method has no side effects)

$this->treatPhpDocTypesAsCertain = true;
$this->analyse([__DIR__ . '/data/all-methods-are-pure.php'], [
[
'Method AllMethodsArePure\Foo::test() is marked as pure but returns void.',
Copy link
Member

Choose a reason for hiding this comment

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

I think that void methods (except the constructor) should be excluded from @phpstan-all-methods-pure by default.

By looking at logic in PhpMethodReflection::hasSideEffects you can see that PHPDocs don't affect that at all.

@VincentLanglet
Copy link
Contributor Author

Lot of test added and void behavior :)

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