From a67edae5bea6410b10e8290c0dccf00b895a44cc Mon Sep 17 00:00:00 2001
From: Mateusz Charytoniuk <mateusz.charytoniuk@protonmail.com>
Date: Tue, 30 Jan 2024 00:28:31 +0100
Subject: [PATCH] style: rector

---
 .../Component/StaticPageBreadcrumbs.php       |   2 +-
 .../StaticPageDocumentTableOfContents.php     |   2 +-
 .../Component/StaticPageDocumentsMenu.php     |   2 +-
 .../StaticPageLayout/Turbo/Document.php       |   4 +-
 app/Template/StaticPageLayout/Turbo/Page.php  |   2 +-
 .../StaticPageLayout/Turbo/Tutorial.php       |   2 +-
 .../StaticPageLayout/Turbo/TutorialList.php   |   2 +-
 rector.php                                    |  55 +++++++
 src/Command/Cron.php                          |   6 +-
 src/Command/GenerateHttpController.php        |   2 +-
 src/Command/GenerateHttpResponder.php         |   2 +-
 src/Command/LlamaCppGenerate/Embedding.php    |   2 +-
 src/Command/LlamaCppHealth.php                |   2 +-
 src/Command/LlamaCppInfill.php                |   4 +-
 src/Command/Serve.php                         |  26 ++--
 src/Command/StaticPagesBuild.php              |   2 +-
 src/Command/StaticPagesDumpContent.php        |   2 +-
 src/Command/StaticPagesMakeEmbeddings.php     |  10 +-
 src/Command/TestHttpResponders.php            |  14 +-
 src/Command/Watch.php                         |   8 +-
 src/CoroutineCommand.php                      |   2 +-
 src/CronJobRunner.php                         |   2 +-
 src/DatabaseConnection.php                    |   2 +-
 src/DependencyInjectionContainer.php          |   6 +-
 src/DoctrineConsoleRunner.php                 |   2 +-
 src/DoctrineEntityManagerRepository.php       |   2 +-
 src/EsbuildMetaBuilder.php                    |  48 +++---
 src/EventDispatcher.php                       |   4 +-
 src/GraphQLExecutionPromise.php               |   6 +-
 src/HttpControllerMetadataException.php       |  10 +-
 .../RespondsToOAuth2EndpointMiddleware.php    |  13 +-
 src/HttpRequestLanguageDetector.php           |   2 +-
 src/HttpResponder/HttpController.php          |   2 +-
 src/HttpResponderAggregate.php                |   4 +-
 src/IntlDateFormatterRepository.php           |   2 +-
 src/LlamaCppClient.php                        |   4 +-
 src/LlamaCppCompletionIterator.php            |   1 -
 src/OAuth2AccessTokenRepository.php           |   6 +-
 src/OAuth2AuthCodeRepository.php              |   6 +-
 src/OAuth2ClaimReader.php                     |   2 +-
 src/OAuth2ClientRepository.php                |   2 +-
 src/OAuth2RefreshTokenRepository.php          |   4 +-
 .../DoctrineEntityRouteParameterExtractor.php |   2 +-
 src/OpenAPISchema.php                         |   2 +-
 ...HPFileReflectionClassAttributeIterator.php |   4 +-
 src/Session.php                               |   2 +-
 src/SingletonContainer.php                    |  25 ++--
 src/StaticPageChunkIterator.php               |   9 +-
 src/StaticPageCollection.php                  |   2 +-
 ...aticPageInternalLinkDelimiterProcessor.php |   2 +-
 src/StaticPageInternalLinkNodeRenderer.php    |  12 +-
 src/SwooleCoroutineHelper.php                 |   2 +-
 src/SwooleLoggerBridge.php                    |   2 +-
 src/TestsGraphQLQueriesTrait.php              |   2 +-
 src/TickTimerScheduler.php                    |   2 +-
 .../RPCProtocolController.php                 |   6 +-
 tools/rector/.gitignore                       |   1 +
 tools/rector/composer.json                    |   5 +
 tools/rector/composer.lock                    | 137 ++++++++++++++++++
 59 files changed, 354 insertions(+), 146 deletions(-)
 create mode 100644 rector.php
 create mode 100644 tools/rector/.gitignore
 create mode 100644 tools/rector/composer.json
 create mode 100644 tools/rector/composer.lock

diff --git a/app/Template/Component/StaticPageBreadcrumbs.php b/app/Template/Component/StaticPageBreadcrumbs.php
index c2d50be6..76c63a46 100644
--- a/app/Template/Component/StaticPageBreadcrumbs.php
+++ b/app/Template/Component/StaticPageBreadcrumbs.php
@@ -10,7 +10,7 @@ use Distantmagic\Resonance\StaticPageParentIterator;
 use Ds\Map;
 use Generator;
 
