Completed
Pull Request — master (#1)
by David
01:42
created

analyzeWithoutTypehint()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 22
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 22
rs 8.6737
c 0
b 0
f 0
cc 5
eloc 13
nc 5
nop 2
1
<?php
2
declare(strict_types=1);
3
4
namespace TheCodingMachine\PHPStan\Rules\TypeHints;
5
6
7
use BetterReflection\Reflection\ReflectionClass;
8
use BetterReflection\Reflection\ReflectionFunction;
9
use BetterReflection\Reflection\ReflectionMethod;
10
use BetterReflection\Reflection\ReflectionParameter;
11
use TheCodingMachine\PHPStan\BetterReflection\FindReflectionOnLine;
12
use phpDocumentor\Reflection\Type;
13
use phpDocumentor\Reflection\Types\Array_;
14
use phpDocumentor\Reflection\Types\Boolean;
15
use phpDocumentor\Reflection\Types\Callable_;
16
use phpDocumentor\Reflection\Types\Float_;
17
use phpDocumentor\Reflection\Types\Integer;
18
use phpDocumentor\Reflection\Types\Mixed;
19
use phpDocumentor\Reflection\Types\Null_;
20
use phpDocumentor\Reflection\Types\Object_;
21
use phpDocumentor\Reflection\Types\Scalar;
22
use phpDocumentor\Reflection\Types\String_;
23
use PhpParser\Node;
24
use PHPStan\Analyser\Scope;
25
use PHPStan\Broker\Broker;
26
use PHPStan\Rules\Rule;
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
39
        $this->broker = $broker;
40
    }
41
42
    abstract public function getNodeType(): string;
43
44
    /**
45
     * @param ReflectionMethod|ReflectionFunction $reflection
46
     * @return string
47
     */
48
    abstract public function getContext($reflection): string;
49
50
    /**
51
     * @param \PhpParser\Node\Stmt\Function_ $node
52
     * @param \PHPStan\Analyser\Scope $scope
53
     * @return string[]
54
     */
55
    public function processNode(Node $node, Scope $scope): array
56
    {
57
        // TODO: improve performance by caching better reflection results.
58
        $finder = FindReflectionOnLine::buildDefaultFinder();
59
60
        $reflection = $finder($scope->getFile(), $node->getLine());
61
62
        // If the method implements/extends another method, we have no choice on the signature so let's bypass this check.
63
        if ($reflection instanceof ReflectionMethod && $this->isInherited($reflection)) {
0 ignored issues
show
Bug introduced by
The class 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...
64
            return [];
65
        }
66
67
        $errors = [];
68
69
        foreach ($reflection->getParameters() as $parameter) {
70
            $result = $this->analyzeParameter($parameter);
71
72
            if ($result !== null) {
73
                $errors[] = $result;
74
            }
75
        }
76
77
        $returnTypeError = $this->analyzeReturnType($reflection);
78
        if ($returnTypeError !== null) {
79
            $errors[] = $returnTypeError;
80
        }
81
82
        return $errors;
83
    }
84
85
    /**
86
     * Analyzes a parameter and returns the error string if xomething goes wrong or null if everything is ok.
87
     *
88
     * @param ReflectionParameter $parameter
89
     * @return null|string
90
     */
91
    private function analyzeParameter(ReflectionParameter $parameter): ?string
92
    {
93
        $phpTypeHint = $parameter->getTypeHint();
94
        $docBlockTypeHints = $parameter->getDocBlockTypes();
95
96
        // If there is a type-hint, we have nothing to say unless it is an array.
97
        if ($phpTypeHint !== null) {
98
            return $this->analyzeWithTypehint($parameter, $phpTypeHint, $docBlockTypeHints);
99
        } else {
100
            return $this->analyzeWithoutTypehint($parameter, $docBlockTypeHints);
101
        }
102
    }
103
104
    /**
105
     * @param ReflectionFunction|ReflectionMethod $function
106
     * @return null|string
107
     */
108
    private function analyzeReturnType($function): ?string
109
    {
110
        $reflectionPhpTypeHint = $function->getReturnType();
111
        $phpTypeHint = null;
112
        if ($reflectionPhpTypeHint !== null) {
113
            $phpTypeHint = $reflectionPhpTypeHint->getTypeObject();
114
        }
115
        $docBlockTypeHints = $function->getDocBlockReturnTypes();
116
117
        // If there is a type-hint, we have nothing to say unless it is an array.
118
        if ($phpTypeHint !== null) {
119
            return $this->analyzeWithTypehint($function, $phpTypeHint, $docBlockTypeHints);
120
        } else {
121
            return $this->analyzeWithoutTypehint($function, $docBlockTypeHints);
122
        }
123
    }
124
125
    /**
126
     * @param ReflectionParameter|ReflectionMethod|ReflectionFunction $context
127
     * @param Type $phpTypeHint
128
     * @param Type[] $docBlockTypeHints
129
     * @return null|string
130
     */
131
    private function analyzeWithTypehint($context, Type $phpTypeHint, array $docBlockTypeHints): ?string
132
    {
133
        $docblockWithoutNullable = $this->typesWithoutNullable($docBlockTypeHints);
134
135
        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...
136
            // Let's detect mismatches between docblock and PHP typehint
137
            foreach ($docblockWithoutNullable as $docblockTypehint) {
138
                if (get_class($docblockTypehint) !== get_class($phpTypeHint)) {
139
                    if ($context instanceof ReflectionParameter) {
0 ignored issues
show
Bug introduced by
The class BetterReflection\Reflection\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...
140
                        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);
141
                    } else {
142
                        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);
143
                    }
144
                }
