Skip to content

Commit

Permalink
Fix Access to an undefined static property in Closure::bind
Browse files Browse the repository at this point in the history
  • Loading branch information
VincentLanglet committed Mar 31, 2021
1 parent 3f712be commit 2f2639c
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 5 deletions.
17 changes: 12 additions & 5 deletions src/Analyser/MutatingScope.php
Expand Up @@ -318,21 +318,29 @@ public function enterDeclareStrictTypes(): self

public function isInClass(): bool
{
return $this->context->getClassReflection() !== null;
return $this->getClassReflection() !== null;
}

public function isInTrait(): bool
{
return $this->context->getTraitReflection() !== null;
return $this->getTraitReflection() !== null;
}

public function getClassReflection(): ?ClassReflection
{
if ($this->inClosureBindScopeClass !== null && $this->inClosureBindScopeClass !== 'static') {
return $this->reflectionProvider->getClass($this->inClosureBindScopeClass);
}

return $this->context->getClassReflection();
}

public function getTraitReflection(): ?ClassReflection
{
if ($this->inClosureBindScopeClass !== null && $this->inClosureBindScopeClass !== 'static') {
return null;
}

return $this->context->getTraitReflection();
}

Expand Down Expand Up @@ -2407,10 +2415,9 @@ public function resolveName(Name $name): string
public function resolveTypeByName(Name $name): TypeWithClassName
{
if ($name->toLowerString() === 'static' && $this->isInClass()) {
$classReflection = $this->getClassReflection();

return new StaticType($classReflection);
return new StaticType($this->getClassReflection());
}

$originalClass = $this->resolveName($name);
if ($this->isInClass()) {
$thisType = new ThisType($this->getClassReflection());
Expand Down
9 changes: 9 additions & 0 deletions tests/PHPStan/Analyser/AnalyserIntegrationTest.php
Expand Up @@ -401,6 +401,15 @@ public function testBug4715(): void
$this->assertCount(0, $errors);
}

public function testBug4734(): void
{
$errors = $this->runAnalyse(__DIR__ . '/data/bug-4734.php');
$this->assertCount(2, $errors);

$this->assertSame('Access to an undefined static property Bug4734\Foo::$httpMethodParameterOverride3.', $errors[0]->getMessage());
$this->assertSame('Access to an undefined property Bug4734\Foo::$httpMethodParameterOverride4.', $errors[1]->getMessage());
}

/**
* @param string $file
* @return \PHPStan\Analyser\Error[]
Expand Down
44 changes: 44 additions & 0 deletions tests/PHPStan/Analyser/data/bug-4734.php
@@ -0,0 +1,44 @@
<?php

namespace Bug4734;

use function PHPStan\Analyser\assertType;

class Foo
{
/**
* @var bool
*/
private static $httpMethodParameterOverride = true;

/**
* @var bool
*/
private $httpMethodParameterOverride2 = true;
}

class Bar
{
public function test(): void
{
$disableHttpMethodParameterOverride = \Closure::bind(static function (): void {
static::$httpMethodParameterOverride = false;
}, new Foo(), Foo::class);
$disableHttpMethodParameterOverride();

$disableHttpMethodParameterOverride2 = \Closure::bind(function (): void {
$this->httpMethodParameterOverride2 = false;
}, new Foo(), Foo::class);
$disableHttpMethodParameterOverride2();

$disableHttpMethodParameterOverride3 = \Closure::bind(function (): void {
static::$httpMethodParameterOverride3 = false;
}, new Foo(), Foo::class);
$disableHttpMethodParameterOverride3();

$disableHttpMethodParameterOverride4 = \Closure::bind(function (): void {
$this->httpMethodParameterOverride4 = false;
}, new Foo(), Foo::class);
$disableHttpMethodParameterOverride4();
}
}

0 comments on commit 2f2639c

Please sign in to comment.