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

Shebang breaks @var namespace resolution #6252

Closed
InvisibleSmiley opened this issue Dec 30, 2021 · 5 comments
Closed

Shebang breaks @var namespace resolution #6252

InvisibleSmiley opened this issue Dec 30, 2021 · 5 comments

Comments

@InvisibleSmiley
Copy link

Bug report

Adding a shebang to a script breaks @var namespace resolution.
Worked until v1.2
Broken in v1.3

Code snippet that reproduces the problem

https://phpstan.org/r/43479d60-e6c5-4319-916a-db41b72942f8

@martin-heralecky
Copy link

I am experiencing this issue as well and can confirm, that it did work in v1.2. Specifically, the commit that broke it is phpstan/phpstan-src@256d11b8.

I was digging a bit deeper today and traced the problem down to FileTypeMapper::createNameScopeMap(), concretely lines 374-395:

$nameScopeKey = $this->getNameScopeKey($originalClassFileName, $className, $lookForTrait, $functionName);
if (
        $node instanceof Node\Stmt
        && !$node instanceof Node\Stmt\Namespace_
        && !$node instanceof Node\Stmt\Declare_
        && !$node instanceof Node\Stmt\DeclareDeclare
        && !$node instanceof Node\Stmt\Use_
        && !$node instanceof Node\Stmt\UseUse
        && !$node instanceof Node\Stmt\GroupUse
        && !$node instanceof Node\Stmt\TraitUse
        && !$node instanceof Node\Stmt\TraitUseAdaptation
        && !array_key_exists($nameScopeKey, $nameScopeMap)
) {
        $nameScopeMap[$nameScopeKey] = static fn (): NameScope => new NameScope(
                $namespace,
                $uses,
                $className,
                $functionName,
                ($typeMapCb !== null ? $typeMapCb() : TemplateTypeMap::createEmpty()),
                $typeAliasesMap,
        );
}

If we assume to analyze the following snippet:

#!/usr/bin/env php
<?php

use FooNamespace\FooClass;

/** @var FooClass $f */

then the if-condition would be satisfied for two Nodes:

  1. The first one is a Node\Stmt\InlineHTML, which represents the shebang line, but is otherwise "empty" ($namespace is null, $uses is empty, $className is null...). I am not sure, whether a NameScope should even be created for this node.
  2. The other one is a Node\Stmt\Nop and it is filled correctly (mainly I was looking at $uses, which, as expected, contained the use from the snippet).

Now the problem is, that the second NameScope is actually never created, because the last condition of the if is not satisfied (!array_key_exists($nameScopeKey, $nameScopeMap)). The reason for this is that $nameScopeKey is only based on the filename, since all $className, $lookForTrait, and $functionName are null ($nameScopeKey = $this->getNameScopeKey($originalClassFileName, $className, $lookForTrait, $functionName);) and thus the keys for both Nodes are the same.

That's as far as my digging went, but unfortunately I don't have the necessary insight into the internal workings of PHPStan to figure out what would be the correct approach to solve this issue.

Any suggestions? @ondrejmirtes

@ondrejmirtes
Copy link
Member

@martin-heralecky Thank you for your research, it seems like you'd be capable at fixing PHPStan bugs! :)

I fixed this one: phpstan/phpstan-src@c87284a

@martin-heralecky
Copy link

Excellent! When can we expect this to be released?

@ondrejmirtes
Copy link
Member

Later today

@github-actions
Copy link

github-actions bot commented Feb 5, 2022

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Feb 5, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants