Code Coverage
 
Lines
Branches
Paths
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
30 / 30
95.24% covered (success)
95.24%
20 / 21
58.82% covered (warning)
58.82%
10 / 17
50.00% covered (danger)
50.00%
1 / 2
CRAP
0.00% covered (danger)
0.00%
0 / 1
ParameterResolver
100.00% covered (success)
100.00%
30 / 30
95.24% covered (success)
95.24%
20 / 21
58.82% covered (warning)
58.82%
10 / 17
100.00% covered (success)
100.00%
2 / 2
16.98
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 resolve
100.00% covered (success)
100.00%
29 / 29
95.00% covered (success)
95.00%
19 / 20
56.25% covered (warning)
56.25%
9 / 16
100.00% covered (success)
100.00%
1 / 1
15.78
1<?php
2
3declare(strict_types=1);
4
5namespace Celema\Wire;
6
7use Celema\Wire\Exception\WireException;
8use ReflectionClass;
9use ReflectionNamedType;
10use ReflectionParameter;
11
12final class ParameterResolver
13{
14    public function __construct(
15        private readonly CreatorInterface $creator,
16    ) {}
17
18    public function resolve(
19        ReflectionParameter $param,
20        array $predefinedTypes,
21        ?callable $injectCallback,
22    ): mixed {
23        $type = $param->getType();
24
25        if ($type instanceof ReflectionNamedType) {
26            $container = $this->creator->container();
27            $typeName = $type->getName();
28
29            if (isset($predefinedTypes[$typeName])) {
30                return $predefinedTypes[$typeName];
31            }
32
33            if ($container?->has($typeName)) {
34                return $container->get($typeName);
35            }
36
37            if (class_exists($typeName)) {
38                if ($param->isDefaultValueAvailable() && !new ReflectionClass($typeName)->isInstantiable()) {
39                    return $param->getDefaultValue();
40                }
41
42                return $this->creator->create(
43                    $typeName,
44                    predefinedTypes: $predefinedTypes,
45                    injectCallback: $injectCallback,
46                );
47            }
48
49            if ($param->isDefaultValueAvailable()) {
50                return $param->getDefaultValue();
51            }
52
53            throw new WireException(
54                "Unresolvable parameter. Source: \n" . ParameterInfo::info($param),
55            );
56        }
57
58        if ($type) {
59            throw new WireException(
60                "Cannot resolve union or intersection types. Source: \n" . ParameterInfo::info($param),
61            );
62        }
63
64        throw new WireException(
65            "To be resolvable, classes must have fully typed constructor parameters. Source: \n"
66                . ParameterInfo::info($param),
67        );
68    }
69}