From 447bbc3da4bca98488ecae186c0e57a945c8d731 Mon Sep 17 00:00:00 2001
From: Sander Bol <s.bol@coolblue.nl>
Date: Wed, 21 Jul 2021 15:56:44 +0200
Subject: [PATCH] Bump Psalm minimum version to 4.x

---
 composer.json                               |  4 +--
 src/Analyzers/PresentationModelAnalyzer.php | 36 ++++++---------------
 2 files changed, 12 insertions(+), 28 deletions(-)

diff --git a/composer.json b/composer.json
index dadc4bf..49e214d 100644
--- a/composer.json
+++ b/composer.json
@@ -21,8 +21,8 @@
     "require": {
         "ext-simplexml": "*",
         "php": "^7.2|^8.0",
-        "shoot/shoot": "^3.1",
-        "vimeo/psalm": "^3.2"
+        "shoot/shoot": "^3.2",
+        "vimeo/psalm": "^4.8"
     },
     "autoload": {
         "psr-4": {
diff --git a/src/Analyzers/PresentationModelAnalyzer.php b/src/Analyzers/PresentationModelAnalyzer.php
index dafb495..13d6709 100644
--- a/src/Analyzers/PresentationModelAnalyzer.php
+++ b/src/Analyzers/PresentationModelAnalyzer.php
@@ -3,14 +3,10 @@
 
 namespace Shoot\PsalmPlugin\Analyzers;
 
-use PhpParser\Node\Stmt\ClassLike;
-use Psalm\Codebase;
-use Psalm\FileManipulation;
 use Psalm\Internal\Analyzer\ClassLikeAnalyzer;
 use Psalm\IssueBuffer;
-use Psalm\Plugin\Hook\AfterClassLikeAnalysisInterface;
-use Psalm\StatementsSource;
-use Psalm\Storage\ClassLikeStorage;
+use Psalm\Plugin\EventHandler\AfterClassLikeAnalysisInterface;
+use Psalm\Plugin\EventHandler\Event\AfterClassLikeAnalysisEvent;
 use Psalm\Storage\PropertyStorage;
 use Shoot\PsalmPlugin\Issues\InvalidPresentationModelFieldCasing;
 use Shoot\PsalmPlugin\Issues\InvalidPresentationModelFieldVisibility;
@@ -18,28 +14,16 @@
 
 final class PresentationModelAnalyzer implements AfterClassLikeAnalysisInterface
 {
-    /**
-     * @param ClassLike          $statement
-     * @param ClassLikeStorage   $class
-     * @param StatementsSource   $source
-     * @param Codebase           $codebase
-     * @param FileManipulation[] $fileManipulations
-     *
-     * @return void
-     */
-    public static function afterStatementAnalysis(
-        ClassLike $statement,
-        ClassLikeStorage $class,
-        StatementsSource $source,
-        Codebase $codebase,
-        array &$fileManipulations = []
-    ): void {
-        if (!$codebase->classExtends($class->name, PresentationModel::class)) {
+    public static function afterStatementAnalysis(AfterClassLikeAnalysisEvent $event): void {
+        $codebase = $event->getCodebase();
+        $classLike = $event->getClasslikeStorage();
+
+        if (!$codebase->classExtends($classLike->name, PresentationModel::class)) {
             return;
         }
 
         /** @var PropertyStorage $property */
-        foreach ($class->properties as $name => $property) {
+        foreach ($classLike->properties as $name => $property) {
             if ($property->location === null) {
                 continue;
             }
@@ -48,14 +32,14 @@ public static function afterStatementAnalysis(
                 IssueBuffer::accepts(new InvalidPresentationModelFieldCasing(
                     "'{$name}' must use `snake_casing`, as per Twig's coding standards",
                     $property->location
-                ), $class->suppressed_issues);
+                ), $classLike->suppressed_issues);
             }
 
             if ($property->visibility !== ClassLikeAnalyzer::VISIBILITY_PROTECTED) {
                 IssueBuffer::accepts(new InvalidPresentationModelFieldVisibility(
                     "'{$name}' must be `protected` to preserve the presentation model's immutability, while allowing access from the PresentationModel base class",
                     $property->location
-                ), $class->suppressed_issues);
+                ), $classLike->suppressed_issues);
             }
         }
     }