Completed
Push — refactor ( 558ab7...25d2de )
by Akihito
08:19
created

Injector::__construct()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 11
rs 9.9
c 0
b 0
f 0
cc 2
nc 2
nop 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Ray\Di;
6
7
use Doctrine\Common\Annotations\AnnotationException;
8
use Ray\Aop\Compiler;
9
use Ray\Di\Exception\Untargeted;
10
11
use function assert;
12
use function file_exists;
13
use function is_dir;
14
use function spl_autoload_register;
15
use function sprintf;
16
use function str_replace;
17
use function sys_get_temp_dir;
18
19
class Injector implements InjectorInterface
20
{
21
    /** @var string */
22
    private $classDir;
23
24
    /** @var Container */
25
    private $container;
26
27
    /**
28
     * @param AbstractModule $module Binding module
29
     * @param string         $tmpDir Temp directory for generated class
30
     */
31
    public function __construct(?AbstractModule $module = null, string $tmpDir = '')
32
    {
33
        $module = $module ?? new NullModule();
34
        $module->install(new AssistedModule());
0 ignored issues
show
Documentation introduced by
new \Ray\Di\AssistedModule() is of type object<Ray\Di\AssistedModule>, but the function expects a object<self>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
35
        $this->container = $module->getContainer();
36
        $this->classDir = is_dir($tmpDir) ? $tmpDir : sys_get_temp_dir();
37
        $this->container->weaveAspects(new Compiler($this->classDir));
38
39
        // builtin injection
40
        (new Bind($this->container, InjectorInterface::class))->toInstance($this);
41
    }
42
43
    /**
44
     * Wakeup
45
     */
46
    public function __wakeup()
47
    {
48
        spl_autoload_register(
49
            function (string $class): void {
50
                $file = sprintf('%s/%s.php', $this->classDir, str_replace('\\', '_', $class));
51
                if (file_exists($file)) {
52
                    include $file; //@codeCoverageIgnore
53
                }
54
            }
55
        );
56
    }
57
58
    /**
59
     * Return instance
60
     *
61
     * @param class-string|string $interface
0 ignored issues
show
Documentation introduced by
The doc-type class-string|string could not be parsed: Unknown type name "class-string" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
62
     * @param string              $name
63
     *
64
     * @return mixed instance
65
     */
66
    public function getInstance($interface, $name = Name::ANY)
67
    {
68
        try {
69
            /** @psalm-suppress MixedAssignment */
70
            $instance = $this->container->getInstance($interface, $name);
71
        } catch (Untargeted $e) {
72
            $this->bind($interface);
73
            /** @psalm-suppress MixedAssignment */
74
            $instance = $this->getInstance($interface, $name);
75
        }
76
77
        return $instance;
78
    }
79
80
    /**
81
     * @phpstan-param class-string|string $class
82
     *
83
     * @throws AnnotationException
84
     */
85
    private function bind(string $class): void
86
    {
87
        new Bind($this->container, $class);
88
        $bound = $this->container->getContainer()[$class . '-' . Name::ANY];
89
        assert($bound instanceof Dependency);
90
        $this->container->weaveAspect(new Compiler($this->classDir), $bound)->getInstance($class, Name::ANY);
91
    }
92
}
93