Skip to content

Commit

Permalink
Merge pull request #3322 from limarkxx/add-psalm
Browse files Browse the repository at this point in the history
Add template generics for PSR-11 implementations in PHPStan and Psalm
  • Loading branch information
akrabat authored Jun 13, 2024
2 parents 8388b33 + c7910ea commit b8de7c1
Show file tree
Hide file tree
Showing 40 changed files with 135 additions and 11 deletions.
10 changes: 10 additions & 0 deletions Slim/App.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@

use function strtoupper;

/**
* @api
* @template TContainerInterface of (ContainerInterface|null)
* @template-extends RouteCollectorProxy<TContainerInterface>
*/
class App extends RouteCollectorProxy implements RequestHandlerInterface
{
/**
Expand All @@ -44,6 +49,9 @@ class App extends RouteCollectorProxy implements RequestHandlerInterface

protected MiddlewareDispatcherInterface $middlewareDispatcher;

/**
* @param TContainerInterface $container
*/
public function __construct(
ResponseFactoryInterface $responseFactory,
?ContainerInterface $container = null,
Expand Down Expand Up @@ -89,6 +97,7 @@ public function getMiddlewareDispatcher(): MiddlewareDispatcherInterface

/**
* @param MiddlewareInterface|string|callable $middleware
* @return App<TContainerInterface>
*/
public function add($middleware): self
{
Expand All @@ -98,6 +107,7 @@ public function add($middleware): self

/**
* @param MiddlewareInterface $middleware
* @return App<TContainerInterface>
*/
public function addMiddleware(MiddlewareInterface $middleware): self
{
Expand Down
10 changes: 8 additions & 2 deletions Slim/CallableResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -120,11 +127,10 @@ private function isMiddleware($toResolve): bool
*/
private function resolveSlimNotation(string $toResolve): array
{
/** @psalm-suppress ArgumentTypeCoercion */
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)) {
Expand Down
1 change: 0 additions & 1 deletion Slim/Error/Renderers/HtmlErrorRenderer.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ private function renderExceptionFragment(Throwable $exception): string
{
$html = sprintf('<div><strong>Type:</strong> %s</div>', get_class($exception));

/** @var int|string $code */
$code = $exception->getCode();
$html .= sprintf('<div><strong>Code:</strong> %s</div>', $code);

Expand Down
1 change: 0 additions & 1 deletion Slim/Error/Renderers/JsonErrorRenderer.php
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down
2 changes: 1 addition & 1 deletion Slim/Error/Renderers/PlainTextErrorRenderer.php
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand Down
1 change: 1 addition & 0 deletions Slim/Exception/HttpBadRequestException.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

namespace Slim\Exception;

/** @api */
class HttpBadRequestException extends HttpSpecializedException
{
/**
Expand Down
1 change: 1 addition & 0 deletions Slim/Exception/HttpException.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
use Throwable;

/**
* @api
* @method int getCode()
*/
class HttpException extends RuntimeException
Expand Down
1 change: 1 addition & 0 deletions Slim/Exception/HttpForbiddenException.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

namespace Slim\Exception;

/** @api */
class HttpForbiddenException extends HttpSpecializedException
{
/**
Expand Down
1 change: 1 addition & 0 deletions Slim/Exception/HttpGoneException.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

namespace Slim\Exception;

/** @api */
class HttpGoneException extends HttpSpecializedException
{
/**
Expand Down
1 change: 1 addition & 0 deletions Slim/Exception/HttpInternalServerErrorException.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

namespace Slim\Exception;

/** @api */
class HttpInternalServerErrorException extends HttpSpecializedException
{
/**
Expand Down
1 change: 1 addition & 0 deletions Slim/Exception/HttpNotImplementedException.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

namespace Slim\Exception;

/** @api */
class HttpNotImplementedException extends HttpSpecializedException
{
/**
Expand Down
1 change: 1 addition & 0 deletions Slim/Exception/HttpTooManyRequestsException.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

namespace Slim\Exception;

/** @api */
class HttpTooManyRequestsException extends HttpSpecializedException
{
/**
Expand Down
1 change: 1 addition & 0 deletions Slim/Exception/HttpUnauthorizedException.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

namespace Slim\Exception;

/** @api */
class HttpUnauthorizedException extends HttpSpecializedException
{
/**
Expand Down
11 changes: 11 additions & 0 deletions Slim/Factory/AppFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
use Slim\Interfaces\RouteCollectorInterface;
use Slim\Interfaces\RouteResolverInterface;

/** @api */
class AppFactory
{
protected static ?Psr17FactoryProviderInterface $psr17FactoryProvider = null;
Expand All @@ -44,6 +45,11 @@ class AppFactory

protected static bool $slimHttpDecoratorsAutomaticDetectionEnabled = true;

/**
* @template TContainerInterface of (ContainerInterface|null)
* @param TContainerInterface $container
* @return (TContainerInterface is ContainerInterface ? App<TContainerInterface> : App<ContainerInterface|null>)
*/
public static function create(
?ResponseFactoryInterface $responseFactory = null,
?ContainerInterface $container = null,
Expand All @@ -63,6 +69,11 @@ public static function create(
);
}

/**
* @template TContainerInterface of (ContainerInterface)
* @param TContainerInterface $container
* @return App<TContainerInterface>
*/
public static function createFromContainer(ContainerInterface $container): App
{
$responseFactory = $container->has(ResponseFactoryInterface::class)
Expand Down
1 change: 1 addition & 0 deletions Slim/Factory/ServerRequestCreatorFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
use Slim\Interfaces\Psr17FactoryProviderInterface;
use Slim\Interfaces\ServerRequestCreatorInterface;

/** @api */
class ServerRequestCreatorFactory
{
protected static ?Psr17FactoryProviderInterface $psr17FactoryProvider = null;
Expand Down
1 change: 1 addition & 0 deletions Slim/Handlers/ErrorHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand Down
1 change: 1 addition & 0 deletions Slim/Handlers/Strategies/RequestResponseArgs.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

/**
* Route callback strategy with route parameters as individual arguments.
* @api
*/
class RequestResponseArgs implements InvocationStrategyInterface
{
Expand Down
1 change: 1 addition & 0 deletions Slim/Handlers/Strategies/RequestResponseNamedArgs.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

/**
* Route callback strategy with route parameters as individual arguments.
* @api
*/
class RequestResponseNamedArgs implements InvocationStrategyInterface
{
Expand Down
1 change: 1 addition & 0 deletions Slim/Interfaces/MiddlewareDispatcherInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;

/** @api */
interface MiddlewareDispatcherInterface extends RequestHandlerInterface
{
/**
Expand Down
1 change: 1 addition & 0 deletions Slim/Interfaces/Psr17FactoryProviderInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

namespace Slim\Interfaces;

/** @api */
interface Psr17FactoryProviderInterface
{
/**
Expand Down
1 change: 1 addition & 0 deletions Slim/Interfaces/RouteCollectorInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use InvalidArgumentException;
use RuntimeException;

/** @api */
interface RouteCollectorInterface
{
/**
Expand Down
8 changes: 8 additions & 0 deletions Slim/Interfaces/RouteCollectorProxyInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,19 @@
use Psr\Http\Message\ResponseFactoryInterface;
use Psr\Http\Message\UriInterface;

/**
* @api
* @template TContainerInterface of (ContainerInterface|null)
*/
interface RouteCollectorProxyInterface
{
public function getResponseFactory(): ResponseFactoryInterface;

public function getCallableResolver(): CallableResolverInterface;

/**
* @return TContainerInterface
*/
public function getContainer(): ?ContainerInterface;

public function getRouteCollector(): RouteCollectorInterface;
Expand All @@ -31,6 +38,7 @@ public function getBasePath(): string;

/**
* Set the RouteCollectorProxy's base path
* @return RouteCollectorProxyInterface<TContainerInterface>
*/
public function setBasePath(string $basePath): RouteCollectorProxyInterface;

Expand Down
2 changes: 2 additions & 0 deletions Slim/Interfaces/RouteGroupInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use Psr\Http\Server\MiddlewareInterface;
use Slim\MiddlewareDispatcher;

/** @api */
interface RouteGroupInterface
{
public function collectRoutes(): RouteGroupInterface;
Expand All @@ -31,6 +32,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;

Expand Down
1 change: 1 addition & 0 deletions Slim/Interfaces/RouteInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;

/** @api */
interface RouteInterface
{
/**
Expand Down
1 change: 1 addition & 0 deletions Slim/Interfaces/RouteParserInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use Psr\Http\Message\UriInterface;
use RuntimeException;

/** @api */
interface RouteParserInterface
{
/**
Expand Down
1 change: 1 addition & 0 deletions Slim/Middleware/BodyParsingMiddleware.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@

use const LIBXML_VERSION;

/** @api */
class BodyParsingMiddleware implements MiddlewareInterface
{
/**
Expand Down
1 change: 1 addition & 0 deletions Slim/Middleware/ContentLengthMiddleware.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions Slim/Middleware/ErrorMiddleware.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
use function get_class;
use function is_subclass_of;

/** @api */
class ErrorMiddleware implements MiddlewareInterface
{
protected CallableResolverInterface $callableResolver;
Expand Down
1 change: 1 addition & 0 deletions Slim/Middleware/MethodOverrideMiddleware.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
use function is_array;
use function strtoupper;

/** @api */
class MethodOverrideMiddleware implements MiddlewareInterface
{
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
Expand Down
1 change: 1 addition & 0 deletions Slim/Middleware/OutputBufferingMiddleware.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
use function ob_get_clean;
use function ob_start;

/** @api */
class OutputBufferingMiddleware implements MiddlewareInterface
{
public const APPEND = 'append';
Expand Down
11 changes: 11 additions & 0 deletions Slim/MiddlewareDispatcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@
use function preg_match;
use function sprintf;

/**
* @api
* @template TContainerInterface of (ContainerInterface|null)
*/
class MiddlewareDispatcher implements MiddlewareDispatcherInterface
{
/**
Expand All @@ -37,8 +41,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,
Expand Down Expand Up @@ -131,6 +139,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<TContainerInterface>
*/
public function addDeferred(string $middleware): self
{
Expand Down Expand Up @@ -183,6 +192,7 @@ public function handle(ServerRequestInterface $request): ResponseInterface
$instance = null;
$method = null;

/** @psalm-suppress ArgumentTypeCoercion */
// Check for Slim callable as `class:method`
if (preg_match(CallableResolver::$callablePattern, $resolved, $matches)) {
$resolved = $matches[1];
Expand Down Expand Up @@ -237,6 +247,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<TContainerInterface>
*/
public function addCallable(callable $middleware): self
{
Expand Down
Loading

0 comments on commit b8de7c1

Please sign in to comment.