Completed
Push — master ( fd7b1f...70ced9 )
by Rasmus
21s queued 14s
created

Reflection   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 69
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 1

Test Coverage

Coverage 76%

Importance

Changes 0
Metric Value
wmc 13
lcom 0
cbo 1
dl 0
loc 69
ccs 19
cts 25
cp 0.76
rs 10
c 0
b 0
f 0

2 Methods

Rating   Name   Duplication   Size   Complexity  
B createFromCallable() 0 22 7
B getParameterType() 0 20 6
1
<?php
2
3
namespace mindplay\unbox;
4
5
use Closure;
6
use ReflectionFunction;
7
use ReflectionFunctionAbstract;
8
use ReflectionMethod;
9
use ReflectionParameter;
10
11
/**
12
 * Pseudo-namespace for some common reflection helper-functions.
13
 */
14
abstract class Reflection
15
{
16
    /**
17
     * @type string pattern for parsing an argument type from a ReflectionParameter string
18
     *
19
     * @see Reflection::getParameterType()
20
     */
21
    const ARG_PATTERN = '/(?:\<required\>|\<optional\>)\\s+([\\w\\\\]+)/';
22
23
    /**
24
     * Create a Reflection of the function references by any type of callable (or object implementing `__invoke()`)
25
     *
26
     * @param callable|object $callback
27
     *
28
     * @return ReflectionFunctionAbstract
29
     *
30
     * @throws InvalidArgumentException
31
     */
32 1
    public static function createFromCallable($callback)
33
    {
34 1
        if (is_object($callback)) {
35 1
            if ($callback instanceof Closure) {
36 1
                return new ReflectionFunction($callback);
37 1
            } elseif (method_exists($callback, '__invoke')) {
38 1
                return new ReflectionMethod($callback, '__invoke');
39
            }
40
41 1
            throw new InvalidArgumentException("class " . get_class($callback) . " does not implement __invoke()");
42 1
        } elseif (is_array($callback)) {
43 1
            if (is_callable($callback)) {
44 1
                return new ReflectionMethod($callback[0], $callback[1]);
45
            }
46
47 1
            throw new InvalidArgumentException("expected callable");
48 1
        } elseif (is_callable($callback)) {
49 1
            return new ReflectionFunction($callback);
50
        }
51
52 1
        throw new InvalidArgumentException("unexpected value: " . var_export($callback, true) . " - expected callable");
53
    }
54
55
    /**
56
     * Obtain the type-hint of a `ReflectionParameter`, but avoid triggering autoload (as a performance optimization)
57
     *
58
     * @param ReflectionParameter $param
59
     *
60
     * @return string|null fully-qualified type-name (or NULL, if no type-hint was available)
61
     */
62 1
    public static function getParameterType(ReflectionParameter $param)
63
    {
64 1
        if (method_exists($param, "getType")) {
65
            $type = $param->getType();
66
67
            if ($type === null || $type->isBuiltin()) {
68
                return null; // ignore scalar type-hints
69
            }
70
71
            return method_exists($type, "getName")
72
                ? $type->getName() // PHP >= 7.1
73
                : $type->__toString(); // PHP < 7.1
74
        }
75
76 1
        if (preg_match(self::ARG_PATTERN, $param->__toString(), $matches) === 1) {
77 1
            return $matches[1];
78
        }
79
80 1
        return null; // no type-hint is available
81
    }
82
}
83