[vala/staging] girwriter: Improve struct creation method binding



commit cf3a4087bcc5dd443f1eb99b893fe8cb2c536ab8
Author: Princeton Ferro <princetonferro gmail com>
Date:   Thu Jul 15 02:32:00 2021 -0400

    girwriter: Improve struct creation method binding
    
    Struct creation methods are supposed to have `void` return type and take
    an implicit `self` as the first instance parameter.

 codegen/valagirwriter.vala               | 11 +++++++----
 tests/girwriter/GirTest-1.0.gir-expected | 32 ++++++++++++++++----------------
 tests/girwriter/girtest.vapigen-expected | 10 ++++------
 vala/valagirparser.vala                  | 25 ++++++++++++++++++++++---
 4 files changed, 49 insertions(+), 29 deletions(-)
---
diff --git a/codegen/valagirwriter.vala b/codegen/valagirwriter.vala
index 997d899ff..22b024513 100644
--- a/codegen/valagirwriter.vala
+++ b/codegen/valagirwriter.vala
@@ -1207,8 +1207,8 @@ public class Vala.GIRWriter : CodeVisitor {
                        }
 
                        if (constructor && ret_is_struct) {
-                               // struct constructor has its result as first parameter
-                               write_param_or_return (return_type, "parameter", ref index, false, "result", 
return_comment, ParameterDirection.OUT, constructor, true);
+                               // struct constructor has a caller-allocates / out-parameter as instance
+                               write_param_or_return (return_type, "instance-parameter", ref index, false, 
"self", return_comment, ParameterDirection.OUT, constructor, true);
                        }
 
                        if (type_params != null) {
@@ -1422,12 +1422,14 @@ public class Vala.GIRWriter : CodeVisitor {
 
                bool is_struct = m.parent_symbol is Struct;
                // GI doesn't like constructors that return void type
-               string tag_name = is_struct ? "function" : "constructor";
+               string tag_name = is_struct ? "method" : "constructor";
 
                if (m.parent_symbol is Class && m == ((Class)m.parent_symbol).default_construction_method ||
                        m.parent_symbol is Struct && m == 
((Struct)m.parent_symbol).default_construction_method) {
                        string m_name = is_struct ? "init" : "new";
                        buffer.append_printf ("<%s name=\"%s\" c:identifier=\"%s\"", tag_name, m_name, 
get_ccode_name (m));
+               } else if (is_struct) {
+                       buffer.append_printf ("<%s name=\"init_%s\" c:identifier=\"%s\"", tag_name, m.name, 
get_ccode_name (m));
                } else {
                        buffer.append_printf ("<%s name=\"%s\" c:identifier=\"%s\"", tag_name, m.name, 
get_ccode_name (m));
                }
@@ -1565,7 +1567,8 @@ public class Vala.GIRWriter : CodeVisitor {
                unowned DelegateType? delegate_type = type as DelegateType;
                unowned ArrayType? array_type = type as ArrayType;
 
-               if (type != null && ((type.value_owned && delegate_type == null) || (constructor && 
!type.type_symbol.is_subtype_of (ginitiallyunowned_type)))) {
+               if (type != null && ((type.value_owned && delegate_type == null) || (constructor
+                   && !(type.type_symbol is Struct || type.type_symbol.is_subtype_of 
(ginitiallyunowned_type))))) {
                        var any_owned = false;
                        foreach (var generic_arg in type.get_type_arguments ()) {
                                any_owned |= generic_arg.value_owned;
diff --git a/tests/girwriter/GirTest-1.0.gir-expected b/tests/girwriter/GirTest-1.0.gir-expected
index 7d30eea03..0843634a0 100644
--- a/tests/girwriter/GirTest-1.0.gir-expected
+++ b/tests/girwriter/GirTest-1.0.gir-expected
@@ -2769,24 +2769,24 @@
                <field name="internal_field_name" writable="1">
                        <type name="gint" c:type="gint"/>
                </field>
-               <function name="init" c:identifier="gir_test_boxed_struct_init">
+               <method name="init" c:identifier="gir_test_boxed_struct_init">
                        <return-value transfer-ownership="none">
                                <type name="none" c:type="void"/>
                        </return-value>
                        <parameters>
-                               <parameter name="result" direction="out" transfer-ownership="full" 
caller-allocates="1">
+                               <instance-parameter name="self" direction="out" transfer-ownership="none" 
caller-allocates="1">
                                        <type name="GirTest.BoxedStruct" c:type="GirTestBoxedStruct*"/>
-                               </parameter>
+                               </instance-parameter>
                        </parameters>
-               </function>
-               <function name="foo" c:identifier="gir_test_boxed_struct_init_foo">
+               </method>
+               <method name="init_foo" c:identifier="gir_test_boxed_struct_init_foo">
                        <return-value transfer-ownership="none">
                                <type name="none" c:type="void"/>
                        </return-value>
                        <parameters>
-                               <parameter name="result" direction="out" transfer-ownership="full" 
caller-allocates="1">
+                               <instance-parameter name="self" direction="out" transfer-ownership="none" 
caller-allocates="1">
                                        <type name="GirTest.BoxedStruct" c:type="GirTestBoxedStruct*"/>
-                               </parameter>
+                               </instance-parameter>
                                <parameter name="param1" transfer-ownership="none">
                                        <type name="gint" c:type="gint"/>
                                </parameter>
@@ -2794,7 +2794,7 @@
                                        <type name="gint" c:type="gint"/>
                                </parameter>
                        </parameters>
-               </function>
+               </method>
                <method name="inv" c:identifier="gir_test_boxed_struct_inv">
                        <return-value transfer-ownership="full">
                                <type name="none" c:type="void"/>
@@ -2813,24 +2813,24 @@
                <field name="internal_field_name" writable="1">
                        <type name="gint" c:type="gint"/>
                </field>
-               <function name="init" c:identifier="gir_test_struct_init">
+               <method name="init" c:identifier="gir_test_struct_init">
                        <return-value transfer-ownership="none">
                                <type name="none" c:type="void"/>
                        </return-value>
                        <parameters>
-                               <parameter name="result" direction="out" transfer-ownership="full" 
caller-allocates="1">
+                               <instance-parameter name="self" direction="out" transfer-ownership="none" 
caller-allocates="1">
                                        <type name="GirTest.Struct" c:type="GirTestStruct*"/>
-                               </parameter>
+                               </instance-parameter>
                        </parameters>
-               </function>
-               <function name="foo" c:identifier="gir_test_struct_init_foo">
+               </method>
+               <method name="init_foo" c:identifier="gir_test_struct_init_foo">
                        <return-value transfer-ownership="none">
                                <type name="none" c:type="void"/>
                        </return-value>
                        <parameters>
-                               <parameter name="result" direction="out" transfer-ownership="full" 
caller-allocates="1">
+                               <instance-parameter name="self" direction="out" transfer-ownership="none" 
caller-allocates="1">
                                        <type name="GirTest.Struct" c:type="GirTestStruct*"/>
-                               </parameter>
+                               </instance-parameter>
                                <parameter name="param1" transfer-ownership="none">
                                        <type name="gint" c:type="gint"/>
                                </parameter>
@@ -2838,7 +2838,7 @@
                                        <type name="gint" c:type="gint"/>
                                </parameter>
                        </parameters>
-               </function>
+               </method>
                <method name="inv" c:identifier="gir_test_struct_inv">
                        <return-value transfer-ownership="full">
                                <type name="none" c:type="void"/>
diff --git a/tests/girwriter/girtest.vapigen-expected b/tests/girwriter/girtest.vapigen-expected
index 1bc67d83a..61d438058 100644
--- a/tests/girwriter/girtest.vapigen-expected
+++ b/tests/girwriter/girtest.vapigen-expected
@@ -202,9 +202,8 @@ namespace GirTest {
        public struct BoxedStruct {
                public int field_name;
                public int internal_field_name;
-               [CCode (cname = "gir_test_boxed_struct_init_foo")]
-               public void foo (int param1, int param2);
-               public static GirTest.BoxedStruct init ();
+               public BoxedStruct ();
+               public BoxedStruct.foo (int param1, int param2);
                public void inv ();
        }
        [CCode (cheader_filename = "girtest.h", cname = "GirTestNamedCompactClass", has_type_id = false)]
@@ -218,9 +217,8 @@ namespace GirTest {
        public struct Struct {
                public int field_name;
                public int internal_field_name;
-               [CCode (cname = "gir_test_struct_init_foo")]
-               public void foo (int param1, int param2);
-               public static GirTest.Struct init ();
+               public Struct ();
+               public Struct.foo (int param1, int param2);
                public void inv ();
        }
        [CCode (cheader_filename = "girtest.h", cprefix = "GIR_TEST_ENUM_TEST_", type_id = 
"gir_test_enum_test_get_type ()")]
diff --git a/vala/valagirparser.vala b/vala/valagirparser.vala
index 9db320a72..a005efdb0 100644
--- a/vala/valagirparser.vala
+++ b/vala/valagirparser.vala
@@ -3475,10 +3475,29 @@ public class Vala.GirParser : CodeVisitor {
                                                        }
                                                        pop_metadata ();
                                                        continue;
-                                               } else {
-                                                       //TODO can more be done here?
-                                                       m.binding = MemberBinding.STATIC;
+                                               } else if (current.parent.symbol is Struct
+                                                   && caller_allocates && param.direction == 
ParameterDirection.OUT) {
+                                                       // struct methods that have instance parameters with 
'out' direction are usually creation methods
+                                                       string? cm_name = m.name;
+                                                       if (cm_name != null && (cm_name == "init" || 
cm_name.has_prefix ("init_"))) {
+                                                               if (cm_name == "init") {
+                                                                       cm_name = null;
+                                                               } else if (cm_name.has_prefix ("init_")) {
+                                                                       cm_name = cm_name.substring 
("init_".length);
+                                                               }
+                                                               s = new CreationMethod (null, cm_name, 
m.source_reference, m.comment);
+                                                               s.access = SymbolAccessibility.PUBLIC;
+                                                               current.symbol = s;
+                                                               pop_metadata ();
+                                                               continue;
+                                                       }
+                                               } else if (current.parent.symbol is Class && ((Class) 
current.parent.symbol).is_compact
+                                                   && caller_allocates && param.direction == 
ParameterDirection.OUT) {
+                                                       pop_metadata ();
+                                                       continue;
                                                }
+                                               //TODO can more be done here?
+                                               m.binding = MemberBinding.STATIC;
                                        }
                                }
 


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