Completed
Push — master ( 3db5e1...c1cd20 )
by Alexander
02:24
created

ReflectionFunctionLikeTrait::getClosureThis()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1
Metric Value
dl 0
loc 6
ccs 3
cts 3
cp 1
rs 9.4286
cc 1
eloc 3
nc 1
nop 0
crap 1
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\Traits;
12
13
14
use Go\ParserReflection\NodeVisitor\GeneratorDetector;
15
use Go\ParserReflection\NodeVisitor\StaticVariablesCollector;
16
use Go\ParserReflection\ReflectionFileNamespace;
17
use Go\ParserReflection\ReflectionParameter;
18
use PhpParser\Node\Expr\Closure;
19
use PhpParser\Node\FunctionLike;
20
use PhpParser\Node\Stmt\ClassMethod;
21
use PhpParser\Node\Stmt\Function_;
22
use PhpParser\NodeTraverser;
23
24
/**
25
 * General trait for all function-like reflections
26
 */
27
trait ReflectionFunctionLikeTrait
28
{
29
    use InitializationTrait;
30
31
    /**
32
     * @var FunctionLike
33
     */
34
    protected $functionLikeNode;
35
36
    /**
37
     * Namespace name
38
     *
39
     * @var string
40
     */
41
    protected $namespaceName = '';
42
43
    /**
44
     * @var array|ReflectionParameter[]
45
     */
46
    protected $parameters;
47
48
    /**
49
     * {@inheritDoc}
50
     */
51 2
    public function getClosureScopeClass()
52
    {
53 2
        $this->initializeInternalReflection();
54
55 2
        return forward_static_call('parent::getClosureScopeClass');
56
    }
57
58
    /**
59
     * {@inheritDoc}
60
     */
61 2
    public function getClosureThis()
62
    {
63 2
        $this->initializeInternalReflection();
64
65 2
        return forward_static_call('parent::getClosureThis');
66
    }
67
68 2
    public function getDocComment()
69
    {
70 2
        $docComment = $this->functionLikeNode->getDocComment();
71
72 2
        return $docComment ? $docComment->getText() : false;
73
    }
74
75 2
    public function getEndLine()
76
    {
77 2
        return $this->functionLikeNode->getAttribute('endLine');
78
    }
79
80 2
    public function getExtension()
81
    {
82 2
        return null;
83
    }
84
85 2
    public function getExtensionName()
86
    {
87 2
        return false;
88
    }
89
90 8
    public function getFileName()
91
    {
92 8
        return $this->functionLikeNode->getAttribute('fileName');
93
    }
94
95
    /**
96
     * {@inheritDoc}
97
     */
98 21
    public function getName()
99
    {
100 21
        if ($this->functionLikeNode instanceof Function_ || $this->functionLikeNode instanceof ClassMethod) {
101 21
            $functionName = $this->functionLikeNode->name;
102
103 21
            return $this->namespaceName ? $this->namespaceName . '\\' . $functionName : $functionName;
104
        }
105
106
        return false;
107
    }
108
109
    /**
110
     * {@inheritDoc}
111
     */
112 8
    public function getNamespaceName()
113
    {
114 8
        return $this->namespaceName;
115
    }
116
117
    /**
118
     * Get the number of parameters that a function defines, both optional and required.
119
     *
120
     * @link http://php.net/manual/en/reflectionfunctionabstract.getnumberofparameters.php
121
     *
122
     * @return int
123
     */
124 2
    public function getNumberOfParameters()
125
    {
126 2
        return count($this->functionLikeNode->getParams());
127
    }
128
129
    /**
130
     * Get the number of required parameters that a function defines.
131
     *
132
     * @link http://php.net/manual/en/reflectionfunctionabstract.getnumberofrequiredparameters.php
133
     *
134
     * @return int
135
     */
136 2
    public function getNumberOfRequiredParameters()
137
    {
138 2
        $requiredParameters = 0;
139 2
        foreach ($this->getParameters() as $parameter) {
140 2
            if (!$parameter->isOptional()) {
141 2
                $requiredParameters++;
142 2
            }
143 2
        }
144
145 2
        return $requiredParameters;
146
    }
147
148
    /**
149
     * {@inheritDoc}
150
     */
151 9
    public function getParameters()
152
    {
153 9
        if (!isset($this->parameters)) {
154 9
            $parameters = [];
155
156 9
            foreach ($this->functionLikeNode->getParams() as $parameterIndex => $parameterNode) {
157 9
                $reflectionParameter = new ReflectionParameter(
158 9
                    $this->getName(),
159 9
                    $parameterNode->name,
160 9
                    $parameterNode,
161 9
                    $parameterIndex,
162
                    $this
163 9
                );
164 9
                $parameters[] = $reflectionParameter;
165 9
            }
166
167 9
            $this->parameters = $parameters;
168 9
        }
169
170 9
        return $this->parameters;
171
    }
172
173
    /**
174
     * {@inheritDoc}
175
     */
176 2
    public function getShortName()
177
    {
178 2
        if ($this->functionLikeNode instanceof Function_ || $this->functionLikeNode instanceof ClassMethod) {
179 2
            return $this->functionLikeNode->name;
180
        }
181
182
        return false;
183
    }
184
185 2
    public function getStartLine()
186
    {
187 2
        return $this->functionLikeNode->getAttribute('startLine');
188
    }
189
190
    /**
191
     * {@inheritDoc}
192
     */
193 2
    public function getStaticVariables()
194
    {
195 2
        $nodeTraverser      = new NodeTraverser(false);
196 2
        $variablesCollector = new StaticVariablesCollector($this);
197 2
        $nodeTraverser->addVisitor($variablesCollector);
198
199
        /* @see https://github.com/nikic/PHP-Parser/issues/235 */
200 2
        $nodeTraverser->traverse($this->functionLikeNode->getStmts() ?: array());
201
202 2
        return $variablesCollector->getStaticVariables();
203
    }
204
205
    /**
206
     * {@inheritDoc}
207
     */
208 2
    public function inNamespace()
209
    {
210 2
        return !empty($this->namespaceName);
211
    }
212
213
    /**
214
     * {@inheritDoc}
215
     */
216 1
    public function isClosure()
217
    {
218 1
        return $this->functionLikeNode instanceof Closure;
219
    }
220
221
    /**
222
     * {@inheritDoc}
223
     */
224 1
    public function isDeprecated()
225
    {
226
        // userland method/function/closure can not be deprecated
227 1
        return false;
228
    }
229
230
    /**
231
     * {@inheritDoc}
232
     */
233 1
    public function isGenerator()
234
    {
235 1
        $nodeTraverser = new NodeTraverser(false);
236 1
        $nodeDetector  = new GeneratorDetector();
237 1
        $nodeTraverser->addVisitor($nodeDetector);
238
239
        /* @see https://github.com/nikic/PHP-Parser/issues/235 */
240 1
        $nodeTraverser->traverse($this->functionLikeNode->getStmts() ?: array());
241
242 1
        return $nodeDetector->isGenerator();
243
    }
244
245
    /**
246
     * {@inheritDoc}
247
     */
248 1
    public function isInternal()
249
    {
250
        // never can be an internal method
251 1
        return false;
252
    }
253
254
    /**
255
     * {@inheritDoc}
256
     */
257 1
    public function isUserDefined()
258
    {
259
        // always defined by user, because we parse the source code
260 1
        return true;
261
    }
262
263
    /**
264
     * {@inheritDoc}
265
     */
266 1
    public function isVariadic()
267
    {
268 1
        foreach ($this->getParameters() as $parameter) {
269 1
            if ($parameter->isVariadic()) {
270
                return true;
271
            }
272 1
        }
273
274 1
        return false;
275
    }
276
277
    /**
278
     * {@inheritDoc}
279
     */
280 2
    public function returnsReference()
281
    {
282 2
        return $this->functionLikeNode->returnsByRef();
283
    }
284
}