Completed
Pull Request — master (#27)
by David
11:28
created

MissingTypeHintInFunctionRule::getReflection()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 14
rs 9.7998
c 0
b 0
f 0
nc 4
cc 3
nop 3
1
<?php
2
3
4
namespace TheCodingMachine\PHPStan\Rules\TypeHints;
5
6
use PHPStan\Analyser\Scope;
7
use PHPStan\Broker\Broker;
8
use PHPStan\Reflection\ParametersAcceptorSelector;
9
use PHPStan\Reflection\ParametersAcceptorWithPhpDocs;
10
use PHPStan\Reflection\Php\PhpParameterReflection;
11
use Roave\BetterReflection\Reflection\ReflectionFunction;
12
use Roave\BetterReflection\Reflection\ReflectionFunctionAbstract;
13
use Roave\BetterReflection\Reflection\ReflectionMethod;
14
use Roave\BetterReflection\Reflection\ReflectionParameter;
15
use PhpParser\Node;
16
17
class MissingTypeHintInFunctionRule extends AbstractMissingTypeHintRule
18
{
19
    public function getNodeType(): string
20
    {
21
        return Node\Stmt\Function_::class;
22
    }
23
24
    public function isReturnIgnored(Node $node): bool
25
    {
26
        return false;
27
    }
28
29
    protected function getReflection(Node\FunctionLike $function, Scope $scope, Broker $broker) : ParametersAcceptorWithPhpDocs
30
    {
31
        $functionName = $function->name->name;
0 ignored issues
show
Bug introduced by
Accessing name on the interface PhpParser\Node\FunctionLike suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
32
        if (isset($function->namespacedName)) {
0 ignored issues
show
Bug introduced by
Accessing namespacedName on the interface PhpParser\Node\FunctionLike suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
33
            $functionName = (string) $function->namespacedName;
0 ignored issues
show
Bug introduced by
Accessing namespacedName on the interface PhpParser\Node\FunctionLike suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
34
        }
35
        $functionNameName = new Node\Name($functionName);
36
        if (!$broker->hasCustomFunction($functionNameName, null)) {
37
            throw new \RuntimeException("Cannot find function '$functionName'");
38
        }
39
        $functionReflection = $broker->getCustomFunction($functionNameName, null);
40
        /** @var \PHPStan\Reflection\ParametersAcceptorWithPhpDocs $parametersAcceptor */
41
        return ParametersAcceptorSelector::selectSingle($functionReflection->getVariants());
42
    }
43
44
    protected function shouldSkip(Node\FunctionLike $function, Scope $scope): bool
45
    {
46
        return false;
47
    }
48
}
49