1
0
mirror of https://github.com/danog/psalm.git synced 2024-11-30 04:39:00 +01:00

Fix issue calculating inherited parent property mutations

This commit is contained in:
Matt Brown 2017-05-12 19:15:08 -04:00
parent 53b81ac2e1
commit 052624fa94
3 changed files with 45 additions and 6 deletions

View File

@ -814,6 +814,14 @@ abstract class ClassLikeChecker extends SourceChecker implements StatementsSourc
$method_name,
Context $context
) {
foreach (self::$storage[strtolower($this->fq_class_name)]->properties as $property_name => $property_storage) {
if (!isset($context->vars_in_scope['$this->' . $property_name]) &&
$property_storage->type !== false
) {
$context->vars_in_scope['$this->' . $property_name] = clone $property_storage->type;
}
}
foreach ($this->class->stmts as $stmt) {
if ($stmt instanceof PhpParser\Node\Stmt\ClassMethod &&
strtolower($stmt->name) === strtolower($method_name)

View File

@ -124,7 +124,7 @@ abstract class FunctionLikeChecker extends SourceChecker implements StatementsSo
$method_id = (string)$this->getMethodId($context->self);
if ($add_mutations) {
$hash = $this->getMethodId() . json_encode([
$hash = $real_method_id . json_encode([
$context->vars_in_scope,
$context->vars_possibly_in_scope
]);
@ -145,11 +145,6 @@ abstract class FunctionLikeChecker extends SourceChecker implements StatementsSo
$declaring_method_id = (string)MethodChecker::getDeclaringMethodId($method_id);
if ($declaring_method_id !== $real_method_id) {
// this trait method has been overridden, so we don't care about it
return;
}
$fq_class_name = (string)$context->self;
$class_storage = ClassLikeChecker::$storage[strtolower($fq_class_name)];

View File

@ -100,4 +100,40 @@ class MethodMutationTest extends TestCase
$this->assertEquals('string', (string)$method_context->vars_in_scope['$this->user_viewdata->name']);
$this->assertEquals(true, (string)$method_context->vars_possibly_in_scope['$this->title']);
}
/**
* @return void
*/
public function testParentControllerSet()
{
$this->project_checker->registerFile(
'somefile.php',
'<?php
class Foo { }
class Controller {
/** @var Foo|null */
public $foo;
public function __construct() {
$this->foo = new Foo();
}
}
class FooController extends Controller {
public function __construct() {
parent::__construct();
}
}'
);
$file_checker = new FileChecker('somefile.php', $this->project_checker);
$context = new Context();
$file_checker->visit($context);
$file_checker->analyze(false, true);
$method_context = new Context();
$this->project_checker->getMethodMutations('FooController::__construct', $method_context);
$this->assertEquals('Foo', (string)$method_context->vars_in_scope['$this->foo']);
}
}