Array and delegate parameters correspond to multiple parameters at the
C level. GObject-introspection expects them them to be written separately,
with special attributes refering to the main ones.

Since implicit output arguments must be generated for return values,
writing params and return values was combined to common methods. The were
always used together, so the main downside is the method now takes long
list of arguments to cover all the cases.

Note, that only default argument positions are supported.

Signed-off-by: Jan Hudec <b...@ucw.cz>
---
 codegen/valagirwriter.vala |  136 +++++++++++++++++++++----------------------
 1 files changed, 66 insertions(+), 70 deletions(-)

The condition in write_params_and_return was wrong. The negations around
'return_type is ArrayType' and 'return_type is DelegateType' should not be
there. Here's an updated patch.

diff --git a/codegen/valagirwriter.vala b/codegen/valagirwriter.vala
index 8b65267..ea75142 100644
--- a/codegen/valagirwriter.vala
+++ b/codegen/valagirwriter.vala
@@ -441,72 +441,49 @@ public class Vala.GIRWriter : CodeVisitor {
                stream.printf ("</field>\n");
        }
 
-       private void write_params (Gee.List<FormalParameter> params, DataType? 
instance_type = null) {
-               if (params.size == 0 && instance_type == null) {
-                       return;
+       private void write_implicit_params (DataType type, ref int index, bool 
has_array_length, string name, ParameterDirection direction) {
+               if (type is ArrayType && has_array_length) {
+                       var int_type = new IntegerType (CodeContext.get 
().root.scope.lookup ("int") as Struct);
+                       write_param_or_return (int_type, "parameter", ref 
index, has_array_length, "%s_length1".printf (name), direction);
+               } else if (type is DelegateType) {
+                       var data_type = new PointerType (new VoidType ());
+                       write_param_or_return (data_type, "parameter", ref 
index, false, "%s_target".printf (name), direction);
+                       if (type.value_owned) {
+                               var notify_type = new DelegateType 
(CodeContext.get ().root.scope.lookup ("GLib").scope.lookup ("DestroyNotify") 
as Delegate);
+                               write_param_or_return (notify_type, 
"parameter", ref index, false, "%s_target_destroy_notify".printf (name), 
direction);
+                       }
                }
+       }
 
-               write_indent ();
-               stream.printf ("<parameters>\n");
-               indent++;
-
-               if (instance_type != null) {
+       private void write_params_and_return (Gee.List<FormalParameter> params, 
DataType? return_type, bool return_array_length, bool constructor = false, 
DataType? instance_type = null) {
+               int last_index = 0;
+               if (params.size != 0 || instance_type != null || (return_type 
is ArrayType && return_array_length) || (return_type is DelegateType)) {
                        write_indent ();
-                       stream.printf ("<parameter name=\"self\" 
transfer-ownership=\"none\">\n");
+                       stream.printf ("<parameters>\n");
                        indent++;
+                       int index = 1;
 
-                       write_type (instance_type);
+                       if (instance_type != null) {
+                               write_param_or_return (instance_type, 
"parameter", ref index, false, "self");
+                       }
 
-                       indent--;
-                       write_indent ();
-                       stream.printf ("</parameter>\n");
-               }
+                       foreach (FormalParameter param in params) {
+                               write_param_or_return (param.parameter_type, 
"parameter", ref index, !param.no_array_length, param.name, param.direction);
 
-               foreach (FormalParameter param in params) {
-                       write_indent ();
-                       stream.printf ("<parameter name=\"%s\"", param.name);
-                       if (param.direction == ParameterDirection.REF) {
-                               stream.printf (" direction=\"inout\"");
-                               // in/out paramter
-                               if (param.parameter_type.value_owned) {
-                                       stream.printf (" 
transfer-ownership=\"full\"");
-                               } else {
-                                       stream.printf (" 
transfer-ownership=\"none\"");
-                               }
-                       } else if (param.direction == ParameterDirection.OUT) {
-                               // out paramter
-                               stream.printf (" direction=\"out\"");
-                               if (param.parameter_type.value_owned) {
-                                       stream.printf (" 
transfer-ownership=\"full\"");
-                               } else {
-                                       stream.printf (" 
transfer-ownership=\"none\"");
-                               }
-                       } else {
-                               // normal in paramter
-                               if (param.parameter_type.value_owned) {
-                                       stream.printf (" 
transfer-ownership=\"full\"");
-                               } else {
-                                       stream.printf (" 
transfer-ownership=\"none\"");
-                               }
-                       }
-                       if (param.parameter_type.nullable) {
-                               stream.printf (" allow-none=\"1\"");
+                               write_implicit_params (param.parameter_type, 
ref index, !param.no_array_length, param.name, param.direction);
                        }
-                       stream.printf (">\n");
-                       indent++;
-
-                       write_annotations (param);
 
-                       write_type (param.parameter_type);
+                       last_index = index - 1;
+                       write_implicit_params (return_type, ref index, 
return_array_length, "result", ParameterDirection.OUT);
 
                        indent--;
                        write_indent ();
-                       stream.printf ("</parameter>\n");
+                       stream.printf ("</parameters>\n");
                }
 
-               indent--;
-               write_indent ();
-               stream.printf ("</parameters>\n");
+               if (return_type != null) {
+                       write_param_or_return (return_type, "return-value", ref 
last_index, return_array_length, null, ParameterDirection.IN, constructor);
+               }
        }
 
        public override void visit_delegate (Delegate cb) {
@@ -529,9 +506,7 @@ public class Vala.GIRWriter : CodeVisitor {
 
                write_annotations (cb);
 
-               write_params (cb.get_parameters ());
-
-               write_return_type (cb.return_type);
+               write_params_and_return (cb.get_parameters (), cb.return_type, 
!cb.no_array_length);
 
                indent--;
                write_indent ();
@@ -598,9 +573,7 @@ public class Vala.GIRWriter : CodeVisitor {
                        instance_type = 
CCodeBaseModule.get_data_type_for_symbol ((TypeSymbol) m.parent_symbol);
                }
 
-               write_params (params, instance_type);
-
-               write_return_type (return_type);
+               write_params_and_return (params, return_type, 
!m.no_array_length, false, instance_type);
 
                indent--;
                write_indent ();
@@ -632,10 +605,9 @@ public class Vala.GIRWriter : CodeVisitor {
 
                write_annotations (m);
 
-               write_params (m.get_parameters ());
 
                var datatype = CCodeBaseModule.get_data_type_for_symbol 
((TypeSymbol) m.parent_symbol);
-               write_return_type (datatype, true);
+               write_params_and_return (m.get_parameters (), datatype, false, 
true);
 
                indent--;
                write_indent ();
@@ -686,9 +658,7 @@ public class Vala.GIRWriter : CodeVisitor {
 
                write_annotations (sig);
 
-               write_params (sig.get_parameters ());
-
-               write_return_type (sig.return_type);
+               write_params_and_return (sig.get_parameters (), 
sig.return_type, false);
 
                indent--;
                write_indent ();
@@ -703,10 +673,21 @@ public class Vala.GIRWriter : CodeVisitor {
                }
        }
 
-       private void write_return_type (DataType type, bool constructor = 
false) {
+       private void write_param_or_return (DataType type, string tag, ref int 
index, bool has_array_length, string? name = null, ParameterDirection direction 
= ParameterDirection.IN, bool constructor = false) {
                write_indent ();
-               stream.printf ("<return-value");
-               if (type.value_owned || constructor) {
+               stream.printf ("<%s", tag);
+               if (name != null) {
+                       stream.printf (" name=\"%s\"", name);
+               }
+               if (direction == ParameterDirection.REF) {
+                       stream.printf (" direction=\"inout\"");
+               } else if (direction == ParameterDirection.OUT) {
+                       stream.printf (" direction=\"out\"");
+               }
+
+               Delegate delegate_type = type.data_type as Delegate;
+
+               if ((type.value_owned && delegate_type == null) || constructor) 
{
                        stream.printf (" transfer-ownership=\"full\"");
                } else {
                        stream.printf (" transfer-ownership=\"none\"");
@@ -714,14 +695,23 @@ public class Vala.GIRWriter : CodeVisitor {
                if (type.nullable) {
                        stream.printf (" allow-none=\"1\"");
                }
+
+               if (delegate_type != null && delegate_type.has_target) {
+                       stream.printf (" closure=\"%i\"", index + 1);
+                       if (type.value_owned) {
+                               stream.printf (" destroy=\"%i\"", index + 2);
+                       }
+               }
+
                stream.printf (">\n");
                indent++;
 
-               write_type (type);
+               write_type (type, has_array_length ? index : -1);
 
                indent--;
                write_indent ();
-               stream.printf ("</return-value>\n");
+               stream.printf ("</%s>\n", tag);
+               index++;
        }
 
        private void write_ctype_attributes (TypeSymbol symbol, string suffix = 
"") {
@@ -734,12 +724,18 @@ public class Vala.GIRWriter : CodeVisitor {
                stream.printf (" glib:get-type=\"%sget_type\"", 
symbol.get_lower_case_cprefix ());
        }
 
-       private void write_type (DataType type) {
+       private void write_type (DataType type, int index = -1) {
                if (type is ArrayType) {
                        var array_type = (ArrayType) type;
 
                        write_indent ();
-                       stream.printf ("<array>\n");
+                       stream.printf ("<array");
+                       if (array_type.fixed_length) {
+                               stream.printf (" fixed-length\"%i\"", 
array_type.length);
+                       } else if (index != -1) {
+                               stream.printf (" length=\"%i\"", index + 1);
+                       }
+                       stream.printf (">\n");
                        indent++;
 
                        write_type (array_type.element_type);
-- 
1.6.4.3

-- 
                                                 Jan 'Bulb' Hudec <b...@ucw.cz>
_______________________________________________
Vala-list mailing list
Vala-list@gnome.org
http://mail.gnome.org/mailman/listinfo/vala-list

Reply via email to