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

Remove inefficient caching from PhpMethodReflection #3534

Merged
merged 15 commits into from
Oct 8, 2024

Conversation

staabm
Copy link
Contributor

@staabm staabm commented Oct 3, 2024

@phpstan-bot
Copy link
Collaborator

You've opened the pull request against the latest branch 2.0.x. PHPStan 2.0 is not going to be released for months. If your code is relevant on 1.12.x and you want it to be released sooner, please rebase your pull request and change its target to 1.12.x.

@staabm
Copy link
Contributor Author

staabm commented Oct 3, 2024

as of now this PR only implements the PhpMethodReflection part. we would need the same thing for PhpFunctionReflection. Will do the 2nd part after a first feedback round.

@staabm staabm force-pushed the less-caching branch 3 times, most recently from af3a0c8 to 0b51b89 Compare October 3, 2024 17:51
@staabm staabm marked this pull request as ready for review October 3, 2024 17:58
@phpstan-bot
Copy link
Collaborator

This pull request has been marked as ready for review.

@ondrejmirtes
Copy link
Member

PhpFunctionReflection too please.

@staabm
Copy link
Contributor Author

staabm commented Oct 3, 2024

PhpFunctionReflection too please.

here we go

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, having SimpleParserTest unit test to check for the attributes existence would also be nice.

conf/config.neon Show resolved Hide resolved
src/Parser/VariadicFunctionsVisitor.php Outdated Show resolved Hide resolved
@staabm staabm force-pushed the less-caching branch 3 times, most recently from 21e164b to 2496e8a Compare October 6, 2024 18:57
@staabm
Copy link
Contributor Author

staabm commented Oct 6, 2024

btw: On my mac with this PR we are ~1-2 seconds slower when running time make phpstan in comparison to before this PR - I will have another look why this is the case

src/Parser/VariadicMethodsVisitor.php Outdated Show resolved Hide resolved
}

$this->classStack[] = $className;
$this->inClassLike = $this->inNamespace !== null ? $this->inNamespace . '\\' . implode('\\', $this->classStack) : implode('\\', $this->classStack);
Copy link
Member

Choose a reason for hiding this comment

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

We don't need this property. We should always read the last entry in classStack

Copy link
Contributor Author

Choose a reason for hiding this comment

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

AnonymousClassNode is not contained in ClassLike

Copy link
Member

Choose a reason for hiding this comment

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

Err, what? final class AnonymousClassNode extends Class_, class Class_ extends ClassLike.

src/Parser/VariadicMethodsVisitor.php Outdated Show resolved Hide resolved
tests/PHPStan/Parser/ParserTest.php Show resolved Hide resolved
|| $node instanceof Node\Stmt\ClassLike
) {
if (!$node->name instanceof Node\Identifier) {
$className = 'class@anonymous:' . $node->getStartLine();
Copy link
Member

Choose a reason for hiding this comment

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

This isn't sufficiently unique. This was recently fixed elsewhere by #3328.

return $this->functionCallStatementFinder->findFunctionCallInStatements(ParametersAcceptor::VARIADIC_FUNCTIONS, $node->getStmts()) !== null;
if (
is_array($variadicMethods)
&& array_key_exists($declaringClass->getName(), $variadicMethods)
Copy link
Member

Choose a reason for hiding this comment

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

This should do the class@anonymous thing that's done by the visitor too. I don't think we'll be able to replicate the anonymous class index here and we should do more something like a column instead.

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 did not find column information in the reflection api.
instead I used start/end-of line combination of the class definition for now.

Comment on lines 61 to 66
$this->classStack[] = $className;
$this->inClassLike = $className; // anonymous classes are in global namespace
Copy link
Contributor Author

Choose a reason for hiding this comment

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

because of this special case I had to re-introduce the inClassLike property to make sure the keys of a anonymous class don't contain a namespace. thats required so I am able to build a matching array-offset in PhpMethodReflection.

@staabm
Copy link
Contributor Author

staabm commented Oct 8, 2024

with the latest push we are now able to properly handle func_get_args based variadics in anonymous classes, which we did not got right before this PR:

https://phpstan.org/r/5c9c464b-5bef-40c3-b902-c9891308a2f7

@staabm staabm marked this pull request as draft October 8, 2024 07:45
@staabm staabm marked this pull request as ready for review October 8, 2024 08:22
@phpstan-bot
Copy link
Collaborator

This pull request has been marked as ready for review.

@ondrejmirtes
Copy link
Member

Hey, I still saw too many things I'd do differently so I rolled up my sleeves and did them: d4d5c1a

No tests are failing for me. Feel free to write more tests if you think your code covered a scenario that mine doesn't. Thanks!

@staabm
Copy link
Contributor Author

staabm commented Oct 8, 2024

thank you. thats way simpler - awesome.

@@ -296,19 +252,4 @@ public function acceptsNamedArguments(): TrinaryLogic
return TrinaryLogic::createFromBoolean($this->acceptsNamedArguments);
}

private function isFunctionNodeVariadic(Function_ $node): bool
Copy link
Contributor Author

@staabm staabm Oct 8, 2024

Choose a reason for hiding this comment

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

I wonder why this $node->params logic is no longer reflected in the patch. it seems it was dead code before

Copy link
Member

Choose a reason for hiding this comment

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

It's really old code, maybe there just wasn't a test for it. Since we're in 2.0.x, we can risk it, and maybe introduce it back if it breaks someone's scenario.

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 think it was unnecessary logic I implemented with 0ee67d5#diff-3ac4e5d4a520618a490963b70e3fcd428d56aea61683641020393167fff2ca5d

deleting the lines on 2.0.x before this PR, also doesn't break tests :).

all good.

@ondrejmirtes ondrejmirtes merged commit dddf984 into phpstan:2.0.x Oct 8, 2024
392 of 449 checks passed
@ondrejmirtes
Copy link
Member

It's a bit slower but maybe we'll find opportunities elsewhere :) Thank you.

@staabm
Copy link
Contributor Author

staabm commented Oct 8, 2024

thank you!

@staabm staabm deleted the less-caching branch October 8, 2024 11:52
@ondrejmirtes
Copy link
Member

Oh yeah, I did it: 19cd999

Previously VariadicMethodsVisitor::$cache was not really useful, it only stored true values so the files were parsed over and over again.

@ondrejmirtes
Copy link
Member

In my measurements it's now fast as before without writing anything to disk.

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.

3 participants