Passed
Push — master ( b089da...2b10b8 )
by Théo
02:12
created

EnrichedReflector   A

Complexity

Total Complexity 40

Size/Duplication

Total Lines 138
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 55
dl 0
loc 138
rs 9.2
c 1
b 0
f 0
wmc 40

18 Methods

Rating   Name   Duplication   Size   Complexity  
A belongsToExcludedNamespace() 0 5 1
A __construct() 0 6 1
A isFunctionInternal() 0 3 1
A isExposedClass() 0 10 5
A isExcludedNamespace() 0 5 1
A isFunctionExcluded() 0 4 2
A belongsToExposedNamespace() 0 5 1
A isExposedFunction() 0 10 5
A _isExposedClassFromGlobalNamespace() 0 3 2
A isConstantInternal() 0 3 1
A _isExposedFunctionFromGlobalNamespace() 0 3 2
A isConstantExcluded() 0 5 2
A isExposedClassFromGlobalNamespace() 0 5 3
A isClassInternal() 0 3 1
A isClassExcluded() 0 4 2
A isExposedFunctionFromGlobalNamespace() 0 5 3
A isExposedConstant() 0 14 5
A isExposedConstantFromGlobalNamespace() 0 3 2

How to fix   Complexity   

Complex Class

Complex classes like EnrichedReflector often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use EnrichedReflector, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Humbug\PhpScoper\Symbol;
6
7
use Humbug\PhpScoper\Configuration\SymbolsConfiguration;
8
use function strpos;
9
10
/**
11
 * Combines the API or the "traditional" reflector which is about to tell
12
 * if a symbol is internal or not with the more PHP-Scoper specific exposed
13
 * API.
14
 */
15
final class EnrichedReflector
16
{
17
    private Reflector $reflector;
18
    private SymbolsConfiguration $symbolsConfiguration;
19
20
    public function __construct(
21
        Reflector $reflector,
22
        SymbolsConfiguration $symbolsConfiguration
23
    ) {
24
        $this->reflector = $reflector;
25
        $this->symbolsConfiguration = $symbolsConfiguration;
26
    }
27
28
    public function belongsToExcludedNamespace(string $name): bool
29
    {
30
        return $this->symbolsConfiguration
31
            ->getExcludedNamespaces()
32
            ->belongsToRegisteredNamespace($name);
33
    }
34
35
    private function belongsToExposedNamespace(string $name): bool
36
    {
37
        return $this->symbolsConfiguration
38
            ->getExposedNamespaces()
39
            ->belongsToRegisteredNamespace($name);
40
    }
41
42
    public function isFunctionInternal(string $name): bool
43
    {
44
        return $this->reflector->isFunctionInternal($name);
45
    }
46
47
    public function isFunctionExcluded(string $name): bool
48
    {
49
        return $this->reflector->isFunctionInternal($name)
50
            || $this->belongsToExcludedNamespace($name);
51
    }
52
53
    public function isClassInternal(string $name): bool
54
    {
55
        return $this->reflector->isClassInternal($name);
56
    }
57
58
    public function isClassExcluded(string $name): bool
59
    {
60
        return $this->reflector->isClassInternal($name)
61
            || $this->belongsToExcludedNamespace($name);
62
    }
63
64
    public function isConstantInternal(string $name): bool
65
    {
66
        return $this->reflector->isConstantInternal($name);
67
    }
68
69
    public function isConstantExcluded(string $name): bool
70
    {
71
        // TODO: double check not sure that internal should mean excluded for constants
72
        return $this->reflector->isConstantInternal($name)
73
            || $this->belongsToExcludedNamespace($name);
74
    }
75
76
    public function isExposedFunction(string $resolvedName): bool
77
    {
78
        return !$this->belongsToExcludedNamespace($resolvedName)
79
            && !$this->reflector->isFunctionInternal($resolvedName)
80
            && (
81
                $this->_isExposedFunctionFromGlobalNamespace($resolvedName)
82
                || $this->symbolsConfiguration
83
                        ->getExposedFunctions()
84
                        ->matches($resolvedName)
85
                || $this->belongsToExposedNamespace($resolvedName)
86
            );
87
    }
88
89
    public function isExposedFunctionFromGlobalNamespace(string $resolvedName): bool
90
    {
91
        return !$this->belongsToExcludedNamespace($resolvedName)
92
            && !$this->reflector->isFunctionInternal($resolvedName)
93
            && $this->_isExposedFunctionFromGlobalNamespace($resolvedName);
94
    }
95
96
    public function isExposedClass(string $resolvedName): bool
97
    {
98
        return !$this->belongsToExcludedNamespace($resolvedName)
99
            && !$this->reflector->isClassInternal($resolvedName)
100
            && (
101
                $this->_isExposedClassFromGlobalNamespace($resolvedName)
102
                || $this->symbolsConfiguration
103
                    ->getExposedClasses()
104
                    ->matches($resolvedName)
105
                || $this->belongsToExposedNamespace($resolvedName)
106
            );
107
    }
108
109
    public function isExposedClassFromGlobalNamespace(string $resolvedName): bool
110
    {
111
        return !$this->belongsToExcludedNamespace($resolvedName)
112
            && !$this->reflector->isClassInternal($resolvedName)
113
            && $this->_isExposedClassFromGlobalNamespace($resolvedName);
114
    }
115
116
    public function isExposedConstant(string $name): bool
117
    {
118
        // Special case: internal constants must be treated as exposed symbols.
119
        //
120
        // Example: when declaring a new internal constant for compatibility
121
        // reasons, it must remain un-prefixed.
122
        return !$this->belongsToExcludedNamespace($name)
123
            && (
124
                $this->reflector->isConstantInternal($name)
125
                || $this->isExposedConstantFromGlobalNamespace($name)
126
                || $this->symbolsConfiguration
127
                    ->getExposedConstants()
128
                    ->matches($name)
129
                || $this->belongsToExposedNamespace($name)
130
            );
131
    }
132
133
    public function isExposedConstantFromGlobalNamespace(string $constantName): bool
134
    {
135
        return $this->symbolsConfiguration->shouldExposeGlobalConstants() && !strpos($constantName, '\\');
136
    }
137
138
    public function isExcludedNamespace(string $name): bool
139
    {
140
        return $this->symbolsConfiguration
141
            ->getExcludedNamespaces()
142
            ->isRegisteredNamespace($name);
143
    }
144
145
    private function _isExposedFunctionFromGlobalNamespace(string $functionName): bool
146
    {
147
        return $this->symbolsConfiguration->shouldExposeGlobalFunctions() && !strpos($functionName, '\\');
148
    }
149
150
    public function _isExposedClassFromGlobalNamespace(string $className): bool
151
    {
152
        return $this->symbolsConfiguration->shouldExposeGlobalClasses() && !strpos($className, '\\');
153
    }
154
}
155