Namespaces

  • Latte
    • Loaders
    • Macros
    • Runtime
  • Nette
    • Application
      • Responses
      • Routers
      • UI
    • Bridges
      • ApplicationDI
      • ApplicationLatte
      • ApplicationTracy
      • CacheDI
      • CacheLatte
      • DatabaseDI
      • DatabaseTracy
      • DITracy
      • FormsDI
      • FormsLatte
      • Framework
      • HttpDI
      • HttpTracy
      • MailDI
      • ReflectionDI
      • SecurityDI
      • SecurityTracy
    • Caching
      • Storages
    • ComponentModel
    • Database
      • Conventions
      • Drivers
      • Reflection
      • Table
    • DI
      • Config
        • Adapters
      • Extensions
    • Forms
      • Controls
      • Rendering
    • Http
    • Iterators
    • Loaders
    • Localization
    • Mail
    • Neon
    • PhpGenerator
    • Reflection
    • Security
    • Utils
  • none
  • Tracy
    • Bridges
      • Nette

Classes

  • ClassType
  • Helpers
  • Method
  • Parameter
  • PhpFile
  • PhpLiteral
  • PhpNamespace
  • Property
  • Overview
  • Namespace
  • Class
  • Tree
  • Deprecated
  • Other releases
  • Nette homepage
  1: <?php
  2: 
  3: /**
  4:  * This file is part of the Nette Framework (https://nette.org)
  5:  * Copyright (c) 2004 David Grudl (https://davidgrudl.com)
  6:  */
  7: 
  8: namespace Nette\PhpGenerator;
  9: 
 10: use Nette;
 11: use Nette\Utils\Strings;
 12: 
 13: 
 14: /**
 15:  * Class/Interface/Trait description.
 16:  */
 17: class ClassType extends Nette\Object
 18: {
 19:     const TYPE_CLASS = 'class';
 20: 
 21:     const TYPE_INTERFACE = 'interface';
 22: 
 23:     const TYPE_TRAIT = 'trait';
 24: 
 25:     /** @var PhpNamespace|NULL */
 26:     private $namespace;
 27: 
 28:     /** @var string */
 29:     private $name;
 30: 
 31:     /** @var string  class|interface|trait */
 32:     private $type = 'class';
 33: 
 34:     /** @var bool */
 35:     private $final = FALSE;
 36: 
 37:     /** @var bool */
 38:     private $abstract = FALSE;
 39: 
 40:     /** @var string|string[] */
 41:     private $extends = array();
 42: 
 43:     /** @var string[] */
 44:     private $implements = array();
 45: 
 46:     /** @var string[] */
 47:     private $traits = array();
 48: 
 49:     /** @var string[] */
 50:     private $documents = array();
 51: 
 52:     /** @var array name => value */
 53:     private $consts = array();
 54: 
 55:     /** @var Property[] name => Property */
 56:     private $properties = array();
 57: 
 58:     /** @var Method[] name => Method */
 59:     private $methods = array();
 60: 
 61: 
 62:     /**
 63:      * @param  \ReflectionClass|string
 64:      * @return self
 65:      */
 66:     public static function from($from)
 67:     {
 68:         $from = new \ReflectionClass($from instanceof \ReflectionClass ? $from->getName() : $from);
 69:         if (PHP_VERSION_ID >= 70000 && $from->isAnonymous()) {
 70:             $class = new static('anonymous');
 71:         } else {
 72:             $class = new static($from->getShortName(), new PhpNamespace($from->getNamespaceName()));
 73:         }
 74:         $class->type = $from->isInterface() ? 'interface' : (PHP_VERSION_ID >= 50400 && $from->isTrait() ? 'trait' : 'class');
 75:         $class->final = $from->isFinal() && $class->type === 'class';
 76:         $class->abstract = $from->isAbstract() && $class->type === 'class';
 77:         $class->implements = $from->getInterfaceNames();
 78:         $class->documents = $from->getDocComment() ? array(preg_replace('#^\s*\* ?#m', '', trim($from->getDocComment(), "/* \r\n\t"))) : array();
 79:         if ($from->getParentClass()) {
 80:             $class->extends = $from->getParentClass()->getName();
 81:             $class->implements = array_diff($class->implements, $from->getParentClass()->getInterfaceNames());
 82:         }
 83:         foreach ($from->getProperties() as $prop) {
 84:             if ($prop->getDeclaringClass()->getName() === $from->getName()) {
 85:                 $class->properties[$prop->getName()] = Property::from($prop);
 86:             }
 87:         }
 88:         foreach ($from->getMethods() as $method) {
 89:             if ($method->getDeclaringClass()->getName() === $from->getName()) {
 90:                 $class->methods[$method->getName()] = Method::from($method)->setNamespace($class->namespace);
 91:             }
 92:         }
 93:         return $class;
 94:     }
 95: 
 96: 
 97:     public function __construct($name = '', PhpNamespace $namespace = NULL)
 98:     {
 99:         $this->setName($name);
100:         $this->namespace = $namespace;
101:     }
102: 
103: 
104:     /**
105:      * @return string  PHP code
106:      */
107:     public function __toString()
108:     {
109:         $consts = array();
110:         foreach ($this->consts as $name => $value) {
111:             $consts[] = "const $name = " . Helpers::dump($value) . ";\n";
112:         }
113: 
114:         $properties = array();
115:         foreach ($this->properties as $property) {
116:             $doc = str_replace("\n", "\n * ", implode("\n", $property->getDocuments()));
117:             $properties[] = ($property->getDocuments() ? (strpos($doc, "\n") === FALSE ? "/** $doc */\n" : "/**\n * $doc\n */\n") : '')
118:                 . $property->getVisibility() . ($property->isStatic() ? ' static' : '') . ' $' . $property->getName()
119:                 . ($property->value === NULL ? '' : ' = ' . Helpers::dump($property->value))
120:                 . ";\n";
121:         }
122: 
123:         $namespace = $this->namespace;
124:         $mapper = function (array $arr) use ($namespace) {
125:             return $namespace ? array_map(array($namespace, 'unresolveName'), $arr) : $arr;
126:         };
127: 
128:         return Strings::normalize(
129:             ($this->documents ? str_replace("\n", "\n * ", "/**\n" . implode("\n", $this->documents)) . "\n */\n" : '')
130:             . ($this->abstract ? 'abstract ' : '')
131:             . ($this->final ? 'final ' : '')
132:             . $this->type . ' '
133:             . $this->name . ' '
134:             . ($this->extends ? 'extends ' . implode(', ', $mapper((array) $this->extends)) . ' ' : '')
135:             . ($this->implements ? 'implements ' . implode(', ', $mapper($this->implements)) . ' ' : '')
136:             . "\n{\n"
137:             . Strings::indent(
138:                 ($this->traits ? 'use ' . implode(";\nuse ", $mapper($this->traits)) . ";\n\n" : '')
139:                 . ($this->consts ? implode('', $consts) . "\n" : '')
140:                 . ($this->properties ? implode("\n", $properties) . "\n" : '')
141:                 . ($this->methods ? "\n" . implode("\n\n\n", $this->methods) . "\n\n" : ''), 1)
142:             . '}'
143:         ) . "\n";
144:     }
145: 
146: 
147:     /**
148:      * @return PhpNamespace|NULL
149:      */
150:     public function getNamespace()
151:     {
152:         return $this->namespace;
153:     }
154: 
155: 
156:     /**
157:      * @param  string
158:      * @return self
159:      */
160:     public function setName($name)
161:     {
162:         $this->name = (string) $name;
163:         return $this;
164:     }
165: 
166: 
167:     /**
168:      * @return string
169:      */
170:     public function getName()
171:     {
172:         return $this->name;
173:     }
174: 
175: 
176:     /**
177:      * @param  string
178:      * @return self
179:      */
180:     public function setType($type)
181:     {
182:         if (!in_array($type, array('class', 'interface', 'trait'), TRUE)) {
183:             throw new Nette\InvalidArgumentException('Argument must be class|interface|trait.');
184:         }
185:         $this->type = $type;
186:         return $this;
187:     }
188: 
189: 
190:     /**
191:      * @return string
192:      */
193:     public function getType()
194:     {
195:         return $this->type;
196:     }
197: 
198: 
199:     /**
200:      * @param  bool
201:      * @return self
202:      */
203:     public function setFinal($state = TRUE)
204:     {
205:         $this->final = (bool) $state;
206:         return $this;
207:     }
208: 
209: 
210:     /**
211:      * @return bool
212:      */
213:     public function isFinal()
214:     {
215:         return $this->final;
216:     }
217: 
218: 
219:     /**
220:      * @param  bool
221:      * @return self
222:      */
223:     public function setAbstract($state = TRUE)
224:     {
225:         $this->abstract = (bool) $state;
226:         return $this;
227:     }
228: 
229: 
230:     /**
231:      * @return bool
232:      */
233:     public function isAbstract()
234:     {
235:         return $this->abstract;
236:     }
237: 
238: 
239:     /**
240:      * @param  string|string[]
241:      * @return self
242:      */
243:     public function setExtends($types)
244:     {
245:         if (!is_string($types) && !(is_array($types) && array_filter($types, 'is_string') === $types)) {
246:             throw new Nette\InvalidArgumentException('Argument must be string or string[].');
247:         }
248:         $this->extends = $types;
249:         return $this;
250:     }
251: 
252: 
253:     /**
254:      * @return string|string[]
255:      */
256:     public function getExtends()
257:     {
258:         return $this->extends;
259:     }
260: 
261: 
262:     /**
263:      * @param  string
264:      * @return self
265:      */
266:     public function addExtend($type)
267:     {
268:         $this->extends = (array) $this->extends;
269:         $this->extends[] = (string) $type;
270:         return $this;
271:     }
272: 
273: 
274:     /**
275:      * @param  string[]
276:      * @return self
277:      */
278:     public function setImplements(array $types)
279:     {
280:         $this->implements = $types;
281:         return $this;
282:     }
283: 
284: 
285:     /**
286:      * @return string[]
287:      */
288:     public function getImplements()
289:     {
290:         return $this->implements;
291:     }
292: 
293: 
294:     /**
295:      * @param  string
296:      * @return self
297:      */
298:     public function addImplement($type)
299:     {
300:         $this->implements[] = (string) $type;
301:         return $this;
302:     }
303: 
304: 
305:     /**
306:      * @param  string[]
307:      * @return self
308:      */
309:     public function setTraits(array $traits)
310:     {
311:         $this->traits = $traits;
312:         return $this;
313:     }
314: 
315: 
316:     /**
317:      * @return string[]
318:      */
319:     public function getTraits()
320:     {
321:         return $this->traits;
322:     }
323: 
324: 
325:     /**
326:      * @param  string
327:      * @return self
328:      */
329:     public function addTrait($trait)
330:     {
331:         $this->traits[] = (string) $trait;
332:         return $this;
333:     }
334: 
335: 
336:     /**
337:      * @param  string|NULL
338:      * @return self
339:      */
340:     public function setComment($val)
341:     {
342:         $this->documents = $val ? array((string) $val) : array();
343:         return $this;
344:     }
345: 
346: 
347:     /**
348:      * @return string|NULL
349:      */
350:     public function getComment()
351:     {
352:         return implode($this->documents) ?: NULL;
353:     }
354: 
355: 
356:     /**
357:      * @param  string
358:      * @return self
359:      */
360:     public function addComment($val)
361:     {
362:         return $this->addDocument($val);
363:     }
364: 
365: 
366:     /**
367:      * @param  string[]
368:      * @return self
369:      */
370:     public function setDocuments(array $s)
371:     {
372:         $this->documents = $s;
373:         return $this;
374:     }
375: 
376: 
377:     /**
378:      * @return string[]
379:      */
380:     public function getDocuments()
381:     {
382:         return $this->documents;
383:     }
384: 
385: 
386:     /**
387:      * @param  string
388:      * @return self
389:      */
390:     public function addDocument($s)
391:     {
392:         $this->documents[] = (string) $s;
393:         return $this;
394:     }
395: 
396: 
397:     /**
398:      * @return self
399:      */
400:     public function setConsts(array $consts)
401:     {
402:         $this->consts = $consts;
403:         return $this;
404:     }
405: 
406: 
407:     /**
408:      * @return array
409:      */
410:     public function getConsts()
411:     {
412:         return $this->consts;
413:     }
414: 
415: 
416:     /**
417:      * @param  string
418:      * @param  mixed
419:      * @return self
420:      */
421:     public function addConst($name, $value)
422:     {
423:         $this->consts[$name] = $value;
424:         return $this;
425:     }
426: 
427: 
428:     /**
429:      * @param  Property[]
430:      * @return self
431:      */
432:     public function setProperties(array $props)
433:     {
434:         $this->properties = array();
435:         foreach ($props as $v) {
436:             if (!$v instanceof Property) {
437:                 throw new Nette\InvalidArgumentException('Argument must be Nette\PhpGenerator\Property[].');
438:             }
439:             $this->properties[$v->getName()] = $v;
440:         }
441:         return $this;
442:     }
443: 
444: 
445:     /**
446:      * @return Property[]
447:      */
448:     public function getProperties()
449:     {
450:         return $this->properties;
451:     }
452: 
453: 
454:     /**
455:      * @return Property
456:      */
457:     public function getProperty($name)
458:     {
459:         if (!isset($this->properties[$name])) {
460:             throw new Nette\InvalidArgumentException("Property '$name' not found.");
461:         }
462:         return $this->properties[$name];
463:     }
464: 
465: 
466:     /**
467:      * @param  string  without $
468:      * @param  mixed
469:      * @return Property
470:      */
471:     public function addProperty($name, $value = NULL)
472:     {
473:         $property = new Property($name);
474:         return $this->properties[$name] = $property->setValue($value);
475:     }
476: 
477: 
478:     /**
479:      * @param  Method[]
480:      * @return self
481:      */
482:     public function setMethods(array $methods)
483:     {
484:         $this->methods = array();
485:         foreach ($methods as $v) {
486:             if (!$v instanceof Method) {
487:                 throw new Nette\InvalidArgumentException('Argument must be Nette\PhpGenerator\Method[].');
488:             }
489:             $this->methods[$v->getName()] = $v->setNamespace($this->namespace);
490:         }
491:         return $this;
492:     }
493: 
494: 
495:     /**
496:      * @return Method[]
497:      */
498:     public function getMethods()
499:     {
500:         return $this->methods;
501:     }
502: 
503: 
504:     /**
505:      * @return Method
506:      */
507:     public function getMethod($name)
508:     {
509:         if (!isset($this->methods[$name])) {
510:             throw new Nette\InvalidArgumentException("Method '$name' not found.");
511:         }
512:         return $this->methods[$name];
513:     }
514: 
515: 
516:     /**
517:      * @param  string
518:      * @return Method
519:      */
520:     public function addMethod($name)
521:     {
522:         $method = new Method($name);
523:         if ($this->type === 'interface') {
524:             $method->setVisibility(NULL)->setBody(FALSE);
525:         } else {
526:             $method->setVisibility('public');
527:         }
528:         return $this->methods[$name] = $method->setNamespace($this->namespace);
529:     }
530: 
531: }
532: 
Nette 2.3-20161221 API API documentation generated by ApiGen 2.8.0