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