[ Index ] |
PHP Cross Reference of phpBB-3.3.14-deutsch |
[Summary view] [Print] [Text view]
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 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Mon Nov 25 19:05:08 2024 | Cross-referenced by PHPXref 0.7.1 |