GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Pull Request — develop (#2)
by Mathieu
03:14
created

ReflectionInstanciator   A

Complexity

Total Complexity 18

Size/Duplication

Total Lines 126
Duplicated Lines 0 %

Test Coverage

Coverage 98.21%

Importance

Changes 0
Metric Value
dl 0
loc 126
ccs 55
cts 56
cp 0.9821
rs 10
c 0
b 0
f 0
wmc 18

4 Methods

Rating   Name   Duplication   Size   Complexity  
A parameters() 0 16 3
B build() 0 31 3
D canInject() 0 35 9
A computeArguments() 0 16 3
1
<?php
2
declare(strict_types = 1);
3
4
namespace Innmind\Reflection\Instanciator;
5
6
use Innmind\Reflection\{
7
    InstanciatorInterface,
8
    Exception\InstanciationFailedException
9
};
10
use Innmind\Immutable\{
11
    MapInterface,
12
    SetInterface,
13
    Map,
14
    Set
15
};
16
17
class ReflectionInstanciator implements InstanciatorInterface
18
{
19
    /**
20
     * {@inheritdoc}
21
     */
22 4
    public function build(string $class, MapInterface $properties)
23
    {
24
        try {
25 4
            $refl = new \ReflectionClass($class);
26
27 4
            if (!$refl->hasMethod('__construct')) {
28 3
                return $refl->newInstance();
29
            }
30
31 3
            $constructor = $refl->getMethod('__construct');
32
33 3
            return $refl->newInstanceArgs(
34
                $this
35 3
                    ->computeArguments($constructor, $properties)
36 3
                    ->reduce(
37 3
                        [],
38 3
                        function(array $carry, string $property, $value): array {
39 2
                            $carry[$property] = $value;
40
41 2
                            return $carry;
42 3
                        }
43
                    )
44
            );
45 1
        } catch (\TypeError $e) {
46 1
            throw new InstanciationFailedException(
47 1
                sprintf(
48 1
                    'Class "%s" cannot be instanciated',
49 1
                    $class
50
                ),
51 1
                $e->getCode(),
52 1
                $e
53
            );
54
        }
55
    }
56
57
    /**
58
     * {@inheritdoc}
59
     */
60 3
    public function parameters(string $class): SetInterface
61
    {
62 3
        $parameters = new Set('string');
63 3
        $refl = new \ReflectionClass($class);
64
65 3
        if (!$refl->hasMethod('__construct')) {
66 3
            return $parameters;
67
        }
68
69 2
        $refl = $refl->getMethod('__construct');
70
71 2
        foreach ($refl->getParameters() as $parameter) {
72 2
            $parameters = $parameters->add($parameter->name);
73
        }
74
75 2
        return $parameters;
76
    }
77
78
    /**
79
     * @param ReflectionMethod $constructor
0 ignored issues
show
Bug introduced by
The type Innmind\Reflection\Instanciator\ReflectionMethod was not found. Did you mean ReflectionMethod? If so, make sure to prefix the type with \.
Loading history...
80
     * @param MapInterface<string, variable> $properties
81
     *
82
     * @return MapInterface<string, variable>
83
     */
84 3
    private function computeArguments(
85
        \ReflectionMethod $constructor,
86
        MapInterface $properties
87
    ): MapInterface {
88 3
        $arguments = $properties->clear();
89
90 3
        foreach ($constructor->getParameters() as $parameter) {
91 3
            if ($this->canInject($parameter, $properties)) {
92 2
                $arguments = $arguments->put(
93 2
                    $parameter->name,
94 3
                    $properties->get($parameter->name)
95
                );
96
            }
97
        }
98
99 3
        return $arguments;
100
    }
101
102
    /**
103
     * @param ReflectionParameter $parameter
0 ignored issues
show
Bug introduced by
The type Innmind\Reflection\Insta...tor\ReflectionParameter was not found. Did you mean ReflectionParameter? If so, make sure to prefix the type with \.
Loading history...
104
     * @param MapInterface<string, variable> $properties
105
     *
106
     * @return bool
107
     */
108 3
    private function canInject(
109
        \ReflectionParameter $parameter,
110
        MapInterface $properties
111
    ): bool {
112
        if (
113 3
            !$parameter->allowsNull() &&
114 3
            !$properties->contains($parameter->name)
115
        ) {
116 1
            return false;
117
        } else if (
118 3
            $parameter->allowsNull() &&
119 3
            !$properties->contains($parameter->name)
120
        ) {
121 2
            return false;
122
        }
123
124 2
        $property = $properties->get($parameter->name);
125
126 2
        if ($parameter->hasType()) {
127 1
            $type = $parameter->getType();
128
129 1
            if ($type->isBuiltin()) {
130 1
                return (string) $type === gettype($property);
131 1
            } else if (!is_object($property)) {
132
                return false;
133
            }
134
135 1
            $refl = new \ReflectionObject($property);
136 1
            $wishedClass = (string) $type;
137
138 1
            return get_class($property) === $wishedClass ||
139 1
                $refl->isSubClassOf($wishedClass);
140
        }
141
142 2
        return true;
143
    }
144
}
145