@@ -8439,7 +8439,9 @@ ZEND_METHOD(ReflectionGenericTypeParameter, getBound)
84398439 GET_GENERIC_PARAMETER_REFERENCE (intern , ref );
84408440
84418441 if (!ZEND_TYPE_IS_SET (ref -> param -> bound )) {
8442- RETURN_NULL ();
8442+ zend_throw_exception_ex (reflection_exception_ptr , 0 ,
8443+ "Type parameter %s has no bound" , ZSTR_VAL (ref -> param -> name ));
8444+ RETURN_THROWS ();
84438445 }
84448446 zend_class_entry * declaring_class = NULL ;
84458447 zend_function * declaring_fn = NULL ;
@@ -8478,7 +8480,9 @@ ZEND_METHOD(ReflectionGenericTypeParameter, getDefault)
84788480 GET_GENERIC_PARAMETER_REFERENCE (intern , ref );
84798481
84808482 if (!ZEND_TYPE_IS_SET (ref -> param -> default_type )) {
8481- RETURN_NULL ();
8483+ zend_throw_exception_ex (reflection_exception_ptr , 0 ,
8484+ "Type parameter %s has no default" , ZSTR_VAL (ref -> param -> name ));
8485+ RETURN_THROWS ();
84828486 }
84838487
84848488 zend_class_entry * declaring_class = NULL ;
@@ -8675,10 +8679,6 @@ ZEND_METHOD(ReflectionNamedType, getGenericArguments)
86758679static void reflection_build_named_args_list (zval * return_value , const zend_type * boxed ,
86768680 zend_class_entry * declaring_class )
86778681{
8678- if (!ZEND_TYPE_HAS_NAMED_WITH_ARGS (* boxed )) {
8679- RETURN_NULL ();
8680- }
8681-
86828682 zend_type_named_with_args * named = ZEND_TYPE_NAMED_WITH_ARGS (* boxed );
86838683 array_init_size (return_value , named -> count );
86848684 for (uint32_t i = 0 ; i < named -> count ; i ++ ) {
@@ -8698,11 +8698,20 @@ ZEND_METHOD(ReflectionClass, getGenericArgumentsForParentClass)
86988698 ZEND_PARSE_PARAMETERS_NONE ();
86998699 GET_REFLECTION_OBJECT_PTR (ce );
87008700
8701- if (!ce -> generic_types || !ce -> generic_types -> extends ) {
8702- RETURN_NULL ();
8701+ bool has_parent = (ce -> ce_flags & ZEND_ACC_LINKED )
8702+ ? ce -> parent != NULL
8703+ : ce -> parent_name != NULL ;
8704+ if (!has_parent ) {
8705+ zend_throw_exception_ex (reflection_exception_ptr , 0 ,
8706+ "Class %s has no parent class" , ZSTR_VAL (ce -> name ));
8707+ RETURN_THROWS ();
87038708 }
87048709
8705- reflection_build_named_args_list (return_value , ce -> generic_types -> extends , ce );
8710+ if (ce -> generic_types && ce -> generic_types -> extends ) {
8711+ reflection_build_named_args_list (return_value , ce -> generic_types -> extends , ce );
8712+ return ;
8713+ }
8714+ RETURN_EMPTY_ARRAY ();
87068715}
87078716
87088717ZEND_METHOD (ReflectionClass , getGenericArgumentsForParentInterface )
@@ -8716,22 +8725,40 @@ ZEND_METHOD(ReflectionClass, getGenericArgumentsForParentInterface)
87168725 ZEND_PARSE_PARAMETERS_END ();
87178726 GET_REFLECTION_OBJECT_PTR (ce );
87188727
8719- if (!ce -> generic_types || !ce -> generic_types -> implements ) {
8720- RETURN_NULL ();
8728+ bool is_ancestor = false;
8729+ if (ce -> ce_flags & ZEND_ACC_LINKED ) {
8730+ for (uint32_t i = 0 ; i < ce -> num_interfaces ; i ++ ) {
8731+ if (zend_string_equals_ci (ce -> interfaces [i ]-> name , name )) {
8732+ is_ancestor = true;
8733+ break ;
8734+ }
8735+ }
8736+ } else {
8737+ for (uint32_t i = 0 ; i < ce -> num_interfaces ; i ++ ) {
8738+ if (zend_string_equals_ci (ce -> interface_names [i ].name , name )) {
8739+ is_ancestor = true;
8740+ break ;
8741+ }
8742+ }
8743+ }
8744+ if (!is_ancestor ) {
8745+ zend_throw_exception_ex (reflection_exception_ptr , 0 ,
8746+ "%s is not an ancestor interface of %s" , ZSTR_VAL (name ), ZSTR_VAL (ce -> name ));
8747+ RETURN_THROWS ();
87218748 }
87228749
8723- zval * zv ;
8724- ZEND_HASH_FOREACH_VAL ( ce -> generic_types -> implements , zv ) {
8725- zend_type * boxed = ( zend_type * ) Z_PTR_P ( zv );
8726- if ( ZEND_TYPE_HAS_NAMED_WITH_ARGS ( * boxed )) {
8750+ if ( ce -> generic_types && ce -> generic_types -> implements ) {
8751+ zval * zv ;
8752+ ZEND_HASH_FOREACH_VAL ( ce -> generic_types -> implements , zv ) {
8753+ zend_type * boxed = ( zend_type * ) Z_PTR_P ( zv );
87278754 zend_type_named_with_args * named = ZEND_TYPE_NAMED_WITH_ARGS (* boxed );
87288755 if (zend_string_equals_ci (named -> name , name )) {
87298756 reflection_build_named_args_list (return_value , boxed , ce );
87308757 return ;
87318758 }
8732- }
8733- } ZEND_HASH_FOREACH_END ();
8734- RETURN_NULL ();
8759+ } ZEND_HASH_FOREACH_END ();
8760+ }
8761+ RETURN_EMPTY_ARRAY ();
87358762}
87368763
87378764ZEND_METHOD (ReflectionClass , getGenericArgumentsForUsedTrait )
@@ -8745,22 +8772,31 @@ ZEND_METHOD(ReflectionClass, getGenericArgumentsForUsedTrait)
87458772 ZEND_PARSE_PARAMETERS_END ();
87468773 GET_REFLECTION_OBJECT_PTR (ce );
87478774
8748- if (!ce -> generic_types || !ce -> generic_types -> trait_uses ) {
8749- RETURN_NULL ();
8775+ bool is_used = false;
8776+ for (uint32_t i = 0 ; i < ce -> num_traits ; i ++ ) {
8777+ if (zend_string_equals_ci (ce -> trait_names [i ].name , name )) {
8778+ is_used = true;
8779+ break ;
8780+ }
8781+ }
8782+ if (!is_used ) {
8783+ zend_throw_exception_ex (reflection_exception_ptr , 0 ,
8784+ "%s is not a trait used by %s" , ZSTR_VAL (name ), ZSTR_VAL (ce -> name ));
8785+ RETURN_THROWS ();
87508786 }
87518787
8752- zval * zv ;
8753- ZEND_HASH_FOREACH_VAL ( ce -> generic_types -> trait_uses , zv ) {
8754- zend_type * boxed = ( zend_type * ) Z_PTR_P ( zv );
8755- if ( ZEND_TYPE_HAS_NAMED_WITH_ARGS ( * boxed )) {
8788+ if ( ce -> generic_types && ce -> generic_types -> trait_uses ) {
8789+ zval * zv ;
8790+ ZEND_HASH_FOREACH_VAL ( ce -> generic_types -> trait_uses , zv ) {
8791+ zend_type * boxed = ( zend_type * ) Z_PTR_P ( zv );
87568792 zend_type_named_with_args * named = ZEND_TYPE_NAMED_WITH_ARGS (* boxed );
87578793 if (zend_string_equals_ci (named -> name , name )) {
87588794 reflection_build_named_args_list (return_value , boxed , ce );
87598795 return ;
87608796 }
8761- }
8762- } ZEND_HASH_FOREACH_END ();
8763- RETURN_NULL ();
8797+ } ZEND_HASH_FOREACH_END ();
8798+ }
8799+ RETURN_EMPTY_ARRAY ();
87648800}
87658801
87668802PHP_MINIT_FUNCTION (reflection ) /* {{{ */
0 commit comments