|
20 | 20 | */
|
21 | 21 | class LazyObjectRegistry
|
22 | 22 | {
|
23 |
| - /** |
24 |
| - * @var array<class-string, \ReflectionClass> |
25 |
| - */ |
26 |
| - public static array $classReflectors = []; |
27 |
| - |
28 |
| - /** |
29 |
| - * @var array<class-string, array<string, mixed>> |
30 |
| - */ |
31 |
| - public static array $defaultProperties = []; |
32 |
| - |
33 |
| - /** |
34 |
| - * @var array<class-string, list<\Closure>> |
35 |
| - */ |
36 |
| - public static array $classResetters = []; |
37 |
| - |
38 |
| - /** |
39 |
| - * @var array<class-string, array{get: \Closure, set: \Closure, isset: \Closure, unset: \Closure}> |
40 |
| - */ |
41 |
| - public static array $classAccessors = []; |
42 |
| - |
43 |
| - /** |
44 |
| - * @var array<class-string, array{set: bool, isset: bool, unset: bool, clone: bool, serialize: bool, unserialize: bool, sleep: bool, wakeup: bool, destruct: bool, get: int}> |
45 |
| - */ |
46 |
| - public static array $parentMethods = []; |
47 |
| - |
48 |
| - public static ?\Closure $noInitializerState = null; |
49 |
| - |
50 |
| - public static function getClassResetters($class) |
51 |
| - { |
52 |
| - $classProperties = []; |
53 |
| - |
54 |
| - if ((self::$classReflectors[$class] ??= new \ReflectionClass($class))->isInternal()) { |
55 |
| - $propertyScopes = []; |
56 |
| - } else { |
57 |
| - $propertyScopes = Hydrator::$propertyScopes[$class] ??= Hydrator::getPropertyScopes($class); |
58 |
| - } |
59 |
| - |
60 |
| - foreach ($propertyScopes as $key => [$scope, $name, $readonlyScope]) { |
61 |
| - $propertyScopes[$k = "\0$scope\0$name"] ?? $propertyScopes[$k = "\0*\0$name"] ?? $k = $name; |
62 |
| - |
63 |
| - if ($k === $key && "\0$class\0lazyObjectState" !== $k) { |
64 |
| - $classProperties[$readonlyScope ?? $scope][$name] = $key; |
65 |
| - } |
66 |
| - } |
67 |
| - |
68 |
| - $resetters = []; |
69 |
| - foreach ($classProperties as $scope => $properties) { |
70 |
| - $resetters[] = \Closure::bind(static function ($instance, $skippedProperties) use ($properties) { |
71 |
| - foreach ($properties as $name => $key) { |
72 |
| - if (!\array_key_exists($key, $skippedProperties)) { |
73 |
| - unset($instance->$name); |
74 |
| - } |
75 |
| - } |
76 |
| - }, null, $scope); |
77 |
| - } |
78 |
| - |
79 |
| - $resetters[] = static function ($instance, $skippedProperties) { |
80 |
| - foreach ((array) $instance as $name => $value) { |
81 |
| - if ("\0" !== ($name[0] ?? '') && !\array_key_exists($name, $skippedProperties)) { |
82 |
| - unset($instance->$name); |
83 |
| - } |
84 |
| - } |
85 |
| - }; |
86 |
| - |
87 |
| - return $resetters; |
88 |
| - } |
89 |
| - |
90 |
| - public static function getClassAccessors($class) |
91 |
| - { |
92 |
| - return \Closure::bind(static fn () => [ |
93 |
| - 'get' => static function &($instance, $name, $readonly) { |
94 |
| - if (!$readonly) { |
95 |
| - return $instance->$name; |
96 |
| - } |
97 |
| - $value = $instance->$name; |
98 |
| - |
99 |
| - return $value; |
100 |
| - }, |
101 |
| - 'set' => static function ($instance, $name, $value) { |
102 |
| - $instance->$name = $value; |
103 |
| - }, |
104 |
| - 'isset' => static fn ($instance, $name) => isset($instance->$name), |
105 |
| - 'unset' => static function ($instance, $name) { |
106 |
| - unset($instance->$name); |
107 |
| - }, |
108 |
| - ], null, \Closure::class === $class ? null : $class)(); |
109 |
| - } |
110 |
| - |
111 |
| - public static function getParentMethods($class) |
112 |
| - { |
113 |
| - $parent = get_parent_class($class); |
114 |
| - $methods = []; |
115 |
| - |
116 |
| - foreach (['set', 'isset', 'unset', 'clone', 'serialize', 'unserialize', 'sleep', 'wakeup', 'destruct', 'get'] as $method) { |
117 |
| - if (!$parent || !method_exists($parent, '__'.$method)) { |
118 |
| - $methods[$method] = false; |
119 |
| - } else { |
120 |
| - $m = new \ReflectionMethod($parent, '__'.$method); |
121 |
| - $methods[$method] = !$m->isAbstract() && !$m->isPrivate(); |
122 |
| - } |
123 |
| - } |
124 |
| - |
125 |
| - $methods['get'] = $methods['get'] ? ($m->returnsReference() ? 2 : 1) : 0; |
126 |
| - |
127 |
| - return $methods; |
128 |
| - } |
129 |
| - |
130 |
| - public static function getScope($propertyScopes, $class, $property, $readonlyScope = null) |
131 |
| - { |
132 |
| - if (null === $readonlyScope && !isset($propertyScopes[$k = "\0$class\0$property"]) && !isset($propertyScopes[$k = "\0*\0$property"])) { |
133 |
| - return null; |
134 |
| - } |
135 |
| - $frame = debug_backtrace(\DEBUG_BACKTRACE_PROVIDE_OBJECT | \DEBUG_BACKTRACE_IGNORE_ARGS, 3)[2]; |
136 |
| - |
137 |
| - if (\ReflectionProperty::class === $scope = $frame['class'] ?? \Closure::class) { |
138 |
| - $scope = $frame['object']->class; |
139 |
| - } |
140 |
| - if (null === $readonlyScope && '*' === $k[1] && ($class === $scope || (is_subclass_of($class, $scope) && !isset($propertyScopes["\0$scope\0$property"])))) { |
141 |
| - return null; |
142 |
| - } |
143 |
| - |
144 |
| - return $scope; |
145 |
| - } |
| 23 | + public static \WeakMap $initializers; |
146 | 24 | }
|
0 commit comments