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

ShouldNotHappenException in NonObjectTypeTrait when analyzing one of the classes #42

Closed
ssaprank opened this issue Feb 4, 2021 · 7 comments · Fixed by #43
Closed

ShouldNotHappenException in NonObjectTypeTrait when analyzing one of the classes #42

ssaprank opened this issue Feb 4, 2021 · 7 comments · Fixed by #43

Comments

@ssaprank
Copy link

ssaprank commented Feb 4, 2021

Hello everyone,

Just tried out your nice tool on one of our projects and in one of the files I get the following error:

Stack trace:

#0 /app/vendor/spaze/phpstan-disallowed-calls/src/ClassConstantUsages.php(73): PHPStan\Type\StringType->getConstant('STEP_NAME')
#1 phar:///app/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/FileAnalyser.php(70): Spaze\PHPStan\Rules\Disallowed\ClassConstantUsages->processNode(Object(PhpParser\Node\Expr\ClassConstFetch), Object(PHPStan\Analyser\MutatingScope))
#2 phar:///app/vendor/phpstan/phpstan/phpstan.phar/src/Node/ClassStatementsGatherer.php(91): PHPStan\Analyser\FileAnalyser->PHPStan\Analyser\{closure}(Object(PhpParser\Node\Expr\ClassConstFetch), Object(PHPStan\Analyser\MutatingScope))
#3 phar:///app/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(389): PHPStan\Node\ClassStatementsGatherer->__invoke(Object(PhpParser\Node\Expr\ClassConstFetch), Object(PHPStan\Analyser\MutatingScope))
#4 phar:///app/vendor/phpstan/phpst in phar:///app/vendor/phpstan/phpstan/phpstan.phar/src/Type/Traits/NonObjectTypeTrait.php on line 47

It breaks when analyzing a class that calls the STEP_NAME constant. The constant with this name is defined in multiple other classes.

Please let me know if you need more details.

@ssaprank
Copy link
Author

ssaprank commented Feb 4, 2021

UPDATE

I traced it down to a certain use case
the error appears when the constant is addressed via a variable like this

$something::STEP_NAME

@spaze
Copy link
Owner

spaze commented Feb 5, 2021

Hi @stanislau93. Thanks for the report. $variable::CONSTANT is certainly supported when defined on a class:

And now also tested where $var is a string or an object: c0195f0

Where's the STEP_NAME constant defined and how it's used?

@ssaprank
Copy link
Author

ssaprank commented Feb 5, 2021

Hello @spaze,

Thank you for the swift response

we use this constant in a static method to create a value object

public function __construct($name)
{
$this->name = $name;
$this->type = static::TYPE_NORMAL;
}

/**
 * @param string $name
 *
 * @return Step
 */
public static function create($name)
{
    return new static($name);
}

It is defined in an abstract class as a public const and later redefined in two classes that extend from it

@ssaprank
Copy link
Author

ssaprank commented Feb 5, 2021

Update:

maybe you'll reproduce it after feeding a classname to a function like this - this was actually our use case.

private function foo(string $myclass = MyClass::class)
{
      $this->bar->baz($myclass::STEP_NAME);
}

As I've mentioned before - there are multiple classes that redefine this constant

For now we've built a workaround to avoid this issue which seems to work:

    private function foo(string $myclass = MyClass::class, string $stepName = MyClass::STEP_NAME)
    {
...
          $this->bar->baz($myclass::STEP_NAME);
   ...
 }

spaze added a commit that referenced this issue Feb 6, 2021
Unfortunately, some valid use cases are not supported yet and an error will be thrown for cases like

/** @var string $monster */
$monster = DateTime::class;
$monster::COOKIE;

/** @var class-string $monster */
$monster = DateTime::class;
$monster::COOKIE;

Fix #42
@spaze spaze closed this as completed in #43 Feb 6, 2021
@spaze
Copy link
Owner

spaze commented Feb 6, 2021

Thanks. I now know where the issue it but I don't know how to fix it properly. I've only made some changes so that PHPStan is not crashing. You'll see errors like Cannot access constant COOKIE on string (or Cannot access constant COOKIE on class-string if you define the variable as class-string) which you need to add to ignoreErrors in your phpstan.neon config file.

Less than ideal but I think still better than crashes. I'll release the fix in a few days unless I get some better idea (don't hold your breath).

@spaze
Copy link
Owner

spaze commented Feb 8, 2021

1.2.0 which contains the crash fix has been released.

spaze added a commit that referenced this issue Feb 9, 2021
Unfortunately, some valid use cases are not supported yet and an error will be thrown for cases like

/** @var string $monster */
$monster = DateTime::class;
$monster::COOKIE;

/** @var class-string $monster */
$monster = DateTime::class;
$monster::COOKIE;

Fix #42
@ssaprank
Copy link
Author

ssaprank commented Feb 9, 2021

Great, many thanks for your help!

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 a pull request may close this issue.

2 participants