145
            }
146
147
            return null;
148
        }
149
150
        if (empty($docblockWithoutNullable)) {
151
            if ($context instanceof ReflectionParameter) {
0 ignored issues
show
Bug introduced by
The class BetterReflection\Reflection\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 "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());
153
            } else {
154
                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));
155
            }
156
        } else {
157
            foreach ($docblockWithoutNullable as $docblockTypehint) {
158
                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...
159
                    if ($context instanceof ReflectionParameter) {
0 ignored issues
show
Bug introduced by
The class BetterReflection\Reflection\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...
160
                        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);
161
                    } else {
162
                        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);
163
                    }
164
                }
165
166
                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...
167
                    if ($context instanceof ReflectionParameter) {
0 ignored issues
show
Bug introduced by
The class BetterReflection\Reflection\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...
168
                        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());
169
                    } else {
170
                        return sprintf('%s, return type is "array". Please provide a more specific @return annotation. For instance: @return int[]', $this->getContext($context));
171
                    }
172
                }
173
            }
174
        }
175
176
        return null;
177
    }
178
179
    /**
180
     * @param ReflectionParameter|ReflectionMethod|ReflectionFunction $context
181
     * @param Type[] $docBlockTypeHints
182
     * @return null|string
183
     */
184
    private function analyzeWithoutTypehint($context, array $docBlockTypeHints): ?string
185
    {
186
        if (empty($docBlockTypeHints)) {
187
            if ($context instanceof ReflectionParameter) {
0 ignored issues
show
Bug introduced by
The class BetterReflection\Reflection\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...
188
                return sprintf('%s, parameter $%s has no type-hint and no @param annotation.', $this->getContext($context), $context->getName());
189
            } else {
190
                return sprintf('%s, there is no return type and no @return annotation.', $this->getContext($context));
191
            }
192
        }
193
194
        $nativeTypehint = $this->isNativelyTypehintable($docBlockTypeHints);
195
196
        if ($nativeTypehint !== null) {
197
            if ($context instanceof ReflectionParameter) {
0 ignored issues
show
Bug introduced by
The class BetterReflection\Reflection\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...
198
                return sprintf('%s, parameter $%s can be type-hinted to "%s".', $this->getContext($context), $context->getName(), $nativeTypehint);
199
            } else {
200
                return sprintf('%s, a "%s" return type can be added.', $this->getContext($context), $nativeTypehint);
201
            }
202
        }
203
204
        return null;
205
    }
206
207
    /**
208
     * @param Type[] $docBlockTypeHints
209
     * @return string|null
210
     */
211
    private function isNativelyTypehintable(array $docBlockTypeHints): ?string
212
    {
213
        if (count($docBlockTypeHints) > 2) {
214
            return null;
215
        }
216
        $isNullable = $this->isNullable($docBlockTypeHints);
217
        if (count($docBlockTypeHints) === 2 && !$isNullable) {
218
            return null;
219
        }
220
221
        $types = $this->typesWithoutNullable($docBlockTypeHints);
222
        // At this point, there is at most one element here
223
        if (empty($types)) {
224
            return null;
225
        }
226
227
        $type = $types[0];
228
229
        if ($this->isNativeType($type)) {
230
            return ($isNullable?'?':'').((string)$type);
231
        }
232
233
        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...
234
            return ($isNullable?'?':'').'array';
235
        }
236
237
        // TODO: more definitions to add here
238
        // Manage interface/classes
239
        // Manage array of things => (cast to array)
240
241
        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...
242
            return ($isNullable?'?':'').((string)$type);
243
        }
244
245
        return null;
246
    }
247
248
    private function isNativeType(Type $type): bool
249
    {
250
        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...
251
            || $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...
252
            || $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...
253
            || $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...
254
            || $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...
255
            || $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...
256
            || ((string) $type) === 'iterable'
257
        ) {
258
            return true;
259
        }
260
        return false;
261
    }
262
263
    /**
264
     * @param Type[] $docBlockTypeHints
265
     * @return bool
266
     */
267
    private function isNullable(array $docBlockTypeHints): bool
268
    {
269
        foreach ($docBlockTypeHints as $docBlockTypeHint) {
270
            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...
271
                return true;
272
            }
273
        }
274
        return false;
275
    }
276
277
    /**
278
     * Removes "null" from the list of types.
279
     *
280
     * @param Type[] $docBlockTypeHints
281
     * @return array
282
     */
283
    private function typesWithoutNullable(array $docBlockTypeHints): array
284
    {
285
        return array_filter($docBlockTypeHints, function($item) {
286
            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...
287
        });
288
    }
289
290
    private function isInherited(ReflectionMethod $method, ReflectionClass $class = null): bool
291
    {
292
        if ($class === null) {
293
            $class = $method->getDeclaringClass();
294
        }
295
        $interfaces = $class->getInterfaces();
296
        foreach ($interfaces as $interface) {
297
            if ($interface->hasMethod($method->getName())) {
298
                return true;
299
            }
300
        }
301
302
        $parentClass = $class->getParentClass();
303
        if ($parentClass !== null) {
304
            return $this->isInherited($method, $parentClass);
305
        }
306
307
        return false;
308
    }
309
}
310