Completed
Push — 2.x ( f03324...33a4a6 )
by Akihito
20s queued 15s
created

NewInstance::enableAop()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 4
c 1
b 0
f 0
dl 0
loc 9
rs 10
cc 2
nc 2
nop 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Ray\Di;
6
7
use Ray\Aop\Bind as AopBind;
8
use Ray\Aop\WeavedInterface;
9
use ReflectionClass;
10
use ReflectionException;
11
12
use function assert;
13
14
final class NewInstance
15
{
16
    /** @var class-string */
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string.
Loading history...
17
    private $class;
18
19
    /** @var SetterMethods */
20
    private $setterMethods;
21
22
    /** @var ?Arguments */
23
    private $arguments;
24
25
    /** @var ?AspectBind */
26
    private $bind;
27
28
    /**
29
     * @phpstan-param ReflectionClass<object> $class
30
     */
31
    public function __construct(
32
        ReflectionClass $class,
33
        SetterMethods $setterMethods,
34
        ?Name $constructorName = null
35
    ) {
36
        $constructorName = $constructorName ?: new Name(Name::ANY);
37
        $this->class = $class->getName();
38
        $constructor = $class->getConstructor();
39
        if ($constructor) {
40
            $this->arguments = new Arguments($constructor, $constructorName);
41
        }
42
43
        $this->setterMethods = $setterMethods;
44
    }
45
46
    /**
47
     * @throws ReflectionException
48
     */
49
    public function __invoke(Container $container): object
50
    {
51
        /** @psalm-suppress MixedMethodCall, ArgumentTypeCoercion */
52
        $instance = $this->arguments instanceof Arguments ? (new ReflectionClass($this->class))->newInstanceArgs($this->arguments->inject($container)) : new $this->class();
53
54
        return $this->postNewInstance($container, $instance);
55
    }
56
57
    /**
58
     * @return class-string
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string.
Loading history...
59
     */
60
    public function __toString()
61
    {
62
        return $this->class;
63
    }
64
65
    /**
66
     * @param array<int, mixed> $params
67
     *
68
     * @throws ReflectionException
69
     */
70
    public function newInstanceArgs(Container $container, array $params): object
71
    {
72
        /** @psalm-suppress ArgumentTypeCoercion */
73
        $instance = (new ReflectionClass($this->class))->newInstanceArgs($params);
74
75
        return $this->postNewInstance($container, $instance);
76
    }
77
78
    /**
79
     * @param class-string $class
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string.
Loading history...
80
     */
81
    public function weaveAspects(string $class, AopBind $bind): void
82
    {
83
        $this->class = $class;
84
        $this->bind = new AspectBind($bind);
85
    }
86
87
    public function accept(VisitorInterface $visitor): void
88
    {
89
        $visitor->visitNewInstance(
90
            $this->class,
91
            $this->setterMethods,
92
            $this->arguments,
93
            $this->bind
94
        );
95
    }
96
97
    private function postNewInstance(Container $container, object $instance): object
98
    {
99
        $this->enableAop($instance, $container);
100
101
        // setter injection
102
        ($this->setterMethods)($instance, $container);
103
104
        return $instance;
105
    }
106
107
    public function enableAop(object $instance, Container $container): void
108
    {
109
        if (! $this->bind instanceof AspectBind) {
110
            return;
111
        }
112
113
        assert($instance instanceof WeavedInterface);
114
115
        $instance->_setBindings($this->bind->inject($container));  // Ray.Aop ^2.18
116
    }
117
}
118