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