GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Pull Request — master (#67)
by
unknown
01:15
created

ReflectionUtils   A

Complexity

Total Complexity 35

Size/Duplication

Total Lines 151
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 0

Importance

Changes 0
Metric Value
wmc 35
lcom 0
cbo 0
dl 0
loc 151
rs 9.6
c 0
b 0
f 0

4 Methods

Rating   Name   Duplication   Size   Complexity  
A isSkipped() 0 4 1
A getUsesAndAliases() 0 22 5
D parseUsesAndAliases() 0 75 24
A fetch() 0 14 5
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Spatie\DataTransferObject;
6
7
use ReflectionClass;
8
use RuntimeException;
9
10
class ReflectionUtils
11
{
12
    private const SKIPPED = [
13
        'string',
14
        'int',
15
        'integer',
16
        'float',
17
        'bool',
18
        'double',
19
        'array',
20
        'object',
21
        'callable',
22
        'callback',
23
        'iterable',
24
        'void',
25
        'null',
26
        'mixed',
27
    ];
28
29
    /**
30
     * @param string $type
31
     * @return bool
32
     */
33
    public static function isSkipped(string $type): bool
34
    {
35
        return in_array(strtolower($type), self::SKIPPED, true);
36
    }
37
38
    /**
39
     * @param ReflectionClass $class
40
     * @return array
41
     */
42
    public static function getUsesAndAliases(ReflectionClass $class): array
43
    {
44
        try {
45
            if ($class->isAnonymous()) {
46
                throw new RuntimeException('Anonymous classes are not supported.');
47
            }
48
            static $cache = [];
49
            if (! isset($cache[$name = $class->getName()])) {
50
                if ($class->isInternal()) {
51
                    $cache[$name] = [];
52
                } else {
53
                    $code = file_get_contents($class->getFileName());
54
                    $cache = self::parseUsesAndAliases($code, $name) + $cache;
55
                }
56
            }
57
58
            return $cache[$name];
59
        } catch (\Exception $exception) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
60
        }
61
62
        return [];
63
    }
64
65
    /**
66
     * @param string $code
67
     * @param string|null $forClass
68
     * @return array
69
     */
70
    private static function parseUsesAndAliases(string $code, string $forClass = null): array
71
    {
72
        try {
73
            $tokens = token_get_all($code, TOKEN_PARSE);
74
        } catch (\Exception $e) {
75
            $tokens = [];
76
        }
77
        $namespace = $class = $classLevel = $level = null;
78
        $res = $uses = [];
79
80
        while ($token = current($tokens)) {
81
            next($tokens);
82
            switch (is_array($token) ? $token[0] : $token) {
83
                case T_NAMESPACE:
84
                    $namespace = ltrim(self::fetch($tokens, [T_STRING, T_NS_SEPARATOR]).'\\', '\\');
85
                    $uses = [];
86
                    break;
87
88
                case T_CLASS:
89
                case T_INTERFACE:
90
                case T_TRAIT:
91
                    if ($name = self::fetch($tokens, T_STRING)) {
92
                        $class = $namespace.$name;
93
                        $classLevel = $level + 1;
94
                        $res[$class] = $uses;
95
                        if ($class === $forClass) {
96
                            return $res;
97
                        }
98
                    }
99
                    break;
100
101
                case T_USE:
102
                    while (! $class && ($name = self::fetch($tokens, [T_STRING, T_NS_SEPARATOR]))) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $class of type string|null is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
103
                        $name = ltrim($name, '\\');
104
                        if (self::fetch($tokens, '{')) {
0 ignored issues
show
Bug Best Practice introduced by
The expression self::fetch($tokens, '{') of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
105
                            while ($suffix = self::fetch($tokens, [T_STRING, T_NS_SEPARATOR])) {
106
                                /* @noinspection NotOptimalIfConditionsInspection */
107
                                if (self::fetch($tokens, T_AS)) {
0 ignored issues
show
Bug Best Practice introduced by
The expression self::fetch($tokens, T_AS) of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
108
                                    $uses[self::fetch($tokens, T_STRING)] = $name.$suffix;
109
                                } else {
110
                                    $tmp = explode('\\', $suffix);
111
                                    $uses[end($tmp)] = $name.$suffix;
112
                                }
113
                                if (! self::fetch($tokens, ',')) {
0 ignored issues
show
Bug Best Practice introduced by
The expression self::fetch($tokens, ',') of type string|null is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
114
                                    break;
115
                                }
116
                            }
117
                        } elseif (self::fetch($tokens, T_AS)) {
0 ignored issues
show
Bug Best Practice introduced by
The expression self::fetch($tokens, T_AS) of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
118
                            $uses[self::fetch($tokens, T_STRING)] = $name;
119
                        } else {
120
                            $tmp = explode('\\', $name);
121
                            $uses[end($tmp)] = $name;
122
                        }
123
                        if (! self::fetch($tokens, ',')) {
0 ignored issues
show
Bug Best Practice introduced by
The expression self::fetch($tokens, ',') of type string|null is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
124
                            break;
125
                        }
126
                    }
127
                    break;
128
129
                case T_CURLY_OPEN:
130
                case T_DOLLAR_OPEN_CURLY_BRACES:
131
                case '{':
132
                    $level++;
133
                    break;
134
135
                case '}':
136
                    if ($level === $classLevel) {
137
                        $class = $classLevel = null;
138
                    }
139
                    $level--;
140
            }
141
        }
142
143
        return $res;
144
    }
145
146
    private static function fetch(&$tokens, $take): ?string
147
    {
148
        $res = null;
149
        while ($token = current($tokens)) {
150
            [$token, $s] = is_array($token) ? $token : [$token, $token];
0 ignored issues
show
Bug introduced by
The variable $s does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
151
            if (in_array($token, (array) $take, true)) {
152
                $res .= $s;
153
            } elseif (! in_array($token, [T_DOC_COMMENT, T_WHITESPACE, T_COMMENT], true)) {
154
                break;
155
            }
156
            next($tokens);
157
        }
158
        return $res;
159
    }
160
}
161