@@ -19,7 +19,7 @@ use crate::{
1919 objects:: { StateObj , ZObj , ZObject } ,
2020 strings:: { ZStr , ZString } ,
2121 sys:: * ,
22- types:: { ArgumentTypeHint , ReturnTypeHint , TypeInfo } ,
22+ types:: { ArgumentTypeHint , ReturnTypeHint } ,
2323 utils:: ensure_end_with_zero,
2424 values:: { ExecuteData , ZVal } ,
2525} ;
@@ -148,34 +148,111 @@ impl FunctionEntry {
148148
149149 let require_arg_count = arguments. iter ( ) . filter ( |arg| arg. required ) . count ( ) ;
150150
151- if let Some ( return_type) = return_type {
152- if let Some ( type_hint) = & return_type. type_hint {
153- let ret_info = match type_hint {
154- ReturnTypeHint :: String => phper_zend_begin_arg_with_return_type_info_ex (
155- return_type. ret_by_ref ,
156- require_arg_count,
157- IS_STRING ,
158- return_type. allow_null ,
159- ) ,
160- _ => phper_zend_begin_arg_with_return_type_info_ex (
161- return_type. ret_by_ref ,
162- require_arg_count,
163- return_type. type_info . into_raw ( ) ,
164- return_type. allow_null ,
165- ) ,
166- } ;
167- infos. push ( ret_info) ;
168- } else {
169- infos. push ( phper_zend_begin_arg_with_return_type_info_ex (
151+ let return_info = if let Some ( return_type) = return_type {
152+ match & return_type. type_hint {
153+ ReturnTypeHint :: Null => Some ( phper_zend_begin_arg_with_return_type_info_ex (
154+ false ,
155+ require_arg_count,
156+ IS_NULL ,
157+ true ,
158+ ) ) ,
159+ ReturnTypeHint :: Bool => Some ( phper_zend_begin_arg_with_return_type_info_ex (
160+ return_type. ret_by_ref ,
161+ require_arg_count,
162+ _IS_BOOL,
163+ return_type. allow_null ,
164+ ) ) ,
165+ ReturnTypeHint :: Int => Some ( phper_zend_begin_arg_with_return_type_info_ex (
170166 return_type. ret_by_ref ,
171167 require_arg_count,
172- return_type . type_info . into_raw ( ) ,
168+ IS_LONG ,
173169 return_type. allow_null ,
174- ) ) ;
170+ ) ) ,
171+ ReturnTypeHint :: Float => Some ( phper_zend_begin_arg_with_return_type_info_ex (
172+ return_type. ret_by_ref ,
173+ require_arg_count,
174+ IS_DOUBLE ,
175+ return_type. allow_null ,
176+ ) ) ,
177+ ReturnTypeHint :: String => Some ( phper_zend_begin_arg_with_return_type_info_ex (
178+ return_type. ret_by_ref ,
179+ require_arg_count,
180+ IS_STRING ,
181+ return_type. allow_null ,
182+ ) ) ,
183+ ReturnTypeHint :: Array => Some ( phper_zend_begin_arg_with_return_type_info_ex (
184+ return_type. ret_by_ref ,
185+ require_arg_count,
186+ IS_ARRAY ,
187+ return_type. allow_null ,
188+ ) ) ,
189+ ReturnTypeHint :: Object => Some ( phper_zend_begin_arg_with_return_type_info_ex (
190+ return_type. ret_by_ref ,
191+ require_arg_count,
192+ IS_OBJECT ,
193+ return_type. allow_null ,
194+ ) ) ,
195+ ReturnTypeHint :: Callable => Some ( phper_zend_begin_arg_with_return_type_info_ex (
196+ return_type. ret_by_ref ,
197+ require_arg_count,
198+ IS_CALLABLE ,
199+ return_type. allow_null ,
200+ ) ) ,
201+ ReturnTypeHint :: Iterable => Some ( phper_zend_begin_arg_with_return_type_info_ex (
202+ return_type. ret_by_ref ,
203+ require_arg_count,
204+ IS_ITERABLE ,
205+ return_type. allow_null ,
206+ ) ) ,
207+ ReturnTypeHint :: Mixed => {
208+ if PHP_MAJOR_VERSION < 8 {
209+ None
210+ } else {
211+ Some ( phper_zend_begin_arg_with_return_type_info_ex (
212+ return_type. ret_by_ref ,
213+ require_arg_count,
214+ IS_MIXED ,
215+ true ,
216+ ) )
217+ }
218+ }
219+ ReturnTypeHint :: Never => {
220+ if PHP_MAJOR_VERSION < 8 || ( PHP_MAJOR_VERSION == 8 && PHP_MINOR_VERSION <= 1 ) {
221+ None
222+ } else {
223+ Some ( phper_zend_begin_arg_with_return_type_info_ex (
224+ return_type. ret_by_ref ,
225+ require_arg_count,
226+ IS_NEVER ,
227+ false ,
228+ ) )
229+ }
230+ }
231+ ReturnTypeHint :: Void => Some ( phper_zend_begin_arg_with_return_type_info_ex (
232+ return_type. ret_by_ref ,
233+ require_arg_count,
234+ IS_VOID ,
235+ false ,
236+ ) ) ,
237+ ReturnTypeHint :: ClassEntry ( class_name) => {
238+ let class_name =
239+ CString :: new ( class_name. clone ( ) ) . expect ( "CString::new failed" ) ;
240+ Some ( phper_zend_begin_arg_with_return_obj_info_ex (
241+ return_type. ret_by_ref ,
242+ require_arg_count,
243+ class_name. as_ptr ( ) ,
244+ return_type. allow_null ,
245+ ) )
246+ }
175247 }
176248 } else {
177- infos. push ( phper_zend_begin_arg_info_ex ( false , require_arg_count) ) ;
178- }
249+ None
250+ } ;
251+
252+ infos. push ( return_info. unwrap_or_else ( || {
253+ phper_zend_begin_arg_info_ex ( false , require_arg_count)
254+ } ) ) ;
255+
179256
180257 for arg in arguments {
181258 let arg_info = if let Some ( ref type_hint) = arg. type_hint {
@@ -205,47 +282,32 @@ impl FunctionEntry {
205282 phper_zend_arg_info_with_type ( arg. pass_by_ref , arg. name . as_ptr ( ) , IS_CALLABLE , arg. nullable )
206283 ) ,
207284 ArgumentTypeHint :: Iterable => {
208- // For iterable typehint - this might need a special handler or could use IS_ITERABLE
209- // if defined in your PHP version
210285 Some ( phper_zend_arg_info_with_type ( arg. pass_by_ref , arg. name . as_ptr ( ) , IS_ITERABLE , arg. nullable ) )
211286 } ,
212287 ArgumentTypeHint :: Mixed => {
213- // Mixed type - depends on PHP version, for PHP 8+ this might be a special constant
214- // For PHP 8.0+, there might be a specific constant for mixed
215- Some ( phper_zend_arg_info_with_type ( arg. pass_by_ref , arg. name . as_ptr ( ) , 0 , true ) ) // 0 might be replaced with appropriate constant
288+ if PHP_MAJOR_VERSION < 8 {
289+ None
290+ } else {
291+ Some ( phper_zend_arg_info_with_type ( arg. pass_by_ref , arg. name . as_ptr ( ) , 0 , true ) )
292+ }
216293 } ,
217294 ArgumentTypeHint :: ClassEntry ( class_name) => {
218- println ! ( "typehint for class entry: {}" , class_name) ;
219- match CString :: new ( class_name. clone ( ) ) {
220- Ok ( c_class_name) => {
221- // Defer actual class entry lookup
222- // Use zend_arg_obj_info with just the class name string
223- Some ( phper_zend_arg_obj_info (
224- arg. pass_by_ref , // Whether argument is passed by reference
225- arg. name . as_ptr ( ) , // Argument name
226- c_class_name. as_ptr ( ) , // Class name as C string
227- arg. nullable // Whether the argument can be null
228- ) )
229- } ,
230- Err ( _) => {
231- // Handle invalid class name (contains null byte)
232- eprintln ! ( "Invalid class name: {}" , class_name) ;
233- None
234- }
235- }
295+ let c_class_name = CString :: new ( class_name. clone ( ) ) . expect ( "CString::new failed" ) ;
296+ Some ( phper_zend_arg_obj_info (
297+ arg. pass_by_ref ,
298+ arg. name . as_ptr ( ) ,
299+ c_class_name. as_ptr ( ) ,
300+ arg. nullable
301+ ) )
236302 } ,
237303 }
238304 } else {
239305 None
240306 } ;
241307
242- if let Some ( arg_info) = arg_info {
243- infos. push ( arg_info) ;
244- } else {
245- // No type hint, use the original function
246- let default_arg_info = phper_zend_arg_info ( arg. pass_by_ref , arg. name . as_ptr ( ) ) ;
247- infos. push ( default_arg_info) ;
248- }
308+ infos. push ( arg_info. unwrap_or_else ( || {
309+ phper_zend_arg_info ( arg. pass_by_ref , arg. name . as_ptr ( ) )
310+ } ) ) ;
249311 }
250312
251313 infos. push ( zeroed :: < zend_internal_arg_info > ( ) ) ;
@@ -472,30 +534,27 @@ impl Argument {
472534
473535/// Function or method return type.
474536pub struct ReturnType {
475- type_info : TypeInfo ,
476- type_hint : Option < ReturnTypeHint > ,
537+ type_hint : ReturnTypeHint ,
477538 ret_by_ref : bool ,
478539 allow_null : bool ,
479540}
480541
481542impl ReturnType {
482543 /// Indicate the return type is return by value.
483544 #[ inline]
484- pub fn by_val ( type_info : TypeInfo ) -> Self {
545+ pub fn by_val ( type_hint : ReturnTypeHint ) -> Self {
485546 Self {
486- type_info,
487- type_hint : None ,
547+ type_hint,
488548 ret_by_ref : false ,
489549 allow_null : false ,
490550 }
491551 }
492552
493553 /// Indicate the return type is return by reference.
494554 #[ inline]
495- pub fn by_ref ( type_info : TypeInfo ) -> Self {
555+ pub fn by_ref ( type_hint : ReturnTypeHint ) -> Self {
496556 Self {
497- type_info,
498- type_hint : None ,
557+ type_hint,
499558 ret_by_ref : true ,
500559 allow_null : false ,
501560 }
@@ -510,7 +569,7 @@ impl ReturnType {
510569
511570 /// Add a type-hint to the return type
512571 pub fn with_type_hint ( mut self , type_hint : ReturnTypeHint ) -> Self {
513- self . type_hint = Some ( type_hint) ;
572+ self . type_hint = type_hint;
514573 self
515574 }
516575}
0 commit comments