Passed
Push — master ( a6702a...790ab7 )
by Théo
02:26
created

SymbolRegistry::getRegexes()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Humbug\PhpScoper\Symbol;
6
7
use function array_key_exists;
8
use function array_keys;
9
use function array_map;
10
use function array_pop;
11
use function array_unique;
12
use function explode;
13
use function implode;
14
use function ltrim;
15
use function Safe\array_flip;
16
use function Safe\preg_match;
17
use function strtolower;
18
19
final class SymbolRegistry
20
{
21
    /**
22
     * @var array<string, mixed>
23
     */
24
    private array $names;
25
26
    /**
27
     * @var list<string>
0 ignored issues
show
Bug introduced by
The type Humbug\PhpScoper\Symbol\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
    private array $regexes;
30
31
    private bool $constants;
32
33
    /**
34
     * @param string[] $names
35
     * @param string[] $regexes
36
     */
37
    public static function create(
38
        array $names = [],
39
        array $regexes = []
40
    ): self {
41
        return new self(
42
            array_unique(
43
                array_map(
44
                    static fn (string $name) => strtolower(ltrim($name, '\\')),
45
                    $names,
46
                ),
47
            ),
48
            array_unique($regexes),
49
            false,
50
        );
51
    }
52
53
    /**
54
     * Unlike classes & functions, constants are not case-insensitive (although
55
     * the namespace part _is_). I.e. \Acme\FOO = \ACME\FOO but Acme\FOO ≠ Acme\Foo.
56
     *
57
     * @param string[] $names
58
     * @param string[] $regexes
59
     */
60
    public static function createForConstants(
61
        array $names = [],
62
        array $regexes = []
63
    ): self {
64
        return new self(
65
            array_unique(
66
                array_map(
67
                    static fn (string $name) => self::lowerCaseConstantName(
68
                        ltrim($name, '\\'),
69
                    ),
70
                    $names,
71
                ),
72
            ),
73
            array_unique($regexes),
74
            true,
75
        );
76
    }
77
78
    /**
79
     * @param list<string> $names
80
     * @param list<string> $regexes
81
     */
82
    private function __construct(
83
        array $names,
84
        array $regexes,
85
        bool $constants
86
    ) {
87
        $this->names = array_flip($names);
88
        $this->regexes = $regexes;
0 ignored issues
show
Documentation Bug introduced by
It seems like $regexes of type array is incompatible with the declared type Humbug\PhpScoper\Symbol\list of property $regexes.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
89
        $this->constants = $constants;
90
    }
91
92
    public function matches(string $symbol): bool
93
    {
94
        $originalSymbol = ltrim($symbol, '\\');
95
        $symbol = $this->constants
96
            ? self::lowerCaseConstantName($originalSymbol)
97
            : strtolower($originalSymbol);
98
99
        if (array_key_exists($symbol, $this->names)) {
100
            return true;
101
        }
102
103
        foreach ($this->regexes as $regex) {
104
            if (preg_match($regex, $originalSymbol)) {
105
                return true;
106
            }
107
        }
108
109
        return false;
110
    }
111
112
    /**
113
     * @param string[] $names
114
     * @param string[] $regexes
115
     */
116
    public function withAdditionalSymbols(array $names = [], array $regexes = []): self
117
    {
118
        $args = [
119
            [
120
                ...$this->getNames(),
121
                ...$names,
122
            ],
123
            [
124
                ...$this->getRegexes(),
125
                ...$regexes,
126
            ],
127
        ];
128
129
        return $this->constants
130
            ? self::createForConstants(...$args)
0 ignored issues
show
Bug introduced by
$args is expanded, but the parameter $names of Humbug\PhpScoper\Symbol\...y::createForConstants() does not expect variable arguments. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

130
            ? self::createForConstants(/** @scrutinizer ignore-type */ ...$args)
Loading history...
131
            : self::create(...$args);
0 ignored issues
show
Bug introduced by
$args is expanded, but the parameter $names of Humbug\PhpScoper\Symbol\SymbolRegistry::create() does not expect variable arguments. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

131
            : self::create(/** @scrutinizer ignore-type */ ...$args);
Loading history...
132
    }
133
134
    /**
135
     * @internal
136
     *
137
     * @return list<string>
138
     */
139
    public function getNames(): array
140
    {
141
        return array_keys($this->names);
0 ignored issues
show
Bug Best Practice introduced by
The expression return array_keys($this->names) returns the type array which is incompatible with the documented return type Humbug\PhpScoper\Symbol\list.
Loading history...
142
    }
143
144
    /**
145
     * @internal
146
     *
147
     * @erturn list<string>
148
     */
149
    public function getRegexes(): array
150
    {
151
        return $this->regexes;
152
    }
153
154
    /**
155
     * Transforms the constant FQ name "Acme\Foo\X" to "acme\foo\X" since the
156
     * namespace remains case-insensitive for constants regardless of whether
157
     * constants actually are case-insensitive.
158
     */
159
    private static function lowerCaseConstantName(string $name): string
160
    {
161
        $parts = explode('\\', $name);
162
163
        $lastPart = array_pop($parts);
164
165
        $parts = array_map('strtolower', $parts);
166
167
        $parts[] = $lastPart;
168
169
        return implode('\\', $parts);
170
    }
171
}
172