mirror of
https://github.com/danog/psalm.git
synced 2024-11-26 12:24:49 +01:00
Trigger dispatch even when only legacy hooks (#4962)
This commit is contained in:
parent
7b43d321ad
commit
fe71e8d16b
@ -370,7 +370,7 @@ class ExistingAtomicMethodCallAnalyzer extends CallAnalyzer
|
||||
}
|
||||
}
|
||||
|
||||
if ($config->eventDispatcher->after_method_checks) {
|
||||
if ($config->eventDispatcher->hasAfterMethodCallAnalysisHandlers()) {
|
||||
$file_manipulations = [];
|
||||
|
||||
$appearing_method_id = $codebase->methods->getAppearingMethodId($method_id);
|
||||
|
@ -469,7 +469,7 @@ class ExistingAtomicStaticCallAnalyzer
|
||||
}
|
||||
}
|
||||
|
||||
if ($config->eventDispatcher->after_method_checks) {
|
||||
if ($config->eventDispatcher->hasAfterMethodCallAnalysisHandlers()) {
|
||||
$file_manipulations = [];
|
||||
|
||||
$appearing_method_id = $codebase->methods->getAppearingMethodId($method_id);
|
||||
|
@ -6,6 +6,7 @@ use Psalm\Plugin\Hook;
|
||||
use Psalm\Plugin\EventHandler;
|
||||
use Psalm\Plugin\EventHandler\Event;
|
||||
use Psalm\Type\Atomic\TLiteralString;
|
||||
use function count;
|
||||
use function is_subclass_of;
|
||||
|
||||
|
||||
@ -16,9 +17,9 @@ class EventDispatcher
|
||||
*
|
||||
* @var list<class-string<EventHandler\AfterMethodCallAnalysisInterface>>
|
||||
*/
|
||||
public $after_method_checks = [];
|
||||
private $after_method_checks = [];
|
||||
/** @var list<class-string<Hook\AfterMethodCallAnalysisInterface>> */
|
||||
public $legacy_after_method_checks = [];
|
||||
private $legacy_after_method_checks = [];
|
||||
|
||||
/**
|
||||
* Static methods to be called after project function checks have completed
|
||||
@ -96,9 +97,9 @@ class EventDispatcher
|
||||
*
|
||||
* @var list<class-string<EventHandler\AfterClassLikeVisitInterface>>
|
||||
*/
|
||||
public $after_visit_classlikes = [];
|
||||
private $after_visit_classlikes = [];
|
||||
/** @var list<class-string<Hook\AfterClassLikeVisitInterface>> */
|
||||
public $legacy_after_visit_classlikes = [];
|
||||
private $legacy_after_visit_classlikes = [];
|
||||
|
||||
/**
|
||||
* Static methods to be called after codebase has been populated
|
||||
@ -235,6 +236,11 @@ class EventDispatcher
|
||||
}
|
||||
}
|
||||
|
||||
public function hasAfterMethodCallAnalysisHandlers(): bool
|
||||
{
|
||||
return count($this->after_method_checks) || count($this->legacy_after_method_checks);
|
||||
}
|
||||
|
||||
public function dispatchAfterMethodCallAnalysis(Event\AfterMethodCallAnalysisEvent $event): void
|
||||
{
|
||||
foreach ($this->after_method_checks as $handler) {
|
||||
@ -409,6 +415,11 @@ class EventDispatcher
|
||||
return null;
|
||||
}
|
||||
|
||||
public function hasAfterClassLikeVisitHandlers(): bool
|
||||
{
|
||||
return count($this->after_visit_classlikes) || count($this->legacy_after_visit_classlikes);
|
||||
}
|
||||
|
||||
public function dispatchAfterClassLikeVisit(Event\AfterClassLikeVisitEvent $event): void
|
||||
{
|
||||
foreach ($this->after_visit_classlikes as $handler) {
|
||||
|
@ -51,7 +51,7 @@ class ClassLikeStorageCacheProvider
|
||||
$storage_dir . 'MethodStorage.php',
|
||||
];
|
||||
|
||||
if ($config->eventDispatcher->after_visit_classlikes) {
|
||||
if ($config->eventDispatcher->hasAfterClassLikeVisitHandlers()) {
|
||||
$dependent_files = array_merge($dependent_files, $config->plugin_paths);
|
||||
}
|
||||
|
||||
|
@ -52,7 +52,7 @@ class FileStorageCacheProvider
|
||||
$storage_dir . 'FunctionLikeParameter.php',
|
||||
];
|
||||
|
||||
if ($config->eventDispatcher->after_visit_classlikes) {
|
||||
if ($config->eventDispatcher->hasAfterClassLikeVisitHandlers()) {
|
||||
$dependent_files = array_merge($dependent_files, $config->plugin_paths);
|
||||
}
|
||||
|
||||
|
@ -1,10 +1,19 @@
|
||||
<?php
|
||||
namespace Psalm\Tests\Config;
|
||||
|
||||
use PhpParser\Node\Expr;
|
||||
use PhpParser\Node\Stmt\ClassLike;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use Psalm\Codebase;
|
||||
use Psalm\FileSource;
|
||||
use Psalm\Plugin\EventHandler\AfterEveryFunctionCallAnalysisInterface;
|
||||
use Psalm\Plugin\EventHandler\Event\AfterCodebasePopulatedEvent;
|
||||
use Psalm\Plugin\EventHandler\Event\AfterEveryFunctionCallAnalysisEvent;
|
||||
use Psalm\Plugin\Hook\AfterClassLikeVisitInterface;
|
||||
use Psalm\Plugin\Hook\AfterMethodCallAnalysisInterface;
|
||||
use Psalm\StatementsSource;
|
||||
use Psalm\Storage\ClassLikeStorage;
|
||||
use Psalm\Type\Union;
|
||||
use function define;
|
||||
use function defined;
|
||||
use const DIRECTORY_SEPARATOR;
|
||||
@ -549,6 +558,82 @@ class PluginTest extends \Psalm\Tests\TestCase
|
||||
);
|
||||
}
|
||||
|
||||
public function testAfterMethodCallAnalysisLegacyHookIsLoaded(): void
|
||||
{
|
||||
$this->project_analyzer = $this->getProjectAnalyzerWithConfig(
|
||||
TestConfig::loadFromXML(
|
||||
dirname(__DIR__, 2) . DIRECTORY_SEPARATOR,
|
||||
'<?xml version="1.0"?>
|
||||
<psalm
|
||||
errorLevel="1"
|
||||
>
|
||||
<projectFiles>
|
||||
<directory name="src" />
|
||||
</projectFiles>
|
||||
</psalm>'
|
||||
)
|
||||
);
|
||||
|
||||
$hook = new class implements AfterMethodCallAnalysisInterface {
|
||||
public static function afterMethodCallAnalysis(
|
||||
Expr $expr,
|
||||
string $method_id,
|
||||
string $appearing_method_id,
|
||||
string $declaring_method_id,
|
||||
Context $context,
|
||||
StatementsSource $statements_source,
|
||||
Codebase $codebase,
|
||||
array &$file_replacements = [],
|
||||
Union &$return_type_candidate = null
|
||||
): void {
|
||||
}
|
||||
};
|
||||
|
||||
$codebase = $this->project_analyzer->getCodebase();
|
||||
|
||||
$config = $codebase->config;
|
||||
|
||||
(new PluginRegistrationSocket($config, $codebase))->registerHooksFromClass(get_class($hook));
|
||||
|
||||
$this->assertTrue($this->project_analyzer->getCodebase()->config->eventDispatcher->hasAfterMethodCallAnalysisHandlers());
|
||||
}
|
||||
|
||||
public function testAfterClassLikeAnalysisLegacyHookIsLoaded(): void
|
||||
{
|
||||
$this->project_analyzer = $this->getProjectAnalyzerWithConfig(
|
||||
TestConfig::loadFromXML(
|
||||
dirname(__DIR__, 2) . DIRECTORY_SEPARATOR,
|
||||
'<?xml version="1.0"?>
|
||||
<psalm
|
||||
errorLevel="1"
|
||||
>
|
||||
<projectFiles>
|
||||
<directory name="src" />
|
||||
</projectFiles>
|
||||
</psalm>'
|
||||
)
|
||||
);
|
||||
|
||||
$hook = new class implements AfterClassLikeVisitInterface {
|
||||
public static function afterClassLikeVisit(
|
||||
ClassLike $stmt,
|
||||
ClassLikeStorage $storage,
|
||||
FileSource $statements_source,
|
||||
Codebase $codebase,
|
||||
array &$file_replacements = []
|
||||
): void {
|
||||
}
|
||||
};
|
||||
|
||||
$codebase = $this->project_analyzer->getCodebase();
|
||||
|
||||
$config = $codebase->config;
|
||||
|
||||
(new PluginRegistrationSocket($config, $codebase))->registerHooksFromClass(get_class($hook));
|
||||
|
||||
$this->assertTrue($this->project_analyzer->getCodebase()->config->eventDispatcher->hasAfterClassLikeVisitHandlers());
|
||||
}
|
||||
|
||||
public function testPropertyProviderHooks(): void
|
||||
{
|
||||
require_once __DIR__ . '/Plugin/PropertyPlugin.php';
|
||||
|
Loading…
Reference in New Issue
Block a user