[ Index ]

PHP Cross Reference of phpBB-3.3.5-deutsch

title

Body

[close]

/vendor/zendframework/zend-code/src/Generator/ -> ClassGenerator.php (source)

   1  <?php
   2  /**
   3   * Zend Framework (http://framework.zend.com/)
   4   *
   5   * @link      http://github.com/zendframework/zf2 for the canonical source repository
   6   * @copyright Copyright (c) 2005-2016 Zend Technologies USA Inc. (http://www.zend.com)
   7   * @license   http://framework.zend.com/license/new-bsd New BSD License
   8   */
   9  
  10  namespace Zend\Code\Generator;
  11  
  12  use Zend\Code\Reflection\ClassReflection;
  13  
  14  use function array_diff;
  15  use function array_map;
  16  use function array_pop;
  17  use function array_search;
  18  use function array_values;
  19  use function array_walk;
  20  use function explode;
  21  use function get_class;
  22  use function gettype;
  23  use function implode;
  24  use function in_array;
  25  use function is_array;
  26  use function is_scalar;
  27  use function is_string;
  28  use function ltrim;
  29  use function sprintf;
  30  use function str_replace;
  31  use function strpos;
  32  use function strrpos;
  33  use function strstr;
  34  use function strtolower;
  35  use function substr;
  36  
  37  class ClassGenerator extends AbstractGenerator implements TraitUsageInterface
  38  {
  39      const OBJECT_TYPE = 'class';
  40      const IMPLEMENTS_KEYWORD = 'implements';
  41  
  42      const FLAG_ABSTRACT = 0x01;
  43      const FLAG_FINAL    = 0x02;
  44  
  45      /**
  46       * @var FileGenerator
  47       */
  48      protected $containingFileGenerator;
  49  
  50      /**
  51       * @var string
  52       */
  53      protected $namespaceName;
  54  
  55      /**
  56       * @var DocBlockGenerator
  57       */
  58      protected $docBlock;
  59  
  60      /**
  61       * @var string
  62       */
  63      protected $name;
  64  
  65      /**
  66       * @var bool
  67       */
  68      protected $flags = 0x00;
  69  
  70      /**
  71       * @var string
  72       */
  73      protected $extendedClass;
  74  
  75      /**
  76       * @var array Array of string names
  77       */
  78      protected $implementedInterfaces = [];
  79  
  80      /**
  81       * @var PropertyGenerator[] Array of properties
  82       */
  83      protected $properties = [];
  84  
  85      /**
  86       * @var PropertyGenerator[] Array of constants
  87       */
  88      protected $constants = [];
  89  
  90      /**
  91       * @var MethodGenerator[] Array of methods
  92       */
  93      protected $methods = [];
  94  
  95      /**
  96       * @var TraitUsageGenerator Object to encapsulate trait usage logic
  97       */
  98      protected $traitUsageGenerator;
  99  
 100      /**
 101       * Build a Code Generation Php Object from a Class Reflection
 102       *
 103       * @param  ClassReflection $classReflection
 104       * @return self
 105       */
 106      public static function fromReflection(ClassReflection $classReflection)
 107      {
 108          $cg = new static($classReflection->getName());
 109  
 110          $cg->setSourceContent($cg->getSourceContent());
 111          $cg->setSourceDirty(false);
 112  
 113          if ($classReflection->getDocComment() != '') {
 114              $cg->setDocBlock(DocBlockGenerator::fromReflection($classReflection->getDocBlock()));
 115          }
 116  
 117          $cg->setAbstract($classReflection->isAbstract());
 118  
 119          // set the namespace
 120          if ($classReflection->inNamespace()) {
 121              $cg->setNamespaceName($classReflection->getNamespaceName());
 122          }
 123  
 124          /* @var \Zend\Code\Reflection\ClassReflection $parentClass */
 125          $parentClass = $classReflection->getParentClass();
 126          $interfaces  = $classReflection->getInterfaces();
 127  
 128          if ($parentClass) {
 129              $cg->setExtendedClass($parentClass->getName());
 130  
 131              $interfaces = array_diff($interfaces, $parentClass->getInterfaces());
 132          }
 133  
 134          $interfaceNames = [];
 135          foreach ($interfaces as $interface) {
 136              /* @var \Zend\Code\Reflection\ClassReflection $interface */
 137              $interfaceNames[] = $interface->getName();
 138          }
 139  
 140          $cg->setImplementedInterfaces($interfaceNames);
 141  
 142          $properties = [];
 143  
 144          foreach ($classReflection->getProperties() as $reflectionProperty) {
 145              if ($reflectionProperty->getDeclaringClass()->getName() == $classReflection->getName()) {
 146                  $properties[] = PropertyGenerator::fromReflection($reflectionProperty);
 147              }
 148          }
 149  
 150          $cg->addProperties($properties);
 151  
 152          $constants = [];
 153  
 154          foreach ($classReflection->getConstants() as $name => $value) {
 155              $constants[] = [
 156                  'name' => $name,
 157                  'value' => $value,
 158              ];
 159          }
 160  
 161          $cg->addConstants($constants);
 162  
 163          $methods = [];
 164  
 165          foreach ($classReflection->getMethods() as $reflectionMethod) {
 166              $className = $cg->getNamespaceName() ? $cg->getNamespaceName() . '\\' . $cg->getName() : $cg->getName();
 167  
 168              if ($reflectionMethod->getDeclaringClass()->getName() == $className) {
 169                  $methods[] = MethodGenerator::fromReflection($reflectionMethod);
 170              }
 171          }
 172  
 173          $cg->addMethods($methods);
 174  
 175          return $cg;
 176      }
 177  
 178      /**
 179       * Generate from array
 180       *
 181       * @configkey name           string        [required] Class Name
 182       * @configkey filegenerator  FileGenerator File generator that holds this class
 183       * @configkey namespacename  string        The namespace for this class
 184       * @configkey docblock       string        The docblock information
 185       * @configkey flags          int           Flags, one of ClassGenerator::FLAG_ABSTRACT ClassGenerator::FLAG_FINAL
 186       * @configkey extendedclass  string        Class which this class is extending
 187       * @configkey implementedinterfaces
 188       * @configkey properties
 189       * @configkey methods
 190       *
 191       * @throws Exception\InvalidArgumentException
 192       * @param  array $array
 193       * @return self
 194       */
 195      public static function fromArray(array $array)
 196      {
 197          if (! isset($array['name'])) {
 198              throw new Exception\InvalidArgumentException(
 199                  'Class generator requires that a name is provided for this object'
 200              );
 201          }
 202  
 203          $cg = new static($array['name']);
 204          foreach ($array as $name => $value) {
 205              // normalize key
 206              switch (strtolower(str_replace(['.', '-', '_'], '', $name))) {
 207                  case 'containingfile':
 208                      $cg->setContainingFileGenerator($value);
 209                      break;
 210                  case 'namespacename':
 211                      $cg->setNamespaceName($value);
 212                      break;
 213                  case 'docblock':
 214                      $docBlock = $value instanceof DocBlockGenerator ? $value : DocBlockGenerator::fromArray($value);
 215                      $cg->setDocBlock($docBlock);
 216                      break;
 217                  case 'flags':
 218                      $cg->setFlags($value);
 219                      break;
 220                  case 'extendedclass':
 221                      $cg->setExtendedClass($value);
 222                      break;
 223                  case 'implementedinterfaces':
 224                      $cg->setImplementedInterfaces($value);
 225                      break;
 226                  case 'properties':
 227                      $cg->addProperties($value);
 228                      break;
 229                  case 'methods':
 230                      $cg->addMethods($value);
 231                      break;
 232              }
 233          }
 234  
 235          return $cg;
 236      }
 237  
 238      /**
 239       * @param  string $name
 240       * @param  string $namespaceName
 241       * @param  array|string $flags
 242       * @param  string $extends
 243       * @param  array $interfaces
 244       * @param  array $properties
 245       * @param  array $methods
 246       * @param  DocBlockGenerator $docBlock
 247       */
 248      public function __construct(
 249          $name = null,
 250          $namespaceName = null,
 251          $flags = null,
 252          $extends = null,
 253          $interfaces = [],
 254          $properties = [],
 255          $methods = [],
 256          $docBlock = null
 257      ) {
 258          $this->traitUsageGenerator = new TraitUsageGenerator($this);
 259  
 260          if ($name !== null) {
 261              $this->setName($name);
 262          }
 263          if ($namespaceName !== null) {
 264              $this->setNamespaceName($namespaceName);
 265          }
 266          if ($flags !== null) {
 267              $this->setFlags($flags);
 268          }
 269          if ($properties !== []) {
 270              $this->addProperties($properties);
 271          }
 272          if ($extends !== null) {
 273              $this->setExtendedClass($extends);
 274          }
 275          if (is_array($interfaces)) {
 276              $this->setImplementedInterfaces($interfaces);
 277          }
 278          if ($methods !== []) {
 279              $this->addMethods($methods);
 280          }
 281          if ($docBlock !== null) {
 282              $this->setDocBlock($docBlock);
 283          }
 284      }
 285  
 286      /**
 287       * @param  string $name
 288       * @return self
 289       */
 290      public function setName($name)
 291      {
 292          if (false !== strpos($name, '\\')) {
 293              $namespace = substr($name, 0, strrpos($name, '\\'));
 294              $name      = substr($name, strrpos($name, '\\') + 1);
 295              $this->setNamespaceName($namespace);
 296          }
 297  
 298          $this->name = $name;
 299          return $this;
 300      }
 301  
 302      /**
 303       * @return string
 304       */
 305      public function getName()
 306      {
 307          return $this->name;
 308      }
 309  
 310      /**
 311       * @param  string $namespaceName
 312       * @return self
 313       */
 314      public function setNamespaceName($namespaceName)
 315      {
 316          $this->namespaceName = $namespaceName;
 317          return $this;
 318      }
 319  
 320      /**
 321       * @return string
 322       */
 323      public function getNamespaceName()
 324      {
 325          return $this->namespaceName;
 326      }
 327  
 328      /**
 329       * @param  FileGenerator $fileGenerator
 330       * @return self
 331       */
 332      public function setContainingFileGenerator(FileGenerator $fileGenerator)
 333      {
 334          $this->containingFileGenerator = $fileGenerator;
 335          return $this;
 336      }
 337  
 338      /**
 339       * @return FileGenerator
 340       */
 341      public function getContainingFileGenerator()
 342      {
 343          return $this->containingFileGenerator;
 344      }
 345  
 346      /**
 347       * @param  DocBlockGenerator $docBlock
 348       * @return self
 349       */
 350      public function setDocBlock(DocBlockGenerator $docBlock)
 351      {
 352          $this->docBlock = $docBlock;
 353          return $this;
 354      }
 355  
 356      /**
 357       * @return DocBlockGenerator
 358       */
 359      public function getDocBlock()
 360      {
 361          return $this->docBlock;
 362      }
 363  
 364      /**
 365       * @param  array|string $flags
 366       * @return self
 367       */
 368      public function setFlags($flags)
 369      {
 370          if (is_array($flags)) {
 371              $flagsArray = $flags;
 372              $flags      = 0x00;
 373              foreach ($flagsArray as $flag) {
 374                  $flags |= $flag;
 375              }
 376          }
 377          // check that visibility is one of three
 378          $this->flags = $flags;
 379  
 380          return $this;
 381      }
 382  
 383      /**
 384       * @param  string $flag
 385       * @return self
 386       */
 387      public function addFlag($flag)
 388      {
 389          $this->setFlags($this->flags | $flag);
 390          return $this;
 391      }
 392  
 393      /**
 394       * @param  string $flag
 395       * @return self
 396       */
 397      public function removeFlag($flag)
 398      {
 399          $this->setFlags($this->flags & ~$flag);
 400          return $this;
 401      }
 402  
 403      /**
 404       * @param  bool $isAbstract
 405       * @return self
 406       */
 407      public function setAbstract($isAbstract)
 408      {
 409          return $isAbstract ? $this->addFlag(self::FLAG_ABSTRACT) : $this->removeFlag(self::FLAG_ABSTRACT);
 410      }
 411  
 412      /**
 413       * @return bool
 414       */
 415      public function isAbstract()
 416      {
 417          return (bool) ($this->flags & self::FLAG_ABSTRACT);
 418      }
 419  
 420      /**
 421       * @param  bool $isFinal
 422       * @return self
 423       */
 424      public function setFinal($isFinal)
 425      {
 426          return $isFinal ? $this->addFlag(self::FLAG_FINAL) : $this->removeFlag(self::FLAG_FINAL);
 427      }
 428  
 429      /**
 430       * @return bool
 431       */
 432      public function isFinal()
 433      {
 434          return $this->flags & self::FLAG_FINAL;
 435      }
 436  
 437      /**
 438       * @param  string $extendedClass
 439       * @return self
 440       */
 441      public function setExtendedClass($extendedClass)
 442      {
 443          $this->extendedClass = $extendedClass;
 444          return $this;
 445      }
 446  
 447      /**
 448       * @return string
 449       */
 450      public function getExtendedClass()
 451      {
 452          return $this->extendedClass;
 453      }
 454  
 455      /**
 456       * @return bool
 457       */
 458      public function hasExtentedClass()
 459      {
 460          return ! empty($this->extendedClass);
 461      }
 462  
 463      /**
 464       * @return self
 465       */
 466      public function removeExtentedClass()
 467      {
 468          $this->setExtendedClass(null);
 469          return $this;
 470      }
 471  
 472      /**
 473       * @param  array $implementedInterfaces
 474       * @return self
 475       */
 476      public function setImplementedInterfaces(array $implementedInterfaces)
 477      {
 478          array_map(function ($implementedInterface) {
 479              return (string) TypeGenerator::fromTypeString($implementedInterface);
 480          }, $implementedInterfaces);
 481  
 482          $this->implementedInterfaces = $implementedInterfaces;
 483          return $this;
 484      }
 485  
 486      /**
 487       * @return array
 488       */
 489      public function getImplementedInterfaces()
 490      {
 491          return $this->implementedInterfaces;
 492      }
 493  
 494      /**
 495       * @param string $implementedInterface
 496       * @return bool
 497       */
 498      public function hasImplementedInterface($implementedInterface)
 499      {
 500          $implementedInterface = (string) TypeGenerator::fromTypeString($implementedInterface);
 501          return in_array($implementedInterface, $this->implementedInterfaces);
 502      }
 503  
 504      /**
 505       * @param string $implementedInterface
 506       * @return self
 507       */
 508      public function removeImplementedInterface($implementedInterface)
 509      {
 510          $implementedInterface = (string) TypeGenerator::fromTypeString($implementedInterface);
 511          unset($this->implementedInterfaces[array_search($implementedInterface, $this->implementedInterfaces)]);
 512          return $this;
 513      }
 514  
 515      /**
 516       * @param  string $constantName
 517       * @return PropertyGenerator|false
 518       */
 519      public function getConstant($constantName)
 520      {
 521          if (isset($this->constants[$constantName])) {
 522              return $this->constants[$constantName];
 523          }
 524  
 525          return false;
 526      }
 527  
 528      /**
 529       * @return PropertyGenerator[] indexed by constant name
 530       */
 531      public function getConstants()
 532      {
 533          return $this->constants;
 534      }
 535  
 536      /**
 537       * @param  string $constantName
 538       * @return self
 539       */
 540      public function removeConstant($constantName)
 541      {
 542          unset($this->constants[$constantName]);
 543  
 544          return $this;
 545      }
 546  
 547      /**
 548       * @param  string $constantName
 549       * @return bool
 550       */
 551      public function hasConstant($constantName)
 552      {
 553          return isset($this->constants[$constantName]);
 554      }
 555  
 556      /**
 557       * Add constant from PropertyGenerator
 558       *
 559       * @param  PropertyGenerator           $constant
 560       * @throws Exception\InvalidArgumentException
 561       * @return self
 562       */
 563      public function addConstantFromGenerator(PropertyGenerator $constant)
 564      {
 565          $constantName = $constant->getName();
 566  
 567          if (isset($this->constants[$constantName])) {
 568              throw new Exception\InvalidArgumentException(sprintf(
 569                  'A constant by name %s already exists in this class.',
 570                  $constantName
 571              ));
 572          }
 573  
 574          if (! $constant->isConst()) {
 575              throw new Exception\InvalidArgumentException(sprintf(
 576                  'The value %s is not defined as a constant.',
 577                  $constantName
 578              ));
 579          }
 580  
 581          $this->constants[$constantName] = $constant;
 582  
 583          return $this;
 584      }
 585  
 586      /**
 587       * Add Constant
 588       *
 589       * @param  string                      $name Non-empty string
 590       * @param  string|int|null|float|array $value Scalar
 591       *
 592       * @throws Exception\InvalidArgumentException
 593       *
 594       * @return self
 595       */
 596      public function addConstant($name, $value)
 597      {
 598          if (empty($name) || ! is_string($name)) {
 599              throw new Exception\InvalidArgumentException(sprintf(
 600                  '%s expects string for name',
 601                  __METHOD__
 602              ));
 603          }
 604  
 605          $this->validateConstantValue($value);
 606  
 607          return $this->addConstantFromGenerator(
 608              new PropertyGenerator($name, new PropertyValueGenerator($value), PropertyGenerator::FLAG_CONSTANT)
 609          );
 610      }
 611  
 612      /**
 613       * @param  PropertyGenerator[]|array[] $constants
 614       *
 615       * @return self
 616       */
 617      public function addConstants(array $constants)
 618      {
 619          foreach ($constants as $constant) {
 620              if ($constant instanceof PropertyGenerator) {
 621                  $this->addPropertyFromGenerator($constant);
 622              } else {
 623                  if (is_array($constant)) {
 624                      $this->addConstant(...array_values($constant));
 625                  }
 626              }
 627          }
 628  
 629          return $this;
 630      }
 631  
 632      /**
 633       * @param  array $properties
 634       * @return self
 635       */
 636      public function addProperties(array $properties)
 637      {
 638          foreach ($properties as $property) {
 639              if ($property instanceof PropertyGenerator) {
 640                  $this->addPropertyFromGenerator($property);
 641              } else {
 642                  if (is_string($property)) {
 643                      $this->addProperty($property);
 644                  } elseif (is_array($property)) {
 645                      $this->addProperty(...array_values($property));
 646                  }
 647              }
 648          }
 649  
 650          return $this;
 651      }
 652  
 653      /**
 654       * Add Property from scalars
 655       *
 656       * @param  string $name
 657       * @param  string|array $defaultValue
 658       * @param  int $flags
 659       * @throws Exception\InvalidArgumentException
 660       * @return self
 661       */
 662      public function addProperty($name, $defaultValue = null, $flags = PropertyGenerator::FLAG_PUBLIC)
 663      {
 664          if (! is_string($name)) {
 665              throw new Exception\InvalidArgumentException(sprintf(
 666                  '%s::%s expects string for name',
 667                  get_class($this),
 668                  __FUNCTION__
 669              ));
 670          }
 671  
 672          // backwards compatibility
 673          // @todo remove this on next major version
 674          if ($flags === PropertyGenerator::FLAG_CONSTANT) {
 675              return $this->addConstant($name, $defaultValue);
 676          }
 677  
 678          return $this->addPropertyFromGenerator(new PropertyGenerator($name, $defaultValue, $flags));
 679      }
 680  
 681      /**
 682       * Add property from PropertyGenerator
 683       *
 684       * @param  PropertyGenerator           $property
 685       * @throws Exception\InvalidArgumentException
 686       * @return self
 687       */
 688      public function addPropertyFromGenerator(PropertyGenerator $property)
 689      {
 690          $propertyName = $property->getName();
 691  
 692          if (isset($this->properties[$propertyName])) {
 693              throw new Exception\InvalidArgumentException(sprintf(
 694                  'A property by name %s already exists in this class.',
 695                  $propertyName
 696              ));
 697          }
 698  
 699          // backwards compatibility
 700          // @todo remove this on next major version
 701          if ($property->isConst()) {
 702              return $this->addConstantFromGenerator($property);
 703          }
 704  
 705          $this->properties[$propertyName] = $property;
 706          return $this;
 707      }
 708  
 709      /**
 710       * @return PropertyGenerator[]
 711       */
 712      public function getProperties()
 713      {
 714          return $this->properties;
 715      }
 716  
 717      /**
 718       * @param  string $propertyName
 719       * @return PropertyGenerator|false
 720       */
 721      public function getProperty($propertyName)
 722      {
 723          foreach ($this->getProperties() as $property) {
 724              if ($property->getName() == $propertyName) {
 725                  return $property;
 726              }
 727          }
 728  
 729          return false;
 730      }
 731  
 732      /**
 733       * Add a class to "use" classes
 734       *
 735       * @param  string $use
 736       * @param  string|null $useAlias
 737       * @return self
 738       */
 739      public function addUse($use, $useAlias = null)
 740      {
 741          $this->traitUsageGenerator->addUse($use, $useAlias);
 742          return $this;
 743      }
 744  
 745      /**
 746       * @param string $use
 747       * @return bool
 748       */
 749      public function hasUse($use)
 750      {
 751          return $this->traitUsageGenerator->hasUse($use);
 752      }
 753  
 754      /**
 755       * @param  string $use
 756       * @return self
 757       */
 758      public function removeUse($use)
 759      {
 760          $this->traitUsageGenerator->removeUse($use);
 761          return $this;
 762      }
 763  
 764      /**
 765       * @param string $use
 766       * @return bool
 767       */
 768      public function hasUseAlias($use)
 769      {
 770          return $this->traitUsageGenerator->hasUseAlias($use);
 771      }
 772  
 773      /**
 774       * @param string $use
 775       * @return self
 776       */
 777      public function removeUseAlias($use)
 778      {
 779          $this->traitUsageGenerator->removeUseAlias($use);
 780          return $this;
 781      }
 782  
 783      /**
 784       * Returns the "use" classes
 785       *
 786       * @return array
 787       */
 788      public function getUses()
 789      {
 790          return $this->traitUsageGenerator->getUses();
 791      }
 792  
 793      /**
 794       * @param  string $propertyName
 795       * @return self
 796       */
 797      public function removeProperty($propertyName)
 798      {
 799          unset($this->properties[$propertyName]);
 800  
 801          return $this;
 802      }
 803  
 804      /**
 805       * @param  string $propertyName
 806       * @return bool
 807       */
 808      public function hasProperty($propertyName)
 809      {
 810          return isset($this->properties[$propertyName]);
 811      }
 812  
 813      /**
 814       * @param  array $methods
 815       * @return self
 816       */
 817      public function addMethods(array $methods)
 818      {
 819          foreach ($methods as $method) {
 820              if ($method instanceof MethodGenerator) {
 821                  $this->addMethodFromGenerator($method);
 822              } else {
 823                  if (is_string($method)) {
 824                      $this->addMethod($method);
 825                  } elseif (is_array($method)) {
 826                      $this->addMethod(...array_values($method));
 827                  }
 828              }
 829          }
 830  
 831          return $this;
 832      }
 833  
 834      /**
 835       * Add Method from scalars
 836       *
 837       * @param  string $name
 838       * @param  array $parameters
 839       * @param  int $flags
 840       * @param  string $body
 841       * @param  string $docBlock
 842       * @throws Exception\InvalidArgumentException
 843       * @return self
 844       */
 845      public function addMethod(
 846          $name,
 847          array $parameters = [],
 848          $flags = MethodGenerator::FLAG_PUBLIC,
 849          $body = null,
 850          $docBlock = null
 851      ) {
 852          if (! is_string($name)) {
 853              throw new Exception\InvalidArgumentException(sprintf(
 854                  '%s::%s expects string for name',
 855                  get_class($this),
 856                  __FUNCTION__
 857              ));
 858          }
 859  
 860          return $this->addMethodFromGenerator(new MethodGenerator($name, $parameters, $flags, $body, $docBlock));
 861      }
 862  
 863      /**
 864       * Add Method from MethodGenerator
 865       *
 866       * @param  MethodGenerator                    $method
 867       * @throws Exception\InvalidArgumentException
 868       * @return self
 869       */
 870      public function addMethodFromGenerator(MethodGenerator $method)
 871      {
 872          $methodName = $method->getName();
 873  
 874          if ($this->hasMethod($methodName)) {
 875              throw new Exception\InvalidArgumentException(sprintf(
 876                  'A method by name %s already exists in this class.',
 877                  $methodName
 878              ));
 879          }
 880  
 881          $this->methods[strtolower($methodName)] = $method;
 882          return $this;
 883      }
 884  
 885      /**
 886       * @return MethodGenerator[]
 887       */
 888      public function getMethods()
 889      {
 890          return $this->methods;
 891      }
 892  
 893      /**
 894       * @param  string $methodName
 895       * @return MethodGenerator|false
 896       */
 897      public function getMethod($methodName)
 898      {
 899          return $this->hasMethod($methodName) ? $this->methods[strtolower($methodName)] : false;
 900      }
 901  
 902      /**
 903       * @param  string $methodName
 904       * @return self
 905       */
 906      public function removeMethod($methodName)
 907      {
 908          unset($this->methods[strtolower($methodName)]);
 909  
 910          return $this;
 911      }
 912  
 913      /**
 914       * @param  string $methodName
 915       * @return bool
 916       */
 917      public function hasMethod($methodName)
 918      {
 919          return isset($this->methods[strtolower($methodName)]);
 920      }
 921  
 922      /**
 923       * @inheritDoc
 924       */
 925      public function addTrait($trait)
 926      {
 927          $this->traitUsageGenerator->addTrait($trait);
 928          return $this;
 929      }
 930  
 931      /**
 932       * @inheritDoc
 933       */
 934      public function addTraits(array $traits)
 935      {
 936          $this->traitUsageGenerator->addTraits($traits);
 937          return $this;
 938      }
 939  
 940      /**
 941       * @inheritDoc
 942       */
 943      public function hasTrait($traitName)
 944      {
 945          return $this->traitUsageGenerator->hasTrait($traitName);
 946      }
 947  
 948      /**
 949       * @inheritDoc
 950       */
 951      public function getTraits()
 952      {
 953          return $this->traitUsageGenerator->getTraits();
 954      }
 955  
 956      /**
 957       * @inheritDoc
 958       */
 959      public function removeTrait($traitName)
 960      {
 961          return $this->traitUsageGenerator->removeTrait($traitName);
 962      }
 963  
 964      /**
 965       * @inheritDoc
 966       */
 967      public function addTraitAlias($method, $alias, $visibility = null)
 968      {
 969          $this->traitUsageGenerator->addTraitAlias($method, $alias, $visibility);
 970          return $this;
 971      }
 972  
 973      /**
 974       * @inheritDoc
 975       */
 976      public function getTraitAliases()
 977      {
 978          return $this->traitUsageGenerator->getTraitAliases();
 979      }
 980  
 981      /**
 982       * @inheritDoc
 983       */
 984      public function addTraitOverride($method, $traitsToReplace)
 985      {
 986          $this->traitUsageGenerator->addTraitOverride($method, $traitsToReplace);
 987          return $this;
 988      }
 989  
 990      /**
 991       * @inheritDoc
 992       */
 993      public function removeTraitOverride($method, $overridesToRemove = null)
 994      {
 995          $this->traitUsageGenerator->removeTraitOverride($method, $overridesToRemove);
 996  
 997          return $this;
 998      }
 999  
1000      /**
1001       * @inheritDoc
1002       */
1003      public function getTraitOverrides()
1004      {
1005          return $this->traitUsageGenerator->getTraitOverrides();
1006      }
1007  
1008      /**
1009       * @return bool
1010       */
1011      public function isSourceDirty()
1012      {
1013          if (($docBlock = $this->getDocBlock()) && $docBlock->isSourceDirty()) {
1014              return true;
1015          }
1016  
1017          foreach ($this->getProperties() as $property) {
1018              if ($property->isSourceDirty()) {
1019                  return true;
1020              }
1021          }
1022  
1023          foreach ($this->getMethods() as $method) {
1024              if ($method->isSourceDirty()) {
1025                  return true;
1026              }
1027          }
1028  
1029          return parent::isSourceDirty();
1030      }
1031  
1032      /**
1033       * @inheritDoc
1034       */
1035      public function generate()
1036      {
1037          if (! $this->isSourceDirty()) {
1038              $output = $this->getSourceContent();
1039              if (! empty($output)) {
1040                  return $output;
1041              }
1042          }
1043  
1044          $indent = $this->getIndentation();
1045          $output = '';
1046  
1047          if (null !== ($namespace = $this->getNamespaceName())) {
1048              $output .= 'namespace ' . $namespace . ';' . self::LINE_FEED . self::LINE_FEED;
1049          }
1050  
1051          $uses = $this->getUses();
1052  
1053          if (! empty($uses)) {
1054              foreach ($uses as $use) {
1055                  $output .= 'use ' . $use . ';' . self::LINE_FEED;
1056              }
1057  
1058              $output .= self::LINE_FEED;
1059          }
1060  
1061          if (null !== ($docBlock = $this->getDocBlock())) {
1062              $docBlock->setIndentation('');
1063              $output .= $docBlock->generate();
1064          }
1065  
1066          if ($this->isAbstract()) {
1067              $output .= 'abstract ';
1068          } elseif ($this->isFinal()) {
1069              $output .= 'final ';
1070          }
1071  
1072          $output .= static::OBJECT_TYPE . ' ' . $this->getName();
1073  
1074          if (! empty($this->extendedClass)) {
1075              $output .= ' extends ' . $this->generateShortOrCompleteClassname($this->extendedClass);
1076          }
1077  
1078          $implemented = $this->getImplementedInterfaces();
1079  
1080          if (! empty($implemented)) {
1081              $implemented = array_map([$this, 'generateShortOrCompleteClassname'], $implemented);
1082              $output .= ' ' . static::IMPLEMENTS_KEYWORD . ' ' . implode(', ', $implemented);
1083          }
1084  
1085          $output .= self::LINE_FEED . '{' . self::LINE_FEED . self::LINE_FEED;
1086          $output .= $this->traitUsageGenerator->generate();
1087  
1088          $constants = $this->getConstants();
1089  
1090          foreach ($constants as $constant) {
1091              $output .= $constant->generate() . self::LINE_FEED . self::LINE_FEED;
1092          }
1093  
1094          $properties = $this->getProperties();
1095  
1096          foreach ($properties as $property) {
1097              $output .= $property->generate() . self::LINE_FEED . self::LINE_FEED;
1098          }
1099  
1100          $methods = $this->getMethods();
1101  
1102          foreach ($methods as $method) {
1103              $output .= $method->generate() . self::LINE_FEED;
1104          }
1105  
1106          $output .= self::LINE_FEED . '}' . self::LINE_FEED;
1107  
1108          return $output;
1109      }
1110  
1111      /**
1112       * @param mixed $value
1113       *
1114       * @return void
1115       *
1116       * @throws Exception\InvalidArgumentException
1117       */
1118      private function validateConstantValue($value)
1119      {
1120          if (null === $value || is_scalar($value)) {
1121              return;
1122          }
1123  
1124          if (is_array($value)) {
1125              array_walk($value, [$this, 'validateConstantValue']);
1126  
1127              return;
1128          }
1129  
1130          throw new Exception\InvalidArgumentException(sprintf(
1131              'Expected value for constant, value must be a "scalar" or "null", "%s" found',
1132              gettype($value)
1133          ));
1134      }
1135  
1136      /**
1137       * @param string $fqnClassName
1138       *
1139       * @return string
1140       */
1141      private function generateShortOrCompleteClassname($fqnClassName)
1142      {
1143          $fqnClassName = ltrim($fqnClassName, '\\');
1144          $parts = explode('\\', $fqnClassName);
1145          $className = array_pop($parts);
1146          $classNamespace = implode('\\', $parts);
1147          $currentNamespace = (string) $this->getNamespaceName();
1148  
1149          if ($this->hasUseAlias($fqnClassName)) {
1150              return $this->traitUsageGenerator->getUseAlias($fqnClassName);
1151          }
1152          if ($this->hasUseAlias($classNamespace)) {
1153              $namespaceAlias = $this->traitUsageGenerator->getUseAlias($classNamespace);
1154  
1155              return $namespaceAlias . '\\' . $className;
1156          }
1157          if ($this->traitUsageGenerator->isUseAlias($fqnClassName)) {
1158              return $fqnClassName;
1159          }
1160          if ($this->traitUsageGenerator->isUseAlias($classNamespace)) {
1161              return $fqnClassName;
1162          }
1163          if ($classNamespace === $currentNamespace || in_array($fqnClassName, $this->getUses())) {
1164              return $className;
1165          }
1166  
1167          return '\\' . $fqnClassName;
1168      }
1169  }


Generated: Mon Oct 4 17:42:11 2021 Cross-referenced by PHPXref 0.7.1