Modifiers.php 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. <?php declare(strict_types=1);
  2. namespace PhpParser;
  3. /**
  4. * Modifiers used (as a bit mask) by various flags subnodes, for example on classes, functions,
  5. * properties and constants.
  6. */
  7. final class Modifiers {
  8. public const PUBLIC = 1;
  9. public const PROTECTED = 2;
  10. public const PRIVATE = 4;
  11. public const STATIC = 8;
  12. public const ABSTRACT = 16;
  13. public const FINAL = 32;
  14. public const READONLY = 64;
  15. public const PUBLIC_SET = 128;
  16. public const PROTECTED_SET = 256;
  17. public const PRIVATE_SET = 512;
  18. public const VISIBILITY_MASK = self::PUBLIC | self::PROTECTED | self::PRIVATE;
  19. public const VISIBILITY_SET_MASK = self::PUBLIC_SET | self::PROTECTED_SET | self::PRIVATE_SET;
  20. private const TO_STRING_MAP = [
  21. self::PUBLIC => 'public',
  22. self::PROTECTED => 'protected',
  23. self::PRIVATE => 'private',
  24. self::STATIC => 'static',
  25. self::ABSTRACT => 'abstract',
  26. self::FINAL => 'final',
  27. self::READONLY => 'readonly',
  28. self::PUBLIC_SET => 'public(set)',
  29. self::PROTECTED_SET => 'protected(set)',
  30. self::PRIVATE_SET => 'private(set)',
  31. ];
  32. public static function toString(int $modifier): string {
  33. if (!isset(self::TO_STRING_MAP[$modifier])) {
  34. throw new \InvalidArgumentException("Unknown modifier $modifier");
  35. }
  36. return self::TO_STRING_MAP[$modifier];
  37. }
  38. private static function isValidModifier(int $modifier): bool {
  39. $isPow2 = ($modifier & ($modifier - 1)) == 0 && $modifier != 0;
  40. return $isPow2 && $modifier <= self::PRIVATE_SET;
  41. }
  42. /**
  43. * @internal
  44. */
  45. public static function verifyClassModifier(int $a, int $b): void {
  46. assert(self::isValidModifier($b));
  47. if (($a & $b) != 0) {
  48. throw new Error(
  49. 'Multiple ' . self::toString($b) . ' modifiers are not allowed');
  50. }
  51. if ($a & 48 && $b & 48) {
  52. throw new Error('Cannot use the final modifier on an abstract class');
  53. }
  54. }
  55. /**
  56. * @internal
  57. */
  58. public static function verifyModifier(int $a, int $b): void {
  59. assert(self::isValidModifier($b));
  60. if (($a & Modifiers::VISIBILITY_MASK && $b & Modifiers::VISIBILITY_MASK) ||
  61. ($a & Modifiers::VISIBILITY_SET_MASK && $b & Modifiers::VISIBILITY_SET_MASK)
  62. ) {
  63. throw new Error('Multiple access type modifiers are not allowed');
  64. }
  65. if (($a & $b) != 0) {
  66. throw new Error(
  67. 'Multiple ' . self::toString($b) . ' modifiers are not allowed');
  68. }
  69. if ($a & 48 && $b & 48) {
  70. throw new Error('Cannot use the final modifier on an abstract class member');
  71. }
  72. }
  73. }