Verzeichnisstruktur phpBB-3.2.0


Veröffentlicht
06.01.2017

So funktioniert es


Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück

Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis.
Auf den Verzeichnisnamen klicken, dies zeigt nur das Verzeichnis mit Inhalt an

(Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

ClassGenerator.php

Zuletzt modifiziert: 09.10.2024, 12:57 - Dateigröße: 25.14 KiB


001  <?php
002  /**
003   * Zend Framework (http://framework.zend.com/)
004   *
005   * @link      http://github.com/zendframework/zf2 for the canonical source repository
006   * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
007   * @license   http://framework.zend.com/license/new-bsd New BSD License
008   */
009   
010  namespace Zend\Code\Generator;
011   
012  use Zend\Code\Reflection\ClassReflection;
013   
014  class ClassGenerator extends AbstractGenerator
015  {
016      const OBJECT_TYPE = "class";
017   
018      const FLAG_ABSTRACT = 0x01;
019      const FLAG_FINAL    = 0x02;
020   
021      /**
022       * @var FileGenerator
023       */
024      protected $containingFileGenerator = null;
025   
026      /**
027       * @var string
028       */
029      protected $namespaceName = null;
030   
031      /**
032       * @var DocBlockGenerator
033       */
034      protected $docBlock = null;
035   
036      /**
037       * @var string
038       */
039      protected $name = null;
040   
041      /**
042       * @var bool
043       */
044      protected $flags = 0x00;
045   
046      /**
047       * @var string
048       */
049      protected $extendedClass = null;
050   
051      /**
052       * @var array Array of string names
053       */
054      protected $implementedInterfaces = array();
055   
056      /**
057       * @var PropertyGenerator[] Array of properties
058       */
059      protected $properties = array();
060   
061      /**
062       * @var PropertyGenerator[] Array of constants
063       */
064      protected $constants = array();
065   
066      /**
067       * @var MethodGenerator[] Array of methods
068       */
069      protected $methods = array();
070   
071      /**
072       * @var TraitUsageGenerator Object to encapsulate trait usage logic
073       */
074      protected $traitUsageGenerator;
075   
076      /**
077       * Build a Code Generation Php Object from a Class Reflection
078       *
079       * @param  ClassReflection $classReflection
080       * @return ClassGenerator
081       */
082      public static function fromReflection(ClassReflection $classReflection)
083      {
084          $cg = new static($classReflection->getName());
085   
086          $cg->setSourceContent($cg->getSourceContent());
087          $cg->setSourceDirty(false);
088   
089          if ($classReflection->getDocComment() != '') {
090              $cg->setDocBlock(DocBlockGenerator::fromReflection($classReflection->getDocBlock()));
091          }
092   
093          $cg->setAbstract($classReflection->isAbstract());
094   
095          // set the namespace
096          if ($classReflection->inNamespace()) {
097              $cg->setNamespaceName($classReflection->getNamespaceName());
098          }
099   
100          /* @var \Zend\Code\Reflection\ClassReflection $parentClass */
101          $parentClass = $classReflection->getParentClass();
102          $interfaces  = $classReflection->getInterfaces();
103   
104          if ($parentClass) {
105              $cg->setExtendedClass($parentClass->getName());
106   
107              $interfaces = array_diff($interfaces, $parentClass->getInterfaces());
108          }
109   
110          $interfaceNames = array();
111          foreach ($interfaces as $interface) {
112              /* @var \Zend\Code\Reflection\ClassReflection $interface */
113              $interfaceNames[] = $interface->getName();
114          }
115   
116          $cg->setImplementedInterfaces($interfaceNames);
117   
118          $properties = array();
119   
120          foreach ($classReflection->getProperties() as $reflectionProperty) {
121              if ($reflectionProperty->getDeclaringClass()->getName() == $classReflection->getName()) {
122                  $properties[] = PropertyGenerator::fromReflection($reflectionProperty);
123              }
124          }
125   
126          $cg->addProperties($properties);
127   
128          $constants = array();
129   
130          foreach ($classReflection->getConstants() as $name => $value) {
131              $constants[] = array(
132                  'name' => $name,
133                  'value' => $value
134              );
135          }
136   
137          $cg->addConstants($constants);
138   
139          $methods = array();
140   
141          foreach ($classReflection->getMethods() as $reflectionMethod) {
142              $className = ($cg->getNamespaceName()) ? $cg->getNamespaceName() . "\\" . $cg->getName() : $cg->getName();
143   
144              if ($reflectionMethod->getDeclaringClass()->getName() == $className) {
145                  $methods[] = MethodGenerator::fromReflection($reflectionMethod);
146              }
147          }
148   
149          $cg->addMethods($methods);
150   
151          return $cg;
152      }
153   
154      /**
155       * Generate from array
156       *
157       * @configkey name           string        [required] Class Name
158       * @configkey filegenerator  FileGenerator File generator that holds this class
159       * @configkey namespacename  string        The namespace for this class
160       * @configkey docblock       string        The docblock information
161       * @configkey flags          int           Flags, one of ClassGenerator::FLAG_ABSTRACT ClassGenerator::FLAG_FINAL
162       * @configkey extendedclass  string        Class which this class is extending
163       * @configkey implementedinterfaces
164       * @configkey properties
165       * @configkey methods
166       *
167       * @throws Exception\InvalidArgumentException
168       * @param  array $array
169       * @return ClassGenerator
170       */
171      public static function fromArray(array $array)
172      {
173          if (!isset($array['name'])) {
174              throw new Exception\InvalidArgumentException(
175                  'Class generator requires that a name is provided for this object'
176              );
177          }
178   
179          $cg = new static($array['name']);
180          foreach ($array as $name => $value) {
181              // normalize key
182              switch (strtolower(str_replace(array('.', '-', '_'), '', $name))) {
183                  case 'containingfile':
184                      $cg->setContainingFileGenerator($value);
185                      break;
186                  case 'namespacename':
187                      $cg->setNamespaceName($value);
188                      break;
189                  case 'docblock':
190                      $docBlock = ($value instanceof DocBlockGenerator) ? $value : DocBlockGenerator::fromArray($value);
191                      $cg->setDocBlock($docBlock);
192                      break;
193                  case 'flags':
194                      $cg->setFlags($value);
195                      break;
196                  case 'extendedclass':
197                      $cg->setExtendedClass($value);
198                      break;
199                  case 'implementedinterfaces':
200                      $cg->setImplementedInterfaces($value);
201                      break;
202                  case 'properties':
203                      $cg->addProperties($value);
204                      break;
205                  case 'methods':
206                      $cg->addMethods($value);
207                      break;
208              }
209          }
210   
211          return $cg;
212      }
213   
214      /**
215       * @param  string $name
216       * @param  string $namespaceName
217       * @param  array|string $flags
218       * @param  string $extends
219       * @param  array $interfaces
220       * @param  array $properties
221       * @param  array $methods
222       * @param  DocBlockGenerator $docBlock
223       */
224      public function __construct(
225          $name = null,
226          $namespaceName = null,
227          $flags = null,
228          $extends = null,
229          $interfaces = array(),
230          $properties = array(),
231          $methods = array(),
232          $docBlock = null
233      ) {
234          $this->traitUsageGenerator = new TraitUsageGenerator($this);
235   
236          if ($name !== null) {
237              $this->setName($name);
238          }
239          if ($namespaceName !== null) {
240              $this->setNamespaceName($namespaceName);
241          }
242          if ($flags !== null) {
243              $this->setFlags($flags);
244          }
245          if ($properties !== array()) {
246              $this->addProperties($properties);
247          }
248          if ($extends !== null) {
249              $this->setExtendedClass($extends);
250          }
251          if (is_array($interfaces)) {
252              $this->setImplementedInterfaces($interfaces);
253          }
254          if ($methods !== array()) {
255              $this->addMethods($methods);
256          }
257          if ($docBlock !== null) {
258              $this->setDocBlock($docBlock);
259          }
260      }
261   
262      /**
263       * @param  string $name
264       * @return ClassGenerator
265       */
266      public function setName($name)
267      {
268          if (strstr($name, '\\')) {
269              $namespace = substr($name, 0, strrpos($name, '\\'));
270              $name      = substr($name, strrpos($name, '\\') + 1);
271              $this->setNamespaceName($namespace);
272          }
273   
274          $this->name = $name;
275          return $this;
276      }
277   
278      /**
279       * @return string
280       */
281      public function getName()
282      {
283          return $this->name;
284      }
285   
286      /**
287       * @param  string $namespaceName
288       * @return ClassGenerator
289       */
290      public function setNamespaceName($namespaceName)
291      {
292          $this->namespaceName = $namespaceName;
293          return $this;
294      }
295   
296      /**
297       * @return string
298       */
299      public function getNamespaceName()
300      {
301          return $this->namespaceName;
302      }
303   
304      /**
305       * @param  FileGenerator $fileGenerator
306       * @return ClassGenerator
307       */
308      public function setContainingFileGenerator(FileGenerator $fileGenerator)
309      {
310          $this->containingFileGenerator = $fileGenerator;
311          return $this;
312      }
313   
314      /**
315       * @return FileGenerator
316       */
317      public function getContainingFileGenerator()
318      {
319          return $this->containingFileGenerator;
320      }
321   
322      /**
323       * @param  DocBlockGenerator $docBlock
324       * @return ClassGenerator
325       */
326      public function setDocBlock(DocBlockGenerator $docBlock)
327      {
328          $this->docBlock = $docBlock;
329          return $this;
330      }
331   
332      /**
333       * @return DocBlockGenerator
334       */
335      public function getDocBlock()
336      {
337          return $this->docBlock;
338      }
339   
340      /**
341       * @param  array|string $flags
342       * @return ClassGenerator
343       */
344      public function setFlags($flags)
345      {
346          if (is_array($flags)) {
347              $flagsArray = $flags;
348              $flags      = 0x00;
349              foreach ($flagsArray as $flag) {
350                  $flags |= $flag;
351              }
352          }
353          // check that visibility is one of three
354          $this->flags = $flags;
355   
356          return $this;
357      }
358   
359      /**
360       * @param  string $flag
361       * @return ClassGenerator
362       */
363      public function addFlag($flag)
364      {
365          $this->setFlags($this->flags | $flag);
366          return $this;
367      }
368   
369      /**
370       * @param  string $flag
371       * @return ClassGenerator
372       */
373      public function removeFlag($flag)
374      {
375          $this->setFlags($this->flags & ~$flag);
376          return $this;
377      }
378   
379      /**
380       * @param  bool $isAbstract
381       * @return ClassGenerator
382       */
383      public function setAbstract($isAbstract)
384      {
385          return (($isAbstract) ? $this->addFlag(self::FLAG_ABSTRACT) : $this->removeFlag(self::FLAG_ABSTRACT));
386      }
387   
388      /**
389       * @return bool
390       */
391      public function isAbstract()
392      {
393          return (bool) ($this->flags & self::FLAG_ABSTRACT);
394      }
395   
396      /**
397       * @param  bool $isFinal
398       * @return ClassGenerator
399       */
400      public function setFinal($isFinal)
401      {
402          return (($isFinal) ? $this->addFlag(self::FLAG_FINAL) : $this->removeFlag(self::FLAG_FINAL));
403      }
404   
405      /**
406       * @return bool
407       */
408      public function isFinal()
409      {
410          return ($this->flags & self::FLAG_FINAL);
411      }
412   
413      /**
414       * @param  string $extendedClass
415       * @return ClassGenerator
416       */
417      public function setExtendedClass($extendedClass)
418      {
419          $this->extendedClass = $extendedClass;
420          return $this;
421      }
422   
423      /**
424       * @return string
425       */
426      public function getExtendedClass()
427      {
428          return $this->extendedClass;
429      }
430   
431      /**
432       * @param  array $implementedInterfaces
433       * @return ClassGenerator
434       */
435      public function setImplementedInterfaces(array $implementedInterfaces)
436      {
437          $this->implementedInterfaces = $implementedInterfaces;
438          return $this;
439      }
440   
441      /**
442       * @return array
443       */
444      public function getImplementedInterfaces()
445      {
446          return $this->implementedInterfaces;
447      }
448   
449      /**
450       * @param  string $constantName
451       *
452       * @return PropertyGenerator|false
453       */
454      public function getConstant($constantName)
455      {
456          if (isset($this->constants[$constantName])) {
457              return $this->constants[$constantName];
458          }
459   
460          return false;
461      }
462   
463      /**
464       * @return PropertyGenerator[] indexed by constant name
465       */
466      public function getConstants()
467      {
468          return $this->constants;
469      }
470   
471      /**
472       * @param  string $constantName
473       * @return bool
474       */
475      public function hasConstant($constantName)
476      {
477          return isset($this->constants[$constantName]);
478      }
479   
480      /**
481       * Add constant from PropertyGenerator
482       *
483       * @param  PropertyGenerator           $constant
484       * @throws Exception\InvalidArgumentException
485       * @return ClassGenerator
486       */
487      public function addConstantFromGenerator(PropertyGenerator $constant)
488      {
489          $constantName = $constant->getName();
490   
491          if (isset($this->constants[$constantName])) {
492              throw new Exception\InvalidArgumentException(sprintf(
493                  'A constant by name %s already exists in this class.',
494                  $constantName
495              ));
496          }
497   
498          if (! $constant->isConst()) {
499              throw new Exception\InvalidArgumentException(sprintf(
500                  'The value %s is not defined as a constant.',
501                  $constantName
502              ));
503          }
504   
505          $this->constants[$constantName] = $constant;
506   
507          return $this;
508      }
509   
510      /**
511       * Add Constant
512       *
513       * @param  string $name
514       * @param  string $value
515       * @throws Exception\InvalidArgumentException
516       * @return ClassGenerator
517       */
518      public function addConstant($name, $value)
519      {
520          if (!is_string($name)) {
521              throw new Exception\InvalidArgumentException(sprintf(
522                  '%s expects string for name',
523                  __METHOD__
524              ));
525          }
526   
527          if (empty($value) || !is_string($value)) {
528              throw new Exception\InvalidArgumentException(sprintf(
529                  '%s expects value for constant, value must be a string',
530                  __METHOD__
531              ));
532          }
533   
534          return $this->addConstantFromGenerator(new PropertyGenerator($name, $value, PropertyGenerator::FLAG_CONSTANT));
535      }
536   
537      /**
538       * @param  PropertyGenerator[]|array[] $constants
539       *
540       * @return ClassGenerator
541       */
542      public function addConstants(array $constants)
543      {
544          foreach ($constants as $constant) {
545              if ($constant instanceof PropertyGenerator) {
546                  $this->addPropertyFromGenerator($constant);
547              } else {
548                  if (is_array($constant)) {
549                      call_user_func_array(array($this, 'addConstant'), $constant);
550                  }
551              }
552          }
553   
554          return $this;
555      }
556   
557      /**
558       * @param  array $properties
559       * @return ClassGenerator
560       */
561      public function addProperties(array $properties)
562      {
563          foreach ($properties as $property) {
564              if ($property instanceof PropertyGenerator) {
565                  $this->addPropertyFromGenerator($property);
566              } else {
567                  if (is_string($property)) {
568                      $this->addProperty($property);
569                  } elseif (is_array($property)) {
570                      call_user_func_array(array($this, 'addProperty'), $property);
571                  }
572              }
573          }
574   
575          return $this;
576      }
577   
578      /**
579       * Add Property from scalars
580       *
581       * @param  string $name
582       * @param  string|array $defaultValue
583       * @param  int $flags
584       * @throws Exception\InvalidArgumentException
585       * @return ClassGenerator
586       */
587      public function addProperty($name, $defaultValue = null, $flags = PropertyGenerator::FLAG_PUBLIC)
588      {
589          if (!is_string($name)) {
590              throw new Exception\InvalidArgumentException(sprintf(
591                  '%s::%s expects string for name',
592                  get_class($this),
593                  __FUNCTION__
594              ));
595          }
596   
597          // backwards compatibility
598          // @todo remove this on next major version
599          if ($flags === PropertyGenerator::FLAG_CONSTANT) {
600              return $this->addConstant($name, $defaultValue);
601          }
602   
603          return $this->addPropertyFromGenerator(new PropertyGenerator($name, $defaultValue, $flags));
604      }
605   
606      /**
607       * Add property from PropertyGenerator
608       *
609       * @param  PropertyGenerator           $property
610       * @throws Exception\InvalidArgumentException
611       * @return ClassGenerator
612       */
613      public function addPropertyFromGenerator(PropertyGenerator $property)
614      {
615          $propertyName = $property->getName();
616   
617          if (isset($this->properties[$propertyName])) {
618              throw new Exception\InvalidArgumentException(sprintf(
619                  'A property by name %s already exists in this class.',
620                  $propertyName
621              ));
622          }
623   
624          // backwards compatibility
625          // @todo remove this on next major version
626          if ($property->isConst()) {
627              return $this->addConstantFromGenerator($property);
628          }
629   
630          $this->properties[$propertyName] = $property;
631          return $this;
632      }
633   
634      /**
635       * @return PropertyGenerator[]
636       */
637      public function getProperties()
638      {
639          return $this->properties;
640      }
641   
642      /**
643       * @param  string $propertyName
644       * @return PropertyGenerator|false
645       */
646      public function getProperty($propertyName)
647      {
648          foreach ($this->getProperties() as $property) {
649              if ($property->getName() == $propertyName) {
650                  return $property;
651              }
652          }
653   
654          return false;
655      }
656   
657      /**
658       * Add a class to "use" classes
659       *
660       * @param  string $use
661       * @param  string|null $useAlias
662       * @return ClassGenerator
663       */
664      public function addUse($use, $useAlias = null)
665      {
666          $this->traitUsageGenerator->addUse($use, $useAlias);
667          return $this;
668      }
669   
670      /**
671       * Returns the "use" classes
672       *
673       * @return array
674       */
675      public function getUses()
676      {
677          return $this->traitUsageGenerator->getUses();
678      }
679   
680      /**
681       * @param  string $propertyName
682       * @return bool
683       */
684      public function hasProperty($propertyName)
685      {
686          return isset($this->properties[$propertyName]);
687      }
688   
689      /**
690       * @param  array $methods
691       * @return ClassGenerator
692       */
693      public function addMethods(array $methods)
694      {
695          foreach ($methods as $method) {
696              if ($method instanceof MethodGenerator) {
697                  $this->addMethodFromGenerator($method);
698              } else {
699                  if (is_string($method)) {
700                      $this->addMethod($method);
701                  } elseif (is_array($method)) {
702                      call_user_func_array(array($this, 'addMethod'), $method);
703                  }
704              }
705          }
706   
707          return $this;
708      }
709   
710      /**
711       * Add Method from scalars
712       *
713       * @param  string $name
714       * @param  array $parameters
715       * @param  int $flags
716       * @param  string $body
717       * @param  string $docBlock
718       * @throws Exception\InvalidArgumentException
719       * @return ClassGenerator
720       */
721      public function addMethod(
722          $name = null,
723          array $parameters = array(),
724          $flags = MethodGenerator::FLAG_PUBLIC,
725          $body = null,
726          $docBlock = null
727      ) {
728          if (!is_string($name)) {
729              throw new Exception\InvalidArgumentException(sprintf(
730                  '%s::%s expects string for name',
731                  get_class($this),
732                  __FUNCTION__
733              ));
734          }
735   
736          return $this->addMethodFromGenerator(new MethodGenerator($name, $parameters, $flags, $body, $docBlock));
737      }
738   
739      /**
740       * Add Method from MethodGenerator
741       *
742       * @param  MethodGenerator                    $method
743       * @throws Exception\InvalidArgumentException
744       * @return ClassGenerator
745       */
746      public function addMethodFromGenerator(MethodGenerator $method)
747      {
748          $methodName = $method->getName();
749   
750          if ($this->hasMethod($methodName)) {
751              throw new Exception\InvalidArgumentException(sprintf(
752                  'A method by name %s already exists in this class.',
753                  $methodName
754              ));
755          }
756   
757          $this->methods[strtolower($methodName)] = $method;
758          return $this;
759      }
760   
761      /**
762       * @return MethodGenerator[]
763       */
764      public function getMethods()
765      {
766          return $this->methods;
767      }
768   
769      /**
770       * @param  string $methodName
771       * @return MethodGenerator|false
772       */
773      public function getMethod($methodName)
774      {
775          return $this->hasMethod($methodName) ? $this->methods[strtolower($methodName)] : false;
776      }
777   
778      /**
779       * @param  string $methodName
780       * @return ClassGenerator
781       */
782      public function removeMethod($methodName)
783      {
784          if ($this->hasMethod($methodName)) {
785              unset($this->methods[strtolower($methodName)]);
786          }
787   
788          return $this;
789      }
790   
791      /**
792       * @param  string $methodName
793       * @return bool
794       */
795      public function hasMethod($methodName)
796      {
797          return isset($this->methods[strtolower($methodName)]);
798      }
799   
800      /**
801       * @inherit Zend\Code\Generator\TraitUsageInterface
802       */
803      public function addTrait($trait)
804      {
805          $this->traitUsageGenerator->addTrait($trait);
806          return $this;
807      }
808   
809      /**
810       * @inherit Zend\Code\Generator\TraitUsageInterface
811       */
812      public function addTraits(array $traits)
813      {
814          $this->traitUsageGenerator->addTraits($traits);
815          return $this;
816      }
817   
818      /**
819       * @inherit Zend\Code\Generator\TraitUsageInterface
820       */
821      public function hasTrait($traitName)
822      {
823          return $this->traitUsageGenerator->hasTrait($traitName);
824      }
825   
826      /**
827       * @inherit Zend\Code\Generator\TraitUsageInterface
828       */
829      public function getTraits()
830      {
831          return $this->traitUsageGenerator->getTraits();
832      }
833   
834      /**
835       * @inherit Zend\Code\Generator\TraitUsageInterface
836       */
837      public function removeTrait($traitName)
838      {
839          return $this->traitUsageGenerator->removeTrait($traitName);
840      }
841   
842      /**
843       * @inherit Zend\Code\Generator\TraitUsageInterface
844       */
845      public function addTraitAlias($method, $alias, $visibility = null)
846      {
847          $this->traitUsageGenerator->addTraitAlias($method, $alias, $visibility);
848          return $this;
849      }
850   
851      /**
852       * @inherit Zend\Code\Generator\TraitUsageInterface
853       */
854      public function getTraitAliases()
855      {
856          return $this->traitUsageGenerator->getTraitAliases();
857      }
858   
859      /**
860       * @inherit Zend\Code\Generator\TraitUsageInterface
861       */
862      public function addTraitOverride($method, $traitsToReplace)
863      {
864          $this->traitUsageGenerator->addTraitOverride($method, $traitsToReplace);
865          return $this;
866      }
867   
868      /**
869       * @inherit Zend\Code\Generator\TraitUsageInterface
870       */
871      public function removeTraitOverride($method, $overridesToRemove = null)
872      {
873          $this->traitUsageGenerator->removeTraitOverride($method, $overridesToRemove);
874   
875          return $this;
876      }
877   
878      /**
879       * @inherit Zend\Code\Generator\TraitUsageInterface
880       */
881      public function getTraitOverrides()
882      {
883          return $this->traitUsageGenerator->getTraitOverrides();
884      }
885   
886      /**
887       * @return bool
888       */
889      public function isSourceDirty()
890      {
891          if (($docBlock = $this->getDocBlock()) && $docBlock->isSourceDirty()) {
892              return true;
893          }
894   
895          foreach ($this->getProperties() as $property) {
896              if ($property->isSourceDirty()) {
897                  return true;
898              }
899          }
900   
901          foreach ($this->getMethods() as $method) {
902              if ($method->isSourceDirty()) {
903                  return true;
904              }
905          }
906   
907          return parent::isSourceDirty();
908      }
909   
910      /**
911       * @inherit Zend\Code\Generator\GeneratorInterface
912       */
913      public function generate()
914      {
915          if (!$this->isSourceDirty()) {
916              $output = $this->getSourceContent();
917              if (!empty($output)) {
918                  return $output;
919              }
920          }
921   
922          $indent = $this->getIndentation();
923          $output = '';
924   
925          if (null !== ($namespace = $this->getNamespaceName())) {
926              $output .= 'namespace ' . $namespace . ';' . self::LINE_FEED . self::LINE_FEED;
927          }
928   
929          $uses = $this->getUses();
930   
931          if (!empty($uses)) {
932              foreach ($uses as $use) {
933                  $output .= 'use ' . $use . ';' . self::LINE_FEED;
934              }
935   
936              $output .= self::LINE_FEED;
937          }
938   
939          if (null !== ($docBlock = $this->getDocBlock())) {
940              $docBlock->setIndentation('');
941              $output .= $docBlock->generate();
942          }
943   
944          if ($this->isAbstract()) {
945              $output .= 'abstract ';
946          } elseif ($this->isFinal()) {
947              $output .= 'final ';
948          }
949   
950          $output .= static::OBJECT_TYPE . ' ' . $this->getName();
951   
952          if (!empty($this->extendedClass)) {
953              $output .= ' extends ' . $this->extendedClass;
954          }
955   
956          $implemented = $this->getImplementedInterfaces();
957   
958          if (!empty($implemented)) {
959              $output .= ' implements ' . implode(', ', $implemented);
960          }
961   
962          $output .= self::LINE_FEED . '{' . self::LINE_FEED . self::LINE_FEED;
963          $output .= $this->traitUsageGenerator->generate();
964   
965          $constants = $this->getConstants();
966   
967          foreach ($constants as $constant) {
968              $output .= $constant->generate() . self::LINE_FEED . self::LINE_FEED;
969          }
970   
971          $properties = $this->getProperties();
972   
973          foreach ($properties as $property) {
974              $output .= $property->generate() . self::LINE_FEED . self::LINE_FEED;
975          }
976   
977          $methods = $this->getMethods();
978   
979          foreach ($methods as $method) {
980              $output .= $method->generate() . self::LINE_FEED;
981          }
982   
983          $output .= self::LINE_FEED . '}' . self::LINE_FEED;
984   
985          return $output;
986      }
987  }
988