ModuleBindings::parseBinding()
last analyzed

Size

Total Lines 61
Code Lines 32

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 32
c 1
b 0
f 0
dl 0
loc 61
nc 56
nop 2

4 Methods

Rating   Name   Duplication   Size   Complexity  
A ModuleBindings.php$0 ➔ visitInstance() 0 1 1
A ModuleBindings.php$0 ➔ visitProvider() 0 1 1
A ModuleBindings.php$0 ➔ visitAspectBind() 0 1 1
A ModuleBindings.php$0 ➔ visitDependency() 0 2 1

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Ray\Di;
6
7
use Ray\Di\Bindings\BindingInfo;
8
use function assert;
9
use function explode;
10
use function get_class;
11
use function is_object;
12
use function serialize;
13
use function unserialize;
14
15
/**
16
 * Provides machine-readable binding information from raw binding data
17
 *
18
 * @psalm-import-type PointcutList from Types
19
 */
20
final class ModuleBindings
21
{
22
    /**
23
     * Get all bindings as machine-readable BindingInfo objects
24
     *
25
     * @param PointcutList $pointcuts
0 ignored issues
show
Bug introduced by
The type Ray\Di\PointcutList 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...
26
     *
27
     * @return list<BindingInfo>
0 ignored issues
show
Bug introduced by
The type Ray\Di\list 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...
28
     */
29
    public function __invoke(Container $container, array $pointcuts): array
30
    {
31
        $bindings = [];
32
        /** @psalm-suppress MixedAssignment */
33
        $container = unserialize(serialize($container), ['allowed_classes' => true]);
34
        assert($container instanceof Container);
35
        $spy = new SpyCompiler();
36
37
        foreach ($container->getContainer() as $dependencyIndex => $dependency) {
38
            if ($dependency instanceof Dependency) {
39
                $dependency->weaveAspects($spy, $pointcuts);
40
            }
41
42
            $bindingInfo = $this->parseBinding($dependencyIndex, $dependency);
43
            if ($bindingInfo !== null) {
44
                $bindings[] = $bindingInfo;
45
            }
46
        }
47
48
        return $bindings;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $bindings returns the type Ray\Di\Bindings\BindingInfo[]|array which is incompatible with the documented return type Ray\Di\list.
Loading history...
49
    }
50
51
    /**
52
     * @return ?BindingInfo
53
     */
54
    private function parseBinding(string $dependencyIndex, DependencyInterface $dependency): ?BindingInfo
55
    {
56
        // Parse index format: "interface-named" or just "interface"
57
        $parts = explode('-', $dependencyIndex, 2);
58
        $interface = $parts[0];
59
        $named = isset($parts[1]) && $parts[1] !== '+' ? $parts[1] : null;
60
61
        $dependencyString = (string) $dependency;
62
63
        // Determine binding type and target
64
        if ($dependency instanceof Instance) {
65
            $value = $dependency->value;
66
            return new BindingInfo(
67
                $interface,
68
                $named,
69
                'toInstance',
70
                is_object($value) ? get_class($value) : $value
71
            );
72
        }
73
74
        if ($dependency instanceof DependencyProvider) {
75
            // Extract the provider class from the string representation
76
            if (preg_match('/\(provider\) \(dependency\) (.+?)(,|$)/', $dependencyString, $matches)) {
77
                return new BindingInfo(
78
                    $interface,
79
                    $named,
80
                    'toProvider',
81
                    $matches[1]
82
                );
83
            }
84
        }
85
86
        if ($dependency instanceof Dependency) {
87
            // Extract target class from NewInstance
88
            $target = (string) $dependency->accept(new class implements VisitorInterface {
89
                public function visitDependency($newInstance, $postConstruct, $isSingleton) {
90
                    return (string) $newInstance;
91
                }
92
                public function visitInstance($instance) { return null; }
93
                public function visitProvider($dependency, $context, $isSingleton) { return null; }
94
                public function visitAspectBind($bind) { return null; }
95
            });
96
            
97
            if ($target === '') {
98
                return null;
99
            }
100
            
101
            // Get AOP bindings directly from VO
102
            $aopInfo = $dependency->getAopInfo();
103
            $aopBindings = $aopInfo && $aopInfo->hasBindings() ? $aopInfo->methodBindings : null;
104
            
105
            return new BindingInfo(
106
                $interface,
107
                $named,
108
                'to',
109
                $target,
110
                $aopBindings
111
            );
112
        }
113
114
        return null;
115
    }
116
}