CompileVisitor   A
last analyzed

Complexity

Total Complexity 19

Size/Duplication

Total Lines 126
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 46
c 1
b 0
f 0
dl 0
loc 126
rs 10
wmc 19

11 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
A visitDependency() 0 9 1
A visitSetterMethods() 0 6 2
A visitProvider() 0 13 1
A visitNewInstance() 0 17 3
A visitArgument() 0 8 1
A visitAspectBind() 0 4 1
A visitSetterMethod() 0 5 1
A visitInstance() 0 10 4
A getProviderScript() 0 11 2
A visitArguments() 0 5 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Ray\Compiler;
6
7
use Override;
0 ignored issues
show
Bug introduced by
The type Override was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
8
use Ray\Aop\Bind;
9
use Ray\Di\Arguments;
10
use Ray\Di\AspectBind;
11
use Ray\Di\Container;
12
use Ray\Di\Dependency;
13
use Ray\Di\NewInstance;
14
use Ray\Di\SetterMethods;
15
use Ray\Di\VisitorInterface;
16
use ReflectionParameter;
17
18
use function assert;
19
use function gettype;
20
use function is_array;
21
use function is_object;
22
use function is_scalar;
23
use function is_string;
24
use function serialize;
25
use function sprintf;
26
use function str_replace;
27
use function var_export;
28
29
final class CompileVisitor implements VisitorInterface
30
{
31
    private readonly InstanceScript $script;
32
33
    public function __construct(Container $container)
34
    {
35
        $this->script = new InstanceScript($container);
0 ignored issues
show
Bug introduced by
The property script is declared read-only in Ray\Compiler\CompileVisitor.
Loading history...
36
    }
37
38
    /** @inheritDoc */
39
    #[Override]
40
    public function visitDependency(
41
        NewInstance $newInstance,
42
        string|null $postConstruct,
43
        bool $isSingleton,
44
    ): string {
45
        $newInstance->accept($this);
46
47
        return $this->script->getScript($postConstruct, $isSingleton);
48
    }
49
50
    /** @inheritDoc */
51
    #[Override]
52
    public function visitProvider(
53
        Dependency $dependency,
54
        string $context,
55
        bool $isSingleton,
56
    ): string {
57
        $this->script->pushProviderContext($context);
58
        $script = $dependency->accept($this);
59
        assert(is_string($script));
60
61
        $providerScript = $this->getProviderScript($isSingleton);
62
63
        return str_replace(InstanceScript::COMMENT, $providerScript, $script);
64
    }
65
66
    /** @inheritDoc */
67
    #[Override]
68
    public function visitInstance($value): string
69
    {
70
        if ($value === null || is_scalar($value)) {
71
            return sprintf('return %s;', var_export($value, true));
72
        }
73
74
        assert(is_object($value) || is_array($value), 'Invalid instance type:' . gettype($value));
75
76
        return sprintf('return unserialize(\'%s\');', serialize($value));
77
    }
78
79
    /** @inheritDoc */
80
    #[Override]
81
    public function visitAspectBind(Bind $aopBind): void
82
    {
83
        $this->script->pushAspectBind($aopBind);
84
    }
85
86
    /** @inheritDoc */
87
    #[Override]
88
    public function visitNewInstance(
89
        string $class,
90
        SetterMethods $setterMethods,
91
        Arguments|null $arguments,
92
        AspectBind|null $bind,
93
    ): void {
94
        $setterMethods->accept($this);
95
        if ($arguments instanceof Arguments) {
96
            $arguments->accept($this);
97
        }
98
99
        if ($bind instanceof AspectBind) {
100
            $bind->accept($this);
101
        }
102
103
        $this->script->pushClass($class);
104
    }
105
106
    /** @inheritDoc */
107
    #[Override]
108
    public function visitSetterMethods(
109
        array $setterMethods,
110
    ): void {
111
        foreach ($setterMethods as $setterMethod) {
112
            $setterMethod->accept($this);
113
        }
114
    }
115
116
    /** @inheritDoc */
117
    #[Override]
118
    public function visitSetterMethod(string $method, Arguments $arguments): void
119
    {
120
        $arguments->accept($this);
121
        $this->script->pushMethod($method);
122
    }
123
124
    /** @inheritDoc */
125
    #[Override]
126
    public function visitArguments(array $arguments): void
127
    {
128
        foreach ($arguments as $argument) {
129
            $argument->accept($this);
130
        }
131
    }
132
133
    /** @inheritDoc */
134
    #[Override]
135
    public function visitArgument(
136
        string $index,
137
        bool $isDefaultAvailable,
138
        $defaultValue,
139
        ReflectionParameter $parameter,
140
    ): void {
141
        $this->script->addArg($index, $isDefaultAvailable, $defaultValue, $parameter);
142
    }
143
144
    private function getProviderScript(bool $isSingleton): string
145
    {
146
        if ($isSingleton) {
147
            return <<<'EOT'
148
$instance = $instance->get();
149
// singleton
150
$singletons[$dependencyIndex] = $instance;
151
EOT;
152
        }
153
154
        return <<<'EOT'
155
$instance = $instance->get();
156
// prototype
157
EOT;
158
    }
159
}
160