-readonly class StaticPageBreadcrumbs extends Component
+final readonly class StaticPageBreadcrumbs extends Component
 {
     /**
      * @param Map<string, StaticPage> $staticPages
diff --git a/app/Template/Component/StaticPageDocumentTableOfContents.php b/app/Template/Component/StaticPageDocumentTableOfContents.php
index b717c75d..bc189934 100644
--- a/app/Template/Component/StaticPageDocumentTableOfContents.php
+++ b/app/Template/Component/StaticPageDocumentTableOfContents.php
@@ -9,7 +9,7 @@ use Distantmagic\Resonance\CommonMarkTableOfContentsLink;
 use Ds\PriorityQueue;
 use Generator;
 
-readonly class StaticPageDocumentTableOfContents extends Component
+final readonly class StaticPageDocumentTableOfContents extends Component
 {
     public function __construct(
         private string $baseClassName,
diff --git a/app/Template/Component/StaticPageDocumentsMenu.php b/app/Template/Component/StaticPageDocumentsMenu.php
index 588aa398..dbe2f393 100644
--- a/app/Template/Component/StaticPageDocumentsMenu.php
+++ b/app/Template/Component/StaticPageDocumentsMenu.php
@@ -12,7 +12,7 @@ use Ds\Map;
 use Generator;
 use Tree\Node\Node;
 
-readonly class StaticPageDocumentsMenu extends Component
+final readonly class StaticPageDocumentsMenu extends Component
 {
     /**
      * @param Map<string, StaticPage> $staticPages
diff --git a/app/Template/StaticPageLayout/Turbo/Document.php b/app/Template/StaticPageLayout/Turbo/Document.php
index d51faaae..15cff63c 100644
--- a/app/Template/StaticPageLayout/Turbo/Document.php
+++ b/app/Template/StaticPageLayout/Turbo/Document.php
@@ -25,7 +25,7 @@ use IntlDateFormatter;
 
 #[Singleton(collection: SingletonCollection::StaticPageLayout)]
 #[StaticPageLayout('dm:document')]
-readonly class Document extends Turbo
+final readonly class Document extends Turbo
 {
     private StaticPageBreadcrumbs $breadcrumbs;
     private StaticPageDocumentsMenu $documentsMenu;
@@ -162,7 +162,7 @@ readonly class Document extends Turbo
     /**
      * @return Generator<string>
      */
-    protected function renderRelatedPageReference(StaticPage $staticPage): Generator
+    private function renderRelatedPageReference(StaticPage $staticPage): Generator
     {
         $nextPage = $this->staticPageCollectionAggregate->pagesFollowers->get($staticPage, null);
         $prevPage = $this->staticPageCollectionAggregate->pagesPredecessors->get($staticPage, null);
diff --git a/app/Template/StaticPageLayout/Turbo/Page.php b/app/Template/StaticPageLayout/Turbo/Page.php
index 0d0901ac..d4134a35 100644
--- a/app/Template/StaticPageLayout/Turbo/Page.php
+++ b/app/Template/StaticPageLayout/Turbo/Page.php
@@ -20,7 +20,7 @@ use Generator;
 
 #[Singleton(collection: SingletonCollection::StaticPageLayout)]
 #[StaticPageLayout('dm:page')]
-readonly class Page extends Turbo
+final readonly class Page extends Turbo
 {
     public function __construct(
         EsbuildMetaBuilder $esbuildMetaBuilder,
diff --git a/app/Template/StaticPageLayout/Turbo/Tutorial.php b/app/Template/StaticPageLayout/Turbo/Tutorial.php
index 43e0ffec..16c87f34 100644
--- a/app/Template/StaticPageLayout/Turbo/Tutorial.php
+++ b/app/Template/StaticPageLayout/Turbo/Tutorial.php
@@ -24,7 +24,7 @@ use IntlDateFormatter;
 
 #[Singleton(collection: SingletonCollection::StaticPageLayout)]
 #[StaticPageLayout('dm:tutorial')]
-readonly class Tutorial extends Turbo
+final readonly class Tutorial extends Turbo
 {
     private StaticPageBreadcrumbs $breadcrumbs;
     private IntlDateFormatter $intlDateFormatter;
diff --git a/app/Template/StaticPageLayout/Turbo/TutorialList.php b/app/Template/StaticPageLayout/Turbo/TutorialList.php
index 866001fd..f79565a5 100644
--- a/app/Template/StaticPageLayout/Turbo/TutorialList.php
+++ b/app/Template/StaticPageLayout/Turbo/TutorialList.php
@@ -21,7 +21,7 @@ use Generator;
 
 #[Singleton(collection: SingletonCollection::StaticPageLayout)]
 #[StaticPageLayout('dm:tutorial-list')]
-readonly class TutorialList extends Turbo
+final readonly class TutorialList extends Turbo
 {
     private StaticPageBreadcrumbs $breadcrumbs;
 
diff --git a/rector.php b/rector.php
new file mode 100644
index 00000000..d70213e7
--- /dev/null
+++ b/rector.php
@@ -0,0 +1,55 @@
+<?php
+
+declare(strict_types=1);
+
+use Rector\CodeQuality\Rector\Empty_\SimplifyEmptyCheckOnEmptyArrayRector;
+use Rector\CodeQuality\Rector\Expression\InlineIfToExplicitIfRector;
+use Rector\CodeQuality\Rector\FuncCall\ChangeArrayPushToArrayAssignRector;
+use Rector\CodeQuality\Rector\If_\ExplicitBoolCompareRector;
+use Rector\CodeQuality\Rector\If_\SimplifyIfElseToTernaryRector;
+use Rector\Config\RectorConfig;
+use Rector\DeadCode\Rector\Node\RemoveNonExistingVarAnnotationRector;
+use Rector\Php74\Rector\Closure\ClosureToArrowFunctionRector;
+use Rector\Php80\Rector\Class_\StringableForToStringRector;
+use Rector\Php81\Rector\ClassMethod\NewInInitializerRector;
+use Rector\Privatization\Rector\Class_\FinalizeClassesWithoutChildrenRector;
+use Rector\Set\ValueObject\LevelSetList;
+use Rector\Set\ValueObject\SetList;
+use Rector\Strict\Rector\Empty_\DisallowedEmptyRuleFixerRector;
+use Rector\TypeDeclaration\Rector\BooleanAnd\BinaryOpNullableToInstanceofRector;
+use Rector\TypeDeclaration\Rector\Empty_\EmptyOnNullableObjectToInstanceOfRector;
+
+return RectorConfig::configure()
+    ->withPaths([
+        __DIR__.'/app',
+        __DIR__.'/src',
+    ])
+    ->withImportNames()
+    ->withRules([
+    ])
+    ->withSkip([
+        BinaryOpNullableToInstanceofRector::class,
+        ChangeArrayPushToArrayAssignRector::class,
+        ClosureToArrowFunctionRector::class,
+        DisallowedEmptyRuleFixerRector::class,
+        EmptyOnNullableObjectToInstanceOfRector::class,
+        ExplicitBoolCompareRector::class,
+        FinalizeClassesWithoutChildrenRector::class,
+        InlineIfToExplicitIfRector::class,
+        NewInInitializerRector::class,
+        RemoveNonExistingVarAnnotationRector::class,
+        SimplifyEmptyCheckOnEmptyArrayRector::class,
+        SimplifyIfElseToTernaryRector::class,
+        StringableForToStringRector::class,
+    ])
+    ->withSets([
+        LevelSetList::UP_TO_PHP_82,
+        SetList::CODE_QUALITY,
+        SetList::DEAD_CODE,
+        SetList::EARLY_RETURN,
+        SetList::INSTANCEOF,
+        SetList::PHP_82,
+        SetList::PRIVATIZATION,
+        SetList::TYPE_DECLARATION,
+    ])
+;
diff --git a/src/Command/Cron.php b/src/Command/Cron.php
index 9d30430d..28f7bca5 100644
--- a/src/Command/Cron.php
+++ b/src/Command/Cron.php
@@ -22,10 +22,10 @@ use Symfony\Component\Console\Output\OutputInterface;
 final class Cron extends CoroutineCommand
 {
     public function __construct(
-        private CronJobAggregate $cronJobAggregate,
-        private LoggerInterface $logger,
+        private readonly CronJobAggregate $cronJobAggregate,
+        private readonly LoggerInterface $logger,
         SwooleConfiguration $swooleConfiguration,
-        private TickTimerScheduler $tickTimerScheduler,
+        private readonly TickTimerScheduler $tickTimerScheduler,
     ) {
         parent::__construct($swooleConfiguration);
     }
diff --git a/src/Command/GenerateHttpController.php b/src/Command/GenerateHttpController.php
index a29fe7bd..4affbcf9 100644
--- a/src/Command/GenerateHttpController.php
+++ b/src/Command/GenerateHttpController.php
@@ -26,7 +26,7 @@ use Symfony\Component\Console\Output\OutputInterface;
 )]
 final class GenerateHttpController extends Command
 {
-    public function __construct(private Printer $printer)
+    public function __construct(private readonly Printer $printer)
     {
         parent::__construct();
     }
diff --git a/src/Command/GenerateHttpResponder.php b/src/Command/GenerateHttpResponder.php
index 24799360..726f292d 100644
--- a/src/Command/GenerateHttpResponder.php
+++ b/src/Command/GenerateHttpResponder.php
@@ -26,7 +26,7 @@ use Symfony\Component\Console\Output\OutputInterface;
 )]
 final class GenerateHttpResponder extends Command
 {
-    public function __construct(private Printer $printer)
+    public function __construct(private readonly Printer $printer)
     {
         parent::__construct();
     }
diff --git a/src/Command/LlamaCppGenerate/Embedding.php b/src/Command/LlamaCppGenerate/Embedding.php
index d1e76f8d..7d5d376a 100644
--- a/src/Command/LlamaCppGenerate/Embedding.php
+++ b/src/Command/LlamaCppGenerate/Embedding.php
@@ -21,7 +21,7 @@ use Symfony\Component\Console\Output\OutputInterface;
 final class Embedding extends LlamaCppGenerate
 {
     public function __construct(
-        private JsonSerializer $jsonSerializer,
+        private readonly JsonSerializer $jsonSerializer,
         LlamaCppClient $llamaCppClient,
         SwooleConfiguration $swooleConfiguration,
     ) {
diff --git a/src/Command/LlamaCppHealth.php b/src/Command/LlamaCppHealth.php
index 4c887b1d..a5b64759 100644
--- a/src/Command/LlamaCppHealth.php
+++ b/src/Command/LlamaCppHealth.php
@@ -19,7 +19,7 @@ use Symfony\Component\Console\Output\OutputInterface;
 final class LlamaCppHealth extends CoroutineCommand
 {
     public function __construct(
-        private LlamaCppClient $llamaCppClient,
+        private readonly LlamaCppClient $llamaCppClient,
         SwooleConfiguration $swooleConfiguration,
     ) {
         parent::__construct($swooleConfiguration);
diff --git a/src/Command/LlamaCppInfill.php b/src/Command/LlamaCppInfill.php
index 30dbf0d1..16f8908e 100644
--- a/src/Command/LlamaCppInfill.php
+++ b/src/Command/LlamaCppInfill.php
@@ -21,8 +21,8 @@ use Symfony\Component\Console\Output\OutputInterface;
 final class LlamaCppInfill extends CoroutineCommand
 {
     public function __construct(
-        private JsonSerializer $jsonSerializer,
-        private LlamaCppClient $llamaCppClient,
+        private readonly JsonSerializer $jsonSerializer,
+        private readonly LlamaCppClient $llamaCppClient,
         SwooleConfiguration $swooleConfiguration,
     ) {
         parent::__construct($swooleConfiguration);
diff --git a/src/Command/Serve.php b/src/Command/Serve.php
index f787f73f..cabcd44e 100644
--- a/src/Command/Serve.php
+++ b/src/Command/Serve.php
@@ -30,16 +30,16 @@ use Symfony\Component\Console\Output\OutputInterface;
 )]
 final class Serve extends Command
 {
-    private HttpServer|WebSocketServer $server;
+    private readonly HttpServer|WebSocketServer $server;
 
     public function __construct(
-        private ApplicationConfiguration $applicationConfiguration,
-        private EventDispatcherInterface $eventDispatcher,
-        private HttpResponderAggregate $httpResponderAggregate,
-        private LoggerInterface $logger,
-        private ServerPipeMessageDispatcher $serverPipeMessageDispatcher,
-        private SwooleConfiguration $swooleConfiguration,
-        private ?WebSocketServerController $webSocketServerController = null,
+        private readonly ApplicationConfiguration $applicationConfiguration,
+        private readonly EventDispatcherInterface $eventDispatcher,
+        private readonly HttpResponderAggregate $httpResponderAggregate,
+        private readonly LoggerInterface $logger,
+        private readonly ServerPipeMessageDispatcher $serverPipeMessageDispatcher,
+        private readonly SwooleConfiguration $swooleConfiguration,
+        private readonly ?WebSocketServerController $webSocketServerController = null,
     ) {
         parent::__construct();
 
@@ -96,16 +96,20 @@ final class Serve extends Command
         $this->eventDispatcher->dispatch(new HttpServerBeforeStop($this->server));
     }
 
-    private function onClose(Server $server, int $fd): void
+    private function onClose(int $fd): void
     {
         $this->webSocketServerController?->onClose($fd);
     }
 
     private function onHandshake(Request $request, Response $response): void
     {
-        if ($this->webSocketServerController && $this->server instanceof WebSocketServer) {
-            $this->webSocketServerController->onHandshake($this->server, $request, $response);
+        if (!$this->webSocketServerController) {
+            return;
+        }
+        if (!$this->server instanceof WebSocketServer) {
+            return;
         }
+        $this->webSocketServerController->onHandshake($this->server, $request, $response);
     }
 
     private function onStart(Server $server): void
diff --git a/src/Command/StaticPagesBuild.php b/src/Command/StaticPagesBuild.php
index 46a2258d..2a0eb632 100644
--- a/src/Command/StaticPagesBuild.php
+++ b/src/Command/StaticPagesBuild.php
@@ -19,7 +19,7 @@ use Symfony\Component\Console\Output\OutputInterface;
 final class StaticPagesBuild extends CoroutineCommand
 {
     public function __construct(
-        private StaticPageProcessor $staticPageProcessor,
+        private readonly StaticPageProcessor $staticPageProcessor,
         SwooleConfiguration $swooleConfiguration,
     ) {
         parent::__construct($swooleConfiguration);
diff --git a/src/Command/StaticPagesDumpContent.php b/src/Command/StaticPagesDumpContent.php
index 6760d585..8d608d28 100644
--- a/src/Command/StaticPagesDumpContent.php
+++ b/src/Command/StaticPagesDumpContent.php
@@ -17,7 +17,7 @@ use Symfony\Component\Console\Output\OutputInterface;
 final class StaticPagesDumpContent extends Command
 {
     public function __construct(
-        private StaticPageAggregate $staticPageAggregate,
+        private readonly StaticPageAggregate $staticPageAggregate,
     ) {
         parent::__construct();
     }
diff --git a/src/Command/StaticPagesMakeEmbeddings.php b/src/Command/StaticPagesMakeEmbeddings.php
index cca6dd09..8953851b 100644
--- a/src/Command/StaticPagesMakeEmbeddings.php
+++ b/src/Command/StaticPagesMakeEmbeddings.php
@@ -22,13 +22,13 @@ use Symfony\Component\Console\Output\OutputInterface;
 )]
 final class StaticPagesMakeEmbeddings extends Command
 {
-    private SQLite3 $embeddingsDatabase;
+    private readonly SQLite3 $embeddingsDatabase;
 
     public function __construct(
-        private JsonSerializer $jsonSerializer,
-        private LlamaCppClient $llamaCppClient,
-        private SQLiteVSSConnectionBuilder $sqliteVSSConnectionBuilder,
-        private StaticPageChunkIterator $staticPageChunkIterator,
+        private readonly JsonSerializer $jsonSerializer,
+        private readonly LlamaCppClient $llamaCppClient,
+        private readonly SQLiteVSSConnectionBuilder $sqliteVSSConnectionBuilder,
+        private readonly StaticPageChunkIterator $staticPageChunkIterator,
     ) {
         parent::__construct();
 
diff --git a/src/Command/TestHttpResponders.php b/src/Command/TestHttpResponders.php
index 75076025..7383495a 100644
--- a/src/Command/TestHttpResponders.php
+++ b/src/Command/TestHttpResponders.php
@@ -6,7 +6,6 @@ namespace Distantmagic\Resonance\Command;
 
 use Distantmagic\Resonance\Attribute\ConsoleCommand;
 use Distantmagic\Resonance\Attribute\RespondsWith;
-use Distantmagic\Resonance\Attribute\TestableHttpResponse;
 use Distantmagic\Resonance\Command;
 use Distantmagic\Resonance\HttpRecursiveResponder;
 use Distantmagic\Resonance\HttpResponderAggregate;
@@ -28,10 +27,10 @@ use Symfony\Component\Console\Output\OutputInterface;
 final class TestHttpResponders extends Command
 {
     public function __construct(
-        private HttpRecursiveResponder $recursiveResponder,
-        private HttpResponderAggregate $httpResponderAggregate,
-        private JsonSchemaValidator $jsonSchemaValidator,
-        private TestableHttpResponseCollection $testableHttpResponseCollection,
+        private readonly HttpRecursiveResponder $recursiveResponder,
+        private readonly HttpResponderAggregate $httpResponderAggregate,
+        private readonly JsonSchemaValidator $jsonSchemaValidator,
+        private readonly TestableHttpResponseCollection $testableHttpResponseCollection,
     ) {
         parent::__construct();
     }
@@ -51,16 +50,14 @@ final class TestHttpResponders extends Command
                     ->get($testableHttpResponse)
                 ;
 
-                $isValid = $isValid and SwooleCoroutineHelper::mustRun(function () use (
+                ($isValid = $isValid) && SwooleCoroutineHelper::mustRun(function () use (
                     $output,
                     $httpResponder,
-                    $testableHttpResponse,
                     $potentialResponses
                 ): bool {
                     return $this->testResponses(
                         $output,
                         $httpResponder,
-                        $testableHttpResponse,
                         $potentialResponses,
                     );
                 });
@@ -80,7 +77,6 @@ final class TestHttpResponders extends Command
     private function testResponses(
         OutputInterface $output,
         HttpResponderInterface $httpResponder,
-        TestableHttpResponse $testableHttpResponse,
         Map $potentialResponses,
     ): bool {
         $output->write(sprintf('Testing <info>%s</info> ... ', $httpResponder::class));
diff --git a/src/Command/Watch.php b/src/Command/Watch.php
index 796e1723..19bf802c 100644
--- a/src/Command/Watch.php
+++ b/src/Command/Watch.php
@@ -21,13 +21,11 @@ use Symfony\Component\Console\Output\OutputInterface;
 )]
 final class Watch extends Command
 {
-    private const THROTTLE_TIME_MS = 10;
-
     private ?Process $process = null;
 
     public function __construct(
-        private ApplicationConfiguration $applicationConfiguration,
-        private LoggerInterface $logger,
+        private readonly ApplicationConfiguration $applicationConfiguration,
+        private readonly LoggerInterface $logger,
     ) {
         parent::__construct();
     }
@@ -84,7 +82,7 @@ final class Watch extends Command
         }
 
         $this->process = new Process(
-            callback: static function (Process $worker) use ($childCommandName) {
+            callback: static function (Process $worker) use ($childCommandName): void {
                 /**
                  * @psalm-suppress InvalidArgument false positive
                  * @psalm-suppress InvalidCast false positive
diff --git a/src/CoroutineCommand.php b/src/CoroutineCommand.php
index 3c29c62a..193b34fa 100644
--- a/src/CoroutineCommand.php
+++ b/src/CoroutineCommand.php
@@ -17,7 +17,7 @@ abstract class CoroutineCommand extends SymfonyCommand
      * the DI.
      */
     public function __construct(
-        private SwooleConfiguration $swooleConfiguration,
+        private readonly SwooleConfiguration $swooleConfiguration,
     ) {
         parent::__construct();
     }
diff --git a/src/CronJobRunner.php b/src/CronJobRunner.php
index fdf776eb..ccca1340 100644
--- a/src/CronJobRunner.php
+++ b/src/CronJobRunner.php
@@ -14,7 +14,7 @@ readonly class CronJobRunner
 
     public function runCronJob(CronRegisteredJob $cronRegisteredJob): void
     {
-        SwooleCoroutineHelper::mustGo(function () use ($cronRegisteredJob) {
+        SwooleCoroutineHelper::mustGo(function () use ($cronRegisteredJob): void {
             $this->logger->info(sprintf('cron_job_start(%s)', $cronRegisteredJob->name));
             $cronRegisteredJob->cronJob->onCronTick();
         });
diff --git a/src/DatabaseConnection.php b/src/DatabaseConnection.php
index 063b0267..2f9dd82c 100644
--- a/src/DatabaseConnection.php
+++ b/src/DatabaseConnection.php
@@ -34,7 +34,7 @@ readonly class DatabaseConnection implements ServerInfoAwareConnection
 
     public function __destruct()
     {
-        Event::defer(function () {
+        Event::defer(function (): void {
             $this->databaseConnectionPoolRepository->putConnection($this->connectionPoolName, $this->pdo);
         });
     }
diff --git a/src/DependencyInjectionContainer.php b/src/DependencyInjectionContainer.php
index d33a5800..cf22513c 100644
--- a/src/DependencyInjectionContainer.php
+++ b/src/DependencyInjectionContainer.php
@@ -50,7 +50,7 @@ readonly class DependencyInjectionContainer
         $this->wantedFeatures = new Set();
 
         $this->singletons = new SingletonContainer();
-        $this->singletons->set($this::class, $this);
+        $this->singletons->set(static::class, $this);
     }
 
     /**
@@ -67,7 +67,7 @@ readonly class DependencyInjectionContainer
         /**
          * @var null|array<string,mixed>
          */
-        $parameters = SwooleCoroutineHelper::mustRun(function () use ($function) {
+        $parameters = SwooleCoroutineHelper::mustRun(function () use ($function): array {
             $reflectionFunction = new ReflectionFunction($function);
 
             return $this->makeParameters($reflectionFunction, new DependencyStack());
@@ -154,7 +154,7 @@ readonly class DependencyInjectionContainer
             throw new DependencyInjectionContainerException(sprintf('Expected: %s, got %s', $className, gettype($providedObject)));
         }
 
-        if (is_a($providedObject, $className, true)) {
+        if ($providedObject instanceof $className) {
             return $providedObject;
         }
 
diff --git a/src/DoctrineConsoleRunner.php b/src/DoctrineConsoleRunner.php
index 7540251a..30ebc273 100644
--- a/src/DoctrineConsoleRunner.php
+++ b/src/DoctrineConsoleRunner.php
@@ -14,7 +14,7 @@ final readonly class DoctrineConsoleRunner
     {
         Runtime::enableCoroutine(SWOOLE_HOOK_ALL);
 
-        $container->call(static function (DoctrineConsoleEntityManagerProvider $entityManagerProvider) {
+        $container->call(static function (DoctrineConsoleEntityManagerProvider $entityManagerProvider): never {
             $cli = new Application('Doctrine Command Line Interface');
 
             $cli->setAutoExit(false);
diff --git a/src/DoctrineEntityManagerRepository.php b/src/DoctrineEntityManagerRepository.php
index 759ee6c0..3398972e 100644
--- a/src/DoctrineEntityManagerRepository.php
+++ b/src/DoctrineEntityManagerRepository.php
@@ -42,7 +42,7 @@ readonly class DoctrineEntityManagerRepository
 
     public function createContextKey(string $name): string
     {
-        return sprintf('%s.%s', __CLASS__, $name);
+        return sprintf('%s.%s', self::class, $name);
     }
 
     public function getEntityManager(Request $request, string $name = 'default'): EntityManagerInterface
diff --git a/src/EsbuildMetaBuilder.php b/src/EsbuildMetaBuilder.php
index 32366400..1fe71d13 100644
--- a/src/EsbuildMetaBuilder.php
+++ b/src/EsbuildMetaBuilder.php
@@ -79,26 +79,29 @@ readonly class EsbuildMetaBuilder
             $entryPointBasename = basename($output->entryPoint);
 
             $esbuildMeta->registerEntryPoint($entryPointBasename, $filename);
+            if (!isset($output->imports)) {
+                continue;
+            }
+            if (!is_array($output->imports)) {
+                continue;
+            }
+            /**
+             * @var mixed $import explicitly mixed for typechecks
+             */
+            foreach ($output->imports as $import) {
+                if (!is_object($import)) {
+                    throw new LogicException('Expected entrypoint import defintion to be an object.');
+                }
 
-            if (isset($output->imports) && is_array($output->imports)) {
-                /**
-                 * @var mixed $import explicitly mixed for typechecks
-                 */
-                foreach ($output->imports as $import) {
-                    if (!is_object($import)) {
-                        throw new LogicException('Expected entrypoint import defintion to be an object.');
-                    }
-
-                    if (
-                        !isset($import->kind, $import->path)
-                        || !is_string($import->kind)
-                        || !is_string($import->path)
-                    ) {
-                        throw new LogicException('Expected "kind" and "path" import fields to be set.');
-                    }
-
-                    yield $filename => $this->stripBaseDirectory($stripOutputPrefix, $import->path);
+                if (
+                    !isset($import->kind, $import->path)
+                    || !is_string($import->kind)
+                    || !is_string($import->path)
+                ) {
+                    throw new LogicException('Expected "kind" and "path" import fields to be set.');
                 }
+
+                yield $filename => $this->stripBaseDirectory($stripOutputPrefix, $import->path);
             }
         }
     }
@@ -120,10 +123,13 @@ readonly class EsbuildMetaBuilder
             if (!is_object($output)) {
                 throw new LogicException('Manifest output is not an object.');
             }
-
-            if (isset($output->entryPoint) && is_string($output->entryPoint)) {
-                yield $this->stripBaseDirectory($stripOutputPrefix, $filename) => $output;
+            if (!isset($output->entryPoint)) {
+                continue;
+            }
+            if (!is_string($output->entryPoint)) {
+                continue;
             }
+            yield $this->stripBaseDirectory($stripOutputPrefix, $filename) => $output;
         }
     }
 
diff --git a/src/EventDispatcher.php b/src/EventDispatcher.php
index b553349b..b3f4fc8e 100644
--- a/src/EventDispatcher.php
+++ b/src/EventDispatcher.php
@@ -20,7 +20,7 @@ readonly class EventDispatcher implements EventDispatcherInterface
 
     public function collect(EventInterface $event): SwooleFutureResult
     {
-        $future = new SwooleFuture(function (EventInterface $event) {
+        $future = new SwooleFuture(function (EventInterface $event): array {
             return $this->doDispatch($event);
         });
 
@@ -29,7 +29,7 @@ readonly class EventDispatcher implements EventDispatcherInterface
 
     public function dispatch(EventInterface $event): void
     {
-        Event::defer(function () use ($event) {
+        Event::defer(function () use ($event): void {
             $this->doDispatch($event);
         });
     }
diff --git a/src/GraphQLExecutionPromise.php b/src/GraphQLExecutionPromise.php
index b3091c0a..083d0210 100644
--- a/src/GraphQLExecutionPromise.php
+++ b/src/GraphQLExecutionPromise.php
@@ -15,13 +15,13 @@ class GraphQLExecutionPromise implements JsonSerializable
     private ?ExecutionResult $executionResult = null;
 
     public function __construct(
-        private ApplicationConfiguration $applicationConfiguration,
-        private Promise $promise,
+        private readonly ApplicationConfiguration $applicationConfiguration,
+        private readonly Promise $promise,
     ) {}
 
     public function getExecutionResult(): ExecutionResult
     {
-        $this->promise->then(function (ExecutionResult $executionResult) {
+        $this->promise->then(function (ExecutionResult $executionResult): void {
             $this->executionResult = $executionResult;
         });
 
diff --git a/src/HttpControllerMetadataException.php b/src/HttpControllerMetadataException.php
index 0ec335fc..0ff51946 100644
--- a/src/HttpControllerMetadataException.php
+++ b/src/HttpControllerMetadataException.php
@@ -13,9 +13,9 @@ class HttpControllerMetadataException extends LogicException
 {
     public function __construct(
         string $message,
-        private ReflectionMethod $reflectionMethod,
-        private ?ReflectionParameter $parameter = null,
-        private ?ReflectionNamedType $type = null,
+        private readonly ReflectionMethod $reflectionMethod,
+        private readonly ?ReflectionParameter $parameter = null,
+        private readonly ?ReflectionNamedType $type = null,
     ) {
         parent::__construct(sprintf(
             '%s in %s',
@@ -36,12 +36,10 @@ class HttpControllerMetadataException extends LogicException
             return $ret;
         }
 
-        $ret .= sprintf(
+        return $ret.sprintf(
             '(%s$%s)',
             isset($this->type) ? $this->type->getName().' ' : '',
             $this->parameter->getName(),
         );
-
-        return $ret;
     }
 }
diff --git a/src/HttpMiddleware/RespondsToOAuth2EndpointMiddleware.php b/src/HttpMiddleware/RespondsToOAuth2EndpointMiddleware.php
index 21b8e10b..e0a1599a 100644
--- a/src/HttpMiddleware/RespondsToOAuth2EndpointMiddleware.php
+++ b/src/HttpMiddleware/RespondsToOAuth2EndpointMiddleware.php
@@ -41,14 +41,11 @@ readonly class RespondsToOAuth2EndpointMiddleware extends HttpMiddleware
         Attribute $attribute,
         HttpInterceptableInterface|HttpResponderInterface $next,
     ): HttpInterceptableInterface|HttpResponderInterface {
-        switch ($attribute->endpoint) {
-            case OAuth2Endpoint::ClientScopeConsentForm:
-                $this
-                    ->authorizationCodeFlowController
-                    ->prepareConsentRequest($request, $response)
-                ;
-
-                break;
+        if (OAuth2Endpoint::ClientScopeConsentForm === $attribute->endpoint) {
+            $this
+                ->authorizationCodeFlowController
+                ->prepareConsentRequest($request, $response)
+            ;
         }
 
         return $next;
diff --git a/src/HttpRequestLanguageDetector.php b/src/HttpRequestLanguageDetector.php
index d6cd8caa..f2f674c8 100644
--- a/src/HttpRequestLanguageDetector.php
+++ b/src/HttpRequestLanguageDetector.php
@@ -9,7 +9,7 @@ use Swoole\Http\Request;
 use WeakMap;
 
 #[Singleton]
-final class HttpRequestLanguageDetector
+final readonly class HttpRequestLanguageDetector
 {
     /**
      * @var WeakMap<Request, string>
diff --git a/src/HttpResponder/HttpController.php b/src/HttpResponder/HttpController.php
index 785c0a7e..c5a05a29 100644
--- a/src/HttpResponder/HttpController.php
+++ b/src/HttpResponder/HttpController.php
@@ -70,7 +70,7 @@ abstract readonly class HttpController extends HttpResponder
         $this->handleReflection = $controllerDependencies
             ->httpControllerReflectionMethodCollection
             ->reflectionMethods
-            ->get($this::class)
+            ->get(static::class)
         ;
     }
 
diff --git a/src/HttpResponderAggregate.php b/src/HttpResponderAggregate.php
index a78d9d4b..c176e881 100644
--- a/src/HttpResponderAggregate.php
+++ b/src/HttpResponderAggregate.php
@@ -112,9 +112,9 @@ readonly class HttpResponderAggregate
                 routeVars: $routeMatch,
                 status: HttpRouteMatchStatus::Found,
             );
-        } catch (MethodNotAllowedException $methodNotAllowed) {
+        } catch (MethodNotAllowedException) {
             return new HttpRouteMatch(HttpRouteMatchStatus::MethodNotAllowed);
-        } catch (ResourceNotFoundException $resourceNotFound) {
+        } catch (ResourceNotFoundException) {
             return new HttpRouteMatch(HttpRouteMatchStatus::NotFound);
         }
     }
diff --git a/src/IntlDateFormatterRepository.php b/src/IntlDateFormatterRepository.php
index 11fccdb3..0141d2b7 100644
--- a/src/IntlDateFormatterRepository.php
+++ b/src/IntlDateFormatterRepository.php
@@ -50,6 +50,6 @@ readonly class IntlDateFormatterRepository
         int $dateTimeFormat,
         int $timeTypeFormat,
     ): string {
-        return $language.(string) $dateTimeFormat.(string) $timeTypeFormat;
+        return $language.$dateTimeFormat.$timeTypeFormat;
     }
 }
diff --git a/src/LlamaCppClient.php b/src/LlamaCppClient.php
index 06c7ba22..48b298e9 100644
--- a/src/LlamaCppClient.php
+++ b/src/LlamaCppClient.php
@@ -162,7 +162,7 @@ readonly class LlamaCppClient
         $channel = new Channel(1);
         $requestData = json_encode($request);
 
-        SwooleCoroutineHelper::mustGo(function () use ($channel, $path, $requestData) {
+        SwooleCoroutineHelper::mustGo(function () use ($channel, $path, $requestData): void {
             $curlHandle = $this->createCurlHandle();
 
             try {
@@ -170,7 +170,7 @@ readonly class LlamaCppClient
                 curl_setopt($curlHandle, CURLOPT_POSTFIELDS, $requestData);
                 curl_setopt($curlHandle, CURLOPT_RETURNTRANSFER, false);
                 curl_setopt($curlHandle, CURLOPT_URL, $this->llamaCppLinkBuilder->build($path));
-                curl_setopt($curlHandle, CURLOPT_WRITEFUNCTION, function (CurlHandle $curlHandle, string $data) use ($channel) {
+                curl_setopt($curlHandle, CURLOPT_WRITEFUNCTION, function (CurlHandle $curlHandle, string $data) use ($channel): int {
                     if ($channel->push($data, $this->llamaCppConfiguration->completionTokenTimeout)) {
                         return strlen($data);
                     }
diff --git a/src/LlamaCppCompletionIterator.php b/src/LlamaCppCompletionIterator.php
index f7499384..5b756c66 100644
--- a/src/LlamaCppCompletionIterator.php
+++ b/src/LlamaCppCompletionIterator.php
@@ -13,7 +13,6 @@ use RuntimeException;
  */
 readonly class LlamaCppCompletionIterator implements IteratorAggregate
 {
-    private const COMPLETION_CHUNKED_DATA_PREFIX = 'data: ';
     private const COMPLETION_CHUNKED_DATA_PREFIX_LENGTH = 6;
 
     /**
diff --git a/src/OAuth2AccessTokenRepository.php b/src/OAuth2AccessTokenRepository.php
index c0e2a682..b4a5ce4d 100644
--- a/src/OAuth2AccessTokenRepository.php
+++ b/src/OAuth2AccessTokenRepository.php
@@ -60,7 +60,7 @@ readonly class OAuth2AccessTokenRepository implements AccessTokenRepositoryInter
     {
         return $this
             ->doctrineEntityManagerRepository
-            ->withEntityManager(function (EntityManagerInterface $entityManager) use ($tokenId) {
+            ->withEntityManager(function (EntityManagerInterface $entityManager) use ($tokenId): bool {
                 return is_null($this->entityRepository->findAccessToken($entityManager, $tokenId));
             })
         ;
@@ -73,7 +73,7 @@ readonly class OAuth2AccessTokenRepository implements AccessTokenRepositoryInter
     {
         $this
             ->doctrineEntityManagerRepository
-            ->withEntityManager(function (EntityManagerInterface $entityManager) use ($accessTokenEntity) {
+            ->withEntityManager(function (EntityManagerInterface $entityManager) use ($accessTokenEntity): void {
                 $client = $this->entityRepository->findClient(
                     $entityManager,
                     $accessTokenEntity->getClient()->getIdentifier(),
@@ -116,7 +116,7 @@ readonly class OAuth2AccessTokenRepository implements AccessTokenRepositoryInter
     {
         $this
             ->doctrineEntityManagerRepository
-            ->withEntityManager(function (EntityManagerInterface $entityManager) use ($tokenId) {
+            ->withEntityManager(function (EntityManagerInterface $entityManager) use ($tokenId): void {
                 $accessToken = $this->entityRepository->findAccessToken($entityManager, $tokenId);
 
                 if ($accessToken) {
diff --git a/src/OAuth2AuthCodeRepository.php b/src/OAuth2AuthCodeRepository.php
index 62d28945..f1a398ba 100644
--- a/src/OAuth2AuthCodeRepository.php
+++ b/src/OAuth2AuthCodeRepository.php
@@ -39,7 +39,7 @@ readonly class OAuth2AuthCodeRepository implements AuthCodeRepositoryInterface
     {
         return $this
             ->doctrineEntityManagerRepository
-            ->withEntityManager(function (EntityManagerInterface $entityManager) use ($codeId) {
+            ->withEntityManager(function (EntityManagerInterface $entityManager) use ($codeId): bool {
                 return is_null($this->entityRepository->findAuthCode($entityManager, $codeId));
             })
         ;
@@ -49,7 +49,7 @@ readonly class OAuth2AuthCodeRepository implements AuthCodeRepositoryInterface
     {
         $this
             ->doctrineEntityManagerRepository
-            ->withEntityManager(function (EntityManagerInterface $entityManager) use ($authCodeEntity) {
+            ->withEntityManager(function (EntityManagerInterface $entityManager) use ($authCodeEntity): void {
                 $client = $this->entityRepository->findClient(
                     $entityManager,
                     $authCodeEntity->getClient()->getIdentifier(),
@@ -92,7 +92,7 @@ readonly class OAuth2AuthCodeRepository implements AuthCodeRepositoryInterface
     {
         $this
             ->doctrineEntityManagerRepository
-            ->withEntityManager(function (EntityManagerInterface $entityManager) use ($codeId) {
+            ->withEntityManager(function (EntityManagerInterface $entityManager) use ($codeId): void {
                 $accessToken = $this->entityRepository->findAuthCode($entityManager, $codeId);
 
                 if ($accessToken) {
diff --git a/src/OAuth2ClaimReader.php b/src/OAuth2ClaimReader.php
index 509d35c9..d4f08d55 100644
--- a/src/OAuth2ClaimReader.php
+++ b/src/OAuth2ClaimReader.php
@@ -80,7 +80,7 @@ readonly class OAuth2ClaimReader implements AuthenticatedUserStoreInterface
 
         return $this
             ->doctrineEntityManagerRepository
-            ->withEntityManager(function (EntityManagerInterface $entityManager) use ($serverRequest) {
+            ->withEntityManager(function (EntityManagerInterface $entityManager) use ($serverRequest): OAuth2Claim {
                 $accessTokenId = $serverRequest->getAttribute('oauth_access_token_id');
 
                 if (!is_string($accessTokenId)) {
diff --git a/src/OAuth2ClientRepository.php b/src/OAuth2ClientRepository.php
index b8ce6eef..9c28ffd7 100644
--- a/src/OAuth2ClientRepository.php
+++ b/src/OAuth2ClientRepository.php
@@ -29,7 +29,7 @@ readonly class OAuth2ClientRepository implements ClientRepositoryInterface
     {
         return $this
             ->doctrineEntityManagerRepository
-            ->withEntityManager(function (EntityManagerInterface $entityManager) use ($clientIdentifier) {
+            ->withEntityManager(function (EntityManagerInterface $entityManager) use ($clientIdentifier): ?ClientEntityInterface {
                 $doctrineClient = $this->entityRepository->findClient(
                     $entityManager,
                     $clientIdentifier,
diff --git a/src/OAuth2RefreshTokenRepository.php b/src/OAuth2RefreshTokenRepository.php
index acec2e61..6e24022c 100644
--- a/src/OAuth2RefreshTokenRepository.php
+++ b/src/OAuth2RefreshTokenRepository.php
@@ -53,7 +53,7 @@ readonly class OAuth2RefreshTokenRepository implements RefreshTokenRepositoryInt
     {
         $this
             ->doctrineEntityManagerRepository
-            ->withEntityManager(function (EntityManagerInterface $entityManager) use ($refreshTokenEntity) {
+            ->withEntityManager(function (EntityManagerInterface $entityManager) use ($refreshTokenEntity): void {
                 $accessToken = $this->entityRepository->findAccessToken(
                     $entityManager,
                     $refreshTokenEntity->getAccessToken()->getIdentifier(),
@@ -81,7 +81,7 @@ readonly class OAuth2RefreshTokenRepository implements RefreshTokenRepositoryInt
     {
         $this
             ->doctrineEntityManagerRepository
-            ->withEntityManager(function (EntityManagerInterface $entityManager) use ($tokenId) {
+            ->withEntityManager(function (EntityManagerInterface $entityManager) use ($tokenId): void {
                 $refreshToken = $this->entityRepository->findRefreshToken($entityManager, $tokenId);
 
                 if ($refreshToken) {
diff --git a/src/OpenAPIRouteParameterExtractor/DoctrineEntityRouteParameterExtractor.php b/src/OpenAPIRouteParameterExtractor/DoctrineEntityRouteParameterExtractor.php
index 3c73fbcc..d1b5320d 100644
--- a/src/OpenAPIRouteParameterExtractor/DoctrineEntityRouteParameterExtractor.php
+++ b/src/OpenAPIRouteParameterExtractor/DoctrineEntityRouteParameterExtractor.php
@@ -54,7 +54,7 @@ readonly class DoctrineEntityRouteParameterExtractor extends OpenAPIRouteParamet
     ): array {
         return $this
             ->doctrineEntityManagerRepository
-            ->withEntityManager(function (EntityManagerInterface $entityManager) use ($attribute, $parameterClass) {
+            ->withEntityManager(function (EntityManagerInterface $entityManager) use ($attribute, $parameterClass): array {
                 return $this->extractWithEntityManager($attribute, $entityManager, $parameterClass);
             })
         ;
diff --git a/src/OpenAPISchema.php b/src/OpenAPISchema.php
index 82abb7a2..252989b8 100644
--- a/src/OpenAPISchema.php
+++ b/src/OpenAPISchema.php
@@ -8,7 +8,7 @@ use JsonSerializable;
 
 readonly class OpenAPISchema implements JsonSerializable
 {
-    public const VERSION = '3.1.0';
+    final public const VERSION = '3.1.0';
 
     public OpenAPISchemaInfo $openAPISchemaInfo;
     public OpenAPISchemaPaths $openAPISchemaPaths;
diff --git a/src/PHPFileReflectionClassAttributeIterator.php b/src/PHPFileReflectionClassAttributeIterator.php
index 3821c37d..b8061045 100644
--- a/src/PHPFileReflectionClassAttributeIterator.php
+++ b/src/PHPFileReflectionClassAttributeIterator.php
@@ -22,8 +22,8 @@ class PHPFileReflectionClassAttributeIterator implements IteratorAggregate
      * @param class-string<TAttribute>          $attributeClass
      */
     public function __construct(
-        private iterable $reflectionClassIterator,
-        private string $attributeClass,
+        private readonly iterable $reflectionClassIterator,
+        private readonly string $attributeClass,
     ) {}
 
     /**
diff --git a/src/Session.php b/src/Session.php
index 3c4d0db2..3aca544b 100644
--- a/src/Session.php
+++ b/src/Session.php
@@ -37,7 +37,7 @@ readonly class Session
 
     public function __destruct()
     {
-        Event::defer(function () {
+        Event::defer(function (): void {
             $this->redisConnectionPoolRepository->putConnection(
                 $this->sessionConfiguration->redisConnectionPool,
                 $this->redis,
diff --git a/src/SingletonContainer.php b/src/SingletonContainer.php
index 06179710..a266f7ed 100644
--- a/src/SingletonContainer.php
+++ b/src/SingletonContainer.php
@@ -22,13 +22,6 @@ final readonly class SingletonContainer implements SingletonContainerInterface
      */
     private Map $singletons;
 
-    private static function assertClassExists(string $class): void
-    {
-        if (!class_exists($class) && !interface_exists($class)) {
-            throw new SingletonContainerException('Class does not exist: '.$class);
-        }
-    }
-
     public function __construct()
     {
         $this->singletons = new Map();
@@ -43,7 +36,7 @@ final readonly class SingletonContainer implements SingletonContainerInterface
      */
     public function get(string $id): object
     {
-        self::assertClassExists($id);
+        $this->assertClassExists($id);
 
         if (!$this->has($id)) {
             throw new NotFoundException('Class is not set: '.$id);
@@ -57,14 +50,14 @@ final readonly class SingletonContainer implements SingletonContainerInterface
 
     public function has(string $id): bool
     {
-        self::assertClassExists($id);
+        $this->assertClassExists($id);
 
         return $this->singletons->hasKey($id);
     }
 
     public function set(string $id, object $object): void
     {
-        self::assertClassExists($id);
+        $this->assertClassExists($id);
 
         if ($this->has($id)) {
             throw new SingletonContainerException('Class is already set: '.$id);
@@ -97,4 +90,16 @@ final readonly class SingletonContainer implements SingletonContainerInterface
     {
         return $this->singletons->values();
     }
+
+    private function assertClassExists(string $class): void
+    {
+        if (class_exists($class)) {
+            return;
+        }
+        if (interface_exists($class)) {
+            return;
+        }
+
+        throw new SingletonContainerException('Class does not exist: '.$class);
+    }
 }
diff --git a/src/StaticPageChunkIterator.php b/src/StaticPageChunkIterator.php
index 4d5c21bb..f196621d 100644
--- a/src/StaticPageChunkIterator.php
+++ b/src/StaticPageChunkIterator.php
@@ -77,10 +77,13 @@ readonly class StaticPageChunkIterator implements IteratorAggregate
             }
 
             $textContent = $this->extractNodeTextContent($child);
-
-            if (!empty($textContent) && str_contains($textContent, ' ')) {
-                yield $textContent;
+            if (empty($textContent)) {
+                continue;
+            }
+            if (!str_contains($textContent, ' ')) {
+                continue;
             }
+            yield $textContent;
         }
     }
 }
diff --git a/src/StaticPageCollection.php b/src/StaticPageCollection.php
index b9e0a98a..0f34886b 100644
--- a/src/StaticPageCollection.php
+++ b/src/StaticPageCollection.php
@@ -54,7 +54,7 @@ readonly class StaticPageCollection
             $this->assertPageExists($staticPages, $next);
         }
 
-        $this->staticPages->sort(function (StaticPage $a, StaticPage $b) {
+        $this->staticPages->sort(function (StaticPage $a, StaticPage $b): int {
             $aPriority = $this->getPriority($a->getBasename());
             $bPriority = $this->getPriority($b->getBasename());
 
diff --git a/src/StaticPageInternalLinkDelimiterProcessor.php b/src/StaticPageInternalLinkDelimiterProcessor.php
index 3e4dedf7..b59cd39c 100644
--- a/src/StaticPageInternalLinkDelimiterProcessor.php
+++ b/src/StaticPageInternalLinkDelimiterProcessor.php
@@ -61,7 +61,7 @@ readonly class StaticPageInternalLinkDelimiterProcessor implements DelimiterProc
     {
         $tmp = $opener->next();
 
-        while (null !== $tmp && $tmp !== $closer) {
+        while ($tmp instanceof Node && $tmp !== $closer) {
             $next = $tmp->next();
             yield $tmp;
             $tmp = $next;
diff --git a/src/StaticPageInternalLinkNodeRenderer.php b/src/StaticPageInternalLinkNodeRenderer.php
index 697619e7..2d46bd91 100644
--- a/src/StaticPageInternalLinkNodeRenderer.php
+++ b/src/StaticPageInternalLinkNodeRenderer.php
@@ -56,7 +56,7 @@ readonly class StaticPageInternalLinkNodeRenderer implements NodeRendererInterfa
         $pageBasename = $this->getPageBasename($node, $childRenderer);
 
         if (str_contains($pageBasename, '*')) {
-            return $this->getStaticPagesByPattern($node, $pageBasename);
+            return $this->getStaticPagesByPattern($pageBasename);
         }
 
         if (!$this->staticPages->hasKey($pageBasename)) {
@@ -69,7 +69,7 @@ readonly class StaticPageInternalLinkNodeRenderer implements NodeRendererInterfa
     /**
      * @return Set<StaticPage>
      */
-    private function getStaticPagesByPattern(Node $node, string $pattern): Set
+    private function getStaticPagesByPattern(string $pattern): Set
     {
         /**
          * @var Set<StaticPage>
@@ -82,9 +82,13 @@ readonly class StaticPageInternalLinkNodeRenderer implements NodeRendererInterfa
         $skip = $chunks[1] ?? null;
 
         foreach ($this->staticPages as $baseUrl => $staticPage) {
-            if (fnmatch($pattern, $baseUrl, FNM_PATHNAME) && $baseUrl !== $skip) {
-                $ret->add($staticPage);
+            if (!fnmatch($pattern, $baseUrl, FNM_PATHNAME)) {
+                continue;
             }
+            if ($baseUrl === $skip) {
+                continue;
+            }
+            $ret->add($staticPage);
         }
 
         if ($ret->isEmpty()) {
diff --git a/src/SwooleCoroutineHelper.php b/src/SwooleCoroutineHelper.php
index 47384cf3..1190ac37 100644
--- a/src/SwooleCoroutineHelper.php
+++ b/src/SwooleCoroutineHelper.php
@@ -52,7 +52,7 @@ final readonly class SwooleCoroutineHelper
         /**
          * @var bool
          */
-        $coroutineResult = run(static function () use ($callback, &$exception, &$ret) {
+        $coroutineResult = run(static function () use ($callback, &$exception, &$ret): void {
             try {
                 $ret = $callback();
             } catch (Throwable $throwable) {
diff --git a/src/SwooleLoggerBridge.php b/src/SwooleLoggerBridge.php
index adab249f..cd2fa3bb 100644
--- a/src/SwooleLoggerBridge.php
+++ b/src/SwooleLoggerBridge.php
@@ -59,7 +59,7 @@ final readonly class SwooleLoggerBridge implements LoggerInterface
             LogLevel::INFO => $this->info($message, $context),
             LogLevel::NOTICE => $this->notice($message, $context),
             LogLevel::WARNING => $this->warning($message, $context),
-            default => throw new InvalidArgumentException('Invalid log level: '.(string) $level),
+            default => throw new InvalidArgumentException('Invalid log level'),
         };
     }
 
diff --git a/src/TestsGraphQLQueriesTrait.php b/src/TestsGraphQLQueriesTrait.php
index 79ae0a28..7113b9bf 100644
--- a/src/TestsGraphQLQueriesTrait.php
+++ b/src/TestsGraphQLQueriesTrait.php
@@ -18,7 +18,7 @@ trait TestsGraphQLQueriesTrait
         $result = self::$container->call(static function (
             CrudActionGateAggregate $crudActionGateAggregate,
             GraphQLAdapter $graphQLAdapter,
-        ) use ($query) {
+        ) use ($query): array {
             $swoolePromiseAdapter = new SwoolePromiseAdapter();
 
             return $graphQLAdapter
diff --git a/src/TickTimerScheduler.php b/src/TickTimerScheduler.php
index fc815c6c..de03d2ee 100644
--- a/src/TickTimerScheduler.php
+++ b/src/TickTimerScheduler.php
@@ -14,7 +14,7 @@ class TickTimerScheduler
     private int $currentTick = 0;
     private ?int $tickTimerId = null;
 
-    public function __construct(private TickTimerJobAggregate $tickTimerJobAggregate) {}
+    public function __construct(private readonly TickTimerJobAggregate $tickTimerJobAggregate) {}
 
     public function shouldRegister(): bool
     {
diff --git a/src/WebSocketProtocolController/RPCProtocolController.php b/src/WebSocketProtocolController/RPCProtocolController.php
index c4ccfd89..e9b2c8b9 100644
--- a/src/WebSocketProtocolController/RPCProtocolController.php
+++ b/src/WebSocketProtocolController/RPCProtocolController.php
@@ -114,10 +114,10 @@ final readonly class RPCProtocolController extends WebSocketProtocolController
             $this->onJsonMessage($server, $frame, $decodedRpcMessage);
         } catch (JsonException $exception) {
             $this->onProtocolError($server, $frame, 'Invalid JSON');
-            $this->onException($server, $frame, $exception);
+            $this->onException($exception);
         } catch (WebSocketProtocolException $exception) {
             $this->onProtocolError($server, $frame, $exception->getMessage());
-            $this->onException($server, $frame, $exception);
+            $this->onException($exception);
         }
     }
 
@@ -151,7 +151,7 @@ final readonly class RPCProtocolController extends WebSocketProtocolController
         return $this->connectionHandles->get($frame->fd);
     }
 
-    private function onException(Server $server, Frame $frame, Throwable $exception): void
+    private function onException(Throwable $exception): void
     {
         $this->logger->debug((string) $exception);
     }
diff --git a/tools/rector/.gitignore b/tools/rector/.gitignore
new file mode 100644
index 00000000..61ead866
--- /dev/null
+++ b/tools/rector/.gitignore
@@ -0,0 +1 @@
+/vendor
diff --git a/tools/rector/composer.json b/tools/rector/composer.json
new file mode 100644
index 00000000..265216b1
--- /dev/null
+++ b/tools/rector/composer.json
@@ -0,0 +1,5 @@
+{
+    "require": {
+        "rector/rector": "^0.19.3"
+    }
+}
diff --git a/tools/rector/composer.lock b/tools/rector/composer.lock
new file mode 100644
index 00000000..ef6e120d
--- /dev/null
+++ b/tools/rector/composer.lock
@@ -0,0 +1,137 @@
+{
+    "_readme": [
+        "This file locks the dependencies of your project to a known state",
+        "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
+        "This file is @generated automatically"
+    ],
+    "content-hash": "b7049790c5103907473947ced941afd8",
+    "packages": [
+        {
+            "name": "phpstan/phpstan",
+            "version": "1.10.57",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/phpstan/phpstan.git",
+                "reference": "1627b1d03446904aaa77593f370c5201d2ecc34e"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/phpstan/phpstan/zipball/1627b1d03446904aaa77593f370c5201d2ecc34e",
+                "reference": "1627b1d03446904aaa77593f370c5201d2ecc34e",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^7.2|^8.0"
+            },
+            "conflict": {
+                "phpstan/phpstan-shim": "*"
+            },
+            "bin": [
+                "phpstan",
+                "phpstan.phar"
+            ],
+            "type": "library",
+            "autoload": {
+                "files": [
+                    "bootstrap.php"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "description": "PHPStan - PHP Static Analysis Tool",
+            "keywords": [
+                "dev",
+                "static analysis"
+            ],
+            "support": {
+                "docs": "https://phpstan.org/user-guide/getting-started",
+                "forum": "https://github.com/phpstan/phpstan/discussions",
+                "issues": "https://github.com/phpstan/phpstan/issues",
+                "security": "https://github.com/phpstan/phpstan/security/policy",
+                "source": "https://github.com/phpstan/phpstan-src"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/ondrejmirtes",
+                    "type": "github"
+                },
+                {
+                    "url": "https://github.com/phpstan",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/phpstan/phpstan",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2024-01-24T11:51:34+00:00"
+        },
+        {
+            "name": "rector/rector",
+            "version": "0.19.3",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/rectorphp/rector.git",
+                "reference": "5c1dd52a62206858660cd39a347ece0ce93af1ba"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/rectorphp/rector/zipball/5c1dd52a62206858660cd39a347ece0ce93af1ba",
+                "reference": "5c1dd52a62206858660cd39a347ece0ce93af1ba",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^7.2|^8.0",
+                "phpstan/phpstan": "^1.10.56"
+            },
+            "conflict": {
+                "rector/rector-doctrine": "*",
+                "rector/rector-downgrade-php": "*",
+                "rector/rector-phpunit": "*",
+                "rector/rector-symfony": "*"
+            },
+            "bin": [
+                "bin/rector"
+            ],
+            "type": "library",
+            "autoload": {
+                "files": [
+                    "bootstrap.php"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "description": "Instant Upgrade and Automated Refactoring of any PHP code",
+            "keywords": [
+                "automation",
+                "dev",
+                "migration",
+                "refactoring"
+            ],
+            "support": {
+                "issues": "https://github.com/rectorphp/rector/issues",
+                "source": "https://github.com/rectorphp/rector/tree/0.19.3"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/tomasvotruba",
+                    "type": "github"
+                }
+            ],
+            "time": "2024-01-29T19:04:58+00:00"
+        }
+    ],
+    "packages-dev": [],
+    "aliases": [],
+    "minimum-stability": "stable",
+    "stability-flags": [],
+    "prefer-stable": false,
+    "prefer-lowest": false,
+    "platform": [],
+    "platform-dev": [],
+    "plugin-api-version": "2.3.0"
+}
-- 
GitLab