@@ -59,40 +59,7 @@ public static function generateLazyGhost(\ReflectionClass $class): string
59
59
}
60
60
}
61
61
62
- $ hooks = '' ;
63
62
$ propertyScopes = Hydrator::$ propertyScopes [$ class ->name ] ??= Hydrator::getPropertyScopes ($ class ->name );
64
- foreach ($ propertyScopes as $ name => $ scope ) {
65
- if (!isset ($ scope [4 ]) || ($ p = $ scope [3 ])->isVirtual ()) {
66
- continue ;
67
- }
68
-
69
- if ($ p ->isFinal ()) {
70
- throw new LogicException (sprintf ('Cannot generate lazy ghost: property "%s::$%s" is final. ' , $ class ->name , $ p ->name ));
71
- }
72
-
73
- $ type = self ::exportType ($ p );
74
- $ hooks .= "\n public {$ type } \${$ name } { \n" ;
75
-
76
- foreach ($ p ->getHooks () as $ hook => $ method ) {
77
- if ($ method ->isFinal ()) {
78
- throw new LogicException (sprintf ('Cannot generate lazy ghost: hook "%s::%s()" is final. ' , $ class ->name , $ method ->name ));
79
- }
80
-
81
- if ('get ' === $ hook ) {
82
- $ ref = ($ method ->returnsReference () ? '& ' : '' );
83
- $ hooks .= " {$ ref }get { \$this->initializeLazyObject(); return parent:: \${$ name }::get(); } \n" ;
84
- } elseif ('set ' === $ hook ) {
85
- $ parameters = self ::exportParameters ($ method , true );
86
- $ arg = '$ ' .$ method ->getParameters ()[0 ]->name ;
87
- $ hooks .= " set( {$ parameters }) { \$this->initializeLazyObject(); parent:: \${$ name }::set( {$ arg }); } \n" ;
88
- } else {
89
- throw new LogicException (sprintf ('Cannot generate lazy ghost: hook "%s::%s()" is not supported. ' , $ class ->name , $ method ->name ));
90
- }
91
- }
92
-
93
- $ hooks .= " } \n" ;
94
- }
95
-
96
63
$ propertyScopes = self ::exportPropertyScopes ($ class ->name , $ propertyScopes );
97
64
98
65
return <<<EOPHP
@@ -101,7 +68,7 @@ public static function generateLazyGhost(\ReflectionClass $class): string
101
68
use \Symfony\Component\VarExporter\LazyGhostTrait;
102
69
103
70
private const LAZY_OBJECT_PROPERTY_SCOPES = {$ propertyScopes };
104
- { $ hooks } }
71
+ }
105
72
106
73
// Help opcache.preload discover always-needed symbols
107
74
class_exists(\Symfony\Component\VarExporter\Internal\Hydrator::class);
@@ -132,20 +99,9 @@ public static function generateLazyProxy(?\ReflectionClass $class, array $interf
132
99
133
100
$ propertyScopes = $ class ? Hydrator::$ propertyScopes [$ class ->name ] ??= Hydrator::getPropertyScopes ($ class ->name ) : [];
134
101
$ abstractProperties = [];
135
- $ hookedProperties = [];
136
102
if (\PHP_VERSION_ID >= 80400 && $ class ) {
137
103
foreach ($ propertyScopes as $ name => $ scope ) {
138
- if (!isset ($ scope [4 ]) || ($ p = $ scope [3 ])->isVirtual ()) {
139
- $ abstractProperties [$ name ] = isset ($ scope [4 ]) && $ p ->isAbstract () ? $ p : false ;
140
- continue ;
141
- }
142
-
143
- if ($ p ->isFinal ()) {
144
- throw new LogicException (\sprintf ('Cannot generate lazy proxy: property "%s::$%s" is final. ' , $ class ->name , $ p ->name ));
145
- }
146
-
147
- $ abstractProperties [$ name ] = false ;
148
- $ hookedProperties [$ name ] = [$ p , $ p ->getHooks ()];
104
+ $ abstractProperties [$ name ] = isset ($ scope [4 ]) && ($ p = $ scope [3 ])->isAbstract () ? $ p : false ;
149
105
}
150
106
}
151
107
@@ -156,12 +112,12 @@ public static function generateLazyProxy(?\ReflectionClass $class, array $interf
156
112
}
157
113
$ methodReflectors [] = $ interface ->getMethods ();
158
114
159
- if (\PHP_VERSION_ID >= 80400 ) {
160
- foreach ( $ interface -> getProperties () as $ p ) {
161
- $ abstractProperties [ $ p -> name ] ??= $ p ;
162
- $ hookedProperties [ $ p -> name ] ??= [ $ p , []];
163
- $ hookedProperties [ $ p -> name ][ 1 ] += $ p-> getHooks ();
164
- }
115
+ if (\PHP_VERSION_ID < 80400 ) {
116
+ continue ;
117
+ }
118
+
119
+ foreach ( $ interface -> getProperties () as $ p) {
120
+ $ abstractProperties [ $ p -> name ] ??= $ p ;
165
121
}
166
122
}
167
123
@@ -173,49 +129,6 @@ public static function generateLazyProxy(?\ReflectionClass $class, array $interf
173
129
unset($ propertyScopes [$ name ][4 ]);
174
130
}
175
131
176
- foreach ($ hookedProperties as $ name => [$ p , $ methods ]) {
177
- $ type = self ::exportType ($ p );
178
- $ hooks .= "\n public {$ type } \${$ p ->name } { \n" ;
179
-
180
- foreach ($ methods as $ hook => $ method ) {
181
- if ($ method ->isFinal ()) {
182
- throw new LogicException (sprintf ('Cannot generate lazy proxy: hook "%s::%s()" is final. ' , $ class ->name , $ method ->name ));
183
- }
184
-
185
- if ('get ' === $ hook ) {
186
- $ ref = ($ method ->returnsReference () ? '& ' : '' );
187
- $ hooks .= <<<EOPHP
188
- {$ ref }get {
189
- if (isset( \$this->lazyObjectState)) {
190
- return ( \$this->lazyObjectState->realInstance ??= ( \$this->lazyObjectState->initializer)())-> {$ p ->name };
191
- }
192
-
193
- return parent:: \${$ p ->name }::get();
194
- }
195
-
196
- EOPHP ;
197
- } elseif ('set ' === $ hook ) {
198
- $ parameters = self ::exportParameters ($ method , true );
199
- $ arg = '$ ' .$ method ->getParameters ()[0 ]->name ;
200
- $ hooks .= <<<EOPHP
201
- set( {$ parameters }) {
202
- if (isset( \$this->lazyObjectState)) {
203
- \$this->lazyObjectState->realInstance ??= ( \$this->lazyObjectState->initializer)();
204
- \$this->lazyObjectState->realInstance-> {$ p ->name } = {$ arg };
205
- }
206
-
207
- parent:: \${$ p ->name }::set( {$ arg });
208
- }
209
-
210
- EOPHP ;
211
- } else {
212
- throw new LogicException (sprintf ('Cannot generate lazy proxy: hook "%s::%s()" is not supported. ' , $ class ->name , $ method ->name ));
213
- }
214
- }
215
-
216
- $ hooks .= " } \n" ;
217
- }
218
-
219
132
$ extendsInternalClass = false ;
220
133
if ($ parent = $ class ) {
221
134
do {
@@ -261,13 +174,23 @@ public static function generateLazyProxy(?\ReflectionClass $class, array $interf
261
174
if ($ method ->isStatic ()) {
262
175
$ body = " $ parentCall; " ;
263
176
} elseif (str_ends_with ($ signature , '): never ' ) || str_ends_with ($ signature , '): void ' )) {
264
- $ body = <<<EOPHP
265
- if (isset( \$this->lazyObjectState)) {
266
- ( \$this->lazyObjectState->realInstance ??= ( \$this->lazyObjectState->initializer)())-> {$ method ->name }( {$ args });
267
- } else {
268
- {$ parentCall };
269
- }
270
- EOPHP ;
177
+ if (PHP_VERSION_ID < 80400 ) {
178
+ $ body = <<<EOPHP
179
+ if (isset( \$this->lazyObjectState)) {
180
+ ( \$this->lazyObjectState->realInstance ??= ( \$this->lazyObjectState->initializer)())-> {$ method ->name }( {$ args });
181
+ } else {
182
+ {$ parentCall };
183
+ }
184
+ EOPHP ;
185
+ } else {
186
+ $ body = <<<EOPHP
187
+ if ( \$this !== \${''} = (\Symfony\Component\VarExporter\Internal\LazyObjectRegistry:: \$classReflectors[static::class] ??= new \ReflectionClass(static::class))->initializeLazyObject( \$this)) {
188
+ \${''}-> {$ method ->name }( {$ args });
189
+ } else {
190
+ {$ parentCall };
191
+ }
192
+ EOPHP ;
193
+ }
271
194
} else {
272
195
if (!$ methodsHaveToBeProxied && !$ method ->isAbstract ()) {
273
196
// Skip proxying methods that might return $this
@@ -283,13 +206,23 @@ public static function generateLazyProxy(?\ReflectionClass $class, array $interf
283
206
}
284
207
}
285
208
286
- $ body = <<<EOPHP
287
- if (isset( \$this->lazyObjectState)) {
288
- return ( \$this->lazyObjectState->realInstance ??= ( \$this->lazyObjectState->initializer)())-> {$ method ->name }( {$ args });
289
- }
209
+ if (PHP_VERSION_ID < 80400 ) {
210
+ $ body = <<<EOPHP
211
+ if (isset( \$this->lazyObjectState)) {
212
+ return ( \$this->lazyObjectState->realInstance ??= ( \$this->lazyObjectState->initializer)())-> {$ method ->name }( {$ args });
213
+ }
290
214
291
- return {$ parentCall };
292
- EOPHP ;
215
+ return {$ parentCall };
216
+ EOPHP ;
217
+ } else {
218
+ $ body = <<<EOPHP
219
+ if ( \$this !== \${''} = (\Symfony\Component\VarExporter\Internal\LazyObjectRegistry:: \$classReflectors[static::class] ??= new \ReflectionClass(static::class))->initializeLazyObject( \$this)) {
220
+ return \${''}-> {$ method ->name }( {$ args });
221
+ }
222
+
223
+ return {$ parentCall };
224
+ EOPHP ;
225
+ }
293
226
}
294
227
$ methods [$ lcName ] = " {$ signature }\n { \n{$ body }\n } " ;
295
228
}
0 commit comments