Skip to content

PHP8 specific removed create_function error #588

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

Closed
wants to merge 1 commit into from

Conversation

mglaman
Copy link
Contributor

@mglaman mglaman commented Jul 23, 2021

Part of phpstan/phpstan#5368

This handles an improved error message when running on PHP8 to explain why the function no longer exists.

@@ -39,6 +44,14 @@ public function processNode(Node $node, Scope $scope): array
}

if (!$this->reflectionProvider->hasFunction($node->name, $scope)) {
// @todo this feels a bit hacky, maybe we need a repository of
// functions that are removed based on version level?
if ($this->phpVersion->getVersionId() >= 80000 && (string) $node->name === 'create_function') {
Copy link
Member

Choose a reason for hiding this comment

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

We already have that: https://github.com/JetBrains/phpstorm-stubs/blob/5cae90f74aa33a4cdbeb4da654525fe665e735c9/Core/Core.php#L755-L768

PHPStan should currently read the @removed annotation That's done here: https://github.com/ondrejmirtes/BetterReflection/blob/348a8777d11b9dd88f13e0d99a84d1671a8cf8a7/src/SourceLocator/SourceStubber/PhpStormStubsSourceStubber.php#L410-L417

But it's probably skipped or unused for functions. It works for classes+methods because RuntimeReflectionProvider is skipped in here:

if ($this->phpStormStubsSourceStubber->hasClass($className)) {
// check that userland class isn't aliased to the same name as a class from stubs
if (!class_exists($className, false)) {
return true;
}

But RuntimeReflectionProvider isn't skipped for functions:

public function hasFunction(\PhpParser\Node\Name $nameNode, ?Scope $scope): bool
{
$has = $this->reflectionProvider->hasFunction($nameNode, $scope);
if (!$has) {
return false;
}
if ($this->singleReflectionInsteadOfFile === null) {
return true;
}
$functionReflection = $this->reflectionProvider->getFunction($nameNode, $scope);
if (!$functionReflection instanceof ReflectionWithFilename) {
return true;
}
return $functionReflection->getFileName() !== $this->singleReflectionInsteadOfFile;
}

Try to prototype some code in the last location to see if you get anywhere and the function is detected as removed.

You could try to check PhpStormStubsSourceStubber::isPresentFunction() === false which should say that the function no longer exists on PHP 8 and skip in that case.

@ondrejmirtes
Copy link
Member

Oh, I haven't noticed this is actually already reported on PHP 8: https://phpstan.org/r/7b7db20f-8b1d-411d-9d9e-41dbec9bae4d

So all of my advice here is actually outdated, it already works. So I don't think it's worth doing a special message about this in PHPStan - the fact that the function does not exist is correct and it's up to the user to educate themselves about it. I understand why you'd want a special message here, but I don't think that widening the scope of this tool is worth it - it would take too much effort to explain everything like this when PHP manual does already a good job at this.

@ondrejmirtes
Copy link
Member

And the reason why this works is this line in RuntimeReflectionProvider:

if ($this->phpStormStubsSourceStubber->isPresentFunction($name) === false) {
return false;
}

@mglaman
Copy link
Contributor Author

mglaman commented Jul 30, 2021

+1 to closing this. Fixing phpstan/phpstan#5373 and getting core functions to report deprecation is a better step.

@mglaman mglaman deleted the php8-create-function-removed branch July 30, 2021 20:11
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.

2 participants