Completed
Pull Request — master (#7)
by Rasmus
04:28
created

Reflection   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 55
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 0

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 9
c 1
b 0
f 0
lcom 0
cbo 0
dl 0
loc 55
ccs 18
cts 18
cp 1
rs 10

2 Methods

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