@@ -17,6 +17,7 @@ use phper::{
1717 values:: ZVal ,
1818} ;
1919use std:: { collections:: HashMap , convert:: Infallible } ;
20+ use std:: rc:: Rc ;
2021
2122pub fn integrate ( module : & mut Module ) {
2223 integrate_a ( module) ;
@@ -25,6 +26,7 @@ pub fn integrate(module: &mut Module) {
2526 integrate_static_props ( module) ;
2627 integrate_i_constants ( module) ;
2728 integrate_bar_extends_foo ( module, foo_class) ;
29+ integrate_dependent_classes ( module) ;
2830 #[ cfg( phper_major_version = "8" ) ]
2931 integrate_stringable ( module) ;
3032}
@@ -230,20 +232,52 @@ fn integrate_bar_extends_foo(module: &mut Module, foo_class: StateClass<Foo>) {
230232}
231233
232234fn integrate_dependent_classes ( module : & mut Module ) {
233- let mut a_cls = ClassEntity :: new ( r"IntegrationTest\Dependency\A" ) ;
234- let mut b_cls = ClassEntity :: new ( r"IntegrationTest\Dependency\B" ) ;
235+ const A_CLS : & str = r"IntegrationTest\Dependency\A" ;
236+ const B_CLS : & str = r"IntegrationTest\Dependency\B" ;
237+ // Build both class entities
238+ let mut a_cls = ClassEntity :: new ( A_CLS ) ;
239+ let mut b_cls = ClassEntity :: new ( B_CLS ) ;
240+
241+ // Placeholder, will clone StateClass into closures after registration
242+ let a_cls_ref = std:: rc:: Rc :: new ( std:: cell:: RefCell :: new ( None ) ) ;
243+ let b_cls_ref = std:: rc:: Rc :: new ( std:: cell:: RefCell :: new ( None ) ) ;
244+
245+ {
246+ let b_cls_ref = Rc :: clone ( & b_cls_ref) ;
247+ a_cls. add_static_method ( "createB" , Visibility :: Public , move |_| {
248+ let borrow = b_cls_ref. borrow ( ) ;
249+ let b_state: & StateClass < ( ) > = borrow
250+ . as_ref ( )
251+ . expect ( "B class not registered" ) ;
252+ let obj = b_state. init_object ( ) ?;
253+ Ok :: < _ , phper:: Error > ( obj)
254+ } )
255+ . return_type ( ReturnType :: new ( ReturnTypeHint :: ClassEntry ( String :: from ( B_CLS ) ) ) ) ;
256+ }
257+
258+ {
259+ let a_cls_ref = Rc :: clone ( & a_cls_ref) ;
260+ b_cls. add_static_method ( "createA" , Visibility :: Public , move |_| {
261+ let borrow = a_cls_ref. borrow ( ) ;
262+ let a_state: & StateClass < ( ) > = borrow
263+ . as_ref ( )
264+ . expect ( "A class not registered" ) ;
265+ let obj = a_state. init_object ( ) ?;
266+ Ok :: < _ , phper:: Error > ( obj)
267+ } )
268+ . return_type ( ReturnType :: new ( ReturnTypeHint :: ClassEntry ( String :: from ( A_CLS ) ) ) ) ;
269+ }
235270
236- a_cls. add_static_method ( "createB" , Visibility :: Public , |_| {
237- let b = b_cls. init_object ( ) ?;
238- Ok :: < _ , phper:: Error > ( b)
239- } ) ;
240271
241- b_cls. add_static_method ( "createA" , Visibility :: Public , |_| {
242- let a = a_cls. init_object ( ) ?;
243- Ok :: < _ , phper:: Error > ( a)
244- } ) ;
272+ // Register both classes and save the StateClass into shared RefCells
273+ let a_state = module. add_class ( a_cls) ;
274+ let b_state = module. add_class ( b_cls) ;
275+
276+ * a_cls_ref. borrow_mut ( ) = Some ( a_state) ;
277+ * b_cls_ref. borrow_mut ( ) = Some ( b_state) ;
245278}
246279
280+
247281#[ cfg( phper_major_version = "8" ) ]
248282fn integrate_stringable ( module : & mut Module ) {
249283 use phper:: { functions:: ReturnType , types:: ReturnTypeHint } ;
0 commit comments