Skip to content

Commit

Permalink
improved type safety and correctness with PHPStan
Browse files Browse the repository at this point in the history
  • Loading branch information
mindplay-dk committed Apr 6, 2024
1 parent d87278b commit 867c97a
Show file tree
Hide file tree
Showing 8 changed files with 40 additions and 35 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ jobs:
with:
fetch-depth: 2 # required by Scrutinizer
- run: composer install --no-progress --no-ansi --no-interaction --dev --prefer-dist
- run: php test/test.php
- run: composer test && composer inspect
- if: matrix.coverage == 'xdebug'
uses: sudo-bot/action-scrutinizer@latest
with:
Expand Down
6 changes: 4 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,12 @@
"mindplay/testies": "^1.1.2",
"php-di/php-di": "^7.0.5",
"pimple/pimple": "^3.5",
"phpunit/php-code-coverage": "^9 || ^10 || ^11"
"phpunit/php-code-coverage": "^9 || ^10 || ^11",
"phpstan/phpstan": "^1.10"
},
"scripts": {
"test": "XDEBUG_MODE=coverage php test/test.php"
"test": "XDEBUG_MODE=coverage php test/test.php",
"inspect": "phpstan"
},
"autoload": {
"psr-4": {
Expand Down
4 changes: 4 additions & 0 deletions phpstan.neon
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
parameters:
level: 6
paths:
- src
16 changes: 8 additions & 8 deletions src/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,33 +2,35 @@

namespace mindplay\unbox;

use Psr\Container\ContainerInterface;

/**
* This abstract base-class defines the internal state of `Container` and `ContainerFactory`
*/
abstract class Configuration
{
/**
* @var mixed[] map where component name => value
* @var array<string,mixed> map where component name => value
*/
protected $values = [];

/**
* @var callable[] map where component name => factory function
* @var array<string,callable> map where component name => factory function
*/
protected $factory = [];

/**
* @var array map where component name => mixed list/map of parameter names
* @var array<string,array<int|string,string>> map where component name => mixed list/map of parameter names
*/
protected $factory_map = [];

/**
* @var callable[][] map where component name => list of configuration functions
* @var array<string,callable[]> map where component name => list of configuration functions
*/
protected $config = [];

/**
* @var callable[][] map where component name => mixed list/map of parameter names
* @var array<string,array<int|string,array<int|string,string>>> map where component name => mixed list/map of parameter names
*/
protected $config_map = [];

Expand All @@ -51,10 +53,8 @@ public function has(string $name): bool

/**
* Internally copy configuration state, e.g. from `ContainerFactory` to `Container`
*
* @param Configuration $target
*/
protected function copyTo(Configuration $target)
protected function copyTo(Configuration $target): void
{
$target->values = $this->values;
$target->factory = $this->factory;
Expand Down
33 changes: 16 additions & 17 deletions src/Container.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,17 @@
class Container extends Configuration implements ContainerInterface, FactoryInterface
{
/**
* @var bool[] map where component name => TRUE, if the component has been initialized
* @var array<string,bool> map where component name => TRUE, if the component has been initialized
*/
protected $active = [];

/**
* @var int[] map where component name => activation depth
* @var array<string,int> map where component name => activation depth
*
* @see get()
*/
private $activations = [];

/**
* @param Configuration $config
*/
public function __construct(Configuration $config)
{
$config->copyTo($this);
Expand All @@ -42,9 +39,11 @@ public function __construct(Configuration $config)
/**
* Resolve the registered component with the given name.
*
* @template T of object
*
* @param string $name component name
*
* @return mixed component instance/value
*
* @return ($name is class-string<T> ? T : mixed) component instance/value
*
* @throws NotFoundException
*/
Expand Down Expand Up @@ -153,8 +152,8 @@ public function isActive(string $name): bool
*
* See also {@see create()} which lets you invoke any constructor.
*
* @param callable|object $callback any arbitrary closure or callable, or object implementing __invoke()
* @param mixed|mixed[] $map mixed list/map of parameter values (and/or boxed values)
* @param callable $callback any arbitrary closure or callable
* @param array<int|string,mixed> $map mixed list/map of parameter values (and/or boxed values)
*
* @return mixed return value from the given callable
*/
Expand All @@ -171,14 +170,14 @@ public function call(callable $callback, array $map = [])
* The container will internally resolve and inject any constructor arguments
* not explicitly provided in the (optional) second parameter.
*
* @param string $class_name fully-qualified class-name
* @param mixed|mixed[] $map mixed list/map of parameter values (and/or boxed values)
* @param string $class_name fully-qualified class-name
* @param array<int|string,mixed> $map mixed list/map of parameter values (and/or boxed values)
*
* @return mixed new instance of the specified class
*
* @throws InvalidArgumentException
*/
public function create(string $class_name, array $map = [])
public function create(string $class_name, array $map = []): mixed
{
if (! class_exists($class_name)) {
throw new InvalidArgumentException("unable to create component: {$class_name} (autoloading failed)");
Expand All @@ -204,15 +203,15 @@ public function create(string $class_name, array $map = [])
*
* This is the heart of the beast.
*
* @param ReflectionParameter[] $params parameter reflections
* @param array $map mixed list/map of parameter values (and/or boxed values)
* @param bool $safe if TRUE, it's considered safe to resolve against parameter names
* @param ReflectionParameter[] $params parameter reflections
* @param array<int|string,mixed> $map mixed list/map of parameter values (and/or boxed values)
* @param bool $safe if TRUE, it's considered safe to resolve against parameter names
*
* @return array parameters
* @return array<mixed> parameters
*
* @throws ContainerException
*/
protected function resolve($params, $map, $safe = true)
protected function resolve($params, $map, $safe = true): array
{
$args = [];

Expand Down
6 changes: 3 additions & 3 deletions src/ContainerFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ public function add(ProviderInterface $provider): void
*
* @see provides()
*/
public function requires(string $requirement, string $description = "")
public function requires(string $requirement, string $description = ""): void
{
$this->required[$requirement][] = $description;
}
Expand All @@ -291,7 +291,7 @@ public function requires(string $requirement, string $description = "")
*
* @see requires()
*/
public function provides(string $requirement, string $description = "")
public function provides(string $requirement, string $description = ""): void
{
if (array_key_exists($requirement, $this->provided)) {
$message = "The following Requirement has already been fulfilled: {$requirement}";
Expand Down Expand Up @@ -338,7 +338,7 @@ public function registerFallback(ContainerInterface $container): void
*
* @throws ContainerException if any Requirements have not been fulfilled
*/
public function createContainer()
public function createContainer(): Container
{
$messages = [];

Expand Down
4 changes: 2 additions & 2 deletions src/FactoryInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ interface FactoryInterface
* The factory will internally resolve and inject any constructor arguments
* not explicitly provided in the (optional) second parameter.
*
* @param string $class_name fully-qualified class-name
* @param mixed|mixed[] $map mixed list/map of parameter values (and/or boxed values)
* @param string $class_name fully-qualified class-name
* @param array<mixed> $map mixed list/map of parameter values (and/or boxed values)
*
* @return mixed new instance of the specified class
*/
Expand Down
4 changes: 2 additions & 2 deletions src/Reflection.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@
abstract class Reflection
{
/**
* Create a Reflection of the function referenced by any type of callable (or object implementing `__invoke()`)
* Create a Reflection of the function referenced by any type of callable
*
* @param callable|object $callback
* @param callable $callback
*
* @return ReflectionFunctionAbstract
*
Expand Down

0 comments on commit 867c97a

Please sign in to comment.