Skip to content

Commit

Permalink
Trigger dispatch even when only legacy hooks
Browse files Browse the repository at this point in the history
  • Loading branch information
adrienlucas committed Jan 8, 2021
1 parent d1398f2 commit b41f3a5
Show file tree
Hide file tree
Showing 6 changed files with 101 additions and 8 deletions.
Expand Up @@ -370,7 +370,7 @@ function (Assertion $assertion) use (
}
}

if ($config->eventDispatcher->after_method_checks) {
if ($config->eventDispatcher->hasAfterMethodCallAnalysisHandlers()) {
$file_manipulations = [];

$appearing_method_id = $codebase->methods->getAppearingMethodId($method_id);
Expand Down
Expand Up @@ -469,7 +469,7 @@ function (Assertion $assertion) use ($generic_params) : Assertion {
}
}

if ($config->eventDispatcher->after_method_checks) {
if ($config->eventDispatcher->hasAfterMethodCallAnalysisHandlers()) {
$file_manipulations = [];

$appearing_method_id = $codebase->methods->getAppearingMethodId($method_id);
Expand Down
18 changes: 14 additions & 4 deletions src/Psalm/Internal/EventDispatcher.php
Expand Up @@ -16,9 +16,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
Expand Down Expand Up @@ -96,9 +96,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
Expand Down Expand Up @@ -235,6 +235,11 @@ public function registerClass(string $class): void
}
}

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) {
Expand Down Expand Up @@ -409,6 +414,11 @@ public function dispatchAfterClassLikeAnalysis(Event\AfterClassLikeAnalysisEvent
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) {
Expand Down
Expand Up @@ -51,7 +51,7 @@ public function __construct(Config $config)
$storage_dir . 'MethodStorage.php',
];

if ($config->eventDispatcher->after_visit_classlikes) {
if ($config->eventDispatcher->hasAfterClassLikeVisitHandlers()) {
$dependent_files = array_merge($dependent_files, $config->plugin_paths);
}

Expand Down
2 changes: 1 addition & 1 deletion src/Psalm/Internal/Provider/FileStorageCacheProvider.php
Expand Up @@ -52,7 +52,7 @@ public function __construct(Config $config)
$storage_dir . 'FunctionLikeParameter.php',
];

if ($config->eventDispatcher->after_visit_classlikes) {
if ($config->eventDispatcher->hasAfterClassLikeVisitHandlers()) {
$dependent_files = array_merge($dependent_files, $config->plugin_paths);
}

Expand Down
83 changes: 83 additions & 0 deletions tests/Config/PluginTest.php
@@ -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;
Expand Down Expand Up @@ -549,6 +558,80 @@ public static function afterCodebasePopulated(AfterCodebasePopulatedEvent $event
);
}

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';
Expand Down

0 comments on commit b41f3a5

Please sign in to comment.