1
0
mirror of https://github.com/danog/psalm.git synced 2024-12-03 10:07:52 +01:00

Fix #805 - allow dead code detection from methods just called internally

This commit is contained in:
Matt Brown 2018-06-19 16:14:51 -04:00
parent f7845616b6
commit e10b2c0fd4
4 changed files with 49 additions and 4 deletions

View File

@ -107,6 +107,7 @@ class MethodChecker extends FunctionLikeChecker
* @param string $method_id * @param string $method_id
* @param CodeLocation $code_location * @param CodeLocation $code_location
* @param array $suppressed_issues * @param array $suppressed_issues
* @param string|null $source_method_id
* *
* @return bool|null * @return bool|null
*/ */
@ -114,9 +115,13 @@ class MethodChecker extends FunctionLikeChecker
ProjectChecker $project_checker, ProjectChecker $project_checker,
$method_id, $method_id,
CodeLocation $code_location, CodeLocation $code_location,
array $suppressed_issues array $suppressed_issues,
$source_method_id = null
) { ) {
if ($project_checker->codebase->methodExists($method_id, $code_location)) { if ($project_checker->codebase->methodExists(
$method_id,
$source_method_id !== $method_id ? $code_location : null
)) {
return true; return true;
} }

View File

@ -379,7 +379,11 @@ class MethodCallChecker extends \Psalm\Checker\Statements\Expression\CallChecker
} }
} }
if (!$codebase->methodExists($method_id, $code_location)) { $source_method_id = $source instanceof FunctionLikeChecker
? $source->getMethodId()
: null;
if (!$codebase->methodExists($method_id, $method_id !== $source_method_id ? $code_location : null)) {
if ($config->use_phpdoc_methods_without_call) { if ($config->use_phpdoc_methods_without_call) {
$class_storage = $project_checker->classlike_storage_provider->get($fq_class_name); $class_storage = $project_checker->classlike_storage_provider->get($fq_class_name);

View File

@ -3,6 +3,7 @@ namespace Psalm\Checker\Statements\Expression\Call;
use PhpParser; use PhpParser;
use Psalm\Checker\ClassLikeChecker; use Psalm\Checker\ClassLikeChecker;
use Psalm\Checker\FunctionLikeChecker;
use Psalm\Checker\MethodChecker; use Psalm\Checker\MethodChecker;
use Psalm\Checker\Statements\ExpressionChecker; use Psalm\Checker\Statements\ExpressionChecker;
use Psalm\Checker\StatementsChecker; use Psalm\Checker\StatementsChecker;
@ -264,11 +265,16 @@ class StaticCallChecker extends \Psalm\Checker\Statements\Expression\CallChecker
$method_id = $fq_class_name . '::' . strtolower($stmt->name->name); $method_id = $fq_class_name . '::' . strtolower($stmt->name->name);
$cased_method_id = $fq_class_name . '::' . $stmt->name->name; $cased_method_id = $fq_class_name . '::' . $stmt->name->name;
$source_method_id = $source instanceof FunctionLikeChecker
? $source->getMethodId()
: null;
$does_method_exist = MethodChecker::checkMethodExists( $does_method_exist = MethodChecker::checkMethodExists(
$project_checker, $project_checker,
$cased_method_id, $cased_method_id,
new CodeLocation($source, $stmt), new CodeLocation($source, $stmt),
$statements_checker->getSuppressedIssues() $statements_checker->getSuppressedIssues(),
$source_method_id
); );
if (!$does_method_exist) { if (!$does_method_exist) {

View File

@ -384,6 +384,36 @@ class UnusedCodeTest extends TestCase
takesA(new B);', takesA(new B);',
'error_message' => 'PossiblyUnusedMethod', 'error_message' => 'PossiblyUnusedMethod',
], ],
'unusedRecursivelyUsedMethod' => [
'<?php
class C {
public function foo() : void {
if (rand(0, 1)) {
$this->foo();
}
}
public function bar() : void {}
}
(new C)->bar();',
'error_message' => 'PossiblyUnusedMethod',
],
'unusedRecursivelyUsedStaticMethod' => [
'<?php
class C {
public static function foo() : void {
if (rand(0, 1)) {
self::foo();
}
}
public function bar() : void {}
}
(new C)->bar();',
'error_message' => 'PossiblyUnusedMethod',
],
]; ];
} }
} }