Skip to content

Add DNF types support for internal functions #10120

Closed
@ju1ius

Description

@ju1ius

Description

Hi, sorry if I'm mistaking, but gen_stub.php doesn't seem to support DNF types ATM.

Input stub file:

<?php
/**
 * @generate-class-entries
 */
class DnfClass {
  public array|(Traversable&Countable)|\Iterator $dnfProp;
  public function dnf(array|(Traversable&Countable)|Iterator $dnf): void {}
}
$ php build/gen_stub.php -f --generate-classsynopses --generate-methodsynopses

Generated arginfo header:

ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_DnfClass_dnf, 0, 1, IS_VOID, 0)
  ZEND_ARG_OBJ_TYPE_MASK(0, dnf, Traversable|Countable|Iterator, MAY_BE_ARRAY, NULL)
ZEND_END_ARG_INFO()

ZEND_METHOD(DnfClass, dnf);

static const zend_function_entry class_DnfClass_methods[] = {
  ZEND_ME(DnfClass, dnf, arginfo_class_DnfClass_dnf, ZEND_ACC_PUBLIC)
  ZEND_FE_END
};

static zend_class_entry *register_class_DnfClass(void) {
  zend_class_entry ce, *class_entry;

  INIT_CLASS_ENTRY(ce, "DnfClass", class_DnfClass_methods);
  class_entry = zend_register_internal_class_ex(&ce, NULL);

  zend_string *property_dnfProp_class_Traversable = zend_string_init("Traversable", sizeof("Traversable") - 1, 1);
  zend_string *property_dnfProp_class_Countable = zend_string_init("Countable", sizeof("Countable") - 1, 1);
  zend_string *property_dnfProp_class_Iterator = zend_string_init("Iterator", sizeof("Iterator") - 1, 1);
  zend_type_list *property_dnfProp_type_list = malloc(ZEND_TYPE_LIST_SIZE(3));
  property_dnfProp_type_list->num_types = 3;
  property_dnfProp_type_list->types[0] = (zend_type) ZEND_TYPE_INIT_CLASS(property_dnfProp_class_Traversable, 0, 0);
  property_dnfProp_type_list->types[1] = (zend_type) ZEND_TYPE_INIT_CLASS(property_dnfProp_class_Countable, 0, 0);
  property_dnfProp_type_list->types[2] = (zend_type) ZEND_TYPE_INIT_CLASS(property_dnfProp_class_Iterator, 0, 0);
  zend_type property_dnfProp_type = ZEND_TYPE_INIT_UNION(property_dnfProp_type_list, MAY_BE_ARRAY);

  zval property_dnfProp_default_value;
  ZVAL_UNDEF(&property_dnfProp_default_value);
  zend_string *property_dnfProp_name = zend_string_init("dnfProp", sizeof("dnfProp") - 1, 1);
  zend_declare_typed_property(class_entry, property_dnfProp_name, &property_dnfProp_default_value, ZEND_ACC_PUBLIC, NULL, property_dnfProp_type);
  zend_string_release(property_dnfProp_name);

  return class_entry;
}

Generated class/method synopses

<classsynopsis>
  <!-- header ommited -->
  <classsynopsisinfo role="comment">&Properties;</classsynopsisinfo>
  <fieldsynopsis>
    <modifier>public</modifier>
    <type class="union">
      <type>array</type><type>Traversable</type><type>Countable</type><type>Iterator</type>
    </type>
    <varname linkend="dnfclass.props.dnfprop">dnfProp</varname>
  </fieldsynopsis>

  <classsynopsisinfo role="comment">&Methods;</classsynopsisinfo>
  <methodsynopsis role="DnfClass">
    <modifier>public</modifier> <type>void</type><methodname>DnfClass::dnf</methodname>
    <methodparam>
        <type class="union">
          <type>array</type><type>Traversable</type><type>Countable</type><type>Iterator</type> 
        </type>
        <parameter>dnf</parameter></methodparam>
  </methodsynopsis>

</classsynopsis>

Expected class/method synopses

  <fieldsynopsis>
    <modifier>public</modifier>
    <type class="union">
      <type>array</type>
      <type class="intersection">
        <type>Traversable</type><type>Countable</type>
      </type>
      <type>Iterator</type>
    </type>
    <varname linkend="dnfclass.props.dnfprop">dnfProp</varname>
  </fieldsynopsis>

  <methodsynopsis role="DnfClass">
    <modifier>public</modifier> <type>void</type><methodname>DnfClass::dnf</methodname>
    <methodparam>
        <type class="union">
          <type>array</type>
          <type class="intersection">
            <type>Traversable</type><type>Countable</type>
          </type>
          <type>Iterator</type>
        </type>
        <parameter>dnf</parameter></methodparam>
  </methodsynopsis>

Expected arginfo header

I'm not super familiar with the new DNF macros API, so WRT the arginfo for DnfClass::dnf() IDK, but for the DnfClass::$dnfProp property I expected the output to look more like the following:

// <snip>, names shortened for readability
zend_string *class_Traversable = zend_string_init("Traversable", sizeof("Traversable") - 1, 1);
zend_string *class_Countable = zend_string_init("Countable", sizeof("Countable") - 1, 1);
zend_string *class_Iterator = zend_string_init("Iterator", sizeof("Iterator") - 1, 1);

zend_type_list *traversable_countable_list = malloc(ZEND_TYPE_LIST_SIZE(2));
traversable_countable_list->num_types = 2;
traversable_countable_list->types[0] = (zend_type) ZEND_TYPE_INIT_CLASS(class_Traversable, 0, 0);
traversable_countable_list->types[1] = (zend_type) ZEND_TYPE_INIT_CLASS(class_Countable, 0, 0);
zend_type traversable_countable_type = ZEND_TYPE_INIT_INTERSECTION(traversable_countable_list, 0);

zend_type_list *dnfProp_type_list = malloc(ZEND_TYPE_LIST_SIZE(2));
dnfProp_type_list->num_types = 2;
dnfProp_type_list->types[0] = traversable_countable_type;
dnfProp_type_list->types[1] = (zend_type) ZEND_TYPE_INIT_CLASS(class_Iterator, 0, 0);
zend_type dnfProp_type = ZEND_TYPE_INIT_UNION(dnfProp_type_list, MAY_BE_ARRAY);
// </snip>

PHP Version

PHP-8.2 (master branch)

Operating System

irrelevant

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions