Skip to content

Commit 247b453

Browse files
Leverage native lazy proxies
1 parent 18fa44a commit 247b453

File tree

8 files changed

+89
-876
lines changed

8 files changed

+89
-876
lines changed

src/Symfony/Component/VarExporter/Internal/LazyObjectRegistry.php

Lines changed: 1 addition & 123 deletions
Original file line numberDiff line numberDiff line change
@@ -20,127 +20,5 @@
2020
*/
2121
class LazyObjectRegistry
2222
{
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;
14624
}

src/Symfony/Component/VarExporter/Internal/LazyObjectState.php

Lines changed: 0 additions & 93 deletions
This file was deleted.

src/Symfony/Component/VarExporter/Internal/LazyObjectTrait.php

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,42 @@
1111

1212
namespace Symfony\Component\VarExporter\Internal;
1313

14-
if (\PHP_VERSION_ID >= 80300) {
14+
/**
15+
* @internal
16+
*/
17+
trait LazyObjectTrait
18+
{
1519
/**
16-
* @internal
20+
* Returns whether the object is initialized.
21+
*
22+
* @param $partial Whether partially initialized objects should be considered as initialized
1723
*/
18-
trait LazyObjectTrait
24+
public function isLazyObjectInitialized(bool $partial = false): bool
1925
{
20-
private readonly LazyObjectState $lazyObjectState;
26+
return !\ReflectionLazyObject::isLazyObject($this);
2127
}
22-
} else {
28+
2329
/**
24-
* @internal
30+
* @return bool Returns false when the object cannot be reset, ie when it's not a lazy object
2531
*/
26-
trait LazyObjectTrait
32+
public function resetLazyObject(): bool
2733
{
28-
private LazyObjectState $lazyObjectState;
34+
if (\ReflectionLazyObject::isLazyObject($this)) {
35+
return true;
36+
}
37+
38+
if (![$initializer, $strategy, $skippedProperties] = LazyObjectRegistry::$initializers[$this] ?? null) {
39+
return false;
40+
}
41+
42+
$r = \ReflectionLazyObject::makeLazy($this, $initializer, $strategy);
43+
44+
foreach ($skippedProperties as $class => $properties) {
45+
foreach ($properties as $property) {
46+
$r->skipProperty($property, $class);
47+
}
48+
}
49+
50+
return true;
2951
}
3052
}

0 commit comments

Comments
 (0)