Skip to content

Readonly classes cannot be combined with #[AllowDynamicProperties] - #3738

Merged
ondrejmirtes merged 7 commits into
phpstan:2.0.xfrom
staabm:readonly-dynm
Dec 20, 2024
Merged

ondrejmirtes merged 7 commits into
phpstan:2.0.xfrom
staabm:readonly-dynm

Conversation

@staabm

@staabm staabm commented Dec 17, 2024

Copy link
Copy Markdown
Contributor

@staabm
staabm marked this pull request as ready for review December 17, 2024 10:57
@phpstan-bot

Copy link
Copy Markdown
Collaborator

This pull request has been marked as ready for review.

Comment thread tests/PHPStan/Rules/Classes/data/bug-12281.php

@ondrejmirtes ondrejmirtes left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We also need to error when this attribute is used above interfaces. Also please check what happens above enums and traits (I'm not sure).

Comment thread src/Rules/Classes/ClassAttributesRule.php Outdated
Comment thread src/Rules/Classes/ClassAttributesRule.php
Comment thread tests/PHPStan/Rules/Classes/data/bug-12281.php
@staabm

staabm commented Dec 17, 2024 •

Copy link
Copy Markdown
Contributor Author

We also need to error when this attribute is used above interfaces. Also please check what happens above enums and traits (I'm not sure).

I have tested this cases and linked the 3v4l.org examples in phpstan/phpstan#12281 (comment)

TL;DR:

  • enums not allowed
  • interfaces not allowed
  • traits not allowed

what do you think about adding a separate AllowDynamicPropertiesAttributeRule which targets ClassLike instead of adding this error to the existing rule?
(atm we don't have a rule which covers attributes on traits)

@ondrejmirtes ondrejmirtes left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Also:

  1. Please do new TraitAttributesRule similar to ClassAttributesRule that will call AttributesCheck. We need the rule to hook onto Trait_ and fetch the reflection ourselves from ReflectionProvider.
  2. Add AllowDynamicProperties check there too.

Comment thread src/Rules/Classes/ClassAttributesRule.php Outdated
Comment thread src/Rules/Classes/ClassAttributesRule.php Outdated
Comment thread src/Rules/Classes/ClassAttributesRule.php Outdated
Comment thread tests/PHPStan/Rules/Classes/data/bug-12281.php Outdated
Comment thread src/Rules/Classes/ClassAttributesRule.php Outdated
Comment thread src/Rules/Classes/ClassAttributesRule.php Outdated
Comment thread src/Rules/Traits/TraitAttributesRule.php Outdated
}

$errors = $this->attributesCheck->check(
$scope,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We need to do something with $scope here. Please recreate this problem 3447391 but with a trait.

We probably need to do $scope->enterTrait() here before calling the check. Just do if !$scope instanceof MutatingScope then throw ShouldNotHappen.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I have adjusted the PR. I think I have reproduced the problem you are after.

adding $scope->enterTrait($classReflection) didn't work and throws:

2) PHPStan\Rules\Traits\TraitAttributesRuleTest::testBug12011
PHPStan\ShouldNotHappenException: Internal error.

C:\dvl\Workspace\phpstan-src-staabm\src\Analyser\ScopeContext.php:44
C:\dvl\Workspace\phpstan-src-staabm\src\Analyser\MutatingScope.php:2935
C:\dvl\Workspace\phpstan-src-staabm\src\Rules\Traits\TraitAttributesRule.php:49
C:\dvl\Workspace\phpstan-src-staabm\src\Analyser\FileAnalyser.php:111
C:\dvl\Workspace\phpstan-src-staabm\src\Analyser\NodeScopeResolver.php:482
C:\dvl\Workspace\phpstan-src-staabm\src\Analyser\NodeScopeResolver.php:354
C:\dvl\Workspace\phpstan-src-staabm\src\Analyser\NodeScopeResolver.php:842
C:\dvl\Workspace\phpstan-src-staabm\src\Analyser\NodeScopeResolver.php:307
C:\dvl\Workspace\phpstan-src-staabm\src\Analyser\FileAnalyser.php:212
C:\dvl\Workspace\phpstan-src-staabm\src\Analyser\Analyser.php:75
C:\dvl\Workspace\phpstan-src-staabm\src\Testing\RuleTestCase.php:177
C:\dvl\Workspace\phpstan-src-staabm\src\Testing\RuleTestCase.php:138
C:\dvl\Workspace\phpstan-src-staabm\tests\PHPStan\Rules\Traits\TraitAttributesRuleTest.php:78

at this point I have no idea what todo. could you fix the remaining thing?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

let me fix the build real quick

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Push the code that's crashing like that please, I will take a look

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

here you are

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Oh right, we need to be in a class first before we can enter a trait.

I'd try two things: try to put the trait reflection into enterClass (but a different ShouldNotHappen might be thrown, not sure).

If that fails, we need to come up with some fake class to put into enterClass before we can enterTrait. It might be okay to simulate some anonymous Class_ node to use.

If it's too much work, don't worry and I'll merge the original code that doesn't use MutatingScope at all.

@staabm staabm Dec 19, 2024 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I have class-faking without a thrown exception working. the test-case is still failling though

Will have another look after sleeping over it

@ondrejmirtes

Copy link
Copy Markdown
Member

Please keep this on 2.0.x. We don't need to be adding new features to 1.12.x anymore.

@clxmstaab
clxmstaab force-pushed the readonly-dynm branch 2 times, most recently from 05dfb04 to 4fc9574 Compare December 19, 2024 17:00
@staabm
staabm changed the base branch from 1.12.x to 2.0.x December 19, 2024 17:00
Comment thread src/Rules/Traits/TraitAttributesRule.php Outdated
ondrejmirtes and others added 3 commits December 19, 2024 21:37
@ondrejmirtes

Copy link
Copy Markdown
Member

I changed my mind, I'm going to adjust it myself, thanks!

Some attribute arguments actually depend on using class instead of the trait

So we have to analyse the attributes in context of each class that uses the trait
@ondrejmirtes

Copy link
Copy Markdown
Member

See my commit and reasoning in description: b1cebc2

@ondrejmirtes

Copy link
Copy Markdown
Member

Please stop force-pushing here, I said I'm taking over. Thanks.

@ondrejmirtes
ondrejmirtes force-pushed the readonly-dynm branch 2 times, most recently from b85805f to b2b833c Compare December 20, 2024 08:52
@staabm

staabm commented Dec 20, 2024

Copy link
Copy Markdown
Contributor Author

Please stop force-pushing here, I said I'm taking over. Thanks.

oh sorry, did not see your comments. I got it working just a moment ago ;)

@ondrejmirtes
ondrejmirtes merged commit 202dd81 into phpstan:2.0.x Dec 20, 2024
@ondrejmirtes

Copy link
Copy Markdown
Member

Thank you!

@staabm
staabm deleted the readonly-dynm branch December 20, 2024 09:00
@staabm

staabm commented Dec 20, 2024

Copy link
Copy Markdown
Contributor Author

thanks

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.

readonly classes cannot be combined with #[AllowDynamicProperties]

3 participants