Completed
Push — master ( 7deb21...253768 )
by Alexander
03:07
created

ReflectionMethod::__debugInfo()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 1
Bugs 1 Features 0
Metric Value
c 1
b 1
f 0
dl 0
loc 7
ccs 0
cts 4
cp 0
rs 9.4286
cc 1
eloc 4
nc 1
nop 0
crap 2
1
<?php
2
/**
3
 * Parser Reflection API
4
 *
5
 * @copyright Copyright 2015, Lisachenko Alexander <[email protected]>
6
 *
7
 * This source file is subject to the license that is bundled
8
 * with this source code in the file LICENSE.
9
 */
10
11
namespace Go\ParserReflection;
12
13
use Go\ParserReflection\Traits\ReflectionFunctionLikeTrait;
14
use PhpParser\Node\Stmt\ClassMethod;
15
use ReflectionMethod as BaseReflectionMethod;
16
17
/**
18
 * AST-based reflection for the method in a class
19
 */
20
class ReflectionMethod extends BaseReflectionMethod
21
{
22
    use ReflectionFunctionLikeTrait;
23
24
    /**
25
     * Name of the class
26
     *
27
     * @var string
28
     */
29
    private $className;
30
31
    /**
32
     * Initializes reflection instance for the method node
33
     *
34
     * @param string $className Name of the class
35
     * @param string $methodName Name of the method
36
     * @param ClassMethod $classMethodNode AST-node for method
37
     */
38 4
    public function __construct($className, $methodName, ClassMethod $classMethodNode = null)
39
    {
40
        //for some reason, ReflectionMethod->getNamespaceName in php always returns '', so we shouldn't use it too
41 4
        $this->className        = $className;
42 4
        $this->functionLikeNode = $classMethodNode ?: ReflectionEngine::parseClassMethod($className, $methodName);
43 4
    }
44
45
    /**
46
     * Emulating original behaviour of reflection
47
     */
48
    public function __debugInfo()
49
    {
50
        return [
51
            'name'  => $this->getClassMethodNode()->name,
52
            'class' => $this->className
53
        ];
54
    }
55
56
    /**
57
     * Returns the string representation of the Reflection method object.
58
     *
59
     * @link http://php.net/manual/en/reflectionmethod.tostring.php
60
     *
61
     * @return string
62
     */
63 1
    public function __toString()
64
    {
65 1
        $paramFormat      = ($this->getNumberOfParameters() > 0) ? "\n\n  - Parameters [%d] {%s\n  }" : '';
66 1
        $methodParameters = $this->getParameters();
67
68 1
        $paramString = '';
69 1
        $identation  = str_repeat(' ', 4);
70 1
        foreach ($methodParameters as $methodParameter) {
71 1
            $paramString .= "\n{$identation}" . $methodParameter;
72 1
        }
73
74 1
        return sprintf(
75 1
            "%sMethod [ <user%s%s>%s%s%s %s method %s ] {\n  @@ %s %d - %d{$paramFormat}\n}\n",
76 1
            $this->getDocComment() ? $this->getDocComment() . "\n" : '',
77 1
            $this->isConstructor() ? ', ctor' : '',
78 1
            $this->isDestructor() ? ', dtor' : '',
79 1
            $this->isFinal() ? ' final' : '',
80 1
            $this->isStatic() ? ' static' : '',
81 1
            $this->isAbstract() ? ' abstract' : '',
82 1
            join(' ', \Reflection::getModifierNames($this->getModifiers() & 1792)),
83 1
            $this->getName(),
84 1
            $this->getFileName(),
85 1
            $this->getStartLine(),
86 1
            $this->getEndLine(),
87 1
            count($methodParameters),
88
            $paramString
89 1
        );
90
    }
91
92
    /**
93
     * {@inheritDoc}
94
     */
95
    public function getClosure($object)
96
    {
97
        $this->initializeInternalReflection();
98
99
        return parent::getClosure($object);
100
    }
101
102
    /**
103
     * {@inheritDoc}
104
     */
105 2
    public function getDeclaringClass()
106
    {
107 2
        return new ReflectionClass($this->className);
108
    }
109
110
    /**
111
     * {@inheritDoc}
112
     */
113 1
    public function getModifiers()
114
    {
115 1
        $modifiers = 0;
116 1
        if ($this->isPublic()) {
117 1
            $modifiers += self::IS_PUBLIC;
118 1
        }
119 1
        if ($this->isProtected()) {
120 1
            $modifiers += self::IS_PROTECTED;
121 1
        }
122 1
        if ($this->isPrivate()) {
123 1
            $modifiers += self::IS_PRIVATE;
124 1
        }
125 1
        if ($this->isAbstract()) {
126 1
            $modifiers += self::IS_ABSTRACT;
127 1
        }
128 1
        if ($this->isFinal()) {
129 1
            $modifiers += self::IS_FINAL;
130 1
        }
131 1
        if ($this->isStatic()) {
132 1
            $modifiers += self::IS_STATIC;
133 1
        }
134
135 1
        return $modifiers;
136
    }
137
138
    /**
139
     * {@inheritDoc}
140
     */
141
    public function getPrototype()
142
    {
143
        $parent = $this->getDeclaringClass()->getParentClass();
144
        if (!$parent) {
145
            throw new ReflectionException("No prototype");
146
        }
147
148
        $prototypeMethod = $parent->getMethod($this->getName());
149
        if (!$prototypeMethod) {
150
            throw new ReflectionException("No prototype");
151
        }
152
153
        return $prototypeMethod;
154
    }
155
156
    /**
157
     * {@inheritDoc}
158
     */
159
    public function invoke($object, $args = null)
160
    {
161
        $this->initializeInternalReflection();
162
163
        return call_user_func_array('parent::invoke', func_get_args());
164
    }
165
166
    /**
167
     * {@inheritDoc}
168
     */
169
    public function invokeArgs($object, array $args)
170
    {
171
        $this->initializeInternalReflection();
172
173
        return parent::invokeArgs($object, $args);
174
    }
175
176
    /**
177
     * {@inheritDoc}
178
     */
179 1
    public function isAbstract()
180
    {
181 1
        return $this->getClassMethodNode()->isAbstract();
182
    }
183
184
    /**
185
     * {@inheritDoc}
186
     */
187 1
    public function isConstructor()
188
    {
189 1
        return $this->getClassMethodNode()->name == '__construct';
190
    }
191
192
    /**
193
     * {@inheritDoc}
194
     */
195 1
    public function isDestructor()
196
    {
197 1
        return $this->getClassMethodNode()->name == '__destruct';
198
    }
199
200
    /**
201
     * {@inheritDoc}
202
     */
203 1
    public function isFinal()
204
    {
205 1
        return $this->getClassMethodNode()->isFinal();
206
    }
207
208
    /**
209
     * {@inheritDoc}
210
     */
211 1
    public function isPrivate()
212
    {
213 1
        return $this->getClassMethodNode()->isPrivate();
214
    }
215
216
    /**
217
     * {@inheritDoc}
218
     */
219 1
    public function isProtected()
220
    {
221 1
        return $this->getClassMethodNode()->isProtected();
222
    }
223
224
    /**
225
     * {@inheritDoc}
226
     */
227 2
    public function isPublic()
228
    {
229 2
        return $this->getClassMethodNode()->isPublic();
230
    }
231
232
    /**
233
     * {@inheritDoc}
234
     */
235 1
    public function isStatic()
236
    {
237 1
        return $this->getClassMethodNode()->isStatic();
238
    }
239
240
    /**
241
     * {@inheritDoc}
242
     */
243
    public function setAccessible($accessible)
244
    {
245
        $this->initializeInternalReflection();
246
247
        parent::setAccessible($accessible);
248
    }
249
250
    /**
251
     * Implementation of internal reflection initialization
252
     *
253
     * @return void
254
     */
255
    protected function __initialize()
256
    {
257
        parent::__construct($this->className, $this->getName());
258
    }
259
260
    /**
261
     * Returns ClassMethod node to prevent all possible type checks with instanceof
262
     *
263
     * @return ClassMethod
264
     */
265 2
    private function getClassMethodNode()
266
    {
267 2
        return $this->functionLikeNode;
268
    }
269
}
270