Completed
Pull Request — master (#5)
by David
02:12
created

AbstractMissingTypeHintRule::isNativeType()   B

Complexity

Conditions 8
Paths 2

Size

Total Lines 14
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 14
rs 7.7777
c 0
b 0
f 0
cc 8
eloc 10
nc 2
nop 1
1
<?php
2
declare(strict_types=1);
3
4
namespace TheCodingMachine\PHPStan\Rules\TypeHints;
5
6
7
use phpDocumentor\Reflection\Type;
8
use phpDocumentor\Reflection\Types\Array_;
9
use phpDocumentor\Reflection\Types\Boolean;
10
use phpDocumentor\Reflection\Types\Callable_;
11
use phpDocumentor\Reflection\Types\Float_;
12
use phpDocumentor\Reflection\Types\Integer;
13
use phpDocumentor\Reflection\Types\Mixed;
14
use phpDocumentor\Reflection\Types\Null_;
15
use phpDocumentor\Reflection\Types\Object_;
16
use phpDocumentor\Reflection\Types\Scalar;
17
use phpDocumentor\Reflection\Types\String_;
18
use PhpParser\Node;
19
use PHPStan\Analyser\Scope;
20
use PHPStan\Broker\Broker;
21
use PHPStan\Rules\Rule;
22
use Roave\BetterReflection\Reflection\ReflectionClass;
23
use Roave\BetterReflection\Reflection\ReflectionFunction;
24
use Roave\BetterReflection\Reflection\ReflectionMethod;
25
use Roave\BetterReflection\Reflection\ReflectionParameter;
26
use Roave\BetterReflection\Util\FindReflectionOnLine;
27
28
abstract class AbstractMissingTypeHintRule implements Rule
29
{
30
31
    /**
32
     * @var Broker
33
     */
34
    private $broker;
35
36
    public function __construct(Broker $broker)
37
    {
38
        $this->broker = $broker;
39
    }
40
41
    abstract public function getNodeType(): string;
42
43
    /**
44
     * @param ReflectionMethod|ReflectionFunction $reflection
45
     * @return string
46
     */
47
    abstract public function getContext($reflection): string;
48
49
    abstract public function isReturnIgnored(Node $node): bool;
50
51
    /**
52
     * @param \PhpParser\Node\Stmt\Function_|\PhpParser\Node\Stmt\ClassMethod $node
53
     * @param \PHPStan\Analyser\Scope $scope
54
     * @return string[]
55
     */
56
    public function processNode(Node $node, Scope $scope): array
57
    {
58
        // TODO: improve performance by caching better reflection results.
59
        $finder = FindReflectionOnLine::buildDefaultFinder();
60
61
        if ($node->getLine() < 0) {
62
            // Fixes some problems with methods in anonymous class (the line number is poorly reported).
63
            return [];
64
        }
65
66
        $reflection = $finder($scope->getFile(), $node->getLine());
67
68
        // If the method implements/extends another method, we have no choice on the signature so let's bypass this check.
69
        if ($reflection instanceof ReflectionMethod && $this->isInherited($reflection)) {
0 ignored issues
show
Bug introduced by
The class Roave\BetterReflection\Reflection\ReflectionMethod does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
70
            return [];
71
        }
72
73
        $errors = [];
74
75
        if ($reflection === null) {
76
            throw new \RuntimeException('Could not find item at '.$scope->getFile().':'.$node->getLine());
77
        }
78
79
        foreach ($reflection->getParameters() as $parameter) {
80
            $result = $this->analyzeParameter($parameter);
81
82
            if ($result !== null) {
83
                $errors[] = $result;
84
            }
85
        }
86
87
        if (!$this->isReturnIgnored($node)) {
88
            $returnTypeError = $this->analyzeReturnType($reflection);
89
            if ($returnTypeError !== null) {
90
                $errors[] = $returnTypeError;
91
            }
92
        }
93
94
        return $errors;
95
    }
96
97
    /**
98
     * Analyzes a parameter and returns the error string if xomething goes wrong or null if everything is ok.
99
     *
100
     * @param ReflectionParameter $parameter
101
     * @return null|string
102
     */
103
    private function analyzeParameter(ReflectionParameter $parameter): ?string
104
    {
105
        $phpTypeHint = $parameter->getTypeHint();
106
        $docBlockTypeHints = $parameter->getDocBlockTypes();
107
108
        // If there is a type-hint, we have nothing to say unless it is an array.
109
        if ($phpTypeHint !== null) {
110
            return $this->analyzeWithTypehint($parameter, $phpTypeHint, $docBlockTypeHints);
111
        } else {
112
            return $this->analyzeWithoutTypehint($parameter, $docBlockTypeHints);
113
        }
114
    }
115
116
    /**
117
     * @param ReflectionFunction|ReflectionMethod $function
118
     * @return null|string
119
     */
120
    private function analyzeReturnType($function): ?string
121
    {
122
        $reflectionPhpTypeHint = $function->getReturnType();
123
        $phpTypeHint = null;
124
        if ($reflectionPhpTypeHint !== null) {
125
            $phpTypeHint = $reflectionPhpTypeHint->getTypeObject();
126
        }
127
        $docBlockTypeHints = $function->getDocBlockReturnTypes();
128
129
        // If there is a type-hint, we have nothing to say unless it is an array.
130
        if ($phpTypeHint !== null) {
131
            return $this->analyzeWithTypehint($function, $phpTypeHint, $docBlockTypeHints);
132
        } else {
133
            return $this->analyzeWithoutTypehint($function, $docBlockTypeHints);
134
        }
135
    }
136
137
    /**
138
     * @param ReflectionParameter|ReflectionMethod|ReflectionFunction $context
139
     * @param Type $phpTypeHint
140
     * @param Type[] $docBlockTypeHints
141
     * @return null|string
142
     */
143
    private function analyzeWithTypehint($context, Type $phpTypeHint, array $docBlockTypeHints): ?string
144
    {
145
        $docblockWithoutNullable = $this->typesWithoutNullable($docBlockTypeHints);
146
147
        if (!$phpTypeHint instanceof Array_) {
0 ignored issues
show
Bug introduced by
The class phpDocumentor\Reflection\Types\Array_ does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
148
            // Let's detect mismatches between docblock and PHP typehint
149
            foreach ($docblockWithoutNullable as $docblockTypehint) {
150
                if (get_class($docblockTypehint) !== get_class($phpTypeHint)) {
151
                    if ($context instanceof ReflectionParameter) {
0 ignored issues
show
Bug introduced by
The class Roave\BetterReflection\R...ion\ReflectionParameter does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
152
                        return sprintf('%s, parameter $%s type is type-hinted to "%s" but the @param annotation says it is a "%s". Please fix the @param annotation.', $this->getContext($context), $context->getName(), (string) $phpTypeHint, (string) $docblockTypehint);
153
                    } else {
154
                        return sprintf('%s, return type is type-hinted to "%s" but the @return annotation says it is a "%s". Please fix the @return annotation.', $this->getContext($context), (string) $phpTypeHint, (string) $docblockTypehint);
155
                    }
156
                }
157
            }
158
159
            return null;
160
        }
161
162
        if (empty($docblockWithoutNullable)) {
163
            if ($context instanceof ReflectionParameter) {
0 ignored issues
show
Bug introduced by
The class Roave\BetterReflection\R...ion\ReflectionParameter does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
164
                return sprintf('%s, parameter $%s type is "array". Please provide a @param annotation to further specify the type of the array. For instance: @param int[] $%s', $this->getContext($context), $context->getName(), $context->getName());
165
            } else {
166
                return sprintf('%s, return type is "array". Please provide a @param annotation to further specify the type of the array. For instance: @return int[]', $this->getContext($context));
167
            }
168
        } else {
169
            foreach ($docblockWithoutNullable as $docblockTypehint) {
170
                if (!$docblockTypehint instanceof Array_) {
0 ignored issues
show
Bug introduced by
The class phpDocumentor\Reflection\Types\Array_ does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
171
                    if ($context instanceof ReflectionParameter) {
0 ignored issues
show
Bug introduced by
The class Roave\BetterReflection\R...ion\ReflectionParameter does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
172
                        return sprintf('%s, mismatching type-hints for parameter %s. PHP type hint is "array" and docblock type hint is %s.', $this->getContext($context), $context->getName(), (string)$docblockTypehint);
173
                    } else {
174
                        return sprintf('%s, mismatching type-hints for return type. PHP type hint is "array" and docblock declared return type is %s.', $this->getContext($context), (string)$docblockTypehint);
175
                    }
176
                }
177
178
                if ($docblockTypehint->getValueType() instanceof Mixed) {
0 ignored issues
show
Bug introduced by
The class phpDocumentor\Reflection\Types\Mixed does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
179
                    if ($context instanceof ReflectionParameter) {
0 ignored issues
show
Bug introduced by
The class Roave\BetterReflection\R...ion\ReflectionParameter does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
180
                        return sprintf('%s, parameter $%s type is "array". Please provide a more specific @param annotation. For instance: @param int[] $%s', $this->getContext($context), $context->getName(), $context->getName());
181
                    } else {
182
                        return sprintf('%s, return type is "array". Please provide a more specific @return annotation. For instance: @return int[]', $this->getContext($context));
183
                    }
184
                }
185
            }
186
        }
187
188
        return null;
189
    }
190
191
    /**
192
     * @param ReflectionParameter|ReflectionMethod|ReflectionFunction $context
193
     * @param Type[] $docBlockTypeHints
194
     * @return null|string
195
     */
196
    private function analyzeWithoutTypehint($context, array $docBlockTypeHints): ?string
197
    {
198
        if (empty($docBlockTypeHints)) {
199
            if ($context instanceof ReflectionParameter) {
0 ignored issues
show
Bug introduced by
The class Roave\BetterReflection\R...ion\ReflectionParameter does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
200
                return sprintf('%s, parameter $%s has no type-hint and no @param annotation.', $this->getContext($context), $context->getName());
201
            } else {
202
                return sprintf('%s, there is no return type and no @return annotation.', $this->getContext($context));
203
            }
204
        }
205
206
        $nativeTypehint = $this->isNativelyTypehintable($docBlockTypeHints);
207
208
        if ($nativeTypehint !== null) {
209
            if ($context instanceof ReflectionParameter) {
0 ignored issues
show
Bug introduced by
The class Roave\BetterReflection\R...ion\ReflectionParameter does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
210
                return sprintf('%s, parameter $%s can be type-hinted to "%s".', $this->getContext($context), $context->getName(), $nativeTypehint);
211
            } else {
212
                return sprintf('%s, a "%s" return type can be added.', $this->getContext($context), $nativeTypehint);
213
            }
214
        }
215
216
        return null;
217
    }
218
219
    /**
220
     * @param Type[] $docBlockTypeHints
221
     * @return string|null
222
     */
223
    private function isNativelyTypehintable(array $docBlockTypeHints): ?string
224
    {
225
        if (count($docBlockTypeHints) > 2) {
226
            return null;
227
        }
228
        $isNullable = $this->isNullable($docBlockTypeHints);
229
        if (count($docBlockTypeHints) === 2 && !$isNullable) {
230
            return null;
231
        }
232
233
        $types = $this->typesWithoutNullable($docBlockTypeHints);
234
        // At this point, there is at most one element here
235
        if (empty($types)) {
236
            return null;
237
        }
238
239
        $type = $types[0];
240
241
        if ($this->isNativeType($type)) {
242
            return ($isNullable?'?':'').((string)$type);
243
        }
244
245
        if ($type instanceof Array_) {
0 ignored issues
show
Bug introduced by
The class phpDocumentor\Reflection\Types\Array_ does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
246
            return ($isNullable?'?':'').'array';
247
        }
248
249
        // TODO: more definitions to add here
250
        // Manage interface/classes
251
        // Manage array of things => (cast to array)
252
253
        if ($type instanceof Object_) {
0 ignored issues
show
Bug introduced by
The class phpDocumentor\Reflection\Types\Object_ does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
254
            return ($isNullable?'?':'').((string)$type);
255
        }
256
257
        return null;
258
    }
259
260
    private function isNativeType(Type $type): bool
261
    {
262
        if ($type instanceof String_
0 ignored issues
show
Bug introduced by
The class phpDocumentor\Reflection\Types\String_ does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
263
            || $type instanceof Integer
0 ignored issues
show
Bug introduced by
The class phpDocumentor\Reflection\Types\Integer does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
264
            || $type instanceof Boolean
0 ignored issues
show
Bug introduced by
The class phpDocumentor\Reflection\Types\Boolean does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
265
            || $type instanceof Float_
0 ignored issues
show
Bug introduced by
The class phpDocumentor\Reflection\Types\Float_ does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
266
            || $type instanceof Scalar
0 ignored issues
show
Bug introduced by
The class phpDocumentor\Reflection\Types\Scalar does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
267
            || $type instanceof Callable_
0 ignored issues
show
Bug introduced by
The class phpDocumentor\Reflection\Types\Callable_ does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
268
            || ((string) $type) === 'iterable'
269
        ) {
270
            return true;
271
        }
272
        return false;
273
    }
274
275
    /**
276
     * @param Type[] $docBlockTypeHints
277
     * @return bool
278
     */
279
    private function isNullable(array $docBlockTypeHints): bool
280
    {
281
        foreach ($docBlockTypeHints as $docBlockTypeHint) {
282
            if ($docBlockTypeHint instanceof Null_) {
0 ignored issues
show
Bug introduced by
The class phpDocumentor\Reflection\Types\Null_ does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
283
                return true;
284
            }
285
        }
286
        return false;
287
    }
288
289
    /**
290
     * Removes "null" from the list of types.
291
     *
292
     * @param Type[] $docBlockTypeHints
293
     * @return Type[]
294
     */
295
    private function typesWithoutNullable(array $docBlockTypeHints): array
296
    {
297
        return array_filter($docBlockTypeHints, function($item) {
298
            return !$item instanceof Null_;
0 ignored issues
show
Bug introduced by
The class phpDocumentor\Reflection\Types\Null_ does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
299
        });
300
    }
301
302
    private function isInherited(ReflectionMethod $method, ReflectionClass $class = null): bool
303
    {
304
        if ($class === null) {
305
            $class = $method->getDeclaringClass();
306
        }
307
        $interfaces = $class->getInterfaces();
308
        foreach ($interfaces as $interface) {
309
            if ($interface->hasMethod($method->getName())) {
310
                return true;
311
            }
312
        }
313
314
        $parentClass = $class->getParentClass();
315
        if ($parentClass !== null) {
316
            return $this->isInherited($method, $parentClass);
317
        }
318
319
        return false;
320
    }
321
}
322