[vala/wip/issue/606] WIP girwriter: Write implicit parameters and properties for generics



commit 689a4fa84341e98f859b9215616feaf6d01c393e
Author: Rico Tzschichholz <ricotz ubuntu com>
Date:   Thu May 2 18:09:19 2019 +0200

    WIP girwriter: Write implicit parameters and properties for generics

 codegen/valagirwriter.vala               |  68 +++++++++++++--
 tests/girwriter/GirTest-1.0.gir-expected | 142 +++++++++++++++++++++++++++++++
 tests/girwriter/girtest.vala             |  13 +++
 tests/girwriter/girtest.vapi-expected    |  10 +++
 4 files changed, 227 insertions(+), 6 deletions(-)
---
diff --git a/codegen/valagirwriter.vala b/codegen/valagirwriter.vala
index b666f5345..cfef5b18e 100644
--- a/codegen/valagirwriter.vala
+++ b/codegen/valagirwriter.vala
@@ -458,6 +458,12 @@ public class Vala.GIRWriter : CodeVisitor {
                        write_indent ();
                        buffer.append_printf("</field>\n");
 
+                       if (cl.base_class != null && cl.base_class.is_subtype_of (gobject_type)) {
+                               foreach (var p in cl.get_type_parameters ()) {
+                                       write_type_parameter (p, "property");
+                               }
+                       }
+
                        hierarchy.insert (0, cl);
                        cl.accept_children (this);
                        hierarchy.remove_at (0);
@@ -972,7 +978,46 @@ public class Vala.GIRWriter : CodeVisitor {
                }
        }
 
