PHPAPI zend_class_entry *reflection_generator_ptr;
PHPAPI zend_class_entry *reflection_parameter_ptr;
PHPAPI zend_class_entry *reflection_type_ptr;
+PHPAPI zend_class_entry *reflection_named_type_ptr;
PHPAPI zend_class_entry *reflection_class_ptr;
PHPAPI zend_class_entry *reflection_object_ptr;
PHPAPI zend_class_entry *reflection_method_ptr;
reflection_object *intern;
type_reference *reference;
- reflection_instantiate(reflection_type_ptr, object);
+ reflection_instantiate(reflection_named_type_ptr, object);
intern = Z_REFLECTION_P(object);
reference = (type_reference*) emalloc(sizeof(type_reference));
reference->arg_info = arg_info;
}
/* }}} */
+/* {{{ reflection_type_name */
+static zend_string *reflection_type_name(type_reference *param) {
+ switch (param->arg_info->type_hint) {
+ case IS_ARRAY: return zend_string_init("array", sizeof("array") - 1, 0);
+ case IS_CALLABLE: return zend_string_init("callable", sizeof("callable") - 1, 0);
+ case IS_OBJECT:
+ if (param->fptr->type == ZEND_INTERNAL_FUNCTION &&
+ !(param->fptr->common.fn_flags & ZEND_ACC_USER_ARG_INFO)) {
+ return zend_string_init(((zend_internal_arg_info*)param->arg_info)->class_name, strlen(((zend_internal_arg_info*)param->arg_info)->class_name), 0);
+ }
+ return zend_string_copy(param->arg_info->class_name);
+ case IS_STRING: return zend_string_init("string", sizeof("string") - 1, 0);
+ case _IS_BOOL: return zend_string_init("bool", sizeof("bool") - 1, 0);
+ case IS_LONG: return zend_string_init("int", sizeof("int") - 1, 0);
+ case IS_DOUBLE: return zend_string_init("float", sizeof("float") - 1, 0);
+ case IS_VOID: return zend_string_init("void", sizeof("void") - 1, 0);
+ case IS_ITERABLE: return zend_string_init("iterable", sizeof("iterable") - 1, 0);
+ EMPTY_SWITCH_DEFAULT_CASE()
+ }
+}
+/* }}} */
+
/* {{{ proto public string ReflectionType::__toString()
Return the text of the type hint */
ZEND_METHOD(reflection_type, __toString)
{
reflection_object *intern;
type_reference *param;
+ zend_string *str;
if (zend_parse_parameters_none() == FAILURE) {
return;
}
GET_REFLECTION_OBJECT_PTR(param);
+
+ str = reflection_type_name(param);
+
+ if (param->arg_info->allow_null) {
+ str = zend_string_extend(str, ZSTR_LEN(str) + 1, 0);
+ memmove(ZSTR_VAL(str) + 1, ZSTR_VAL(str), ZSTR_LEN(str) + 1);
+ ZSTR_VAL(str)[0] = '?';
+ }
+
+ RETURN_STR(str);
+}
+/* }}} */
- switch (param->arg_info->type_hint) {
- case IS_ARRAY: RETURN_STRINGL("array", sizeof("array") - 1);
- case IS_CALLABLE: RETURN_STRINGL("callable", sizeof("callable") - 1);
- case IS_OBJECT:
- if (param->fptr->type == ZEND_INTERNAL_FUNCTION &&
- !(param->fptr->common.fn_flags & ZEND_ACC_USER_ARG_INFO)) {
- RETURN_STRING(((zend_internal_arg_info*)param->arg_info)->class_name);
- }
- RETURN_STR_COPY(param->arg_info->class_name);
- case IS_STRING: RETURN_STRINGL("string", sizeof("string") - 1);
- case _IS_BOOL: RETURN_STRINGL("bool", sizeof("bool") - 1);
- case IS_LONG: RETURN_STRINGL("int", sizeof("int") - 1);
- case IS_DOUBLE: RETURN_STRINGL("float", sizeof("float") - 1);
- case IS_VOID: RETURN_STRINGL("void", sizeof("void") - 1);
- case IS_ITERABLE: RETURN_STRINGL("iterable", sizeof("iterable") - 1);
- EMPTY_SWITCH_DEFAULT_CASE()
+/* {{{ proto public string ReflectionNamedType::getName()
+ Return the text of the type hint */
+ZEND_METHOD(reflection_named_type, getName)
+{
+ reflection_object *intern;
+ type_reference *param;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
}
+ GET_REFLECTION_OBJECT_PTR(param);
+
+ RETURN_STR(reflection_type_name(param));
}
/* }}} */
PHP_FE_END
};
+static const zend_function_entry reflection_named_type_functions[] = {
+ ZEND_ME(reflection_named_type, getName, arginfo_reflection__void, 0)
+ PHP_FE_END
+};
+
ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_extension_export, 0, 0, 1)
ZEND_ARG_INFO(0, name)
ZEND_ARG_INFO(0, return)
INIT_CLASS_ENTRY(_reflection_entry, "ReflectionType", reflection_type_functions);
_reflection_entry.create_object = reflection_objects_new;
reflection_type_ptr = zend_register_internal_class(&_reflection_entry);
+
+ INIT_CLASS_ENTRY(_reflection_entry, "ReflectionNamedType", reflection_named_type_functions);
+ _reflection_entry.create_object = reflection_objects_new;
+ reflection_named_type_ptr = zend_register_internal_class_ex(&_reflection_entry, reflection_type_ptr);
INIT_CLASS_ENTRY(_reflection_entry, "ReflectionMethod", reflection_method_functions);
_reflection_entry.create_object = reflection_objects_new;
?>
==DONE==
--EXPECT--
-array(15) {
+array(16) {
["ReflectionException"]=>
object(ReflectionClass)#2 (1) {
["name"]=>
["name"]=>
string(14) "ReflectionType"
}
- ["ReflectionMethod"]=>
+ ["ReflectionNamedType"]=>
object(ReflectionClass)#10 (1) {
+ ["name"]=>
+ string(19) "ReflectionNamedType"
+ }
+ ["ReflectionMethod"]=>
+ object(ReflectionClass)#11 (1) {
["name"]=>
string(16) "ReflectionMethod"
}
["ReflectionClass"]=>
- object(ReflectionClass)#11 (1) {
+ object(ReflectionClass)#12 (1) {
["name"]=>
string(15) "ReflectionClass"
}
["ReflectionObject"]=>
- object(ReflectionClass)#12 (1) {
+ object(ReflectionClass)#13 (1) {
["name"]=>
string(16) "ReflectionObject"
}
["ReflectionProperty"]=>
- object(ReflectionClass)#13 (1) {
+ object(ReflectionClass)#14 (1) {
["name"]=>
string(18) "ReflectionProperty"
}
["ReflectionClassConstant"]=>
- object(ReflectionClass)#14 (1) {
+ object(ReflectionClass)#15 (1) {
["name"]=>
string(23) "ReflectionClassConstant"
}
["ReflectionExtension"]=>
- object(ReflectionClass)#15 (1) {
+ object(ReflectionClass)#16 (1) {
["name"]=>
string(19) "ReflectionExtension"
}
["ReflectionZendExtension"]=>
- object(ReflectionClass)#16 (1) {
+ object(ReflectionClass)#17 (1) {
["name"]=>
string(23) "ReflectionZendExtension"
}
--- /dev/null
+--TEST--
+ReflectionNamedType::getName() and ReflectionNamedType::__toString()
+--FILE--
+<?php
+
+function testInternalTypes(?Traversable $traversable): ?string {
+ return 'test';
+}
+
+function testUserDefinedTypes(?Test $traversable): ?Test {
+ return new Test;
+}
+
+$function = new ReflectionFunction('testInternalTypes');
+$type = $function->getParameters()[0]->getType();
+$return = $function->getReturnType();
+
+var_dump($type->getName());
+var_dump((string) $type);
+var_dump($return->getName());
+var_dump((string) $return);
+
+$function = new ReflectionFunction('testUserDefinedTypes');
+$type = $function->getParameters()[0]->getType();
+$return = $function->getReturnType();
+
+var_dump($type->getName());
+var_dump((string) $type);
+var_dump($return->getName());
+var_dump((string) $return);
+
+?>
+--EXPECTF--
+string(11) "Traversable"
+string(12) "?Traversable"
+string(6) "string"
+string(7) "?string"
+string(4) "Test"
+string(5) "?Test"
+string(4) "Test"
+string(5) "?Test"