Passed
Push — master ( 77aa03...453f7d )
by Nikita
02:16
created

Utils   B

Complexity

Total Complexity 42

Size/Duplication

Total Lines 193
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 2

Importance

Changes 0
Metric Value
wmc 42
lcom 0
cbo 2
dl 0
loc 193
rs 8.295
c 0
b 0
f 0

10 Methods

Rating   Name   Duplication   Size   Complexity  
B isWhite() 0 4 5
A isSymChar() 0 4 2
A isOctal() 0 6 2
C characterValue() 0 44 14
B stableSort() 0 22 4
A vacantRow() 0 10 3
A eqRow() 0 10 3
A printAction() 0 8 2
B isSameSet() 0 14 5
A dumpSet() 0 10 2

How to fix   Complexity   

Complex Class

Complex classes like Utils 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. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

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 Utils, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * This file is part of Yacc package.
4
 *
5
 * For the full copyright and license information, please view the LICENSE
6
 * file that was distributed with this source code.
7
 */
8
declare(strict_types=1);
9
10
namespace PhpYacc\Support;
11
use PhpYacc\Compress\Compress;
12
use PhpYacc\Grammar\Context;
13
use PhpYacc\Lalr\BitSet;
14
use PhpYacc\Lalr\Lr1;
15
16
/**
17
 * Class Utils.
18
 */
19
final class Utils
20
{
21
    /**
22
     * @param string $char
23
     *
24
     * @return bool
25
     */
26
    public static function isWhite(string $char): bool
27
    {
28
        return $char === ' ' || $char === "\t" || $char === "\r" || $char === "\x0b" || $char === "\x0c";
29
    }
30
31
    /**
32
     * @param string $char
33
     *
34
     * @return bool
35
     */
36
    public static function isSymChar(string $char): bool
37
    {
38
        return ctype_alnum($char) || $char === '_';
39
    }
40
41
    /**
42
     * @param string $char
43
     *
44
     * @return bool
45
     */
46
    public static function isOctal(string $char): bool
47
    {
48
        $n = \ord($char);
49
50
        return $n >= 48 && $n <= 55;
51
    }
52
53
    /**
54
     * @param string $string
55
     *
56
     * @return int
57
     */
58
    public static function characterValue(string $string): int
59
    {
60
        $n = 0;
61
        $length = \mb_strlen($string);
62
63
        if ($length === 0) {
64
            return 0;
65
        }
66
67
        $c = $string[$n++];
68
69
        if ($c !== '\\') {
70
            return \ord($c);
71
        }
72
73
        $c = $string[$n++];
74
        if (self::isOctal($c)) {
75
            $value = (int) $c;
76
            for ($i = 0; $n < $length && self::isOctal($string[$n]) && $i < 3; $i++) {
77
                $value = $value * 8 + $string[$n++];
78
            }
79
80
            return $value;
81
        }
82
83
        switch ($c) {
84
            case 'n':
85
                return \ord("\n");
86
            case 't':
87
                return \ord("\t");
88
            case 'b':
89
                return \ord("\x08");
90
            case 'r':
91
                return \ord("\r");
92
            case 'f':
93
                return \ord("\x0C");
94
            case 'v':
95
                return \ord("\x0B");
96
            case 'a':
97
                return \ord("\x07");
98
            default:
99
                return \ord($c);
100
        }
101
    }
102
103
    /**
104
     * @param array    $array
105
     * @param callable $cmp
106
     */
107
    public static function stableSort(array &$array, callable $cmp)
108
    {
109
        $indexedArray = [];
110
        $i = 0;
111
        foreach ($array as $item) {
112
            $indexedArray[] = [$item, $i++];
113
        }
114
115
        \usort($indexedArray, function (array $a, array $b) use ($cmp) {
116
            $result = $cmp($a[0], $b[0]);
117
            if ($result !== 0) {
118
                return $result;
119
            }
120
121
            return $a[1] - $b[1];
122
        });
123
124
        $array = [];
125
        foreach ($indexedArray as $item) {
126
            $array[] = $item[0];
127
        }
128
    }
129
130
    /**
131
     * @param array $array
132
     * @param int $length
133
     * @return bool
134
     */
135
    public static function vacantRow(array $array, int $length): bool
136
    {
137
        for ($i = 0; $i < $length; $i++) {
138
            if ($array[$i] !== Compress::VACANT) {
139
                return false;
140
            }
141
        }
142
143
        return true;
144
    }
145
146
    /**
147
     * @param array $a
148
     * @param array $b
149
     * @param int $length
150
     * @return bool
151
     */
152
    public static function eqRow(array $a, array $b, int $length): bool
153
    {
154
        for ($i = 0; $i < $length; $i++) {
155
            if ($a[$i] !== $b[$i]) {
156
                return false;
157
            }
158
        }
159
160
        return true;
161
    }
162
163
    /**
164
     * @param int $action
165
     * @return string
166
     */
167
    public static function printAction(int $action): string
168
    {
169
        if ($action === Compress::VACANT) {
170
            return '  . ';
171
        }
172
173
        return \sprintf('%4d', $action);
174
    }
175
176
    /**
177
     * @param Lr1|null $left
178
     * @param Lr1|null $right
179
     * @return bool
180
     */
181
    public static function isSameSet(Lr1 $left = null, Lr1 $right = null): bool
182
    {
183
        $p = $left;
184
        $t = $right;
185
        while ($t !== null) {
186
            // Not using !== here intentionally
187
            if ($p === null || $p->item != $t->item) {
188
                return false;
189
            }
190
            $p = $p->next;
191
            $t = $t->next;
192
        }
193
        return $p === null || $p->isHeadItem();
194
    }
195
196
    /**
197
     * @param Context $ctx
198
     * @param BitSet $set
199
     * @return string
200
     */
201
    public static function dumpSet(Context $ctx, BitSet $set): string
202
    {
203
        $result = '';
204
        foreach ($set as $code) {
205
            $symbol = $ctx->symbols[$code];
206
            $result .= "{$symbol->name} ";
207
        }
208
209
        return $result;
210
    }
211
}
212