Passed
Pull Request — master (#593)
by Théo
02:03
created

SymbolRegistry::lowerCaseConstantName()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 5
nc 1
nop 1
dl 0
loc 11
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_map;
9
use function array_pop;
10
use function array_unique;
11
use function explode;
12
use function implode;
13
use function ltrim;
14
use function Safe\array_flip;
15
use function Safe\preg_match;
16
use function strtolower;
17
18
final class SymbolRegistry
19
{
20
    /**
21
     * @var array<string, mixed>
22
     */
23
    private array $names;
24
25
    /**
26
     * @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...
27
     */
28
    private array $regexes;
29
    private bool $constants;
30
31
    /**
32
     * @param string[] $names
33
     * @param string[] $regexes
34
     */
35
    public static function create(
36
        array $names = [],
37
        array $regexes = []
38
    ): self {
39
        return new self(
40
            array_unique(
41
                array_map('strtolower', $names),
42
            ),
43
            array_unique($regexes),
44
            false,
45
        );
46
    }
47
48
    /**
49
     * Unlike classes & functions, constants are not case-insensitive (although
50
     * the namespace part _is_). I.e. \Acme\FOO = \ACME\FOO but Acme\FOO ≠ Acme\Foo.
51
     *
52
     * @param string[] $names
53
     * @param string[] $regexes
54
     */
55
    public static function createForConstants(
56
        array $names = [],
57
        array $regexes = []
58
    ): self {
59
        return new self(
60
            array_unique(
61
                array_map(
62
                    static fn (string $name) => self::lowerCaseConstantName($name),
63
                    $names,
64
                ),
65
            ),
66
            array_unique($regexes),
67
            true,
68
        );
69
    }
70
71
    /**
72
     * @param list<string> $names
73
     * @param list<string> $regexes
74
     */
75
    private function __construct(
76
        array $names,
77
        array $regexes,
78
        bool $constants
79
    ) {
80
        $this->names = array_flip($names);
81
        $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...
82
        $this->constants = $constants;
83
    }
84
85
    public function matches(string $symbol): bool
86
    {
87
        $originalSymbol = ltrim($symbol, '\\');
88
        $symbol = $this->constants
89
            ? self::lowerCaseConstantName($originalSymbol)
90
            : strtolower($originalSymbol);
91
92
        if (array_key_exists($symbol, $this->names)) {
93
            return true;
94
        }
95
96
        foreach ($this->regexes as $regex) {
97
            if (preg_match($regex, $originalSymbol)) {
98
                return true;
99
            }
100
        }
101
102
        return false;
103
    }
104
105
    /**
106
     * Transforms the constant FQ name "Acme\Foo\X" to "acme\foo\X" since the
107
     * namespace remains case-insensitive for constants regardless of whether
108
     * constants actually are case-insensitive.
109
     */
110
    private static function lowerCaseConstantName(string $name): string
111
    {
112
        $parts = explode('\\', $name);
113
114
        $lastPart = array_pop($parts);
115
116
        $parts = array_map('strtolower', $parts);
117
118
        $parts[] = $lastPart;
119
120
        return implode('\\', $parts);
121
    }
122
}
123