mirror of
https://github.com/danog/psalm.git
synced 2025-01-21 21:31:13 +01:00
Fix #3897 - support aliasing final methods
This commit is contained in:
parent
eddd7b8c11
commit
23f5d66516
@ -45,7 +45,7 @@ class CallAnalyzer
|
||||
*/
|
||||
public static function collectSpecialInformation(
|
||||
FunctionLikeAnalyzer $source,
|
||||
$method_name,
|
||||
string $method_name,
|
||||
Context $context
|
||||
) {
|
||||
$fq_class_name = (string)$source->getFQCLN();
|
||||
@ -167,11 +167,27 @@ class CallAnalyzer
|
||||
|
||||
$class_analyzer = $source->getSource();
|
||||
|
||||
$is_final = $method_storage->final;
|
||||
|
||||
if ($method_name !== $declaring_method_id->method_name) {
|
||||
$appearing_method_id = $codebase->methods->getAppearingMethodId($method_id);
|
||||
|
||||
if ($appearing_method_id) {
|
||||
$appearing_class_storage = $codebase->classlike_storage_provider->get(
|
||||
$appearing_method_id->fq_class_name
|
||||
);
|
||||
|
||||
if (isset($appearing_class_storage->trait_final_map[strtolower($method_name)])) {
|
||||
$is_final = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($class_analyzer instanceof ClassLikeAnalyzer
|
||||
&& !$method_storage->is_static
|
||||
&& ($context->collect_nonprivate_initializations
|
||||
|| $method_storage->visibility === ClassLikeAnalyzer::VISIBILITY_PRIVATE
|
||||
|| $method_storage->final)
|
||||
|| $is_final)
|
||||
) {
|
||||
$local_vars_in_scope = [];
|
||||
$local_vars_possibly_in_scope = [];
|
||||
@ -191,7 +207,7 @@ class CallAnalyzer
|
||||
$old_calling_method_id = $context->calling_method_id;
|
||||
|
||||
if ($fq_class_name === $source->getFQCLN()) {
|
||||
$class_analyzer->getMethodMutations(strtolower($method_name), $context);
|
||||
$class_analyzer->getMethodMutations(strtolower($declaring_method_id->method_name), $context);
|
||||
} else {
|
||||
$declaring_fq_class_name = $declaring_method_id->fq_class_name;
|
||||
|
||||
|
@ -373,6 +373,7 @@ class ReflectorVisitor extends PhpParser\NodeVisitorAbstract implements PhpParse
|
||||
|
||||
$method_map = $storage->trait_alias_map ?: [];
|
||||
$visibility_map = $storage->trait_visibility_map ?: [];
|
||||
$final_map = $storage->trait_visibility_map ?: [];
|
||||
|
||||
foreach ($node->adaptations as $adaptation) {
|
||||
if ($adaptation instanceof PhpParser\Node\Stmt\TraitUseAdaptation\Alias) {
|
||||
@ -400,6 +401,14 @@ class ReflectorVisitor extends PhpParser\NodeVisitorAbstract implements PhpParse
|
||||
case 4:
|
||||
$visibility_map[$new_name] = ClassLikeAnalyzer::VISIBILITY_PRIVATE;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
$visibility_map[$new_name] = ClassLikeAnalyzer::VISIBILITY_PRIVATE;
|
||||
break;
|
||||
|
||||
case 32:
|
||||
$final_map[$new_name] = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -407,6 +416,7 @@ class ReflectorVisitor extends PhpParser\NodeVisitorAbstract implements PhpParse
|
||||
|
||||
$storage->trait_alias_map = $method_map;
|
||||
$storage->trait_visibility_map = $visibility_map;
|
||||
$storage->trait_final_map = $final_map;
|
||||
|
||||
foreach ($node->traits as $trait) {
|
||||
$trait_fqcln = ClassLikeAnalyzer::getFQCLNFromNameObject($trait, $this->aliases);
|
||||
|
@ -1985,6 +1985,44 @@ class PropertyTypeTest extends TestCase
|
||||
}
|
||||
}'
|
||||
],
|
||||
'aliasedFinalMethod' => [
|
||||
'<?php
|
||||
trait A {
|
||||
private int $prop;
|
||||
public final function setProp(int $prop): void {
|
||||
$this->prop = $prop;
|
||||
}
|
||||
}
|
||||
|
||||
class B {
|
||||
use A {
|
||||
setProp as setPropFinal;
|
||||
}
|
||||
|
||||
public function __construct() {
|
||||
$this->setPropFinal(1);
|
||||
}
|
||||
}'
|
||||
],
|
||||
'aliasedAsFinalMethod' => [
|
||||
'<?php
|
||||
trait A {
|
||||
private int $prop;
|
||||
public function setProp(int $prop): void {
|
||||
$this->prop = $prop;
|
||||
}
|
||||
}
|
||||
|
||||
class B {
|
||||
use A {
|
||||
setProp as final setPropFinal;
|
||||
}
|
||||
|
||||
public function __construct() {
|
||||
$this->setPropFinal(1);
|
||||
}
|
||||
}'
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user