From 9b866724d5f2a3724784fbd3a2bc711b8b481ba1 Mon Sep 17 00:00:00 2001 From: Mark Li Date: Fri, 10 May 2024 17:39:15 -0500 Subject: [PATCH 1/7] add psalm, resolve issues --- Slim/CallableResolver.php | 3 +++ Slim/MiddlewareDispatcher.php | 3 +++ Slim/Routing/RouteCollector.php | 1 + composer.json | 3 ++- psalm.xml | 17 +++++++++++++++++ 5 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 psalm.xml diff --git a/Slim/CallableResolver.php b/Slim/CallableResolver.php index 66f225de8..14848b7a8 100644 --- a/Slim/CallableResolver.php +++ b/Slim/CallableResolver.php @@ -120,6 +120,9 @@ private function isMiddleware($toResolve): bool */ private function resolveSlimNotation(string $toResolve): array { + if(!CallableResolver::$callablePattern) { + throw new RuntimeException("CallableResolver::\$callablePattern was modified to an invalid value"); + } preg_match(CallableResolver::$callablePattern, $toResolve, $matches); [$class, $method] = $matches ? [$matches[1], $matches[2]] : [$toResolve, null]; diff --git a/Slim/MiddlewareDispatcher.php b/Slim/MiddlewareDispatcher.php index 7e0564414..af8d8619b 100644 --- a/Slim/MiddlewareDispatcher.php +++ b/Slim/MiddlewareDispatcher.php @@ -183,6 +183,9 @@ public function handle(ServerRequestInterface $request): ResponseInterface $instance = null; $method = null; + if(!CallableResolver::$callablePattern) { + throw new RuntimeException("CallableResolver::\$callablePattern was modified to an invalid value"); + } // Check for Slim callable as `class:method` if (preg_match(CallableResolver::$callablePattern, $resolved, $matches)) { $resolved = $matches[1]; diff --git a/Slim/Routing/RouteCollector.php b/Slim/Routing/RouteCollector.php index 61b450300..41ac0325a 100644 --- a/Slim/Routing/RouteCollector.php +++ b/Slim/Routing/RouteCollector.php @@ -181,6 +181,7 @@ public function removeNamedRoute(string $name): RouteCollectorInterface { $route = $this->getNamedRoute($name); + /** @psalm-suppress PossiblyNullArrayOffset */ unset($this->routesByName[$route->getName()], $this->routes[$route->getIdentifier()]); return $this; } diff --git a/composer.json b/composer.json index f98064ff2..5e93851f7 100644 --- a/composer.json +++ b/composer.json @@ -68,7 +68,8 @@ "phpunit/phpunit": "^9.6", "slim/http": "^1.3", "slim/psr7": "^1.6", - "squizlabs/php_codesniffer": "^3.9" + "squizlabs/php_codesniffer": "^3.9", + "vimeo/psalm": "^5.24" }, "autoload": { "psr-4": { diff --git a/psalm.xml b/psalm.xml new file mode 100644 index 000000000..66c9171d0 --- /dev/null +++ b/psalm.xml @@ -0,0 +1,17 @@ + + + + + + + + + From 65a1c7700e8e7dc9c115372de9f1b703927645d0 Mon Sep 17 00:00:00 2001 From: Mark Li Date: Fri, 10 May 2024 18:38:05 -0500 Subject: [PATCH 2/7] add psalm-template for App ContainerInterface --- Slim/App.php | 8 +++++++- Slim/Interfaces/RouteCollectorProxyInterface.php | 6 ++++++ Slim/Routing/RouteCollectorProxy.php | 9 +++++++++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/Slim/App.php b/Slim/App.php index ebcc751f6..18a7b2178 100644 --- a/Slim/App.php +++ b/Slim/App.php @@ -30,7 +30,10 @@ use Slim\Routing\RouteRunner; use function strtoupper; - +/** + * @psalm-template TContainerInterface of (ContainerInterface|null) + * @template-extends RouteCollectorProxy + */ class App extends RouteCollectorProxy implements RequestHandlerInterface { /** @@ -44,6 +47,9 @@ class App extends RouteCollectorProxy implements RequestHandlerInterface protected MiddlewareDispatcherInterface $middlewareDispatcher; + /** + * @psalm-param TContainerInterface $container + */ public function __construct( ResponseFactoryInterface $responseFactory, ?ContainerInterface $container = null, diff --git a/Slim/Interfaces/RouteCollectorProxyInterface.php b/Slim/Interfaces/RouteCollectorProxyInterface.php index fcbed92b6..7943d8df1 100644 --- a/Slim/Interfaces/RouteCollectorProxyInterface.php +++ b/Slim/Interfaces/RouteCollectorProxyInterface.php @@ -14,12 +14,18 @@ use Psr\Http\Message\ResponseFactoryInterface; use Psr\Http\Message\UriInterface; +/** + * @psalm-template TContainerInterface of (ContainerInterface|null) + */ interface RouteCollectorProxyInterface { public function getResponseFactory(): ResponseFactoryInterface; public function getCallableResolver(): CallableResolverInterface; + /** + * @psalm-return TContainerInterface + */ public function getContainer(): ?ContainerInterface; public function getRouteCollector(): RouteCollectorInterface; diff --git a/Slim/Routing/RouteCollectorProxy.php b/Slim/Routing/RouteCollectorProxy.php index f8bc232bc..cac930ddd 100644 --- a/Slim/Routing/RouteCollectorProxy.php +++ b/Slim/Routing/RouteCollectorProxy.php @@ -18,18 +18,26 @@ use Slim\Interfaces\RouteGroupInterface; use Slim\Interfaces\RouteInterface; +/** + * @psalm-template TContainerInterface of (ContainerInterface|null) + * @template-implements RouteCollectorProxyInterface + */ class RouteCollectorProxy implements RouteCollectorProxyInterface { protected ResponseFactoryInterface $responseFactory; protected CallableResolverInterface $callableResolver; + /** @psalm-var TContainerInterface */ protected ?ContainerInterface $container = null; protected RouteCollectorInterface $routeCollector; protected string $groupPattern; + /** + * @psalm-param TContainerInterface $container + */ public function __construct( ResponseFactoryInterface $responseFactory, CallableResolverInterface $callableResolver, @@ -62,6 +70,7 @@ public function getCallableResolver(): CallableResolverInterface /** * {@inheritdoc} + * @psalm-return TContainerInterface */ public function getContainer(): ?ContainerInterface { From d586615b13a819578b4df49a72e74bd3a69640f4 Mon Sep 17 00:00:00 2001 From: Mark Li Date: Fri, 10 May 2024 19:20:37 -0500 Subject: [PATCH 3/7] fix phpstan too --- Slim/App.php | 6 ++++-- Slim/Factory/AppFactory.php | 10 ++++++++++ Slim/Interfaces/RouteCollectorProxyInterface.php | 5 +++-- Slim/Routing/RouteCollector.php | 3 +++ Slim/Routing/RouteCollectorProxy.php | 8 ++++---- Slim/Routing/RouteGroup.php | 4 ++++ Slim/Routing/RouteRunner.php | 6 ++++++ composer.json | 6 ++++-- 8 files changed, 38 insertions(+), 10 deletions(-) diff --git a/Slim/App.php b/Slim/App.php index 18a7b2178..5017626e7 100644 --- a/Slim/App.php +++ b/Slim/App.php @@ -31,7 +31,7 @@ use function strtoupper; /** - * @psalm-template TContainerInterface of (ContainerInterface|null) + * @template TContainerInterface of (ContainerInterface|null) * @template-extends RouteCollectorProxy */ class App extends RouteCollectorProxy implements RequestHandlerInterface @@ -48,7 +48,7 @@ class App extends RouteCollectorProxy implements RequestHandlerInterface protected MiddlewareDispatcherInterface $middlewareDispatcher; /** - * @psalm-param TContainerInterface $container + * @param TContainerInterface $container */ public function __construct( ResponseFactoryInterface $responseFactory, @@ -95,6 +95,7 @@ public function getMiddlewareDispatcher(): MiddlewareDispatcherInterface /** * @param MiddlewareInterface|string|callable $middleware + * @return App */ public function add($middleware): self { @@ -104,6 +105,7 @@ public function add($middleware): self /** * @param MiddlewareInterface $middleware + * @return App */ public function addMiddleware(MiddlewareInterface $middleware): self { diff --git a/Slim/Factory/AppFactory.php b/Slim/Factory/AppFactory.php index 6fc5f86ea..307c63586 100644 --- a/Slim/Factory/AppFactory.php +++ b/Slim/Factory/AppFactory.php @@ -44,6 +44,11 @@ class AppFactory protected static bool $slimHttpDecoratorsAutomaticDetectionEnabled = true; + /** + * @template TContainerInterface of (ContainerInterface|null) + * @param TContainerInterface $container + * @return (App|App) + */ public static function create( ?ResponseFactoryInterface $responseFactory = null, ?ContainerInterface $container = null, @@ -63,6 +68,11 @@ public static function create( ); } + /** + * @template TContainerInterface of (ContainerInterface) + * @param TContainerInterface $container + * @return App + */ public static function createFromContainer(ContainerInterface $container): App { $responseFactory = $container->has(ResponseFactoryInterface::class) diff --git a/Slim/Interfaces/RouteCollectorProxyInterface.php b/Slim/Interfaces/RouteCollectorProxyInterface.php index 7943d8df1..8bbde0e47 100644 --- a/Slim/Interfaces/RouteCollectorProxyInterface.php +++ b/Slim/Interfaces/RouteCollectorProxyInterface.php @@ -15,7 +15,7 @@ use Psr\Http\Message\UriInterface; /** - * @psalm-template TContainerInterface of (ContainerInterface|null) + * @template TContainerInterface of (ContainerInterface|null) */ interface RouteCollectorProxyInterface { @@ -24,7 +24,7 @@ public function getResponseFactory(): ResponseFactoryInterface; public function getCallableResolver(): CallableResolverInterface; /** - * @psalm-return TContainerInterface + * @return TContainerInterface */ public function getContainer(): ?ContainerInterface; @@ -37,6 +37,7 @@ public function getBasePath(): string; /** * Set the RouteCollectorProxy's base path + * @return RouteCollectorProxyInterface */ public function setBasePath(string $basePath): RouteCollectorProxyInterface; diff --git a/Slim/Routing/RouteCollector.php b/Slim/Routing/RouteCollector.php index 41ac0325a..182196656 100644 --- a/Slim/Routing/RouteCollector.php +++ b/Slim/Routing/RouteCollector.php @@ -244,6 +244,9 @@ protected function createGroup(string $pattern, $callable): RouteGroupInterface return new RouteGroup($pattern, $callable, $this->callableResolver, $routeCollectorProxy); } + /** + * @return RouteCollectorProxyInterface + */ protected function createProxy(string $pattern): RouteCollectorProxyInterface { return new RouteCollectorProxy( diff --git a/Slim/Routing/RouteCollectorProxy.php b/Slim/Routing/RouteCollectorProxy.php index cac930ddd..a946d148f 100644 --- a/Slim/Routing/RouteCollectorProxy.php +++ b/Slim/Routing/RouteCollectorProxy.php @@ -19,7 +19,7 @@ use Slim\Interfaces\RouteInterface; /** - * @psalm-template TContainerInterface of (ContainerInterface|null) + * @template TContainerInterface of (ContainerInterface|null) * @template-implements RouteCollectorProxyInterface */ class RouteCollectorProxy implements RouteCollectorProxyInterface @@ -28,7 +28,7 @@ class RouteCollectorProxy implements RouteCollectorProxyInterface protected CallableResolverInterface $callableResolver; - /** @psalm-var TContainerInterface */ + /** @var TContainerInterface */ protected ?ContainerInterface $container = null; protected RouteCollectorInterface $routeCollector; @@ -36,7 +36,7 @@ class RouteCollectorProxy implements RouteCollectorProxyInterface protected string $groupPattern; /** - * @psalm-param TContainerInterface $container + * @param TContainerInterface $container */ public function __construct( ResponseFactoryInterface $responseFactory, @@ -70,7 +70,7 @@ public function getCallableResolver(): CallableResolverInterface /** * {@inheritdoc} - * @psalm-return TContainerInterface + * @return TContainerInterface */ public function getContainer(): ?ContainerInterface { diff --git a/Slim/Routing/RouteGroup.php b/Slim/Routing/RouteGroup.php index cd2f4e79a..eb03dd563 100644 --- a/Slim/Routing/RouteGroup.php +++ b/Slim/Routing/RouteGroup.php @@ -26,6 +26,9 @@ class RouteGroup implements RouteGroupInterface protected CallableResolverInterface $callableResolver; + /** + * @var RouteCollectorProxyInterface<\Psr\Container\ContainerInterface|null> + */ protected RouteCollectorProxyInterface $routeCollectorProxy; /** @@ -37,6 +40,7 @@ class RouteGroup implements RouteGroupInterface /** * @param callable|string $callable + * @param RouteCollectorProxyInterface<\Psr\Container\ContainerInterface|null> $routeCollectorProxy */ public function __construct( string $pattern, diff --git a/Slim/Routing/RouteRunner.php b/Slim/Routing/RouteRunner.php index 40946af56..8856f5195 100644 --- a/Slim/Routing/RouteRunner.php +++ b/Slim/Routing/RouteRunner.php @@ -26,8 +26,14 @@ class RouteRunner implements RequestHandlerInterface private RouteParserInterface $routeParser; + /** + * @var RouteCollectorProxyInterface<\Psr\Container\ContainerInterface|null> + */ private ?RouteCollectorProxyInterface $routeCollectorProxy; + /** + * @param RouteCollectorProxyInterface<\Psr\Container\ContainerInterface|null> $routeCollectorProxy + */ public function __construct( RouteResolverInterface $routeResolver, RouteParserInterface $routeParser, diff --git a/composer.json b/composer.json index 5e93851f7..4fcfcc377 100644 --- a/composer.json +++ b/composer.json @@ -85,11 +85,13 @@ "test": [ "@phpunit", "@phpcs", - "@phpstan" + "@phpstan", + "@psalm" ], "phpunit": "phpunit", "phpcs": "phpcs", - "phpstan": "phpstan --memory-limit=-1" + "phpstan": "phpstan --memory-limit=-1", + "psalm": "psalm" }, "suggest": { "ext-simplexml": "Needed to support XML format in BodyParsingMiddleware", From 2a31bc4e892246d91f3dac7300f5dbb7a2751a63 Mon Sep 17 00:00:00 2001 From: Mark Li Date: Sat, 11 May 2024 00:26:43 +0000 Subject: [PATCH 4/7] fix formatting for phpcs --- Slim/App.php | 1 + Slim/CallableResolver.php | 6 ++++-- Slim/MiddlewareDispatcher.php | 6 ++++-- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/Slim/App.php b/Slim/App.php index 5017626e7..b298fab7b 100644 --- a/Slim/App.php +++ b/Slim/App.php @@ -30,6 +30,7 @@ use Slim\Routing\RouteRunner; use function strtoupper; + /** * @template TContainerInterface of (ContainerInterface|null) * @template-extends RouteCollectorProxy diff --git a/Slim/CallableResolver.php b/Slim/CallableResolver.php index 14848b7a8..8ed8a247b 100644 --- a/Slim/CallableResolver.php +++ b/Slim/CallableResolver.php @@ -120,8 +120,10 @@ private function isMiddleware($toResolve): bool */ private function resolveSlimNotation(string $toResolve): array { - if(!CallableResolver::$callablePattern) { - throw new RuntimeException("CallableResolver::\$callablePattern was modified to an invalid value"); + if (!CallableResolver::$callablePattern) { + throw new RuntimeException( + "CallableResolver::\$callablePattern was modified to an invalid value" + ); } preg_match(CallableResolver::$callablePattern, $toResolve, $matches); [$class, $method] = $matches ? [$matches[1], $matches[2]] : [$toResolve, null]; diff --git a/Slim/MiddlewareDispatcher.php b/Slim/MiddlewareDispatcher.php index af8d8619b..870531aaf 100644 --- a/Slim/MiddlewareDispatcher.php +++ b/Slim/MiddlewareDispatcher.php @@ -183,8 +183,10 @@ public function handle(ServerRequestInterface $request): ResponseInterface $instance = null; $method = null; - if(!CallableResolver::$callablePattern) { - throw new RuntimeException("CallableResolver::\$callablePattern was modified to an invalid value"); + if (!CallableResolver::$callablePattern) { + throw new RuntimeException( + "CallableResolver::\$callablePattern was modified to an invalid value" + ); } // Check for Slim callable as `class:method` if (preg_match(CallableResolver::$callablePattern, $resolved, $matches)) { From ed5a022ff5c3bba2d304c6390613eb92492533c6 Mon Sep 17 00:00:00 2001 From: Mark Li Date: Sat, 11 May 2024 00:43:09 +0000 Subject: [PATCH 5/7] revert possibly unnecessary change --- Slim/CallableResolver.php | 6 +----- Slim/MiddlewareDispatcher.php | 6 +----- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/Slim/CallableResolver.php b/Slim/CallableResolver.php index 8ed8a247b..93a36c0f4 100644 --- a/Slim/CallableResolver.php +++ b/Slim/CallableResolver.php @@ -120,11 +120,7 @@ private function isMiddleware($toResolve): bool */ private function resolveSlimNotation(string $toResolve): array { - if (!CallableResolver::$callablePattern) { - throw new RuntimeException( - "CallableResolver::\$callablePattern was modified to an invalid value" - ); - } + /** @psalm-suppress ArgumentTypeCoercion */ preg_match(CallableResolver::$callablePattern, $toResolve, $matches); [$class, $method] = $matches ? [$matches[1], $matches[2]] : [$toResolve, null]; diff --git a/Slim/MiddlewareDispatcher.php b/Slim/MiddlewareDispatcher.php index 870531aaf..f28b5ae09 100644 --- a/Slim/MiddlewareDispatcher.php +++ b/Slim/MiddlewareDispatcher.php @@ -183,11 +183,7 @@ public function handle(ServerRequestInterface $request): ResponseInterface $instance = null; $method = null; - if (!CallableResolver::$callablePattern) { - throw new RuntimeException( - "CallableResolver::\$callablePattern was modified to an invalid value" - ); - } + /** @psalm-suppress ArgumentTypeCoercion */ // Check for Slim callable as `class:method` if (preg_match(CallableResolver::$callablePattern, $resolved, $matches)) { $resolved = $matches[1]; From 542c05f686b277a8696a71460649f9c74431493a Mon Sep 17 00:00:00 2001 From: Mark Li Date: Sat, 11 May 2024 04:57:48 +0000 Subject: [PATCH 6/7] more refined templates for any internal that has ContainerInterface --- Slim/CallableResolver.php | 7 +++++++ Slim/Factory/AppFactory.php | 2 +- Slim/Interfaces/RouteGroupInterface.php | 1 + Slim/MiddlewareDispatcher.php | 9 +++++++++ Slim/Routing/Route.php | 7 ++++++- Slim/Routing/RouteCollector.php | 7 ++++++- Slim/Routing/RouteGroup.php | 1 + Slim/Routing/RouteRunner.php | 2 +- 8 files changed, 32 insertions(+), 4 deletions(-) diff --git a/Slim/CallableResolver.php b/Slim/CallableResolver.php index 93a36c0f4..e4a8841d9 100644 --- a/Slim/CallableResolver.php +++ b/Slim/CallableResolver.php @@ -26,12 +26,19 @@ use function preg_match; use function sprintf; +/** + * @template TContainerInterface of (ContainerInterface|null) + */ final class CallableResolver implements AdvancedCallableResolverInterface { public static string $callablePattern = '!^([^\:]+)\:([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)$!'; + /** @var TContainerInterface $container */ private ?ContainerInterface $container; + /** + * @param TContainerInterface $container + */ public function __construct(?ContainerInterface $container = null) { $this->container = $container; diff --git a/Slim/Factory/AppFactory.php b/Slim/Factory/AppFactory.php index 307c63586..456d9d70e 100644 --- a/Slim/Factory/AppFactory.php +++ b/Slim/Factory/AppFactory.php @@ -47,7 +47,7 @@ class AppFactory /** * @template TContainerInterface of (ContainerInterface|null) * @param TContainerInterface $container - * @return (App|App) + * @return (TContainerInterface is ContainerInterface ? App : App) */ public static function create( ?ResponseFactoryInterface $responseFactory = null, diff --git a/Slim/Interfaces/RouteGroupInterface.php b/Slim/Interfaces/RouteGroupInterface.php index 0411ce944..c5e33ad7e 100644 --- a/Slim/Interfaces/RouteGroupInterface.php +++ b/Slim/Interfaces/RouteGroupInterface.php @@ -31,6 +31,7 @@ public function addMiddleware(MiddlewareInterface $middleware): RouteGroupInterf /** * Append the group's middleware to the MiddlewareDispatcher + * @param MiddlewareDispatcher<\Psr\Container\ContainerInterface|null> $dispatcher */ public function appendMiddlewareToDispatcher(MiddlewareDispatcher $dispatcher): RouteGroupInterface; diff --git a/Slim/MiddlewareDispatcher.php b/Slim/MiddlewareDispatcher.php index f28b5ae09..cc0a17b7c 100644 --- a/Slim/MiddlewareDispatcher.php +++ b/Slim/MiddlewareDispatcher.php @@ -28,6 +28,9 @@ use function preg_match; use function sprintf; +/** + * @template TContainerInterface of (ContainerInterface|null) + */ class MiddlewareDispatcher implements MiddlewareDispatcherInterface { /** @@ -37,8 +40,12 @@ class MiddlewareDispatcher implements MiddlewareDispatcherInterface protected ?CallableResolverInterface $callableResolver; + /** @var TContainerInterface $container */ protected ?ContainerInterface $container; + /** + * @param TContainerInterface $container + */ public function __construct( RequestHandlerInterface $kernel, ?CallableResolverInterface $callableResolver = null, @@ -131,6 +138,7 @@ public function handle(ServerRequestInterface $request): ResponseInterface * Middleware are organized as a stack. That means middleware * that have been added before will be executed after the newly * added one (last in, first out). + * @return MiddlewareDispatcher */ public function addDeferred(string $middleware): self { @@ -238,6 +246,7 @@ public function handle(ServerRequestInterface $request): ResponseInterface * Middleware are organized as a stack. That means middleware * that have been added before will be executed after the newly * added one (last in, first out). + * @return MiddlewareDispatcher */ public function addCallable(callable $middleware): self { diff --git a/Slim/Routing/Route.php b/Slim/Routing/Route.php index 2cd9fa567..3d36666f5 100644 --- a/Slim/Routing/Route.php +++ b/Slim/Routing/Route.php @@ -33,6 +33,9 @@ use function in_array; use function is_array; +/** + * @template TContainerInterface of (ContainerInterface|null) + */ class Route implements RouteInterface, RequestHandlerInterface { /** @@ -77,9 +80,11 @@ class Route implements RouteInterface, RequestHandlerInterface /** * Container + * @var TContainerInterface $container */ protected ?ContainerInterface $container = null; + /** @var MiddlewareDispatcher $middlewareDispatcher */ protected MiddlewareDispatcher $middlewareDispatcher; /** @@ -106,7 +111,7 @@ class Route implements RouteInterface, RequestHandlerInterface * @param callable|string $callable The route callable * @param ResponseFactoryInterface $responseFactory * @param CallableResolverInterface $callableResolver - * @param ContainerInterface|null $container + * @param TContainerInterface $container * @param InvocationStrategyInterface|null $invocationStrategy * @param RouteGroupInterface[] $groups The parent route groups * @param int $identifier The route identifier diff --git a/Slim/Routing/RouteCollector.php b/Slim/Routing/RouteCollector.php index 182196656..6f9f0f66b 100644 --- a/Slim/Routing/RouteCollector.php +++ b/Slim/Routing/RouteCollector.php @@ -32,6 +32,7 @@ /** * RouteCollector is used to collect routes and route groups * as well as generate paths and URLs relative to its environment + * @template TContainerInterface of (ContainerInterface|null) */ class RouteCollector implements RouteCollectorInterface { @@ -81,6 +82,9 @@ class RouteCollector implements RouteCollectorInterface protected ResponseFactoryInterface $responseFactory; + /** + * @param TContainerInterface $container + */ public function __construct( ResponseFactoryInterface $responseFactory, CallableResolverInterface $callableResolver, @@ -245,10 +249,11 @@ protected function createGroup(string $pattern, $callable): RouteGroupInterface } /** - * @return RouteCollectorProxyInterface + * @return RouteCollectorProxyInterface */ protected function createProxy(string $pattern): RouteCollectorProxyInterface { + /** @var RouteCollectorProxyInterface */ return new RouteCollectorProxy( $this->responseFactory, $this->callableResolver, diff --git a/Slim/Routing/RouteGroup.php b/Slim/Routing/RouteGroup.php index eb03dd563..60d3df3d8 100644 --- a/Slim/Routing/RouteGroup.php +++ b/Slim/Routing/RouteGroup.php @@ -88,6 +88,7 @@ public function addMiddleware(MiddlewareInterface $middleware): RouteGroupInterf /** * {@inheritdoc} + * @param MiddlewareDispatcher<\Psr\Container\ContainerInterface|null> $dispatcher */ public function appendMiddlewareToDispatcher(MiddlewareDispatcher $dispatcher): RouteGroupInterface { diff --git a/Slim/Routing/RouteRunner.php b/Slim/Routing/RouteRunner.php index 8856f5195..3fb541352 100644 --- a/Slim/Routing/RouteRunner.php +++ b/Slim/Routing/RouteRunner.php @@ -69,7 +69,7 @@ public function handle(ServerRequestInterface $request): ResponseInterface ); } - /** @var Route $route */ + /** @var Route<\Psr\Container\ContainerInterface|null> $route */ $route = $request->getAttribute(RouteContext::ROUTE); return $route->run($request); } From 3ab597e25e7496d8e8f56fbd399527f73d7a2cc1 Mon Sep 17 00:00:00 2001 From: Mark Li Date: Tue, 14 May 2024 04:02:33 +0000 Subject: [PATCH 7/7] disable cache on psalm and enable unused code auditing --- Slim/App.php | 1 + Slim/CallableResolver.php | 2 -- Slim/Error/Renderers/HtmlErrorRenderer.php | 1 - Slim/Error/Renderers/JsonErrorRenderer.php | 1 - Slim/Error/Renderers/PlainTextErrorRenderer.php | 2 +- Slim/Exception/HttpBadRequestException.php | 1 + Slim/Exception/HttpException.php | 1 + Slim/Exception/HttpForbiddenException.php | 1 + Slim/Exception/HttpGoneException.php | 1 + Slim/Exception/HttpInternalServerErrorException.php | 1 + Slim/Exception/HttpNotImplementedException.php | 1 + Slim/Exception/HttpTooManyRequestsException.php | 1 + Slim/Exception/HttpUnauthorizedException.php | 1 + Slim/Factory/AppFactory.php | 1 + Slim/Factory/ServerRequestCreatorFactory.php | 1 + Slim/Handlers/ErrorHandler.php | 1 + Slim/Handlers/Strategies/RequestResponseArgs.php | 1 + Slim/Handlers/Strategies/RequestResponseNamedArgs.php | 1 + Slim/Interfaces/MiddlewareDispatcherInterface.php | 1 + Slim/Interfaces/Psr17FactoryProviderInterface.php | 1 + Slim/Interfaces/RouteCollectorInterface.php | 1 + Slim/Interfaces/RouteCollectorProxyInterface.php | 1 + Slim/Interfaces/RouteGroupInterface.php | 1 + Slim/Interfaces/RouteInterface.php | 1 + Slim/Interfaces/RouteParserInterface.php | 1 + Slim/Middleware/BodyParsingMiddleware.php | 1 + Slim/Middleware/ContentLengthMiddleware.php | 1 + Slim/Middleware/ErrorMiddleware.php | 1 + Slim/Middleware/MethodOverrideMiddleware.php | 1 + Slim/Middleware/OutputBufferingMiddleware.php | 1 + Slim/MiddlewareDispatcher.php | 1 + Slim/Routing/Route.php | 2 +- Slim/Routing/RouteContext.php | 1 + Slim/Routing/RoutingResults.php | 1 + composer.json | 2 +- psalm.xml | 2 +- 36 files changed, 33 insertions(+), 8 deletions(-) diff --git a/Slim/App.php b/Slim/App.php index b298fab7b..68b900023 100644 --- a/Slim/App.php +++ b/Slim/App.php @@ -32,6 +32,7 @@ use function strtoupper; /** + * @api * @template TContainerInterface of (ContainerInterface|null) * @template-extends RouteCollectorProxy */ diff --git a/Slim/CallableResolver.php b/Slim/CallableResolver.php index e4a8841d9..dab46c460 100644 --- a/Slim/CallableResolver.php +++ b/Slim/CallableResolver.php @@ -131,8 +131,6 @@ private function resolveSlimNotation(string $toResolve): array preg_match(CallableResolver::$callablePattern, $toResolve, $matches); [$class, $method] = $matches ? [$matches[1], $matches[2]] : [$toResolve, null]; - /** @var string $class */ - /** @var string|null $method */ if ($this->container && $this->container->has($class)) { $instance = $this->container->get($class); if (!is_object($instance)) { diff --git a/Slim/Error/Renderers/HtmlErrorRenderer.php b/Slim/Error/Renderers/HtmlErrorRenderer.php index e030522aa..8fd838bcb 100644 --- a/Slim/Error/Renderers/HtmlErrorRenderer.php +++ b/Slim/Error/Renderers/HtmlErrorRenderer.php @@ -39,7 +39,6 @@ private function renderExceptionFragment(Throwable $exception): string { $html = sprintf('
Type: %s
', get_class($exception)); - /** @var int|string $code */ $code = $exception->getCode(); $html .= sprintf('
Code: %s
', $code); diff --git a/Slim/Error/Renderers/JsonErrorRenderer.php b/Slim/Error/Renderers/JsonErrorRenderer.php index 63d905b3c..06085d2e5 100644 --- a/Slim/Error/Renderers/JsonErrorRenderer.php +++ b/Slim/Error/Renderers/JsonErrorRenderer.php @@ -43,7 +43,6 @@ public function __invoke(Throwable $exception, bool $displayErrorDetails): strin */ private function formatExceptionFragment(Throwable $exception): array { - /** @var int|string $code */ $code = $exception->getCode(); return [ 'type' => get_class($exception), diff --git a/Slim/Error/Renderers/PlainTextErrorRenderer.php b/Slim/Error/Renderers/PlainTextErrorRenderer.php index 9788568d5..fcb6e8a15 100644 --- a/Slim/Error/Renderers/PlainTextErrorRenderer.php +++ b/Slim/Error/Renderers/PlainTextErrorRenderer.php @@ -43,7 +43,7 @@ private function formatExceptionFragment(Throwable $exception): string $text = sprintf("Type: %s\n", get_class($exception)); $code = $exception->getCode(); - /** @var int|string $code */ + $text .= sprintf("Code: %s\n", $code); $text .= sprintf("Message: %s\n", $exception->getMessage()); diff --git a/Slim/Exception/HttpBadRequestException.php b/Slim/Exception/HttpBadRequestException.php index 9be551cf9..000c2480a 100644 --- a/Slim/Exception/HttpBadRequestException.php +++ b/Slim/Exception/HttpBadRequestException.php @@ -10,6 +10,7 @@ namespace Slim\Exception; +/** @api */ class HttpBadRequestException extends HttpSpecializedException { /** diff --git a/Slim/Exception/HttpException.php b/Slim/Exception/HttpException.php index d9dbd6cbe..c714dbbe5 100644 --- a/Slim/Exception/HttpException.php +++ b/Slim/Exception/HttpException.php @@ -15,6 +15,7 @@ use Throwable; /** + * @api * @method int getCode() */ class HttpException extends RuntimeException diff --git a/Slim/Exception/HttpForbiddenException.php b/Slim/Exception/HttpForbiddenException.php index dd3bb230a..d262a63f6 100644 --- a/Slim/Exception/HttpForbiddenException.php +++ b/Slim/Exception/HttpForbiddenException.php @@ -10,6 +10,7 @@ namespace Slim\Exception; +/** @api */ class HttpForbiddenException extends HttpSpecializedException { /** diff --git a/Slim/Exception/HttpGoneException.php b/Slim/Exception/HttpGoneException.php index 42899e1e6..b1005d83e 100644 --- a/Slim/Exception/HttpGoneException.php +++ b/Slim/Exception/HttpGoneException.php @@ -10,6 +10,7 @@ namespace Slim\Exception; +/** @api */ class HttpGoneException extends HttpSpecializedException { /** diff --git a/Slim/Exception/HttpInternalServerErrorException.php b/Slim/Exception/HttpInternalServerErrorException.php index b43226190..f9cb60f7b 100644 --- a/Slim/Exception/HttpInternalServerErrorException.php +++ b/Slim/Exception/HttpInternalServerErrorException.php @@ -10,6 +10,7 @@ namespace Slim\Exception; +/** @api */ class HttpInternalServerErrorException extends HttpSpecializedException { /** diff --git a/Slim/Exception/HttpNotImplementedException.php b/Slim/Exception/HttpNotImplementedException.php index 607a6f49a..af4fe253d 100644 --- a/Slim/Exception/HttpNotImplementedException.php +++ b/Slim/Exception/HttpNotImplementedException.php @@ -10,6 +10,7 @@ namespace Slim\Exception; +/** @api */ class HttpNotImplementedException extends HttpSpecializedException { /** diff --git a/Slim/Exception/HttpTooManyRequestsException.php b/Slim/Exception/HttpTooManyRequestsException.php index be4b29bb3..af438bad4 100644 --- a/Slim/Exception/HttpTooManyRequestsException.php +++ b/Slim/Exception/HttpTooManyRequestsException.php @@ -10,6 +10,7 @@ namespace Slim\Exception; +/** @api */ class HttpTooManyRequestsException extends HttpSpecializedException { /** diff --git a/Slim/Exception/HttpUnauthorizedException.php b/Slim/Exception/HttpUnauthorizedException.php index 07bd70d01..afb0e5407 100644 --- a/Slim/Exception/HttpUnauthorizedException.php +++ b/Slim/Exception/HttpUnauthorizedException.php @@ -10,6 +10,7 @@ namespace Slim\Exception; +/** @api */ class HttpUnauthorizedException extends HttpSpecializedException { /** diff --git a/Slim/Factory/AppFactory.php b/Slim/Factory/AppFactory.php index 456d9d70e..be91e88e9 100644 --- a/Slim/Factory/AppFactory.php +++ b/Slim/Factory/AppFactory.php @@ -24,6 +24,7 @@ use Slim\Interfaces\RouteCollectorInterface; use Slim\Interfaces\RouteResolverInterface; +/** @api */ class AppFactory { protected static ?Psr17FactoryProviderInterface $psr17FactoryProvider = null; diff --git a/Slim/Factory/ServerRequestCreatorFactory.php b/Slim/Factory/ServerRequestCreatorFactory.php index 94f639d2a..2bd95d77c 100644 --- a/Slim/Factory/ServerRequestCreatorFactory.php +++ b/Slim/Factory/ServerRequestCreatorFactory.php @@ -17,6 +17,7 @@ use Slim\Interfaces\Psr17FactoryProviderInterface; use Slim\Interfaces\ServerRequestCreatorInterface; +/** @api */ class ServerRequestCreatorFactory { protected static ?Psr17FactoryProviderInterface $psr17FactoryProvider = null; diff --git a/Slim/Handlers/ErrorHandler.php b/Slim/Handlers/ErrorHandler.php index f9606e364..e11eb0c53 100644 --- a/Slim/Handlers/ErrorHandler.php +++ b/Slim/Handlers/ErrorHandler.php @@ -43,6 +43,7 @@ * * It outputs the error message and diagnostic information in one of the following formats: * JSON, XML, Plain Text or HTML based on the Accept header. + * @api */ class ErrorHandler implements ErrorHandlerInterface { diff --git a/Slim/Handlers/Strategies/RequestResponseArgs.php b/Slim/Handlers/Strategies/RequestResponseArgs.php index c4ab16df5..6eab63a25 100644 --- a/Slim/Handlers/Strategies/RequestResponseArgs.php +++ b/Slim/Handlers/Strategies/RequestResponseArgs.php @@ -18,6 +18,7 @@ /** * Route callback strategy with route parameters as individual arguments. + * @api */ class RequestResponseArgs implements InvocationStrategyInterface { diff --git a/Slim/Handlers/Strategies/RequestResponseNamedArgs.php b/Slim/Handlers/Strategies/RequestResponseNamedArgs.php index 651111dde..f36059646 100644 --- a/Slim/Handlers/Strategies/RequestResponseNamedArgs.php +++ b/Slim/Handlers/Strategies/RequestResponseNamedArgs.php @@ -17,6 +17,7 @@ /** * Route callback strategy with route parameters as individual arguments. + * @api */ class RequestResponseNamedArgs implements InvocationStrategyInterface { diff --git a/Slim/Interfaces/MiddlewareDispatcherInterface.php b/Slim/Interfaces/MiddlewareDispatcherInterface.php index aa7a26ad2..9fa34a6ad 100644 --- a/Slim/Interfaces/MiddlewareDispatcherInterface.php +++ b/Slim/Interfaces/MiddlewareDispatcherInterface.php @@ -13,6 +13,7 @@ use Psr\Http\Server\MiddlewareInterface; use Psr\Http\Server\RequestHandlerInterface; +/** @api */ interface MiddlewareDispatcherInterface extends RequestHandlerInterface { /** diff --git a/Slim/Interfaces/Psr17FactoryProviderInterface.php b/Slim/Interfaces/Psr17FactoryProviderInterface.php index c7b87aa78..24590fe0f 100644 --- a/Slim/Interfaces/Psr17FactoryProviderInterface.php +++ b/Slim/Interfaces/Psr17FactoryProviderInterface.php @@ -10,6 +10,7 @@ namespace Slim\Interfaces; +/** @api */ interface Psr17FactoryProviderInterface { /** diff --git a/Slim/Interfaces/RouteCollectorInterface.php b/Slim/Interfaces/RouteCollectorInterface.php index 921a2365f..aa83883f6 100644 --- a/Slim/Interfaces/RouteCollectorInterface.php +++ b/Slim/Interfaces/RouteCollectorInterface.php @@ -13,6 +13,7 @@ use InvalidArgumentException; use RuntimeException; +/** @api */ interface RouteCollectorInterface { /** diff --git a/Slim/Interfaces/RouteCollectorProxyInterface.php b/Slim/Interfaces/RouteCollectorProxyInterface.php index 8bbde0e47..0220af030 100644 --- a/Slim/Interfaces/RouteCollectorProxyInterface.php +++ b/Slim/Interfaces/RouteCollectorProxyInterface.php @@ -15,6 +15,7 @@ use Psr\Http\Message\UriInterface; /** + * @api * @template TContainerInterface of (ContainerInterface|null) */ interface RouteCollectorProxyInterface diff --git a/Slim/Interfaces/RouteGroupInterface.php b/Slim/Interfaces/RouteGroupInterface.php index c5e33ad7e..efc1c5a3b 100644 --- a/Slim/Interfaces/RouteGroupInterface.php +++ b/Slim/Interfaces/RouteGroupInterface.php @@ -13,6 +13,7 @@ use Psr\Http\Server\MiddlewareInterface; use Slim\MiddlewareDispatcher; +/** @api */ interface RouteGroupInterface { public function collectRoutes(): RouteGroupInterface; diff --git a/Slim/Interfaces/RouteInterface.php b/Slim/Interfaces/RouteInterface.php index c15333123..8ed817ef4 100644 --- a/Slim/Interfaces/RouteInterface.php +++ b/Slim/Interfaces/RouteInterface.php @@ -14,6 +14,7 @@ use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Server\MiddlewareInterface; +/** @api */ interface RouteInterface { /** diff --git a/Slim/Interfaces/RouteParserInterface.php b/Slim/Interfaces/RouteParserInterface.php index 03d932665..8ccea3bc3 100644 --- a/Slim/Interfaces/RouteParserInterface.php +++ b/Slim/Interfaces/RouteParserInterface.php @@ -14,6 +14,7 @@ use Psr\Http\Message\UriInterface; use RuntimeException; +/** @api */ interface RouteParserInterface { /** diff --git a/Slim/Middleware/BodyParsingMiddleware.php b/Slim/Middleware/BodyParsingMiddleware.php index 9a90f30c4..94bba3713 100644 --- a/Slim/Middleware/BodyParsingMiddleware.php +++ b/Slim/Middleware/BodyParsingMiddleware.php @@ -33,6 +33,7 @@ use const LIBXML_VERSION; +/** @api */ class BodyParsingMiddleware implements MiddlewareInterface { /** diff --git a/Slim/Middleware/ContentLengthMiddleware.php b/Slim/Middleware/ContentLengthMiddleware.php index 8fa13bcf7..e289fa365 100644 --- a/Slim/Middleware/ContentLengthMiddleware.php +++ b/Slim/Middleware/ContentLengthMiddleware.php @@ -15,6 +15,7 @@ use Psr\Http\Server\MiddlewareInterface; use Psr\Http\Server\RequestHandlerInterface; +/** @api */ class ContentLengthMiddleware implements MiddlewareInterface { public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface diff --git a/Slim/Middleware/ErrorMiddleware.php b/Slim/Middleware/ErrorMiddleware.php index 2eb5cc96f..39b1e585d 100644 --- a/Slim/Middleware/ErrorMiddleware.php +++ b/Slim/Middleware/ErrorMiddleware.php @@ -25,6 +25,7 @@ use function get_class; use function is_subclass_of; +/** @api */ class ErrorMiddleware implements MiddlewareInterface { protected CallableResolverInterface $callableResolver; diff --git a/Slim/Middleware/MethodOverrideMiddleware.php b/Slim/Middleware/MethodOverrideMiddleware.php index 079a1f189..553463e2d 100644 --- a/Slim/Middleware/MethodOverrideMiddleware.php +++ b/Slim/Middleware/MethodOverrideMiddleware.php @@ -18,6 +18,7 @@ use function is_array; use function strtoupper; +/** @api */ class MethodOverrideMiddleware implements MiddlewareInterface { public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface diff --git a/Slim/Middleware/OutputBufferingMiddleware.php b/Slim/Middleware/OutputBufferingMiddleware.php index 69ee1f6f1..8bfbbf64e 100644 --- a/Slim/Middleware/OutputBufferingMiddleware.php +++ b/Slim/Middleware/OutputBufferingMiddleware.php @@ -23,6 +23,7 @@ use function ob_get_clean; use function ob_start; +/** @api */ class OutputBufferingMiddleware implements MiddlewareInterface { public const APPEND = 'append'; diff --git a/Slim/MiddlewareDispatcher.php b/Slim/MiddlewareDispatcher.php index cc0a17b7c..1d4c668ff 100644 --- a/Slim/MiddlewareDispatcher.php +++ b/Slim/MiddlewareDispatcher.php @@ -29,6 +29,7 @@ use function sprintf; /** + * @api * @template TContainerInterface of (ContainerInterface|null) */ class MiddlewareDispatcher implements MiddlewareDispatcherInterface diff --git a/Slim/Routing/Route.php b/Slim/Routing/Route.php index 3d36666f5..a2d9d04a2 100644 --- a/Slim/Routing/Route.php +++ b/Slim/Routing/Route.php @@ -34,6 +34,7 @@ use function is_array; /** + * @api * @template TContainerInterface of (ContainerInterface|null) */ class Route implements RouteInterface, RequestHandlerInterface @@ -328,7 +329,6 @@ protected function appendGroupMiddlewareToRoute(): void $inner = $this->middlewareDispatcher; $this->middlewareDispatcher = new MiddlewareDispatcher($inner, $this->callableResolver, $this->container); - /** @var RouteGroupInterface $group */ foreach (array_reverse($this->groups) as $group) { $group->appendMiddlewareToDispatcher($this->middlewareDispatcher); } diff --git a/Slim/Routing/RouteContext.php b/Slim/Routing/RouteContext.php index 3ba5e23a6..853b0df3e 100644 --- a/Slim/Routing/RouteContext.php +++ b/Slim/Routing/RouteContext.php @@ -15,6 +15,7 @@ use Slim\Interfaces\RouteInterface; use Slim\Interfaces\RouteParserInterface; +/** @api */ final class RouteContext { public const ROUTE = '__route__'; diff --git a/Slim/Routing/RoutingResults.php b/Slim/Routing/RoutingResults.php index ac2fa64f9..4fd8973f8 100644 --- a/Slim/Routing/RoutingResults.php +++ b/Slim/Routing/RoutingResults.php @@ -14,6 +14,7 @@ use function rawurldecode; +/** @api */ class RoutingResults { public const NOT_FOUND = 0; diff --git a/composer.json b/composer.json index 4fcfcc377..30fe81c9b 100644 --- a/composer.json +++ b/composer.json @@ -91,7 +91,7 @@ "phpunit": "phpunit", "phpcs": "phpcs", "phpstan": "phpstan --memory-limit=-1", - "psalm": "psalm" + "psalm": "psalm --no-cache" }, "suggest": { "ext-simplexml": "Needed to support XML format in BodyParsingMiddleware", diff --git a/psalm.xml b/psalm.xml index 66c9171d0..af258ff89 100644 --- a/psalm.xml +++ b/psalm.xml @@ -6,7 +6,7 @@ xmlns="https://getpsalm.org/schema/config" xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd" findUnusedBaselineEntry="true" - findUnusedCode="false" + findUnusedCode="true" >