From f8bea8995417234bbdbeb2016b5abf11dc55be55 Mon Sep 17 00:00:00 2001 From: Sergei Predvoditelev Date: Tue, 19 Mar 2024 17:53:00 +0300 Subject: [PATCH 01/23] raise psalm version --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 239ba696..12f9d471 100644 --- a/composer.json +++ b/composer.json @@ -50,7 +50,7 @@ "rector/rector": "^1.0.0", "roave/infection-static-analysis-plugin": "^1.16", "spatie/phpunit-watcher": "^1.23", - "vimeo/psalm": "^5.18", + "vimeo/psalm": "^5.23", "yiisoft/error-handler": "^3.0", "yiisoft/event-dispatcher": "^1.0", "yiisoft/log": "^2.0", From 9a5510c5e9f3950c210997a9f4dd6780a46ae2e9 Mon Sep 17 00:00:00 2001 From: Sergei Predvoditelev Date: Tue, 19 Mar 2024 18:03:00 +0300 Subject: [PATCH 02/23] 1 --- psalm.xml | 2 +- src/Storage/FileStorage.php | 38 ++++++++++++++++++-------------- src/Storage/StorageInterface.php | 2 +- 3 files changed, 24 insertions(+), 18 deletions(-) diff --git a/psalm.xml b/psalm.xml index 2a2f7e56..b48c894e 100644 --- a/psalm.xml +++ b/psalm.xml @@ -1,6 +1,6 @@ path, - $id ?? '**', - $type, + + $dataFiles = $this->findFilesOrderByModifiedTime( + sprintf( + '%s/**/%s/%s.json', + $this->path, + $id ?? '**', + $type, + ) ); - $dataFiles = glob($pattern, GLOB_NOSORT); - uasort($dataFiles, static fn ($a, $b) => filemtime($a) <=> filemtime($b)); + $data = []; foreach ($dataFiles as $file) { $dir = dirname($file); $id = substr($dir, strlen(dirname($file, 2)) + 1); @@ -122,12 +122,11 @@ private function collectSummaryData(): array */ private function gc(): void { - $summaryFiles = glob($this->path . '/**/**/summary.json', GLOB_NOSORT); + $summaryFiles = $this->findFilesOrderByModifiedTime($this->path . '/**/**/summary.json'); if (empty($summaryFiles) || count($summaryFiles) <= $this->historySize) { return; } - uasort($summaryFiles, static fn ($a, $b) => filemtime($b) <=> filemtime($a)); $excessFiles = array_slice($summaryFiles, $this->historySize); foreach ($excessFiles as $file) { $path1 = dirname($file); @@ -145,13 +144,20 @@ private function gc(): void } } - private function reindexObjects(array $objectsAsArraysCollection): array + /** + * @return string[] + */ + private function findFilesOrderByModifiedTime(string $pattern): array { - $toMerge = []; - foreach ($objectsAsArraysCollection as $objectAsArray) { - $toMerge[] = $objectAsArray; + $files = glob($pattern, GLOB_NOSORT); + if ($files === false) { + return []; } - return array_merge(...$toMerge); + uasort( + $files, + static fn (string $a, string $b) => filemtime($b) <=> filemtime($a) + ); + return $files; } } diff --git a/src/Storage/StorageInterface.php b/src/Storage/StorageInterface.php index e6027248..3da2cfe2 100644 --- a/src/Storage/StorageInterface.php +++ b/src/Storage/StorageInterface.php @@ -25,7 +25,7 @@ public function addCollector(CollectorInterface $collector): void; /** * Returns collected data from collectors added * - * @return array collected data + * @return array[] The collected data */ public function getData(): array; From b12eae17730aabafaaba0d8b9521e679fd432d1a Mon Sep 17 00:00:00 2001 From: Sergei Predvoditelev Date: Tue, 19 Mar 2024 18:05:20 +0300 Subject: [PATCH 03/23] 2 --- src/ProxyServiceProvider.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/ProxyServiceProvider.php b/src/ProxyServiceProvider.php index 02cbd8d3..19be6265 100644 --- a/src/ProxyServiceProvider.php +++ b/src/ProxyServiceProvider.php @@ -12,12 +12,15 @@ final class ProxyServiceProvider implements ServiceProviderInterface { /** - * @psalm-suppress InaccessibleMethod + * @psalm-suppress MixedArgument */ public function getDefinitions(): array { return [ - ContainerInterface::class => static fn (ContainerInterface $container) => new ContainerInterfaceProxy($container, $container->get(ContainerProxyConfig::class)), + ContainerInterface::class => static fn (ContainerInterface $container) => new ContainerInterfaceProxy( + $container, + $container->get(ContainerProxyConfig::class) + ), ]; } From 4848c1b880e186d335856e085c413e49eebd4f9b Mon Sep 17 00:00:00 2001 From: Sergei Predvoditelev Date: Wed, 20 Mar 2024 16:31:35 +0300 Subject: [PATCH 04/23] 3 --- src/Storage/FileStorage.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Storage/FileStorage.php b/src/Storage/FileStorage.php index aecd52fc..d1289504 100644 --- a/src/Storage/FileStorage.php +++ b/src/Storage/FileStorage.php @@ -154,7 +154,7 @@ private function findFilesOrderByModifiedTime(string $pattern): array return []; } - uasort( + usort( $files, static fn (string $a, string $b) => filemtime($b) <=> filemtime($a) ); From 3cb39b96eccfcef0661ff30a482ccfc89ec5d9dc Mon Sep 17 00:00:00 2001 From: Sergei Predvoditelev Date: Wed, 20 Mar 2024 16:50:27 +0300 Subject: [PATCH 05/23] 4 --- src/Helper/StreamWrapper/StreamWrapper.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Helper/StreamWrapper/StreamWrapper.php b/src/Helper/StreamWrapper/StreamWrapper.php index 608e1ff4..af6baccc 100644 --- a/src/Helper/StreamWrapper/StreamWrapper.php +++ b/src/Helper/StreamWrapper/StreamWrapper.php @@ -217,6 +217,7 @@ public function url_stat(string $path, int $flags): array|false public function stream_metadata(string $path, int $option, mixed $value): bool { + /** @psalm-suppress MixedArgument */ return match ($option) { STREAM_META_TOUCH => touch($path, ...$value), STREAM_META_OWNER_NAME, STREAM_META_OWNER => chown($path, $value), From b639cada88ac415f96d28192b5b2a840c222f503 Mon Sep 17 00:00:00 2001 From: Sergei Predvoditelev Date: Wed, 20 Mar 2024 16:58:59 +0300 Subject: [PATCH 06/23] 5 --- src/Helper/BacktraceIgnoreMatcher.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/Helper/BacktraceIgnoreMatcher.php b/src/Helper/BacktraceIgnoreMatcher.php index 11f0f8c4..6a271dc6 100644 --- a/src/Helper/BacktraceIgnoreMatcher.php +++ b/src/Helper/BacktraceIgnoreMatcher.php @@ -15,9 +15,13 @@ */ final class BacktraceIgnoreMatcher { + /** + * @param string[] $patterns + * @psalm-param list $backtrace + */ public static function isIgnoredByFile(array $backtrace, array $patterns): bool { - if (!isset($backtrace[2])) { + if (!isset($backtrace[2]['file'])) { return false; } $path = $backtrace[2]['file']; @@ -30,6 +34,9 @@ public static function isIgnoredByClass(array $backtrace, array $classes): bool return isset($backtrace[3]['class']) && in_array($backtrace[3]['class'], $classes, true); } + /** + * @param string[] $patterns + */ public static function doesStringMatchPattern(string $string, array $patterns): bool { if (empty($patterns)) { From 1fdfac2fb227029a3aa77a1c8d24b14db8723e40 Mon Sep 17 00:00:00 2001 From: Sergei Predvoditelev Date: Wed, 20 Mar 2024 17:04:45 +0300 Subject: [PATCH 07/23] 6 --- src/Debugger.php | 3 +++ src/FlattenException.php | 7 ++++++- src/Helper/BacktraceIgnoreMatcher.php | 8 +++++++- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/Debugger.php b/src/Debugger.php index 276e18ae..1c39c6f4 100644 --- a/src/Debugger.php +++ b/src/Debugger.php @@ -11,6 +11,9 @@ use Yiisoft\Yii\Debug\Storage\StorageInterface; use Yiisoft\Yii\Http\Event\BeforeRequest; +/** + * @psalm-type debug_backtrace_type = list + */ final class Debugger { private bool $skipCollect = false; diff --git a/src/FlattenException.php b/src/FlattenException.php index 442991df..3ac13873 100644 --- a/src/FlattenException.php +++ b/src/FlattenException.php @@ -14,6 +14,8 @@ * Implements the Throwable interface * Basically, this class removes all objects from the trace. * Ported from Symfony components @link https://github.com/symfony/symfony/blob/master/src/Symfony/Component/Debug/Exception/FlattenException.php + * + * @psalm-import-type debug_backtrace_type from Debugger */ final class FlattenException implements \Stringable { @@ -162,6 +164,8 @@ public function getTrace(): array /** * @param array $trace the Exception stack trace as an array. + * + * @psalm-param debug_backtrace_type $trace */ private function setTrace(array $trace): void { @@ -292,12 +296,13 @@ private function flattenArgs(array $args, $level = 0, &$count = 0): array } /** - * @return string the real class name of an incomplete class + * @return string The real class name of an incomplete class */ private function getClassNameFromIncomplete(__PHP_Incomplete_Class $value): string { $array = new ArrayObject($value); + /** @var string */ return $array['__PHP_Incomplete_Class_Name']; } } diff --git a/src/Helper/BacktraceIgnoreMatcher.php b/src/Helper/BacktraceIgnoreMatcher.php index 6a271dc6..fe537cb4 100644 --- a/src/Helper/BacktraceIgnoreMatcher.php +++ b/src/Helper/BacktraceIgnoreMatcher.php @@ -5,6 +5,7 @@ namespace Yiisoft\Yii\Debug\Helper; use Yiisoft\Strings\CombinedRegexp; +use Yiisoft\Yii\Debug\Debugger; /** * All backtrace parameters should contain at least 4 elements in the following order: @@ -12,12 +13,14 @@ * 1 – Proxy * 2 – Real using place / Composer\ClassLoader include function * 3 – Whatever / Composer\ClassLoader + * + * @psalm-import-type debug_backtrace_type from Debugger */ final class BacktraceIgnoreMatcher { /** * @param string[] $patterns - * @psalm-param list $backtrace + * @psalm-param debug_backtrace_type $backtrace */ public static function isIgnoredByFile(array $backtrace, array $patterns): bool { @@ -29,6 +32,9 @@ public static function isIgnoredByFile(array $backtrace, array $patterns): bool return self::doesStringMatchPattern($path, $patterns); } + /** + * @psalm-param debug_backtrace_type $backtrace + */ public static function isIgnoredByClass(array $backtrace, array $classes): bool { return isset($backtrace[3]['class']) && in_array($backtrace[3]['class'], $classes, true); From 812e40e2f47126b26a2883f44b7ee99184783112 Mon Sep 17 00:00:00 2001 From: Sergei Predvoditelev Date: Wed, 20 Mar 2024 17:08:39 +0300 Subject: [PATCH 08/23] 7 --- src/Debugger.php | 2 +- src/FlattenException.php | 4 ++-- src/Helper/BacktraceIgnoreMatcher.php | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Debugger.php b/src/Debugger.php index 1c39c6f4..73b9dbf0 100644 --- a/src/Debugger.php +++ b/src/Debugger.php @@ -12,7 +12,7 @@ use Yiisoft\Yii\Http\Event\BeforeRequest; /** - * @psalm-type debug_backtrace_type = list + * @psalm-type BacktraceType = list */ final class Debugger { diff --git a/src/FlattenException.php b/src/FlattenException.php index 3ac13873..47502139 100644 --- a/src/FlattenException.php +++ b/src/FlattenException.php @@ -15,7 +15,7 @@ * Basically, this class removes all objects from the trace. * Ported from Symfony components @link https://github.com/symfony/symfony/blob/master/src/Symfony/Component/Debug/Exception/FlattenException.php * - * @psalm-import-type debug_backtrace_type from Debugger + * @psalm-import-type BacktraceType from Debugger */ final class FlattenException implements \Stringable { @@ -165,7 +165,7 @@ public function getTrace(): array /** * @param array $trace the Exception stack trace as an array. * - * @psalm-param debug_backtrace_type $trace + * @psalm-param BacktraceType $trace */ private function setTrace(array $trace): void { diff --git a/src/Helper/BacktraceIgnoreMatcher.php b/src/Helper/BacktraceIgnoreMatcher.php index fe537cb4..59f0dc9d 100644 --- a/src/Helper/BacktraceIgnoreMatcher.php +++ b/src/Helper/BacktraceIgnoreMatcher.php @@ -14,13 +14,13 @@ * 2 – Real using place / Composer\ClassLoader include function * 3 – Whatever / Composer\ClassLoader * - * @psalm-import-type debug_backtrace_type from Debugger + * @psalm-import-type BacktraceType from Debugger */ final class BacktraceIgnoreMatcher { /** * @param string[] $patterns - * @psalm-param debug_backtrace_type $backtrace + * @psalm-param BacktraceType $backtrace */ public static function isIgnoredByFile(array $backtrace, array $patterns): bool { @@ -33,7 +33,7 @@ public static function isIgnoredByFile(array $backtrace, array $patterns): bool } /** - * @psalm-param debug_backtrace_type $backtrace + * @psalm-param BacktraceType $backtrace */ public static function isIgnoredByClass(array $backtrace, array $classes): bool { From 03c1b00bac6692047fd98755b33dbc4fbe3de7a5 Mon Sep 17 00:00:00 2001 From: Sergei Predvoditelev Date: Wed, 20 Mar 2024 17:10:19 +0300 Subject: [PATCH 09/23] 8 --- src/Debugger.php | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/Debugger.php b/src/Debugger.php index 73b9dbf0..555fd7bb 100644 --- a/src/Debugger.php +++ b/src/Debugger.php @@ -19,12 +19,14 @@ final class Debugger private bool $skipCollect = false; private bool $active = false; + /** + * @param CollectorInterface[] $collectors + * @param string[] $ignoredRequests + * @param string[] $ignoredCommands + */ public function __construct( private DebuggerIdGenerator $idGenerator, private StorageInterface $target, - /** - * @var CollectorInterface[] - */ private array $collectors, private array $ignoredRequests = [], private array $ignoredCommands = [], @@ -120,7 +122,7 @@ private function isCommandIgnored(?string $command): bool } /** - * @param array $ignoredRequests Patterns for ignored request URLs. + * @param string[] $ignoredRequests Patterns for ignored request URLs. * * @see WildcardPattern */ @@ -132,7 +134,7 @@ public function withIgnoredRequests(array $ignoredRequests): self } /** - * @param array $ignoredCommands Patterns for ignored commands names. + * @param string[] $ignoredCommands Patterns for ignored commands names. * * @see WildcardPattern */ From c26805816a00697ab8bdbba525858bbc32ded019 Mon Sep 17 00:00:00 2001 From: Sergei Predvoditelev Date: Wed, 20 Mar 2024 17:14:04 +0300 Subject: [PATCH 10/23] 9 --- src/DebugServiceProvider.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/DebugServiceProvider.php b/src/DebugServiceProvider.php index 132816ae..0bd3666c 100644 --- a/src/DebugServiceProvider.php +++ b/src/DebugServiceProvider.php @@ -20,6 +20,9 @@ public function getDefinitions(): array return []; } + /** + * @psalm-suppress MixedArgument + */ public function getExtensions(): array { return [ From 87ccd886370e365fe04fbe8bc36d7dbdc02d49fb Mon Sep 17 00:00:00 2001 From: StyleCI Bot Date: Wed, 20 Mar 2024 14:14:29 +0000 Subject: [PATCH 11/23] Apply fixes from StyleCI --- src/Storage/FileStorage.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Storage/FileStorage.php b/src/Storage/FileStorage.php index d1289504..875e2305 100644 --- a/src/Storage/FileStorage.php +++ b/src/Storage/FileStorage.php @@ -18,7 +18,6 @@ use function glob; use function strlen; use function substr; -use function uasort; final class FileStorage implements StorageInterface { From 3c6e8cf907683a590838a8dbd69f1de43377bbfc Mon Sep 17 00:00:00 2001 From: Sergei Predvoditelev Date: Mon, 5 Aug 2024 09:49:18 +0300 Subject: [PATCH 12/23] Remove `ProxyServiceProvider` --- src/ProxyServiceProvider.php | 28 ---------------------------- 1 file changed, 28 deletions(-) delete mode 100644 src/ProxyServiceProvider.php diff --git a/src/ProxyServiceProvider.php b/src/ProxyServiceProvider.php deleted file mode 100644 index 02cbd8d3..00000000 --- a/src/ProxyServiceProvider.php +++ /dev/null @@ -1,28 +0,0 @@ - static fn (ContainerInterface $container) => new ContainerInterfaceProxy($container, $container->get(ContainerProxyConfig::class)), - ]; - } - - public function getExtensions(): array - { - return []; - } -} From 4a09b8d8e02664a32e4e25a4b1a9ed934f2dc45f Mon Sep 17 00:00:00 2001 From: StyleCI Bot Date: Mon, 5 Aug 2024 06:49:48 +0000 Subject: [PATCH 13/23] Apply fixes from StyleCI --- src/Storage/FileStorage.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Storage/FileStorage.php b/src/Storage/FileStorage.php index 7dd23762..453dedd7 100644 --- a/src/Storage/FileStorage.php +++ b/src/Storage/FileStorage.php @@ -11,7 +11,6 @@ use Yiisoft\Yii\Debug\DebuggerIdGenerator; use Yiisoft\Yii\Debug\Dumper; -use function array_merge; use function array_slice; use function count; use function dirname; @@ -19,7 +18,6 @@ use function glob; use function strlen; use function substr; -use function uasort; final class FileStorage implements StorageInterface { From 37ad22010fc6ea59b04fd288510c7e0e11779168 Mon Sep 17 00:00:00 2001 From: Sergei Predvoditelev Date: Mon, 5 Aug 2024 09:54:01 +0300 Subject: [PATCH 14/23] cleanup --- src/DebugServiceProvider.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/DebugServiceProvider.php b/src/DebugServiceProvider.php index d65183a1..29498bbc 100644 --- a/src/DebugServiceProvider.php +++ b/src/DebugServiceProvider.php @@ -21,9 +21,6 @@ public function getDefinitions(): array ]; } - /** - * @psalm-suppress MixedArgument - */ public function getExtensions(): array { return []; From 261c0e789f2894272c4b4a03c40d9f0773393c1b Mon Sep 17 00:00:00 2001 From: Sergei Predvoditelev Date: Thu, 19 Dec 2024 15:28:35 +0300 Subject: [PATCH 15/23] fix --- src/Storage/FileStorage.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Storage/FileStorage.php b/src/Storage/FileStorage.php index 453dedd7..78d54b68 100644 --- a/src/Storage/FileStorage.php +++ b/src/Storage/FileStorage.php @@ -49,7 +49,7 @@ public function read(string $type, ?string $id = null): array { clearstatcache(); - $dataFiles = $this->findFilesOrderByModifiedTime( + $dataFiles = $this->findFilesOrderedByModifiedTime( sprintf( '%s/**/%s/%s.json', $this->path, @@ -121,7 +121,7 @@ private function collectSummaryData(): array */ private function gc(): void { - $summaryFiles = $this->findFilesOrderByModifiedTime($this->path . '/**/**/summary.json'); + $summaryFiles = $this->findFilesOrderedByModifiedTime($this->path . '/**/**/summary.json'); if (empty($summaryFiles) || count($summaryFiles) <= $this->historySize) { return; } @@ -146,7 +146,7 @@ private function gc(): void /** * @return string[] */ - private function findFilesOrderByModifiedTime(string $pattern): array + private function findFilesOrderedByModifiedTime(string $pattern): array { $files = glob($pattern, GLOB_NOSORT); if ($files === false) { From 4ab8635ad5af747cb7631e3ba3bf968acfc62ef1 Mon Sep 17 00:00:00 2001 From: Sergei Predvoditelev Date: Thu, 19 Dec 2024 15:32:01 +0300 Subject: [PATCH 16/23] 10 --- src/ProxyDecoratedCalls.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/ProxyDecoratedCalls.php b/src/ProxyDecoratedCalls.php index 57ce12bb..c9b8235b 100644 --- a/src/ProxyDecoratedCalls.php +++ b/src/ProxyDecoratedCalls.php @@ -21,6 +21,9 @@ public function __get(string $name) public function __call(string $name, array $arguments) { + /** + * @psalm-suppress MixedMethodCall + */ return $this->decorated->$name(...$arguments); } } From 6e0754da1da3279e2e3fa964890ab88d6ab2d204 Mon Sep 17 00:00:00 2001 From: Sergei Predvoditelev Date: Thu, 19 Dec 2024 15:36:37 +0300 Subject: [PATCH 17/23] 11 --- src/DebugServiceProvider.php | 9 +++++---- src/ProxyDecoratedCalls.php | 3 --- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/DebugServiceProvider.php b/src/DebugServiceProvider.php index 29498bbc..d84b1d66 100644 --- a/src/DebugServiceProvider.php +++ b/src/DebugServiceProvider.php @@ -14,10 +14,11 @@ final class DebugServiceProvider implements ServiceProviderInterface public function getDefinitions(): array { return [ - ContainerInterface::class => static fn (ContainerInterface $container) => new ContainerInterfaceProxy( - $container, - $container->get(ContainerProxyConfig::class), - ), + ContainerInterface::class => + static fn (ContainerInterface $container, ContainerProxyConfig $config) => new ContainerInterfaceProxy( + $container, + $config, + ), ]; } diff --git a/src/ProxyDecoratedCalls.php b/src/ProxyDecoratedCalls.php index c9b8235b..e2ccae0f 100644 --- a/src/ProxyDecoratedCalls.php +++ b/src/ProxyDecoratedCalls.php @@ -4,9 +4,6 @@ namespace Yiisoft\Yii\Debug; -/** - * @property object $decorated - */ trait ProxyDecoratedCalls { public function __set(string $name, mixed $value): void From 8e329317d5c1bac06d201b7e0aeda30dec5722a9 Mon Sep 17 00:00:00 2001 From: Sergei Predvoditelev Date: Thu, 19 Dec 2024 15:44:06 +0300 Subject: [PATCH 18/23] 12 --- src/Collector/Stream/HttpStreamProxy.php | 27 +++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/src/Collector/Stream/HttpStreamProxy.php b/src/Collector/Stream/HttpStreamProxy.php index a178a038..eea15bd9 100644 --- a/src/Collector/Stream/HttpStreamProxy.php +++ b/src/Collector/Stream/HttpStreamProxy.php @@ -9,15 +9,32 @@ use Yiisoft\Yii\Debug\Helper\StreamWrapper\StreamWrapper; use Yiisoft\Yii\Debug\Helper\StreamWrapper\StreamWrapperInterface; +use function func_get_args; +use function in_array; use function stream_get_wrappers; use const SEEK_SET; +/** + * @psalm-suppress MixedInferredReturnType, MixedReturnStatement + */ final class HttpStreamProxy implements StreamWrapperInterface { public static bool $registered = false; + + /** + * @var string[] + */ public static array $ignoredPathPatterns = []; + + /** + * @var string[] + */ public static array $ignoredClasses = []; + + /** + * @var string[] + */ public static array $ignoredUrls = []; /** * @var resource|null @@ -27,6 +44,10 @@ final class HttpStreamProxy implements StreamWrapperInterface public bool $ignored = false; public static ?HttpStreamCollector $collector = null; + + /** + * @psalm-var array + */ public array $operations = []; public function __construct() @@ -120,7 +141,7 @@ public function stream_read(int $count): string|false $headers = (array) ($context['http']['header'] ?? $context['https']['header'] ?? []); $this->operations['read'] = [ - 'path' => $this->decorated->filename, + 'path' => $this->decorated->filename ?? '', 'args' => [ 'method' => $method, 'response_headers' => $metadata['wrapper_data'], @@ -175,7 +196,7 @@ public function dir_readdir(): false|string { if (!$this->ignored) { $this->operations[__FUNCTION__] = [ - 'path' => $this->decorated->filename, + 'path' => $this->decorated->filename ?? '', 'args' => [], ]; } @@ -256,7 +277,7 @@ public function stream_write(string $data): int { if (!$this->ignored) { $this->operations['write'] = [ - 'path' => $this->decorated->filename, + 'path' => $this->decorated->filename ?? '', 'args' => [], ]; } From 8d3dd494c9c3fc84e712d15ebe62b8c45950f4f1 Mon Sep 17 00:00:00 2001 From: Sergei Predvoditelev Date: Thu, 19 Dec 2024 15:48:50 +0300 Subject: [PATCH 19/23] 13 --- src/Collector/Stream/FilesystemStreamProxy.php | 3 +++ src/Collector/Stream/HttpStreamCollector.php | 18 +++++++++++++++--- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/Collector/Stream/FilesystemStreamProxy.php b/src/Collector/Stream/FilesystemStreamProxy.php index 75fdd865..51a71a66 100644 --- a/src/Collector/Stream/FilesystemStreamProxy.php +++ b/src/Collector/Stream/FilesystemStreamProxy.php @@ -11,6 +11,9 @@ use const SEEK_SET; +/** + * @psalm-suppress MixedInferredReturnType, MixedReturnStatement + */ final class FilesystemStreamProxy implements StreamWrapperInterface { public static bool $registered = false; diff --git a/src/Collector/Stream/HttpStreamCollector.php b/src/Collector/Stream/HttpStreamCollector.php index 9cda2e82..61634066 100644 --- a/src/Collector/Stream/HttpStreamCollector.php +++ b/src/Collector/Stream/HttpStreamCollector.php @@ -7,17 +7,31 @@ use Yiisoft\Yii\Debug\Collector\CollectorTrait; use Yiisoft\Yii\Debug\Collector\SummaryCollectorInterface; +use function count; + final class HttpStreamCollector implements SummaryCollectorInterface { use CollectorTrait; public function __construct( + /** + * @var string[] + */ private readonly array $ignoredPathPatterns = [], + /** + * @var string[] + */ private readonly array $ignoredClasses = [], + /** + * @var string[] + */ private readonly array $ignoredUrls = [] ) { } + /** + * @psalm-var array> + */ private array $requests = []; public function getCollected(): array @@ -76,9 +90,7 @@ public function getSummary(): array 'http_stream' => array_merge( ...array_map( fn (string $operation) => [ - $operation => is_countable($this->requests[$operation]) ? count( - $this->requests[$operation] - ) : 0, + $operation => count($this->requests[$operation]), ], array_keys($this->requests) ) From b4cdf7f0b9d75c812801c7f9c520116ea3133afe Mon Sep 17 00:00:00 2001 From: Sergei Predvoditelev Date: Thu, 19 Dec 2024 15:54:09 +0300 Subject: [PATCH 20/23] 14 --- .../Stream/FilesystemStreamCollector.php | 14 +++++++++----- src/Collector/Stream/FilesystemStreamProxy.php | 18 +++++++++++++++--- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/src/Collector/Stream/FilesystemStreamCollector.php b/src/Collector/Stream/FilesystemStreamCollector.php index 0c567d86..699a5616 100644 --- a/src/Collector/Stream/FilesystemStreamCollector.php +++ b/src/Collector/Stream/FilesystemStreamCollector.php @@ -7,6 +7,8 @@ use Yiisoft\Yii\Debug\Collector\CollectorTrait; use Yiisoft\Yii\Debug\Collector\SummaryCollectorInterface; +use function count; + final class FilesystemStreamCollector implements SummaryCollectorInterface { use CollectorTrait; @@ -17,23 +19,25 @@ public function __construct( * Examples: * - '/' . preg_quote('yii-debug/src/Dumper', '/') . '/' * - '/ClosureExporter/' + * + * @var string[] */ private readonly array $ignoredPathPatterns = [], + /** + * @var string[] + */ private readonly array $ignoredClasses = [], ) { } /** - * @var array[] + * @psalm-var array> */ private array $operations = []; public function getCollected(): array { - if (!$this->isActive()) { - return []; - } - return array_map('array_values', $this->operations); + return $this->isActive() ? $this->operations : []; } public function startup(): void diff --git a/src/Collector/Stream/FilesystemStreamProxy.php b/src/Collector/Stream/FilesystemStreamProxy.php index 51a71a66..528c9321 100644 --- a/src/Collector/Stream/FilesystemStreamProxy.php +++ b/src/Collector/Stream/FilesystemStreamProxy.php @@ -25,8 +25,20 @@ final class FilesystemStreamProxy implements StreamWrapperInterface public bool $ignored = false; public static ?FilesystemStreamCollector $collector = null; + + /** + * @var string[] + */ public static array $ignoredPathPatterns = []; + + /** + * @var string[] + */ public static array $ignoredClasses = []; + + /** + * @psalm-var array + */ public array $operations = []; public function __construct() @@ -107,7 +119,7 @@ public function stream_read(int $count): string|false { if (!$this->ignored) { $this->operations['read'] = [ - 'path' => $this->decorated->filename, + 'path' => $this->decorated->filename ?? '', 'args' => [], ]; } @@ -158,7 +170,7 @@ public function dir_readdir(): false|string { if (!$this->ignored) { $this->operations['readdir'] = [ - 'path' => $this->decorated->filename, + 'path' => $this->decorated->filename ?? '', 'args' => [], ]; } @@ -239,7 +251,7 @@ public function stream_write(string $data): int { if (!$this->ignored) { $this->operations['write'] = [ - 'path' => $this->decorated->filename, + 'path' => $this->decorated->filename ?? '', 'args' => [], ]; } From c323c83bc088914b1eaf3d1a74541da7aaf682b8 Mon Sep 17 00:00:00 2001 From: Sergei Predvoditelev Date: Thu, 19 Dec 2024 15:56:55 +0300 Subject: [PATCH 21/23] 15 --- src/Collector/LoggerInterfaceProxy.php | 1 + src/Collector/ServiceMethodProxy.php | 3 +++ 2 files changed, 4 insertions(+) diff --git a/src/Collector/LoggerInterfaceProxy.php b/src/Collector/LoggerInterfaceProxy.php index a3a72f16..ebeac119 100644 --- a/src/Collector/LoggerInterfaceProxy.php +++ b/src/Collector/LoggerInterfaceProxy.php @@ -95,6 +95,7 @@ public function debug(string|Stringable $message, array $context = []): void public function log(mixed $level, string|Stringable $message, array $context = []): void { + $level = (string) $level; $callStack = $this->getCallStack(); $this->collector->collect($level, $message, $context, $callStack['file'] . ':' . $callStack['line']); diff --git a/src/Collector/ServiceMethodProxy.php b/src/Collector/ServiceMethodProxy.php index bddb467d..00df67f3 100644 --- a/src/Collector/ServiceMethodProxy.php +++ b/src/Collector/ServiceMethodProxy.php @@ -11,6 +11,9 @@ class ServiceMethodProxy extends ServiceProxy public function __construct( string $service, object $instance, + /** + * @psalm-var array + */ private readonly array $methods, ContainerProxyConfig $config ) { From 71645c4e2405df11ae9bc71f84999567f1c0b327 Mon Sep 17 00:00:00 2001 From: Sergei Predvoditelev Date: Thu, 19 Dec 2024 16:08:43 +0300 Subject: [PATCH 22/23] 16 --- src/Collector/ContainerInterfaceProxy.php | 18 ++++++++++++++++-- src/Collector/ContainerProxyConfig.php | 4 ++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/Collector/ContainerInterfaceProxy.php b/src/Collector/ContainerInterfaceProxy.php index 2c53f06b..68cdaa45 100644 --- a/src/Collector/ContainerInterfaceProxy.php +++ b/src/Collector/ContainerInterfaceProxy.php @@ -7,6 +7,7 @@ use Exception; use Psr\Container\ContainerExceptionInterface; use Psr\Container\ContainerInterface; +use Yiisoft\Proxy\ObjectProxy; use Yiisoft\Proxy\ProxyManager; use Yiisoft\Proxy\ProxyTrait; use Yiisoft\Yii\Debug\ProxyDecoratedCalls; @@ -30,6 +31,9 @@ final class ContainerInterfaceProxy implements ContainerInterface private array $decoratedServices = []; + /** + * @psalm-var array + */ private array $serviceProxy = []; public function __construct( @@ -40,6 +44,9 @@ public function __construct( $this->proxyManager = new ProxyManager($this->config->getProxyCachePath()); } + /** + * @psalm-param array $decoratedServices + */ public function withDecoratedServices(array $decoratedServices): self { $new = clone $this; @@ -108,10 +115,12 @@ private function getServiceProxy(string $service, object $instance): ?object } if ($this->config->hasDecoratedServiceCallableConfig($service)) { + /** @psalm-suppress MixedArgument */ return $this->getServiceProxyFromCallable($this->config->getDecoratedServiceConfig($service), $instance); } if ($this->config->hasDecoratedServiceArrayConfigWithStringKeys($service)) { + /** @psalm-suppress MixedArgument */ return $this->getCommonMethodProxy( interface_exists($service) || class_exists($service) ? $service : $instance::class, $instance, @@ -120,6 +129,7 @@ interface_exists($service) || class_exists($service) ? $service : $instance::cla } if ($this->config->hasDecoratedServiceArrayConfig($service)) { + /** @psalm-suppress MixedArgument */ return $this->getServiceProxyFromArray($instance, $this->config->getDecoratedServiceConfig($service)); } @@ -130,6 +140,9 @@ interface_exists($service) || class_exists($service) ? $service : $instance::cla return null; } + /** + * @psalm-param callable(ContainerInterface, object):(object|null) $callback + */ private function getServiceProxyFromCallable(callable $callback, object $instance): ?object { return $callback($this, $instance); @@ -138,7 +151,7 @@ private function getServiceProxyFromCallable(callable $callback, object $instanc /** * @psalm-param class-string $service */ - private function getCommonMethodProxy(string $service, object $instance, array $callbacks): ?object + private function getCommonMethodProxy(string $service, object $instance, array $callbacks): ObjectProxy { $methods = []; foreach ($callbacks as $method => $callback) { @@ -163,10 +176,11 @@ private function getServiceProxyFromArray(object $instance, array $params): ?obj try { $params[$index] = $this->get($param); } catch (Exception) { - //leave as is + // leave as is } } } + /** @psalm-suppress MixedMethodCall */ return new $proxyClass($instance, ...$params); } catch (Exception) { return null; diff --git a/src/Collector/ContainerProxyConfig.php b/src/Collector/ContainerProxyConfig.php index 969096bd..933cd75e 100644 --- a/src/Collector/ContainerProxyConfig.php +++ b/src/Collector/ContainerProxyConfig.php @@ -7,6 +7,7 @@ use Psr\EventDispatcher\EventDispatcherInterface; use function in_array; +use function is_array; use function is_callable; final class ContainerProxyConfig @@ -64,6 +65,9 @@ public function withCollector(ServiceCollector $collector): self return $config; } + /** + * @psalm-param array $decoratedServices + */ public function withDecoratedServices(array $decoratedServices): self { $config = clone $this; From 334a3a4bced147fecd667b89f6a48179e2dd1a39 Mon Sep 17 00:00:00 2001 From: Sergei Predvoditelev Date: Thu, 19 Dec 2024 16:13:09 +0300 Subject: [PATCH 23/23] 17 --- src/Collector/Console/CommandCollector.php | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/Collector/Console/CommandCollector.php b/src/Collector/Console/CommandCollector.php index bd2a2d14..db763132 100644 --- a/src/Collector/Console/CommandCollector.php +++ b/src/Collector/Console/CommandCollector.php @@ -15,6 +15,8 @@ use Yiisoft\Yii\Debug\Collector\SummaryCollectorInterface; use Yiisoft\Yii\Debug\Collector\TimelineCollector; +use function array_key_exists; + final class CommandCollector implements SummaryCollectorInterface { use CollectorTrait; @@ -23,6 +25,19 @@ final class CommandCollector implements SummaryCollectorInterface * Let -1 mean that it was not set during the process. */ private const UNDEFINED_EXIT_CODE = -1; + + /** + * @psalm-var array + */ private array $commands = []; public function __construct( @@ -127,6 +142,9 @@ private function castInputToString(InputInterface $input): ?string return method_exists($input, '__toString') ? $input->__toString() : null; } + /** + * @return string[] + */ private function getSupportedEvents(): array { return [