mirror of
https://github.com/danog/psalm.git
synced 2024-11-30 04:39:00 +01:00
Fix #798 - update magic property handling so it corresponds to PHP behaviour
This commit is contained in:
parent
dfc32216b3
commit
091fa53c72
@ -3,6 +3,7 @@ namespace Psalm\Checker\Statements\Expression\Fetch;
|
||||
|
||||
use PhpParser;
|
||||
use Psalm\Checker\ClassLikeChecker;
|
||||
use Psalm\Checker\FunctionLikeChecker;
|
||||
use Psalm\Checker\Statements\ExpressionChecker;
|
||||
use Psalm\Checker\StatementsChecker;
|
||||
use Psalm\CodeLocation;
|
||||
@ -250,19 +251,23 @@ class PropertyFetchChecker
|
||||
|
||||
$property_id = $lhs_type_part->value . '::$' . $prop_name;
|
||||
|
||||
if ($stmt_var_id !== '$this'
|
||||
&& $lhs_type_part->value !== $context->self
|
||||
&& $codebase->methodExists($lhs_type_part->value . '::__get')
|
||||
$statements_checker_source = $statements_checker->getSource();
|
||||
|
||||
if ($codebase->methodExists($lhs_type_part->value . '::__get')
|
||||
&& (!$statements_checker_source instanceof FunctionLikeChecker
|
||||
|| $statements_checker_source->getMethodId() !== $lhs_type_part->value . '::__get')
|
||||
&& (!$context->self || !$codebase->classExtends($context->self, $lhs_type_part->value))
|
||||
&& (!$codebase->properties->propertyExists($property_id)
|
||||
|| ClassLikeChecker::checkPropertyVisibility(
|
||||
$property_id,
|
||||
$context->self,
|
||||
$statements_checker->getSource(),
|
||||
new CodeLocation($statements_checker->getSource(), $stmt),
|
||||
$statements_checker->getSuppressedIssues(),
|
||||
false
|
||||
) !== true
|
||||
|| ($stmt_var_id !== '$this'
|
||||
&& $lhs_type_part->value !== $context->self
|
||||
&& ClassLikeChecker::checkPropertyVisibility(
|
||||
$property_id,
|
||||
$context->self,
|
||||
$statements_checker_source,
|
||||
new CodeLocation($statements_checker->getSource(), $stmt),
|
||||
$statements_checker->getSuppressedIssues(),
|
||||
false
|
||||
) !== true)
|
||||
)
|
||||
) {
|
||||
$class_storage = $project_checker->classlike_storage_provider->get((string)$lhs_type_part);
|
||||
|
@ -243,6 +243,50 @@ class MagicPropertyTest extends TestCase
|
||||
}
|
||||
}',
|
||||
],
|
||||
'undefinedThisPropertyFetchWithMagic' => [
|
||||
'<?php
|
||||
/**
|
||||
* @property-read string $name
|
||||
* @property string $otherName
|
||||
*/
|
||||
class A {
|
||||
public function __get(string $name): void {
|
||||
}
|
||||
|
||||
public function goodGet(): void {
|
||||
echo $this->name;
|
||||
}
|
||||
public function goodGet2(): void {
|
||||
echo $this->otherName;
|
||||
}
|
||||
}
|
||||
$a = new A();
|
||||
echo $a->name;
|
||||
echo $a->otherName;',
|
||||
],
|
||||
'directFetchForMagicProperty' => [
|
||||
'<?php
|
||||
/**
|
||||
* @property string $test
|
||||
*/
|
||||
class C {
|
||||
public function __get(string $name)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $value
|
||||
*/
|
||||
public function __set(string $name, $value)
|
||||
{
|
||||
}
|
||||
|
||||
public function test(): string
|
||||
{
|
||||
return $this->test;
|
||||
}
|
||||
}',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
@ -528,30 +572,6 @@ class MagicPropertyTest extends TestCase
|
||||
}',
|
||||
'error_message' => 'UndefinedThisPropertyFetch',
|
||||
],
|
||||
'directFetchForMagicProperty' => [
|
||||
'<?php
|
||||
/**
|
||||
* @property string $test
|
||||
*/
|
||||
class C {
|
||||
public function __get(string $name)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $value
|
||||
*/
|
||||
public function __set(string $name, $value)
|
||||
{
|
||||
}
|
||||
|
||||
public function test(): string
|
||||
{
|
||||
return $this->test;
|
||||
}
|
||||
}',
|
||||
'error_message' => 'UndefinedThisPropertyFetch',
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user