Target.php 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. <?php
  2. namespace Doctrine\Common\Annotations\Annotation;
  3. use InvalidArgumentException;
  4. use function array_keys;
  5. use function get_class;
  6. use function gettype;
  7. use function implode;
  8. use function is_array;
  9. use function is_object;
  10. use function is_string;
  11. use function sprintf;
  12. /**
  13. * Annotation that can be used to signal to the parser
  14. * to check the annotation target during the parsing process.
  15. *
  16. * @Annotation
  17. */
  18. final class Target
  19. {
  20. public const TARGET_CLASS = 1;
  21. public const TARGET_METHOD = 2;
  22. public const TARGET_PROPERTY = 4;
  23. public const TARGET_ANNOTATION = 8;
  24. public const TARGET_FUNCTION = 16;
  25. public const TARGET_ALL = 31;
  26. /** @var array<string, int> */
  27. private static $map = [
  28. 'ALL' => self::TARGET_ALL,
  29. 'CLASS' => self::TARGET_CLASS,
  30. 'METHOD' => self::TARGET_METHOD,
  31. 'PROPERTY' => self::TARGET_PROPERTY,
  32. 'FUNCTION' => self::TARGET_FUNCTION,
  33. 'ANNOTATION' => self::TARGET_ANNOTATION,
  34. ];
  35. /** @phpstan-var list<string> */
  36. public $value;
  37. /**
  38. * Targets as bitmask.
  39. *
  40. * @var int
  41. */
  42. public $targets;
  43. /**
  44. * Literal target declaration.
  45. *
  46. * @var string
  47. */
  48. public $literal;
  49. /**
  50. * @throws InvalidArgumentException
  51. *
  52. * @phpstan-param array{value?: string|list<string>} $values
  53. */
  54. public function __construct(array $values)
  55. {
  56. if (! isset($values['value'])) {
  57. $values['value'] = null;
  58. }
  59. if (is_string($values['value'])) {
  60. $values['value'] = [$values['value']];
  61. }
  62. if (! is_array($values['value'])) {
  63. throw new InvalidArgumentException(
  64. sprintf(
  65. '@Target expects either a string value, or an array of strings, "%s" given.',
  66. is_object($values['value']) ? get_class($values['value']) : gettype($values['value'])
  67. )
  68. );
  69. }
  70. $bitmask = 0;
  71. foreach ($values['value'] as $literal) {
  72. if (! isset(self::$map[$literal])) {
  73. throw new InvalidArgumentException(
  74. sprintf(
  75. 'Invalid Target "%s". Available targets: [%s]',
  76. $literal,
  77. implode(', ', array_keys(self::$map))
  78. )
  79. );
  80. }
  81. $bitmask |= self::$map[$literal];
  82. }
  83. $this->targets = $bitmask;
  84. $this->value = $values['value'];
  85. $this->literal = implode(', ', $this->value);
  86. }
  87. }