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