-       private void write_params_and_return (List<Parameter> params, DataType? return_type, bool 
return_array_length, string? return_comment = null, bool constructor = false, DataType? instance_type = null, 
bool user_data = false) {
+       private void write_type_parameter (TypeParameter type_parameter, string tag_type) {
+               write_indent ();
+               if (tag_type == "property") {
+                       buffer.append_printf ("<%s name=\"%s-type\" writable=\"1\" construct-only=\"1\">\n", 
tag_type, type_parameter.name.down ());
+               } else {
+                       buffer.append_printf ("<%s name=\"%s_type\" transfer-ownership=\"none\">\n", 
tag_type, type_parameter.name.down ());
+               }
+               indent++;
+               write_indent ();
+               buffer.append_printf ("<type name=\"GType\" c:type=\"GType\"/>\n");
+               indent--;
+               write_indent ();
+               buffer.append_printf ("</%s>\n", tag_type);
+               write_indent ();
+               if (tag_type == "property") {
+                       buffer.append_printf ("<%s name=\"%s-dup-func\" writable=\"1\" 
construct-only=\"1\">\n", tag_type, type_parameter.name.down ());
+               } else {
+                       buffer.append_printf ("<%s name=\"%s_dup_func\" transfer-ownership=\"none\">\n", 
tag_type, type_parameter.name.down ());
+               }
+               indent++;
+               write_indent ();
+               buffer.append_printf ("<type name=\"GObject.BoxedCopyFunc\" c:type=\"GBoxedCopyFunc\"/>\n");
+               indent--;
+               write_indent ();
+               buffer.append_printf ("</%s>\n", tag_type);
+               write_indent ();
+               if (tag_type == "property") {
+                       buffer.append_printf ("<%s name=\"%s-destroy-func\" writable=\"1\" 
construct-only=\"1\">\n", tag_type, type_parameter.name.down ());
+               } else {
+                       buffer.append_printf ("<%s name=\"%s_destroy_func\" transfer-ownership=\"none\">\n", 
tag_type, type_parameter.name.down ());
+               }
+               indent++;
+               write_indent ();
+               buffer.append_printf ("<type name=\"GLib.DestroyNotify\" c:type=\"GDestroyNotify\"/>\n");
+               indent--;
+               write_indent ();
+               buffer.append_printf ("</%s>\n", tag_type);
+       }
+
+       private void write_params_and_return (List<Parameter> params, List<TypeParameter>? type_params, 
DataType? return_type, bool return_array_length, string? return_comment = null, bool constructor = false, 
DataType? instance_type = null, bool user_data = false) {
                int last_index = 0;
                bool ret_is_struct = return_type != null && return_type.is_real_non_null_struct_type ();
 
@@ -1007,7 +1052,7 @@ public class Vala.GIRWriter : CodeVisitor {
                        write_param_or_return (new VoidType (), false, ref last_index, false, null, 
return_comment, ParameterDirection.IN);
                }
 
-               if (params.size != 0 || instance_type != null || (return_type is ArrayType && 
return_array_length) || (return_type is DelegateType) || ret_is_struct) {
+               if (params.size != 0 || (type_params != null && type_params.size > 0) || instance_type != 
null || (return_type is ArrayType && return_array_length) || (return_type is DelegateType) || ret_is_struct) {
                        write_indent ();
                        buffer.append_printf ("<parameters>\n");
                        indent++;
@@ -1017,6 +1062,13 @@ public class Vala.GIRWriter : CodeVisitor {
                                write_param_or_return (instance_type, true, ref index, false, "self");
                        }
 
+                       if (type_params != null) {
+                               foreach (var p in type_params) {
+                                       write_type_parameter (p, "parameter");
+                                       index += 3;
+                               }
+                       }
+
                        foreach (Parameter param in params) {
                                write_param_or_return (param.variable_type, true, ref index, 
get_ccode_array_length (param), param.name, get_parameter_comment (param), param.direction, false, false, 
param.ellipsis);
 
@@ -1068,7 +1120,7 @@ public class Vala.GIRWriter : CodeVisitor {
 
                write_doc (get_delegate_comment (cb));
 
-               write_params_and_return (cb.get_parameters (), cb.return_type, get_ccode_array_length (cb), 
get_delegate_return_comment (cb), false, null, cb.has_target);
+               write_params_and_return (cb.get_parameters (), cb.get_type_parameters (), cb.return_type, 
get_ccode_array_length (cb), get_delegate_return_comment (cb), false, null, cb.has_target);
 
                indent--;
                write_indent ();
@@ -1188,7 +1240,7 @@ public class Vala.GIRWriter : CodeVisitor {
                        instance_type = CCodeBaseModule.get_data_type_for_symbol ((TypeSymbol) 
m.parent_symbol);
                }
 
-               write_params_and_return (params, return_type, get_ccode_array_length (m), return_comment, 
false, instance_type);
+               write_params_and_return (params, m.get_type_parameters (), return_type, 
get_ccode_array_length (m), return_comment, false, instance_type);
 
                indent--;
                write_indent ();
@@ -1232,7 +1284,11 @@ public class Vala.GIRWriter : CodeVisitor {
                write_doc (get_method_comment (m));
 
                var datatype = CCodeBaseModule.get_data_type_for_symbol ((TypeSymbol) m.parent_symbol);
-               write_params_and_return (m.get_parameters (), datatype, false, get_method_return_comment (m), 
true);
+               List<TypeParameter>? type_params = null;
+               if (m.parent_symbol is Class) {
+                       type_params = ((Class) m.parent_symbol).get_type_parameters ();
+               }
+               write_params_and_return (m.get_parameters (), type_params, datatype, false, 
get_method_return_comment (m), true);
 
                indent--;
                write_indent ();
@@ -1305,7 +1361,7 @@ public class Vala.GIRWriter : CodeVisitor {
 
                write_doc (get_signal_comment (sig));
 
-               write_params_and_return (sig.get_parameters (), sig.return_type, false, 
get_signal_return_comment (sig));
+               write_params_and_return (sig.get_parameters (), null, sig.return_type, false, 
get_signal_return_comment (sig));
 
                indent--;
                write_indent ();
diff --git a/tests/girwriter/GirTest-1.0.gir-expected b/tests/girwriter/GirTest-1.0.gir-expected
index a8bf8181d..9aba2a5f8 100644
--- a/tests/girwriter/GirTest-1.0.gir-expected
+++ b/tests/girwriter/GirTest-1.0.gir-expected
@@ -960,6 +960,148 @@
                </field>
        </record>
        <record name="DeprecatedClassTestPrivate" c:type="GirTestDeprecatedClassTestPrivate" disguised="1"/>
+       <class name="GenericsTest" c:type="GirTestGenericsTest" glib:type-name="GirTestGenericsTest" 
glib:get-type="gir_test_generics_test_get_type" glib:type-struct="GenericsTestClass" glib:fundamental="1" 
glib:ref-func="gir_test_generics_test_ref" glib:unref-func="gir_test_generics_test_unref" 
glib:set-value-func="gir_test_value_set_generics_test" glib:get-value-func="gir_test_value_get_generics_test">
+               <field name="parent_instance">
+                       <type name="GObject.TypeInstance" c:type="GTypeInstance"/>
+               </field>
+               <field name="ref_count">
+                       <type name="gint" c:type="volatile int"/>
+               </field>
+               <field name="priv">
+                       <type name="GenericsTestPrivate" c:type="GirTestGenericsTestPrivate*"/>
+               </field>
+               <constructor name="new" c:identifier="gir_test_generics_test_new">
+                       <return-value transfer-ownership="full">
+                               <type name="GirTest.GenericsTest" c:type="GirTestGenericsTest*"/>
+                       </return-value>
+                       <parameters>
+                               <parameter name="g_type" transfer-ownership="none">
+                                       <type name="GType" c:type="GType"/>
+                               </parameter>
+                               <parameter name="g_dup_func" transfer-ownership="none">
+                                       <type name="GObject.BoxedCopyFunc" c:type="GBoxedCopyFunc"/>
+                               </parameter>
+                               <parameter name="g_destroy_func" transfer-ownership="none">
+                                       <type name="GLib.DestroyNotify" c:type="GDestroyNotify"/>
+                               </parameter>
+                               <parameter name="t_type" transfer-ownership="none">
+                                       <type name="GType" c:type="GType"/>
+                               </parameter>
+                               <parameter name="t_dup_func" transfer-ownership="none">
+                                       <type name="GObject.BoxedCopyFunc" c:type="GBoxedCopyFunc"/>
+                               </parameter>
+                               <parameter name="t_destroy_func" transfer-ownership="none">
+                                       <type name="GLib.DestroyNotify" c:type="GDestroyNotify"/>
+                               </parameter>
+                               <parameter name="cb" transfer-ownership="none" closure="7" scope="notified" 
destroy="8">
+                                       <type name="GirTest.DelegateTest" c:type="GirTestDelegateTest"/>
+                               </parameter>
+                               <parameter name="cb_target" transfer-ownership="none" allow-none="1">
+                                       <type name="gpointer" c:type="void*"/>
+                               </parameter>
+                               <parameter name="cb_target_destroy_notify" transfer-ownership="none" 
scope="call">
+                                       <type name="GLib.DestroyNotify" c:type="GDestroyNotify"/>
+                               </parameter>
+                       </parameters>
+               </constructor>
+               <method name="method" c:identifier="gir_test_generics_test_method">
+                       <return-value transfer-ownership="full">
+                               <type name="none"/>
+                       </return-value>
+                       <parameters>
+                               <parameter name="param" transfer-ownership="none" allow-none="1">
+                                       <type name="gpointer" c:type="gpointer"/>
+                               </parameter>
+                       </parameters>
+               </method>
+       </class>
+       <record name="GenericsTestClass" c:type="GirTestGenericsTestClass" 
glib:is-gtype-struct-for="GenericsTest">
+               <field name="parent_class">
+                       <type name="GObject.TypeClass" c:type="GTypeClass"/>
+               </field>
+       </record>
+       <record name="GenericsTestPrivate" c:type="GirTestGenericsTestPrivate" disguised="1"/>
+       <class name="GenericsObjectTest" c:type="GirTestGenericsObjectTest" 
glib:type-name="GirTestGenericsObjectTest" glib:get-type="gir_test_generics_object_test_get_type" 
glib:type-struct="GenericsObjectTestClass" parent="GObject.Object">
+               <field name="parent_instance">
+                       <type name="GObject.Object" c:type="GObject"/>
+               </field>
+               <field name="priv">
+                       <type name="GenericsObjectTestPrivate" c:type="GirTestGenericsObjectTestPrivate*"/>
+               </field>
+               <property name="g-type" writable="1" construct-only="1">
+                       <type name="GType" c:type="GType"/>
+               </property>
+               <property name="g-dup-func" writable="1" construct-only="1">
+                       <type name="GObject.BoxedCopyFunc" c:type="GBoxedCopyFunc"/>
+               </property>
+               <property name="g-destroy-func" writable="1" construct-only="1">
+                       <type name="GLib.DestroyNotify" c:type="GDestroyNotify"/>
+               </property>
+               <property name="t-type" writable="1" construct-only="1">
+                       <type name="GType" c:type="GType"/>
+               </property>
+               <property name="t-dup-func" writable="1" construct-only="1">
+                       <type name="GObject.BoxedCopyFunc" c:type="GBoxedCopyFunc"/>
+               </property>
+               <property name="t-destroy-func" writable="1" construct-only="1">
+                       <type name="GLib.DestroyNotify" c:type="GDestroyNotify"/>
+               </property>
+               <method name="method" c:identifier="gir_test_generics_object_test_method">
+                       <return-value transfer-ownership="full">
+                               <type name="none"/>
+                       </return-value>
+                       <parameters>
+                               <parameter name="k_type" transfer-ownership="none">
+                                       <type name="GType" c:type="GType"/>
+                               </parameter>
+                               <parameter name="k_dup_func" transfer-ownership="none">
+                                       <type name="GObject.BoxedCopyFunc" c:type="GBoxedCopyFunc"/>
+                               </parameter>
+                               <parameter name="k_destroy_func" transfer-ownership="none">
+                                       <type name="GLib.DestroyNotify" c:type="GDestroyNotify"/>
+                               </parameter>
+                               <parameter name="param" transfer-ownership="none">
+                                       <array length="4" c:type="gpointer*">
+                                               <type name="gpointer" c:type="gpointer"/>
+                                       </array>
+                               </parameter>
+                               <parameter name="param_length1" transfer-ownership="none">
+                                       <type name="gint" c:type="gint"/>
+                               </parameter>
+                       </parameters>
+               </method>
+               <constructor name="new" c:identifier="gir_test_generics_object_test_new">
+                       <return-value transfer-ownership="full">
+                               <type name="GirTest.GenericsObjectTest" c:type="GirTestGenericsObjectTest*"/>
+                       </return-value>
+                       <parameters>
+                               <parameter name="g_type" transfer-ownership="none">
+                                       <type name="GType" c:type="GType"/>
+                               </parameter>
+                               <parameter name="g_dup_func" transfer-ownership="none">
+                                       <type name="GObject.BoxedCopyFunc" c:type="GBoxedCopyFunc"/>
+                               </parameter>
+                               <parameter name="g_destroy_func" transfer-ownership="none">
+                                       <type name="GLib.DestroyNotify" c:type="GDestroyNotify"/>
+                               </parameter>
+                               <parameter name="t_type" transfer-ownership="none">
+                                       <type name="GType" c:type="GType"/>
+                               </parameter>
+                               <parameter name="t_dup_func" transfer-ownership="none">
+                                       <type name="GObject.BoxedCopyFunc" c:type="GBoxedCopyFunc"/>
+                               </parameter>
+                               <parameter name="t_destroy_func" transfer-ownership="none">
+                                       <type name="GLib.DestroyNotify" c:type="GDestroyNotify"/>
+                               </parameter>
+                       </parameters>
+               </constructor>
+       </class>
+       <record name="GenericsObjectTestClass" c:type="GirTestGenericsObjectTestClass" 
glib:is-gtype-struct-for="GenericsObjectTest">
+               <field name="parent_class">
+                       <type name="GObject.ObjectClass" c:type="GObjectClass"/>
+               </field>
+       </record>
+       <record name="GenericsObjectTestPrivate" c:type="GirTestGenericsObjectTestPrivate" disguised="1"/>
        <interface name="InterfaceTest" c:type="GirTestInterfaceTest" glib:type-name="GirTestInterfaceTest" 
glib:get-type="gir_test_interface_test_get_type" glib:type-struct="InterfaceTestIface">
                <prerequisite name="GObject.Object"/>
                <method name="int8_in" c:identifier="gir_test_interface_test_int8_in">
diff --git a/tests/girwriter/girtest.vala b/tests/girwriter/girtest.vala
index ef35e8ec8..1164ab1da 100644
--- a/tests/girwriter/girtest.vala
+++ b/tests/girwriter/girtest.vala
@@ -272,4 +272,17 @@ namespace GirTest {
        [Version (deprecated = true, deprecated_since = "0.1.2", since = "0.1.0")]
        public class DeprecatedClassTest {
        }
+
+       public class GenericsTest<G,T> {
+               public GenericsTest (owned DelegateTest cb) {
+               }
+
+               public void method (T param) {
+               }
+       }
+
+       public class GenericsObjectTest<G,T> : Object {
+               public void method<K> (K[] param) {
+               }
+       }
 }
diff --git a/tests/girwriter/girtest.vapi-expected b/tests/girwriter/girtest.vapi-expected
index 4a0709bc2..8e3b3b697 100644
--- a/tests/girwriter/girtest.vapi-expected
+++ b/tests/girwriter/girtest.vapi-expected
@@ -14,6 +14,16 @@ namespace GirTest {
                public DeprecatedClassTest ();
        }
        [CCode (cheader_filename = "girtest.h")]
+       public class GenericsObjectTest<G,T> : GLib.Object {
+               public GenericsObjectTest ();
+               public void method<K> (K[] param);
+       }
+       [CCode (cheader_filename = "girtest.h")]
+       public class GenericsTest<G,T> {
+               public GenericsTest (owned GirTest.DelegateTest cb);
+               public void method (T param);
+       }
+       [CCode (cheader_filename = "girtest.h")]
        public class ImplementionTest : GLib.Object, GirTest.InterfaceTest {
                public ImplementionTest ();
        }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]