| 1: | <?php | 
| 2: |  | 
| 3: | declare(strict_types=1); | 
| 4: |  | 
| 5: | namespace PHPStan\BetterReflection\Reflection\Adapter; | 
| 6: |  | 
| 7: | use OutOfBoundsException; | 
| 8: | use ReflectionClass as CoreReflectionClass; | 
| 9: | use ReflectionException as CoreReflectionException; | 
| 10: | use ReflectionExtension as CoreReflectionExtension; | 
| 11: | use ReflectionMethod as CoreReflectionMethod; | 
| 12: | use ReturnTypeWillChange; | 
| 13: | use PHPStan\BetterReflection\Reflection\ReflectionAttribute as BetterReflectionAttribute; | 
| 14: | use PHPStan\BetterReflection\Reflection\ReflectionClass as BetterReflectionClass; | 
| 15: | use PHPStan\BetterReflection\Reflection\ReflectionClassConstant as BetterReflectionClassConstant; | 
| 16: | use PHPStan\BetterReflection\Reflection\ReflectionEnum as BetterReflectionEnum; | 
| 17: | use PHPStan\BetterReflection\Reflection\ReflectionEnumCase as BetterReflectionEnumCase; | 
| 18: | use PHPStan\BetterReflection\Reflection\ReflectionMethod as BetterReflectionMethod; | 
| 19: | use PHPStan\BetterReflection\Reflection\ReflectionProperty as BetterReflectionProperty; | 
| 20: | use PHPStan\BetterReflection\Util\ClassExistenceChecker; | 
| 21: | use PHPStan\BetterReflection\Util\FileHelper; | 
| 22: | use ValueError; | 
| 23: |  | 
| 24: | use function array_combine; | 
| 25: | use function array_map; | 
| 26: | use function array_values; | 
| 27: | use function constant; | 
| 28: | use function func_get_args; | 
| 29: | use function func_num_args; | 
| 30: | use function sprintf; | 
| 31: | use function strtolower; | 
| 32: |  | 
| 33: |  | 
| 34: | final class ReflectionClass extends CoreReflectionClass | 
| 35: | { | 
| 36: | public const IS_READONLY = 65536; | 
| 37: |  | 
| 38: |  | 
| 39: |  | 
| 40: | private $betterReflectionClass; | 
| 41: |  | 
| 42: |  | 
| 43: |  | 
| 44: |  | 
| 45: | public function __construct($betterReflectionClass) | 
| 46: | { | 
| 47: | $this->betterReflectionClass = $betterReflectionClass; | 
| 48: | unset($this->name); | 
| 49: | } | 
| 50: |  | 
| 51: | public function __toString(): string | 
| 52: | { | 
| 53: | return $this->betterReflectionClass->__toString(); | 
| 54: | } | 
| 55: |  | 
| 56: |  | 
| 57: |  | 
| 58: |  | 
| 59: | public function __get(string $name) | 
| 60: | { | 
| 61: | if ($name === 'name') { | 
| 62: | return $this->betterReflectionClass->getName(); | 
| 63: | } | 
| 64: |  | 
| 65: | throw new OutOfBoundsException(sprintf('Property %s::$%s does not exist.', self::class, $name)); | 
| 66: | } | 
| 67: |  | 
| 68: |  | 
| 69: | public function getName(): string | 
| 70: | { | 
| 71: | return $this->betterReflectionClass->getName(); | 
| 72: | } | 
| 73: |  | 
| 74: | public function isAnonymous(): bool | 
| 75: | { | 
| 76: | return $this->betterReflectionClass->isAnonymous(); | 
| 77: | } | 
| 78: |  | 
| 79: | public function isInternal(): bool | 
| 80: | { | 
| 81: | return $this->betterReflectionClass->isInternal(); | 
| 82: | } | 
| 83: |  | 
| 84: | public function isUserDefined(): bool | 
| 85: | { | 
| 86: | return $this->betterReflectionClass->isUserDefined(); | 
| 87: | } | 
| 88: |  | 
| 89: | public function isInstantiable(): bool | 
| 90: | { | 
| 91: | return $this->betterReflectionClass->isInstantiable(); | 
| 92: | } | 
| 93: |  | 
| 94: | public function isCloneable(): bool | 
| 95: | { | 
| 96: | return $this->betterReflectionClass->isCloneable(); | 
| 97: | } | 
| 98: |  | 
| 99: |  | 
| 100: |  | 
| 101: |  | 
| 102: | #[ReturnTypeWillChange] | 
| 103: | public function getFileName() | 
| 104: | { | 
| 105: | $fileName = $this->betterReflectionClass->getFileName(); | 
| 106: |  | 
| 107: | return $fileName !== null ? FileHelper::normalizeSystemPath($fileName) : false; | 
| 108: | } | 
| 109: |  | 
| 110: |  | 
| 111: |  | 
| 112: |  | 
| 113: | #[ReturnTypeWillChange] | 
| 114: | public function getStartLine() | 
| 115: | { | 
| 116: | return $this->betterReflectionClass->getStartLine(); | 
| 117: | } | 
| 118: |  | 
| 119: |  | 
| 120: |  | 
| 121: |  | 
| 122: | #[ReturnTypeWillChange] | 
| 123: | public function getEndLine() | 
| 124: | { | 
| 125: | return $this->betterReflectionClass->getEndLine(); | 
| 126: | } | 
| 127: |  | 
| 128: |  | 
| 129: |  | 
| 130: |  | 
| 131: | #[ReturnTypeWillChange] | 
| 132: | public function getDocComment() | 
| 133: | { | 
| 134: | return $this->betterReflectionClass->getDocComment() ?? false; | 
| 135: | } | 
| 136: |  | 
| 137: |  | 
| 138: | public function getConstructor(): ?CoreReflectionMethod | 
| 139: | { | 
| 140: | $constructor = $this->betterReflectionClass->getConstructor(); | 
| 141: |  | 
| 142: | if ($constructor === null) { | 
| 143: | return null; | 
| 144: | } | 
| 145: |  | 
| 146: | return new ReflectionMethod($constructor); | 
| 147: | } | 
| 148: |  | 
| 149: |  | 
| 150: |  | 
| 151: |  | 
| 152: | public function hasMethod($name): bool | 
| 153: | { | 
| 154: | if ($name === '') { | 
| 155: | return false; | 
| 156: | } | 
| 157: |  | 
| 158: | return $this->betterReflectionClass->hasMethod($name); | 
| 159: | } | 
| 160: |  | 
| 161: |  | 
| 162: |  | 
| 163: |  | 
| 164: |  | 
| 165: | public function getMethod($name): CoreReflectionMethod | 
| 166: | { | 
| 167: | $method = $name !== '' ? $this->betterReflectionClass->getMethod($name) : null; | 
| 168: |  | 
| 169: | if ($method === null) { | 
| 170: | throw new CoreReflectionException(sprintf('Method %s::%s() does not exist', $this->betterReflectionClass->getName(), $name)); | 
| 171: | } | 
| 172: |  | 
| 173: | return new ReflectionMethod($method); | 
| 174: | } | 
| 175: |  | 
| 176: |  | 
| 177: |  | 
| 178: |  | 
| 179: |  | 
| 180: | public function getMethods($filter = null): array | 
| 181: | { | 
| 182: | return array_values(array_map(static function (BetterReflectionMethod $method) : ReflectionMethod { | 
| 183: | return new ReflectionMethod($method); | 
| 184: | }, $this->betterReflectionClass->getMethods($filter ?? 0))); | 
| 185: | } | 
| 186: |  | 
| 187: |  | 
| 188: |  | 
| 189: |  | 
| 190: | public function hasProperty($name): bool | 
| 191: | { | 
| 192: | if ($name === '') { | 
| 193: | return false; | 
| 194: | } | 
| 195: |  | 
| 196: | return $this->betterReflectionClass->hasProperty($name); | 
| 197: | } | 
| 198: |  | 
| 199: |  | 
| 200: |  | 
| 201: |  | 
| 202: |  | 
| 203: | public function getProperty($name): \ReflectionProperty | 
| 204: | { | 
| 205: | $betterReflectionProperty = $name !== '' ? $this->betterReflectionClass->getProperty($name) : null; | 
| 206: |  | 
| 207: | if ($betterReflectionProperty === null) { | 
| 208: | throw new CoreReflectionException(sprintf('Property %s::$%s does not exist', $this->betterReflectionClass->getName(), $name)); | 
| 209: | } | 
| 210: |  | 
| 211: | return new ReflectionProperty($betterReflectionProperty); | 
| 212: | } | 
| 213: |  | 
| 214: |  | 
| 215: |  | 
| 216: |  | 
| 217: |  | 
| 218: | public function getProperties($filter = null): array | 
| 219: | { | 
| 220: | return array_values(array_map(static function (BetterReflectionProperty $property) : ReflectionProperty { | 
| 221: | return new ReflectionProperty($property); | 
| 222: | }, $this->betterReflectionClass->getProperties($filter ?? 0))); | 
| 223: | } | 
| 224: |  | 
| 225: |  | 
| 226: |  | 
| 227: |  | 
| 228: | public function hasConstant($name): bool | 
| 229: | { | 
| 230: | if ($name === '') { | 
| 231: | return false; | 
| 232: | } | 
| 233: |  | 
| 234: | if ($this->betterReflectionClass instanceof BetterReflectionEnum && $this->betterReflectionClass->hasCase($name)) { | 
| 235: | return true; | 
| 236: | } | 
| 237: |  | 
| 238: | return $this->betterReflectionClass->hasConstant($name); | 
| 239: | } | 
| 240: |  | 
| 241: |  | 
| 242: |  | 
| 243: |  | 
| 244: |  | 
| 245: |  | 
| 246: |  | 
| 247: |  | 
| 248: | public function getConstants(?int $filter = null): array | 
| 249: | { | 
| 250: | return array_map(function ($betterConstantOrEnumCase) { | 
| 251: | return $this->getConstantValue($betterConstantOrEnumCase); | 
| 252: | }, $this->filterBetterReflectionClassConstants($filter)); | 
| 253: | } | 
| 254: |  | 
| 255: |  | 
| 256: |  | 
| 257: |  | 
| 258: |  | 
| 259: | #[ReturnTypeWillChange] | 
| 260: | public function getConstant($name) | 
| 261: | { | 
| 262: | if ($name === '') { | 
| 263: | return false; | 
| 264: | } | 
| 265: |  | 
| 266: | if ($this->betterReflectionClass instanceof BetterReflectionEnum) { | 
| 267: | $enumCase = $this->betterReflectionClass->getCase($name); | 
| 268: | if ($enumCase !== null) { | 
| 269: | return $this->getConstantValue($enumCase); | 
| 270: | } | 
| 271: | } | 
| 272: |  | 
| 273: | $betterReflectionConstant = $this->betterReflectionClass->getConstant($name); | 
| 274: | if ($betterReflectionConstant === null) { | 
| 275: | return false; | 
| 276: | } | 
| 277: |  | 
| 278: | return $betterReflectionConstant->getValue(); | 
| 279: | } | 
| 280: |  | 
| 281: |  | 
| 282: |  | 
| 283: |  | 
| 284: |  | 
| 285: | private function getConstantValue($betterConstantOrEnumCase) | 
| 286: | { | 
| 287: | if ($betterConstantOrEnumCase instanceof BetterReflectionEnumCase) { | 
| 288: | throw new Exception\NotImplemented('Not implemented'); | 
| 289: | } | 
| 290: |  | 
| 291: | return $betterConstantOrEnumCase->getValue(); | 
| 292: | } | 
| 293: |  | 
| 294: |  | 
| 295: |  | 
| 296: |  | 
| 297: |  | 
| 298: | #[ReturnTypeWillChange] | 
| 299: | public function getReflectionConstant($name) | 
| 300: | { | 
| 301: | if ($name === '') { | 
| 302: | return false; | 
| 303: | } | 
| 304: |  | 
| 305: | if ($this->betterReflectionClass instanceof BetterReflectionEnum) { | 
| 306: | $enumCase = $this->betterReflectionClass->getCase($name); | 
| 307: | if ($enumCase !== null) { | 
| 308: | return new ReflectionClassConstant($enumCase); | 
| 309: | } | 
| 310: | } | 
| 311: |  | 
| 312: | $betterReflectionConstant = $this->betterReflectionClass->getConstant($name); | 
| 313: | if ($betterReflectionConstant === null) { | 
| 314: | return false; | 
| 315: | } | 
| 316: |  | 
| 317: | return new ReflectionClassConstant($betterReflectionConstant); | 
| 318: | } | 
| 319: |  | 
| 320: |  | 
| 321: |  | 
| 322: |  | 
| 323: |  | 
| 324: |  | 
| 325: | public function getReflectionConstants(?int $filter = null): array | 
| 326: | { | 
| 327: | return array_values(array_map(static function ($betterConstantOrEnum) : ReflectionClassConstant { | 
| 328: | return new ReflectionClassConstant($betterConstantOrEnum); | 
| 329: | }, $this->filterBetterReflectionClassConstants($filter))); | 
| 330: | } | 
| 331: |  | 
| 332: |  | 
| 333: |  | 
| 334: |  | 
| 335: |  | 
| 336: |  | 
| 337: | private function filterBetterReflectionClassConstants(?int $filter): array | 
| 338: | { | 
| 339: | $reflectionConstants = $this->betterReflectionClass->getConstants($filter ?? 0); | 
| 340: |  | 
| 341: | if ( | 
| 342: | $this->betterReflectionClass instanceof BetterReflectionEnum | 
| 343: | && ( | 
| 344: | $filter === null | 
| 345: | || $filter & ReflectionClassConstant::IS_PUBLIC | 
| 346: | ) | 
| 347: | ) { | 
| 348: | $reflectionConstants += $this->betterReflectionClass->getCases(); | 
| 349: | } | 
| 350: |  | 
| 351: | return $reflectionConstants; | 
| 352: | } | 
| 353: |  | 
| 354: |  | 
| 355: | public function getInterfaces(): array | 
| 356: | { | 
| 357: | return array_map(static function (BetterReflectionClass $interface) : self { | 
| 358: | return new self($interface); | 
| 359: | }, $this->betterReflectionClass->getInterfaces()); | 
| 360: | } | 
| 361: |  | 
| 362: |  | 
| 363: | public function getInterfaceNames(): array | 
| 364: | { | 
| 365: | return $this->betterReflectionClass->getInterfaceNames(); | 
| 366: | } | 
| 367: |  | 
| 368: | public function isInterface(): bool | 
| 369: | { | 
| 370: | return $this->betterReflectionClass->isInterface(); | 
| 371: | } | 
| 372: |  | 
| 373: |  | 
| 374: | public function getTraits(): array | 
| 375: | { | 
| 376: | $traits = $this->betterReflectionClass->getTraits(); | 
| 377: |  | 
| 378: |  | 
| 379: | $traitNames = array_map(static function (BetterReflectionClass $trait) : string { | 
| 380: | return $trait->getName(); | 
| 381: | }, $traits); | 
| 382: |  | 
| 383: | return array_combine($traitNames, array_map(static function (BetterReflectionClass $trait) : self { | 
| 384: | return new self($trait); | 
| 385: | }, $traits)); | 
| 386: | } | 
| 387: |  | 
| 388: |  | 
| 389: | public function getTraitNames(): array | 
| 390: | { | 
| 391: | return $this->betterReflectionClass->getTraitNames(); | 
| 392: | } | 
| 393: |  | 
| 394: |  | 
| 395: | public function getTraitAliases(): array | 
| 396: | { | 
| 397: | return $this->betterReflectionClass->getTraitAliases(); | 
| 398: | } | 
| 399: |  | 
| 400: | public function isTrait(): bool | 
| 401: | { | 
| 402: | return $this->betterReflectionClass->isTrait(); | 
| 403: | } | 
| 404: |  | 
| 405: | public function isAbstract(): bool | 
| 406: | { | 
| 407: | return $this->betterReflectionClass->isAbstract(); | 
| 408: | } | 
| 409: |  | 
| 410: | public function isFinal(): bool | 
| 411: | { | 
| 412: | return $this->betterReflectionClass->isFinal(); | 
| 413: | } | 
| 414: |  | 
| 415: | public function isReadOnly(): bool | 
| 416: | { | 
| 417: | return $this->betterReflectionClass->isReadOnly(); | 
| 418: | } | 
| 419: |  | 
| 420: | public function getModifiers(): int | 
| 421: | { | 
| 422: | return $this->betterReflectionClass->getModifiers(); | 
| 423: | } | 
| 424: |  | 
| 425: |  | 
| 426: |  | 
| 427: |  | 
| 428: | public function isInstance($object): bool | 
| 429: | { | 
| 430: | return $this->betterReflectionClass->isInstance($object); | 
| 431: | } | 
| 432: |  | 
| 433: |  | 
| 434: |  | 
| 435: |  | 
| 436: |  | 
| 437: |  | 
| 438: | #[ReturnTypeWillChange] | 
| 439: | public function newInstance($arg = null, ...$args) | 
| 440: | { | 
| 441: | ClassExistenceChecker::classExists($this->getName(), true); | 
| 442: | $reflection = new CoreReflectionClass($this->getName()); | 
| 443: |  | 
| 444: | return $reflection->newInstance(...func_get_args()); | 
| 445: | } | 
| 446: |  | 
| 447: | public function newInstanceWithoutConstructor(): object | 
| 448: | { | 
| 449: | ClassExistenceChecker::classExists($this->getName(), true); | 
| 450: | $reflection = new CoreReflectionClass($this->getName()); | 
| 451: |  | 
| 452: | return $reflection->newInstanceWithoutConstructor(); | 
| 453: | } | 
| 454: |  | 
| 455: | public function newInstanceArgs(array $args = null): object | 
| 456: | { | 
| 457: | ClassExistenceChecker::classExists($this->getName(), true); | 
| 458: | $reflection = new CoreReflectionClass($this->getName()); | 
| 459: |  | 
| 460: | return $reflection->newInstanceArgs($args); | 
| 461: | } | 
| 462: |  | 
| 463: |  | 
| 464: |  | 
| 465: |  | 
| 466: | #[ReturnTypeWillChange] | 
| 467: | public function getParentClass() | 
| 468: | { | 
| 469: | $parentClass = $this->betterReflectionClass->getParentClass(); | 
| 470: |  | 
| 471: | if ($parentClass === null) { | 
| 472: | return false; | 
| 473: | } | 
| 474: |  | 
| 475: | return new self($parentClass); | 
| 476: | } | 
| 477: |  | 
| 478: |  | 
| 479: |  | 
| 480: |  | 
| 481: | public function isSubclassOf($class): bool | 
| 482: | { | 
| 483: | $realParentClassNames = $this->betterReflectionClass->getParentClassNames(); | 
| 484: |  | 
| 485: | $parentClassNames = array_combine(array_map(static function (string $parentClassName) : string { | 
| 486: | return strtolower($parentClassName); | 
| 487: | }, $realParentClassNames), $realParentClassNames); | 
| 488: |  | 
| 489: | $className           = $class instanceof CoreReflectionClass ? $class->getName() : $class; | 
| 490: | $lowercasedClassName = strtolower($className); | 
| 491: |  | 
| 492: | $realParentClassName = $parentClassNames[$lowercasedClassName] ?? $className; | 
| 493: |  | 
| 494: | return $this->betterReflectionClass->isSubclassOf($realParentClassName) || $this->implementsInterface($className); | 
| 495: | } | 
| 496: |  | 
| 497: |  | 
| 498: |  | 
| 499: |  | 
| 500: |  | 
| 501: |  | 
| 502: | public function getStaticProperties(): array | 
| 503: | { | 
| 504: | return $this->betterReflectionClass->getStaticProperties(); | 
| 505: | } | 
| 506: |  | 
| 507: |  | 
| 508: |  | 
| 509: |  | 
| 510: | #[ReturnTypeWillChange] | 
| 511: | public function getStaticPropertyValue($name, $default = null) | 
| 512: | { | 
| 513: | $betterReflectionProperty = $name !== '' ? $this->betterReflectionClass->getProperty($name) : null; | 
| 514: |  | 
| 515: | if ($betterReflectionProperty === null) { | 
| 516: | if (func_num_args() === 2) { | 
| 517: | return $default; | 
| 518: | } | 
| 519: |  | 
| 520: | throw new CoreReflectionException(sprintf('Property %s::$%s does not exist', $this->betterReflectionClass->getName(), $name)); | 
| 521: | } | 
| 522: |  | 
| 523: | $property = new ReflectionProperty($betterReflectionProperty); | 
| 524: |  | 
| 525: | if (! $property->isStatic()) { | 
| 526: | throw new CoreReflectionException(sprintf('Property %s::$%s does not exist', $this->betterReflectionClass->getName(), $name)); | 
| 527: | } | 
| 528: |  | 
| 529: | return $property->getValue(); | 
| 530: | } | 
| 531: |  | 
| 532: |  | 
| 533: |  | 
| 534: |  | 
| 535: | public function setStaticPropertyValue($name, $value): void | 
| 536: | { | 
| 537: | $betterReflectionProperty = $name !== '' ? $this->betterReflectionClass->getProperty($name) : null; | 
| 538: |  | 
| 539: | if ($betterReflectionProperty === null) { | 
| 540: | throw new CoreReflectionException(sprintf('Class %s does not have a property named %s', $this->betterReflectionClass->getName(), $name)); | 
| 541: | } | 
| 542: |  | 
| 543: | $property = new ReflectionProperty($betterReflectionProperty); | 
| 544: |  | 
| 545: | if (! $property->isStatic()) { | 
| 546: | throw new CoreReflectionException(sprintf('Class %s does not have a property named %s', $this->betterReflectionClass->getName(), $name)); | 
| 547: | } | 
| 548: |  | 
| 549: | $property->setValue($value); | 
| 550: | } | 
| 551: |  | 
| 552: |  | 
| 553: | public function getDefaultProperties(): array | 
| 554: | { | 
| 555: | return $this->betterReflectionClass->getDefaultProperties(); | 
| 556: | } | 
| 557: |  | 
| 558: | public function isIterateable(): bool | 
| 559: | { | 
| 560: | return $this->betterReflectionClass->isIterateable(); | 
| 561: | } | 
| 562: |  | 
| 563: | public function isIterable(): bool | 
| 564: | { | 
| 565: | return $this->isIterateable(); | 
| 566: | } | 
| 567: |  | 
| 568: |  | 
| 569: |  | 
| 570: |  | 
| 571: | public function implementsInterface($interface): bool | 
| 572: | { | 
| 573: | $realInterfaceNames = $this->betterReflectionClass->getInterfaceNames(); | 
| 574: |  | 
| 575: | $interfaceNames = array_combine(array_map(static function (string $interfaceName) : string { | 
| 576: | return strtolower($interfaceName); | 
| 577: | }, $realInterfaceNames), $realInterfaceNames); | 
| 578: |  | 
| 579: | $interfaceName          = $interface instanceof CoreReflectionClass ? $interface->getName() : $interface; | 
| 580: | $lowercasedIntefaceName = strtolower($interfaceName); | 
| 581: |  | 
| 582: | $realInterfaceName = $interfaceNames[$lowercasedIntefaceName] ?? $interfaceName; | 
| 583: |  | 
| 584: | return $this->betterReflectionClass->implementsInterface($realInterfaceName); | 
| 585: | } | 
| 586: |  | 
| 587: | public function getExtension(): ?CoreReflectionExtension | 
| 588: | { | 
| 589: | throw new Exception\NotImplemented('Not implemented'); | 
| 590: | } | 
| 591: |  | 
| 592: |  | 
| 593: |  | 
| 594: |  | 
| 595: | #[ReturnTypeWillChange] | 
| 596: | public function getExtensionName() | 
| 597: | { | 
| 598: | return $this->betterReflectionClass->getExtensionName() ?? false; | 
| 599: | } | 
| 600: |  | 
| 601: | public function inNamespace(): bool | 
| 602: | { | 
| 603: | return $this->betterReflectionClass->inNamespace(); | 
| 604: | } | 
| 605: |  | 
| 606: | public function getNamespaceName(): string | 
| 607: | { | 
| 608: | return $this->betterReflectionClass->getNamespaceName() ?? ''; | 
| 609: | } | 
| 610: |  | 
| 611: | public function getShortName(): string | 
| 612: | { | 
| 613: | return $this->betterReflectionClass->getShortName(); | 
| 614: | } | 
| 615: |  | 
| 616: |  | 
| 617: |  | 
| 618: |  | 
| 619: |  | 
| 620: |  | 
| 621: | public function getAttributes(?string $name = null, int $flags = 0): array | 
| 622: | { | 
| 623: | if ($flags !== 0 && $flags !== ReflectionAttribute::IS_INSTANCEOF) { | 
| 624: | throw new ValueError('Argument #2 ($flags) must be a valid attribute filter flag'); | 
| 625: | } | 
| 626: |  | 
| 627: | if ($name !== null && $flags !== 0) { | 
| 628: | $attributes = $this->betterReflectionClass->getAttributesByInstance($name); | 
| 629: | } elseif ($name !== null) { | 
| 630: | $attributes = $this->betterReflectionClass->getAttributesByName($name); | 
| 631: | } else { | 
| 632: | $attributes = $this->betterReflectionClass->getAttributes(); | 
| 633: | } | 
| 634: |  | 
| 635: | return array_map(static function (BetterReflectionAttribute $betterReflectionAttribute) { | 
| 636: | return ReflectionAttributeFactory::create($betterReflectionAttribute); | 
| 637: | }, $attributes); | 
| 638: | } | 
| 639: |  | 
| 640: | public function isEnum(): bool | 
| 641: | { | 
| 642: | return $this->betterReflectionClass->isEnum(); | 
| 643: | } | 
| 644: | } | 
| 645: |  |