mirror of
https://github.com/danog/psalm.git
synced 2024-11-26 20:34:47 +01:00
Fix #416 - make sure trait methods are treated better by dead code detection
This commit is contained in:
parent
04cc920101
commit
d47980df13
@ -77,8 +77,6 @@
|
||||
<PossiblyUnusedMethod>
|
||||
<errorLevel type="suppress">
|
||||
<directory name="tests" />
|
||||
<file name="src/Psalm/Type/Atomic/CallableTrait.php" />
|
||||
<file name="src/Psalm/Type/Atomic/GenericTrait.php" />
|
||||
<file name="src/Psalm/Plugin.php" />
|
||||
<referencedMethod name="Psalm\Codebase::getParentInterfaces" />
|
||||
<referencedMethod name="Psalm\Codebase::getMethodParams" />
|
||||
|
@ -628,9 +628,10 @@ class ClassLikes
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($classlike_storage->location &&
|
||||
$this->config &&
|
||||
$this->config->isInProjectDirs($classlike_storage->location->file_path)
|
||||
if ($classlike_storage->location
|
||||
&& $this->config
|
||||
&& $this->config->isInProjectDirs($classlike_storage->location->file_path)
|
||||
&& !$classlike_storage->is_trait
|
||||
) {
|
||||
if (!isset($this->classlike_references[$fq_class_name_lc])) {
|
||||
if (IssueBuffer::accepts(
|
||||
@ -712,7 +713,29 @@ class ClassLikes
|
||||
*/
|
||||
private function checkMethodReferences(ClassLikeStorage $classlike_storage)
|
||||
{
|
||||
foreach ($classlike_storage->methods as $method_name => $method_storage) {
|
||||
foreach ($classlike_storage->appearing_method_ids as $method_name => $appearing_method_id) {
|
||||
list($appearing_fq_classlike_name) = explode('::', $appearing_method_id);
|
||||
|
||||
if ($appearing_fq_classlike_name !== $classlike_storage->name) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isset($classlike_storage->methods[$method_name])) {
|
||||
$method_storage = $classlike_storage->methods[$method_name];
|
||||
} else {
|
||||
$declaring_method_id = $classlike_storage->declaring_method_ids[$method_name];
|
||||
|
||||
list($declaring_fq_classlike_name) = explode('::', $declaring_method_id);
|
||||
|
||||
try {
|
||||
$declaring_classlike_storage = $this->classlike_storage_provider->get($declaring_fq_classlike_name);
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$method_storage = $declaring_classlike_storage->methods[$method_name];
|
||||
}
|
||||
|
||||
if (($method_storage->referencing_locations === null
|
||||
|| count($method_storage->referencing_locations) === 0)
|
||||
&& (substr($method_name, 0, 2) !== '__' || $method_name === '__construct')
|
||||
@ -727,6 +750,7 @@ class ClassLikes
|
||||
|
||||
$has_parent_references = false;
|
||||
|
||||
if (isset($classlike_storage->overridden_method_ids[$method_name_lc])) {
|
||||
foreach ($classlike_storage->overridden_method_ids[$method_name_lc] as $parent_method_id) {
|
||||
$parent_method_storage = $this->methods->getStorage($parent_method_id);
|
||||
|
||||
@ -735,6 +759,7 @@ class ClassLikes
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($classlike_storage->class_implements as $fq_interface_name) {
|
||||
$interface_storage = $this->classlike_storage_provider->get($fq_interface_name);
|
||||
@ -777,6 +802,7 @@ class ClassLikes
|
||||
|
||||
$method_name_lc = strtolower($method_name);
|
||||
|
||||
if (isset($classlike_storage->overridden_method_ids[$method_name_lc])) {
|
||||
foreach ($classlike_storage->overridden_method_ids[$method_name_lc] as $parent_method_id) {
|
||||
$parent_method_storage = $this->methods->getStorage($parent_method_id);
|
||||
|
||||
@ -787,6 +813,7 @@ class ClassLikes
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!$has_parent_references && !isset($method_storage->used_params[$offset])) {
|
||||
if (IssueBuffer::accepts(
|
||||
|
@ -229,7 +229,7 @@ class UnusedCodeTest extends TestCase
|
||||
$m->modifyFoo("value2");
|
||||
echo $m->getFoo();',
|
||||
],
|
||||
'usedTraitMethod' => [
|
||||
'usedTraitMethodWithExplicitCall' => [
|
||||
'<?php
|
||||
class A {
|
||||
public function foo(): void {
|
||||
@ -717,6 +717,22 @@ class UnusedCodeTest extends TestCase
|
||||
class A { }
|
||||
new A();',
|
||||
],
|
||||
'usedTraitMethodWithImplicitCall' => [
|
||||
'<?php
|
||||
class A {
|
||||
public function foo() : void {}
|
||||
}
|
||||
trait T {
|
||||
public function foo() : void {}
|
||||
}
|
||||
class B extends A {
|
||||
use T;
|
||||
}
|
||||
function takesA(A $a) : void {
|
||||
$a->foo();
|
||||
}
|
||||
takesA(new B);'
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
@ -1067,6 +1083,25 @@ class UnusedCodeTest extends TestCase
|
||||
}',
|
||||
'error_message' => 'UnevaluatedCode',
|
||||
],
|
||||
'unusedTraitMethodInParent' => [
|
||||
'<?php
|
||||
class A {
|
||||
public function foo() : void {}
|
||||
}
|
||||
trait T {
|
||||
public function foo() : void {}
|
||||
|
||||
public function bar() : void {}
|
||||
}
|
||||
class B extends A {
|
||||
use T;
|
||||
}
|
||||
function takesA(A $a) : void {
|
||||
$a->foo();
|
||||
}
|
||||
takesA(new B);',
|
||||
'error_message' => 'PossiblyUnusedMethod',
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user