diff --git a/Zend/zend_exceptions_arginfo.h b/Zend/zend_exceptions_arginfo.h index 8e8fb7c20bd9c..b1e4844717763 100644 --- a/Zend/zend_exceptions_arginfo.h +++ b/Zend/zend_exceptions_arginfo.h @@ -245,7 +245,7 @@ static zend_class_entry *register_class_Exception(zend_class_entry *class_entry_ zval property_previous_default_value; ZVAL_NULL(&property_previous_default_value); zend_string *property_previous_name = zend_string_init("previous", sizeof("previous") - 1, 1); - zend_declare_typed_property(class_entry, property_previous_name, &property_previous_default_value, ZEND_ACC_PRIVATE, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_previous_class_Throwable, 1, 0)); + zend_declare_typed_property(class_entry, property_previous_name, &property_previous_default_value, ZEND_ACC_PRIVATE, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_previous_class_Throwable, 0, MAY_BE_NULL)); zend_string_release(property_previous_name); return class_entry; @@ -309,7 +309,7 @@ static zend_class_entry *register_class_Error(zend_class_entry *class_entry_Thro zval property_previous_default_value; ZVAL_NULL(&property_previous_default_value); zend_string *property_previous_name = zend_string_init("previous", sizeof("previous") - 1, 1); - zend_declare_typed_property(class_entry, property_previous_name, &property_previous_default_value, ZEND_ACC_PRIVATE, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_previous_class_Throwable, 1, 0)); + zend_declare_typed_property(class_entry, property_previous_name, &property_previous_default_value, ZEND_ACC_PRIVATE, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_previous_class_Throwable, 0, MAY_BE_NULL)); zend_string_release(property_previous_name); return class_entry; diff --git a/build/gen_stub.php b/build/gen_stub.php index ee4033ab1097e..084e142e34598 100755 --- a/build/gen_stub.php +++ b/build/gen_stub.php @@ -1047,16 +1047,30 @@ function (Expr $expr) use (&$defaultValueConstant) { if ($this->type) { $arginfoType = $this->type->toArginfoType(); if ($arginfoType->hasClassType()) { - $simpleType = $this->type->tryToSimpleType(); + if (count($arginfoType->classTypes) >= 2) { + foreach ($arginfoType->classTypes as $classType) { + $className = $classType->name; + $code .= "\tzend_string *property_{$propertyName}_class_{$className} = zend_string_init(\"$className\", sizeof(\"$className\") - 1, 1);\n"; + } - $className = $arginfoType->classTypes[0]->name; - $code .= " zend_string *property_{$propertyName}_class_{$className} = zend_string_init(\"$className\", sizeof(\"$className\")-1, 1);\n"; - if ($simpleType) { - $typeCode = "(zend_type) ZEND_TYPE_INIT_CLASS(property_{$propertyName}_class_{$className}, " . ((int) $this->type->isNullable()) . ", 0)"; - } elseif (count($arginfoType->classTypes) === 1) { - $typeCode = "(zend_type) ZEND_TYPE_INIT_CLASS(property_{$propertyName}_class_{$className}, 0, " . $arginfoType->toTypeMask() . ")"; + $classTypeCount = count($arginfoType->classTypes); + $code .= "\tzend_type_list *property_{$propertyName}_type_list = malloc(ZEND_TYPE_LIST_SIZE($classTypeCount));\n"; + $code .= "\tproperty_{$propertyName}_type_list->num_types = $classTypeCount;\n"; + + foreach ($arginfoType->classTypes as $k => $classType) { + $className = $classType->name; + $code .= "\tproperty_{$propertyName}_type_list->types[$k] = (zend_type) ZEND_TYPE_INIT_CLASS(property_{$propertyName}_class_{$className}, 0, 0);\n"; + } + + $typeMaskCode = $this->type->toArginfoType()->toTypeMask(); + + $code .= "\tzend_type property_{$propertyName}_type = ZEND_TYPE_INIT_PTR(property_{$propertyName}_type_list, _ZEND_TYPE_LIST_BIT, 0, $typeMaskCode);\n"; + $typeCode = "property_{$propertyName}_type"; } else { - throw new Exception("Property $this->name has an unsupported union type"); + $className = $arginfoType->classTypes[0]->name; + $code .= "\tzend_string *property_{$propertyName}_class_{$className} = zend_string_init(\"$className\", sizeof(\"$className\")-1, 1);\n"; + + $typeCode = "(zend_type) ZEND_TYPE_INIT_CLASS(property_{$propertyName}_class_{$className}, 0, " . $arginfoType->toTypeMask() . ")"; } } else { $typeCode = "(zend_type) ZEND_TYPE_INIT_MASK(" . $arginfoType->toTypeMask() . ")"; diff --git a/ext/zend_test/test.c b/ext/zend_test/test.c index e54c201891e46..27be53faea574 100644 --- a/ext/zend_test/test.c +++ b/ext/zend_test/test.c @@ -366,21 +366,6 @@ PHP_MINIT_FUNCTION(zend_test) zend_test_class->create_object = zend_test_class_new; zend_test_class->get_static_method = zend_test_class_static_method_get; - { - zend_string *name = zend_string_init("classUnionProp", sizeof("classUnionProp") - 1, 1); - zend_string *class_name1 = zend_string_init("stdClass", sizeof("stdClass") - 1, 1); - zend_string *class_name2 = zend_string_init("Iterator", sizeof("Iterator") - 1, 1); - zend_type_list *type_list = malloc(ZEND_TYPE_LIST_SIZE(2)); - type_list->num_types = 2; - type_list->types[0] = (zend_type) ZEND_TYPE_INIT_CLASS(class_name1, 0, 0); - type_list->types[1] = (zend_type) ZEND_TYPE_INIT_CLASS(class_name2, 0, 0); - zend_type type = ZEND_TYPE_INIT_PTR(type_list, _ZEND_TYPE_LIST_BIT, 1, 0); - zval val; - ZVAL_NULL(&val); - zend_declare_typed_property(zend_test_class, name, &val, ZEND_ACC_PUBLIC, NULL, type); - zend_string_release(name); - } - zend_test_child_class = register_class__ZendTestChildClass(zend_test_class); memcpy(&zend_test_class_handlers, &std_object_handlers, sizeof(zend_object_handlers)); diff --git a/ext/zend_test/test.stub.php b/ext/zend_test/test.stub.php index 98dba6a396586..624ba1195f3cd 100644 --- a/ext/zend_test/test.stub.php +++ b/ext/zend_test/test.stub.php @@ -16,7 +16,7 @@ class _ZendTestClass implements _ZendTestInterface { public int $intProp = 123; public ?stdClass $classProp = null; - //public stdClass|Iterator|null $classUnionProp = null; + public stdClass|Iterator|null $classUnionProp = null; public static function is_object(): int {} diff --git a/ext/zend_test/test_arginfo.h b/ext/zend_test/test_arginfo.h index b7dd3dbe28386..dc040a568043f 100644 --- a/ext/zend_test/test_arginfo.h +++ b/ext/zend_test/test_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: cfe2668e6d45a45dafb313cc8b053e2c81ef053a */ + * Stub hash: cf8958513064fb7257203b3304c8dc67c8e008b9 */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_zend_test_array_return, 0, 0, IS_ARRAY, 0) ZEND_END_ARG_INFO() @@ -201,9 +201,22 @@ static zend_class_entry *register_class__ZendTestClass(zend_class_entry *class_e zval property_classProp_default_value; ZVAL_NULL(&property_classProp_default_value); zend_string *property_classProp_name = zend_string_init("classProp", sizeof("classProp") - 1, 1); - zend_declare_typed_property(class_entry, property_classProp_name, &property_classProp_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_classProp_class_stdClass, 1, 0)); + zend_declare_typed_property(class_entry, property_classProp_name, &property_classProp_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_classProp_class_stdClass, 0, MAY_BE_NULL)); zend_string_release(property_classProp_name); + zend_string *property_classUnionProp_class_stdClass = zend_string_init("stdClass", sizeof("stdClass") - 1, 1); + zend_string *property_classUnionProp_class_Iterator = zend_string_init("Iterator", sizeof("Iterator") - 1, 1); + zend_type_list *property_classUnionProp_type_list = malloc(ZEND_TYPE_LIST_SIZE(2)); + property_classUnionProp_type_list->num_types = 2; + property_classUnionProp_type_list->types[0] = (zend_type) ZEND_TYPE_INIT_CLASS(property_classUnionProp_class_stdClass, 0, 0); + property_classUnionProp_type_list->types[1] = (zend_type) ZEND_TYPE_INIT_CLASS(property_classUnionProp_class_Iterator, 0, 0); + zend_type property_classUnionProp_type = ZEND_TYPE_INIT_PTR(property_classUnionProp_type_list, _ZEND_TYPE_LIST_BIT, 0, MAY_BE_NULL); + zval property_classUnionProp_default_value; + ZVAL_NULL(&property_classUnionProp_default_value); + zend_string *property_classUnionProp_name = zend_string_init("classUnionProp", sizeof("classUnionProp") - 1, 1); + zend_declare_typed_property(class_entry, property_classUnionProp_name, &property_classUnionProp_default_value, ZEND_ACC_PUBLIC, NULL, property_classUnionProp_type); + zend_string_release(property_classUnionProp_name); + return class_entry; }