1: <?php
2: /**
3: * PHP Token Reflection
4: *
5: * Version 1.3.1
6: *
7: * LICENSE
8: *
9: * This source file is subject to the new BSD license that is bundled
10: * with this library in the file LICENSE.
11: *
12: * @author Ondřej Nešpor
13: * @author Jaroslav Hanslík
14: */
15:
16: namespace TokenReflection\Invalid;
17:
18: use TokenReflection, TokenReflection\IReflectionFunction, TokenReflection\Exception, TokenReflection\Broker, TokenReflection\ReflectionBase;
19:
20: /**
21: * Invalid function reflection.
22: *
23: * The reflected function is not unique.
24: */
25: class ReflectionFunction extends ReflectionElement implements IReflectionFunction
26: {
27: /**
28: * Class name (FQN).
29: *
30: * @var string
31: */
32: private $name;
33:
34: /**
35: * Original definition file name.
36: *
37: * @var string
38: */
39: private $fileName;
40:
41: /**
42: * Reflection broker.
43: *
44: * @var \TokenReflection\Broker
45: */
46: private $broker;
47:
48: /**
49: * Constructor.
50: *
51: * @param string $name Function name
52: * @param string $fileName Original definiton file name
53: * @param \TokenReflection\Broker $broker Reflection broker
54: */
55: public function __construct($name, $fileName, Broker $broker)
56: {
57: $this->name = ltrim($name, '\\');
58: $this->broker = $broker;
59: $this->fileName = $fileName;
60: }
61:
62: /**
63: * Returns the name (FQN).
64: *
65: * @return string
66: */
67: public function getName()
68: {
69: return $this->name;
70: }
71:
72: /**
73: * Returns the unqualified name (UQN).
74: *
75: * @return string
76: */
77: public function getShortName()
78: {
79: $pos = strrpos($this->name, '\\');
80: return false === $pos ? $this->name : substr($this->name, $pos + 1);
81: }
82:
83: /**
84: * Returns the namespace name.
85: *
86: * @return string
87: */
88: public function getNamespaceName()
89: {
90: $pos = strrpos($this->name, '\\');
91: return false === $pos ? '' : substr($this->name, 0, $pos);
92: }
93:
94: /**
95: * Returns if the class is defined within a namespace.
96: *
97: * @return boolean
98: */
99: public function inNamespace()
100: {
101: return false !== strrpos($this->name, '\\');
102: }
103:
104: /**
105: * Returns if the reflection object is internal.
106: *
107: * @return boolean
108: */
109: public function isInternal()
110: {
111: return false;
112: }
113:
114: /**
115: * Returns if the reflection object is user defined.
116: *
117: * @return boolean
118: */
119: public function isUserDefined()
120: {
121: return true;
122: }
123:
124: /**
125: * Returns if the current reflection comes from a tokenized source.
126: *
127: * @return boolean
128: */
129: public function isTokenized()
130: {
131: return true;
132: }
133:
134: /**
135: * Returns the reflection broker used by this reflection object.
136: *
137: * @return \TokenReflection\Broker
138: */
139: public function getBroker()
140: {
141: return $this->broker;
142: }
143:
144: /**
145: * Returns an element pretty (docblock compatible) name.
146: *
147: * @return string
148: */
149: public function getPrettyName()
150: {
151: return $this->name . '()';
152: }
153:
154: /**
155: * Returns the PHP extension reflection.
156: *
157: * @return \TokenReflection\IReflectionExtension|null
158: */
159: public function getExtension()
160: {
161: return null;
162: }
163:
164: /**
165: * Returns the PHP extension name.
166: *
167: * @return false
168: */
169: public function getExtensionName()
170: {
171: return false;
172: }
173:
174: /**
175: * Returns the file name the reflection object is defined in.
176: *
177: * @return null
178: */
179: public function getFileName()
180: {
181: return $this->fileName;
182: }
183:
184: /**
185: * Returns a file reflection.
186: *
187: * @return \TokenReflection\ReflectionFile
188: * @throws \TokenReflection\Exception\RuntimeException If the file is not stored inside the broker
189: */
190: public function getFileReflection()
191: {
192: throw new Exception\BrokerException($this->getBroker(), sprintf('Function was not parsed from a file', $this->getPrettyName()), Exception\BrokerException::UNSUPPORTED);
193: }
194:
195: /**
196: * Returns the appropriate source code part.
197: *
198: * @return string
199: */
200: public function getSource()
201: {
202: return '';
203: }
204:
205: /**
206: * Returns the start position in the file token stream.
207: *
208: * @return integer
209: */
210: public function getStartPosition()
211: {
212: return -1;
213: }
214:
215: /**
216: * Returns the end position in the file token stream.
217: *
218: * @return integer
219: */
220: public function getEndPosition()
221: {
222: return -1;
223: }
224:
225: /**
226: * Returns the definition start line number in the file.
227: *
228: * @return integer
229: */
230: public function getStartLine()
231: {
232: return null;
233: }
234:
235: /**
236: * Returns the definition end line number in the file.
237: *
238: * @return integer
239: */
240: public function getEndLine()
241: {
242: return null;
243: }
244:
245: /**
246: * Returns the appropriate docblock definition.
247: *
248: * @return boolean
249: */
250: public function getDocComment()
251: {
252: return false;
253: }
254:
255: /**
256: * Checks if there is a particular annotation.
257: *
258: * @param string $name Annotation name
259: * @return boolean
260: */
261: public function hasAnnotation($name)
262: {
263: return false;
264: }
265:
266: /**
267: * Returns a particular annotation value.
268: *
269: * @param string $name Annotation name
270: * @return string|array|null
271: */
272: public function getAnnotation($name)
273: {
274: return null;
275: }
276:
277: /**
278: * Returns all annotations.
279: *
280: * @return array
281: */
282: public function getAnnotations()
283: {
284: return array();
285: }
286:
287: /**
288: * Returns if the function/method is a closure.
289: *
290: * @return boolean
291: */
292: public function isClosure()
293: {
294: return false;
295: }
296:
297: /**
298: * Returns if the function/method is deprecated.
299: *
300: * @return boolean
301: */
302: public function isDeprecated()
303: {
304: return false;
305: }
306:
307: /**
308: * Returns if the function/method returns its value as reference.
309: *
310: * @return boolean
311: */
312: public function returnsReference()
313: {
314: return false;
315: }
316:
317: /**
318: * Returns a function/method parameter.
319: *
320: * @param integer|string $parameter Parameter name or position
321: */
322: public function getParameter($parameter)
323: {
324: if (is_numeric($parameter)) {
325: throw new Exception\RuntimeException(sprintf('There is no parameter at position "%d".', $parameter), Exception\RuntimeException::DOES_NOT_EXIST, $this);
326: } else {
327: throw new Exception\RuntimeException(sprintf('There is no parameter "%s".', $parameter), Exception\RuntimeException::DOES_NOT_EXIST, $this);
328: }
329: }
330:
331: /**
332: * Returns function/method parameters.
333: *
334: * @return array
335: */
336: public function getParameters(){
337: return array();
338: }
339:
340: /**
341: * Returns the number of parameters.
342: *
343: * @return integer
344: */
345: public function getNumberOfParameters()
346: {
347: return 0;
348: }
349:
350: /**
351: * Returns the number of required parameters.
352: *
353: * @return integer
354: */
355: public function getNumberOfRequiredParameters()
356: {
357: return 0;
358: }
359:
360: /**
361: * Returns static variables.
362: *
363: * @return array
364: */
365: public function getStaticVariables()
366: {
367: return array();
368: }
369:
370: /**
371: * Returns if the method is is disabled via the disable_functions directive.
372: *
373: * @return boolean
374: */
375: public function isDisabled()
376: {
377: return false;
378: }
379:
380: /**
381: * Calls the function.
382: *
383: * @return mixed
384: */
385: public function invoke()
386: {
387: return $this->invokeArgs(array());
388: }
389:
390: /**
391: * Calls the function.
392: *
393: * @param array $args Function parameter values
394: * @return mixed
395: */
396: public function invokeArgs(array $args)
397: {
398: throw new Exception\RuntimeException('Cannot invoke invalid functions', Exception\RuntimeException::UNSUPPORTED, $this);
399: }
400:
401: /**
402: * Returns imported namespaces and aliases from the declaring namespace.
403: *
404: * @return array
405: */
406: public function getNamespaceAliases()
407: {
408: return array();
409: }
410:
411: /**
412: * Returns the function/method as closure.
413: *
414: * @return \Closure
415: */
416: public function getClosure()
417: {
418: throw new Exception\RuntimeException('Cannot invoke invalid functions', Exception\RuntimeException::UNSUPPORTED, $this);
419: }
420:
421: /**
422: * Returns the closure scope class.
423: *
424: * @return null
425: */
426: public function getClosureScopeClass()
427: {
428: return null;
429: }
430:
431: /**
432: * Returns this pointer bound to closure.
433: *
434: * @return null
435: */
436: public function getClosureThis()
437: {
438: return null;
439: }
440:
441: /**
442: * Returns if the function definition is valid.
443: *
444: * @return boolean
445: */
446: public function isValid()
447: {
448: return false;
449: }
450:
451: /**
452: * Returns the string representation of the reflection object.
453: *
454: * @return string
455: */
456: public function __toString()
457: {
458: return sprintf(
459: "%sFunction [ <user> function %s%s ] {\n @@ %s %d - %d\n}\n",
460: $this->getDocComment() ? $this->getDocComment() . "\n" : '',
461: $this->returnsReference() ? '&' : '',
462: $this->getName(),
463: $this->getFileName(),
464: $this->getStartLine(),
465: $this->getEndLine()
466: );
467: }
468:
469: /**
470: * Magic __get method.
471: *
472: * @param string $key Variable name
473: * @return mixed
474: */
475: final public function __get($key)
476: {
477: return ReflectionBase::get($this, $key);
478: }
479:
480: /**
481: * Magic __isset method.
482: *
483: * @param string $key Variable name
484: * @return boolean
485: */
486: final public function __isset($key)
487: {
488: return ReflectionBase::exists($this, $key);
489: }
490: }
491: