1: <?php
2:
3: 4: 5: 6:
7:
8: namespace Nette\PhpGenerator;
9:
10: use Nette;
11:
12:
13: 14: 15:
16: class Method extends Nette\Object
17: {
18:
19: private $name;
20:
21:
22: private $parameters = array();
23:
24:
25: private $uses = array();
26:
27:
28: private $body = '';
29:
30:
31: private $static = FALSE;
32:
33:
34: private $visibility;
35:
36:
37: private $final = FALSE;
38:
39:
40: private $abstract = FALSE;
41:
42:
43: private $returnReference = FALSE;
44:
45:
46: private $variadic = FALSE;
47:
48:
49: private $documents = array();
50:
51:
52: private $namespace;
53:
54:
55: private $returnType;
56:
57:
58: 59: 60:
61: public static function from($from)
62: {
63: if (is_string($from) && strpos($from, '::')) {
64: $from = new \ReflectionMethod($from);
65: } elseif (is_array($from)) {
66: $from = new \ReflectionMethod($from[0], $from[1]);
67: } elseif (!$from instanceof \ReflectionFunctionAbstract) {
68: $from = new \ReflectionFunction($from);
69: }
70:
71: $method = new static($from->isClosure() ? NULL : $from->getName());
72: foreach ($from->getParameters() as $param) {
73: $method->parameters[$param->getName()] = Parameter::from($param);
74: }
75: if ($from instanceof \ReflectionMethod) {
76: $method->static = $from->isStatic();
77: $method->visibility = $from->isPrivate() ? 'private' : ($from->isProtected() ? 'protected' : NULL);
78: $method->final = $from->isFinal();
79: $method->abstract = $from->isAbstract() && !$from->getDeclaringClass()->isInterface();
80: $method->body = $from->isAbstract() ? FALSE : '';
81: }
82: $method->returnReference = $from->returnsReference();
83: $method->variadic = PHP_VERSION_ID >= 50600 && $from->isVariadic();
84: $method->documents = $from->getDocComment() ? array(preg_replace('#^\s*\* ?#m', '', trim($from->getDocComment(), "/* \r\n\t"))) : array();
85: if (PHP_VERSION_ID >= 70000 && $from->hasReturnType()) {
86: $method->returnType = (string) $from->getReturnType();
87: }
88: return $method;
89: }
90:
91:
92: 93: 94:
95: public function __construct($name = NULL)
96: {
97: $this->setName($name);
98: }
99:
100:
101: 102: 103:
104: public function __toString()
105: {
106: $parameters = array();
107: foreach ($this->parameters as $param) {
108: $variadic = $this->variadic && $param === end($this->parameters);
109: $hint = $param->getTypeHint();
110: $parameters[] = ($hint ? ($this->namespace ? $this->namespace->unresolveName($hint) : $hint) . ' ' : '')
111: . ($param->isReference() ? '&' : '')
112: . ($variadic ? '...' : '')
113: . '$' . $param->getName()
114: . ($param->isOptional() && !$variadic ? ' = ' . Helpers::dump($param->defaultValue) : '');
115: }
116: $uses = array();
117: foreach ($this->uses as $param) {
118: $uses[] = ($param->isReference() ? '&' : '') . '$' . $param->getName();
119: }
120:
121: return ($this->documents ? str_replace("\n", "\n * ", "/**\n" . implode("\n", $this->documents)) . "\n */\n" : '')
122: . ($this->abstract ? 'abstract ' : '')
123: . ($this->final ? 'final ' : '')
124: . ($this->visibility ? $this->visibility . ' ' : '')
125: . ($this->static ? 'static ' : '')
126: . 'function'
127: . ($this->returnReference ? ' &' : '')
128: . ' ' . $this->name
129: . '(' . implode(', ', $parameters) . ')'
130: . ($this->uses ? ' use (' . implode(', ', $uses) . ')' : '')
131: . ($this->returnType ? ': ' . ($this->namespace ? $this->namespace->unresolveName($this->returnType) : $this->returnType) : '')
132: . ($this->abstract || $this->body === FALSE ? ';'
133: : ($this->name ? "\n" : ' ') . "{\n" . Nette\Utils\Strings::indent(ltrim(rtrim($this->body) . "\n"), 1) . '}');
134: }
135:
136:
137: 138: 139: 140:
141: public function setName($name)
142: {
143: $this->name = $name ? (string) $name : NULL;
144: return $this;
145: }
146:
147:
148: 149: 150:
151: public function getName()
152: {
153: return $this->name;
154: }
155:
156:
157: 158: 159: 160:
161: public function setParameters(array $val)
162: {
163: $this->parameters = array();
164: foreach ($val as $v) {
165: if (!$v instanceof Parameter) {
166: throw new Nette\InvalidArgumentException('Argument must be Nette\PhpGenerator\Parameter[].');
167: }
168: $this->parameters[$v->getName()] = $v;
169: }
170: return $this;
171: }
172:
173:
174: 175: 176:
177: public function getParameters()
178: {
179: return $this->parameters;
180: }
181:
182:
183: 184: 185: 186:
187: public function addParameter($name, $defaultValue = NULL)
188: {
189: $param = new Parameter($name);
190: if (func_num_args() > 1) {
191: $param->setOptional(TRUE)->setDefaultValue($defaultValue);
192: }
193: return $this->parameters[$name] = $param;
194: }
195:
196:
197: 198: 199:
200: public function setUses(array $val)
201: {
202: $this->uses = $val;
203: return $this;
204: }
205:
206:
207: 208: 209:
210: public function getUses()
211: {
212: return $this->uses;
213: }
214:
215:
216: 217: 218:
219: public function addUse($name)
220: {
221: return $this->uses[] = new Parameter($name);
222: }
223:
224:
225: 226: 227:
228: public function setBody($statement, array $args = NULL)
229: {
230: $this->body = func_num_args() > 1 ? Helpers::formatArgs($statement, $args) : $statement;
231: return $this;
232: }
233:
234:
235: 236: 237:
238: public function getBody()
239: {
240: return $this->body;
241: }
242:
243:
244: 245: 246:
247: public function addBody($statement, array $args = NULL)
248: {
249: $this->body .= (func_num_args() > 1 ? Helpers::formatArgs($statement, $args) : $statement) . "\n";
250: return $this;
251: }
252:
253:
254: 255: 256: 257:
258: public function setStatic($val)
259: {
260: $this->static = (bool) $val;
261: return $this;
262: }
263:
264:
265: 266: 267:
268: public function isStatic()
269: {
270: return $this->static;
271: }
272:
273:
274: 275: 276: 277:
278: public function setVisibility($val)
279: {
280: if (!in_array($val, array('public', 'protected', 'private', NULL), TRUE)) {
281: throw new Nette\InvalidArgumentException('Argument must be public|protected|private|NULL.');
282: }
283: $this->visibility = $val ? (string) $val : NULL;
284: return $this;
285: }
286:
287:
288: 289: 290:
291: public function getVisibility()
292: {
293: return $this->visibility;
294: }
295:
296:
297: 298: 299: 300:
301: public function setFinal($val)
302: {
303: $this->final = (bool) $val;
304: return $this;
305: }
306:
307:
308: 309: 310:
311: public function isFinal()
312: {
313: return $this->final;
314: }
315:
316:
317: 318: 319: 320:
321: public function setAbstract($val)
322: {
323: $this->abstract = (bool) $val;
324: return $this;
325: }
326:
327:
328: 329: 330:
331: public function isAbstract()
332: {
333: return $this->abstract;
334: }
335:
336:
337: 338: 339: 340:
341: public function setReturnReference($val)
342: {
343: $this->returnReference = (bool) $val;
344: return $this;
345: }
346:
347:
348: 349: 350:
351: public function getReturnReference()
352: {
353: return $this->returnReference;
354: }
355:
356:
357: 358: 359: 360:
361: public function setVariadic($val)
362: {
363: $this->variadic = (bool) $val;
364: return $this;
365: }
366:
367:
368: 369: 370:
371: public function isVariadic()
372: {
373: return $this->variadic;
374: }
375:
376:
377: 378: 379: 380:
381: public function ($val)
382: {
383: $this->documents = $val ? array((string) $val) : array();
384: return $this;
385: }
386:
387:
388: 389: 390:
391: public function ()
392: {
393: return implode($this->documents) ?: NULL;
394: }
395:
396:
397: 398: 399: 400:
401: public function ($val)
402: {
403: return $this->addDocument($val);
404: }
405:
406:
407: 408: 409: 410:
411: public function setDocuments(array $val)
412: {
413: $this->documents = $val;
414: return $this;
415: }
416:
417:
418: 419: 420:
421: public function getDocuments()
422: {
423: return $this->documents;
424: }
425:
426:
427: 428: 429: 430:
431: public function addDocument($val)
432: {
433: $this->documents[] = (string) $val;
434: return $this;
435: }
436:
437:
438: 439: 440:
441: public function setNamespace(PhpNamespace $val = NULL)
442: {
443: $this->namespace = $val;
444: return $this;
445: }
446:
447:
448: 449: 450: 451:
452: public function setReturnType($val)
453: {
454: $this->returnType = $val ? (string) $val : NULL;
455: return $this;
456: }
457:
458:
459: 460: 461:
462: public function getReturnType()
463: {
464: return $this->returnType;
465: }
466:
467: }
468: