1
0
mirror of https://github.com/danog/psalm.git synced 2025-01-22 05:41:20 +01:00

Fix issue using abstract methods from traits

This commit is contained in:
Matthew Brown 2017-02-22 01:25:51 -05:00
parent 12cb72ae4b
commit 47de866601
3 changed files with 57 additions and 1 deletions

View File

@ -547,6 +547,10 @@ abstract class ClassLikeChecker extends SourceChecker implements StatementsSourc
$this->source
);
if (!isset(self::$trait_checkers[$fq_trait_name])) {
throw new \UnexpectedValueException('Expecting trait to be hydrated');
}
$trait_checker = self::$trait_checkers[$fq_trait_name];
foreach ($trait_checker->class->stmts as $trait_stmt) {
@ -842,7 +846,7 @@ abstract class ClassLikeChecker extends SourceChecker implements StatementsSourc
FunctionLikeChecker::register($stmt, $this);
}
if (!$stmt->isAbstract() && $class_context->self) {
if ((!$stmt->isAbstract() || $this instanceof TraitChecker) && $class_context->self) {
$implemented_method_id =
$class_context->self . '::' . strtolower($this->getMappedMethodName(strtolower($stmt->name)));

View File

@ -532,6 +532,30 @@ class ClassTest extends PHPUnit_Framework_TestCase
$file_checker->visitAndAnalyzeMethods($context);
}
/**
* @return void
*/
public function testAbstractExtendsAbstract()
{
$stmts = self::$parser->parse('<?php
abstract class A {
/** @return void */
abstract public function foo();
}
abstract class B extends A {
/** @return void */
public function bar() {
$this->foo();
}
}
');
$file_checker = new FileChecker('somefile.php', $this->project_checker, $stmts);
$context = new Context();
$file_checker->visitAndAnalyzeMethods($context);
}
/**
* @expectedException \Psalm\Exception\CodeException
* @expectedExceptionMessage UndefinedClass

View File

@ -437,4 +437,32 @@ class TraitTest extends PHPUnit_Framework_TestCase
$context = new Context();
$file_checker->visitAndAnalyzeMethods($context);
}
/**
* @return void
*/
public function testAbstractTraitMethod()
{
$stmts = self::$parser->parse('<?php
trait T {
/** @return void */
abstract public function foo();
}
abstract class A {
use T;
/** @return void */
public function bar() {
$this->foo();
}
}
');
$file_checker = new FileChecker('somefile.php', $this->project_checker, $stmts);
$context = new Context();
$file_checker->visitAndAnalyzeMethods($context);
}
}