mirror of
https://github.com/danog/psalm.git
synced 2024-11-26 20:34:47 +01:00
Check $this
in static closures
Fixes vimeo/psalm#9148 Fixes vimeo/psalm#2813
This commit is contained in:
parent
b63061a27f
commit
70f2fb7d1b
@ -84,7 +84,7 @@ class ClosureAnalyzer extends FunctionLikeAnalyzer
|
|||||||
|
|
||||||
$codebase = $statements_analyzer->getCodebase();
|
$codebase = $statements_analyzer->getCodebase();
|
||||||
|
|
||||||
if (!$statements_analyzer->isStatic()) {
|
if (!$statements_analyzer->isStatic() && !$closure_analyzer->isStatic()) {
|
||||||
if ($context->collect_mutations &&
|
if ($context->collect_mutations &&
|
||||||
$context->self &&
|
$context->self &&
|
||||||
$codebase->classExtends(
|
$codebase->classExtends(
|
||||||
|
@ -217,7 +217,9 @@ abstract class FunctionLikeAnalyzer extends SourceAnalyzer
|
|||||||
$this->suppressed_issues += $appearing_class_storage->suppressed_issues;
|
$this->suppressed_issues += $appearing_class_storage->suppressed_issues;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($storage instanceof MethodStorage && $storage->is_static) {
|
if (($storage instanceof MethodStorage || $storage instanceof FunctionStorage)
|
||||||
|
&& $storage->is_static
|
||||||
|
) {
|
||||||
$this->is_static = true;
|
$this->is_static = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1120,6 +1120,8 @@ class FunctionLikeNodeScanner
|
|||||||
|
|
||||||
$storage = $this->storage = $this->file_storage->functions[$function_id] = new FunctionStorage();
|
$storage = $this->storage = $this->file_storage->functions[$function_id] = new FunctionStorage();
|
||||||
|
|
||||||
|
$storage->is_static = $stmt->static;
|
||||||
|
|
||||||
if ($stmt instanceof PhpParser\Node\Expr\Closure) {
|
if ($stmt instanceof PhpParser\Node\Expr\Closure) {
|
||||||
foreach ($stmt->uses as $closure_use) {
|
foreach ($stmt->uses as $closure_use) {
|
||||||
if ($closure_use->byRef && is_string($closure_use->var->name)) {
|
if ($closure_use->byRef && is_string($closure_use->var->name)) {
|
||||||
|
@ -6,4 +6,10 @@ final class FunctionStorage extends FunctionLikeStorage
|
|||||||
{
|
{
|
||||||
/** @var array<string, bool> */
|
/** @var array<string, bool> */
|
||||||
public $byref_uses = [];
|
public $byref_uses = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var bool
|
||||||
|
* @todo lift this property to FunctionLikeStorage in Psalm 6
|
||||||
|
*/
|
||||||
|
public $is_static = false;
|
||||||
}
|
}
|
||||||
|
@ -1368,6 +1368,34 @@ class ClosureTest extends TestCase
|
|||||||
'ignored_issues' => [],
|
'ignored_issues' => [],
|
||||||
'php_version' => '8.1',
|
'php_version' => '8.1',
|
||||||
],
|
],
|
||||||
|
'thisInStaticClosure' => [
|
||||||
|
'code' => '<?php
|
||||||
|
class C {
|
||||||
|
public string $a = "zzz";
|
||||||
|
public function f(): void {
|
||||||
|
$f = static function (): void {
|
||||||
|
echo $this->a;
|
||||||
|
};
|
||||||
|
$f();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
',
|
||||||
|
'error_message' => 'InvalidScope',
|
||||||
|
],
|
||||||
|
'thisInStaticArrowFunction' => [
|
||||||
|
'code' => '<?php
|
||||||
|
class C {
|
||||||
|
public int $a = 1;
|
||||||
|
public function f(): int {
|
||||||
|
$f = static fn(): int => $this->a;
|
||||||
|
return $f();;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
',
|
||||||
|
'error_message' => 'InvalidScope',
|
||||||
|
'ignored_issues' => [],
|
||||||
|
'php_version' => '7.4',
|
||||||
|
],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user