1
0
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:
Matt Brown 2018-06-08 11:08:57 -04:00
parent dfc32216b3
commit 091fa53c72
2 changed files with 60 additions and 35 deletions

View File

@ -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);

View File

@ -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',
],
];
}
}