[vala/staging] codegen: Use a parameter-map for creation of delegate declaration



commit 704188bf81302862a45ed1b9a4ac336225598e50
Author: Rico Tzschichholz <ricotz ubuntu com>
Date:   Thu Jan 10 09:21:54 2019 +0100

    codegen: Use a parameter-map for creation of delegate declaration
    
    This is required to take instance_pos into account and will allow the error
    parameter to be put before the target (aka instance) in delegates.
    
    See https://gitlab.gnome.org/GNOME/vala/issues/728

 codegen/valaccodedelegatemodule.vala | 75 ++++++++++++++++--------------------
 1 file changed, 34 insertions(+), 41 deletions(-)
---
diff --git a/codegen/valaccodedelegatemodule.vala b/codegen/valaccodedelegatemodule.vala
index 71c63e92a..e71d87a5c 100644
--- a/codegen/valaccodedelegatemodule.vala
+++ b/codegen/valaccodedelegatemodule.vala
@@ -53,72 +53,65 @@ public class Vala.CCodeDelegateModule : CCodeArrayModule {
                        generate_type_declaration (d.return_type, decl_space);
                }
 
+               var cparam_map = new HashMap<int,CCodeParameter> (direct_hash, direct_equal);
+
                var cfundecl = new CCodeFunctionDeclarator (get_ccode_name (d));
                foreach (Parameter param in d.get_parameters ()) {
-                       var cparam = generate_parameter (param, decl_space, new HashMap<int,CCodeParameter> 
(), null);
-
-                       cfundecl.add_parameter (cparam);
-
-                       // handle array parameters
-                       if (get_ccode_array_length (param) && param.variable_type is ArrayType) {
-                               var array_type = (ArrayType) param.variable_type;
+                       generate_parameter (param, decl_space, cparam_map, null);
+               }
 
-                               var length_ctype = get_ccode_array_length_type (array_type);
-                               if (param.direction != ParameterDirection.IN) {
-                                       length_ctype += "*";
-                               }
+               // FIXME partial code duplication with CCodeMethodModule.generate_cparameters
 
-                               for (int dim = 1; dim <= array_type.rank; dim++) {
-                                       cparam = new CCodeParameter (get_parameter_array_length_cname (param, 
dim), length_ctype);
-                                       cfundecl.add_parameter (cparam);
-                               }
-                       }
-                       // handle delegate parameters
-                       if (param.variable_type is DelegateType) {
-                               var deleg_type = (DelegateType) param.variable_type;
-                               var param_d = deleg_type.delegate_symbol;
-                               if (param_d.has_target) {
-                                       cparam = new CCodeParameter (get_delegate_target_cname 
(get_variable_cname (param.name)), get_ccode_name (delegate_target_type));
-                                       cfundecl.add_parameter (cparam);
-                                       if (deleg_type.is_disposable ()) {
-                                               cparam = new CCodeParameter 
(get_delegate_target_destroy_notify_cname (get_variable_cname (param.name)), get_ccode_name 
(delegate_target_destroy_type));
-                                               cfundecl.add_parameter (cparam);
-                                       }
-                               }
-                       }
-               }
-               if (get_ccode_array_length (d) && d.return_type is ArrayType) {
+               if (d.return_type.is_real_non_null_struct_type ()) {
+                       // structs are returned via out parameter
+                       var cparam = new CCodeParameter ("result", get_ccode_name (d.return_type) + "*");
+                       cparam_map.set (get_param_pos (-3), cparam);
+               } else if (get_ccode_array_length (d) && d.return_type is ArrayType) {
                        // return array length if appropriate
                        var array_type = (ArrayType) d.return_type;
                        var length_ctype = (get_ccode_array_length_type (d) ?? get_ccode_array_length_type 
(array_type)) + "*";
 
                        for (int dim = 1; dim <= array_type.rank; dim++) {
                                var cparam = new CCodeParameter (get_array_length_cname ("result", dim), 
length_ctype);
-                               cfundecl.add_parameter (cparam);
+                               cparam_map.set (get_param_pos (get_ccode_array_length_pos (d) + 0.01 * dim), 
cparam);
                        }
                } else if (d.return_type is DelegateType) {
                        // return delegate target if appropriate
                        var deleg_type = (DelegateType) d.return_type;
-                       var result_d = deleg_type.delegate_symbol;
-                       if (result_d.has_target) {
+                       if (deleg_type.delegate_symbol.has_target) {
                                var cparam = new CCodeParameter (get_delegate_target_cname ("result"), 
get_ccode_name (delegate_target_type) + "*");
-                               cfundecl.add_parameter (cparam);
+                               cparam_map.set (get_param_pos (get_ccode_delegate_target_pos (d)), cparam);
                                if (deleg_type.is_disposable ()) {
                                        cparam = new CCodeParameter (get_delegate_target_destroy_notify_cname 
("result"), get_ccode_name (delegate_target_destroy_type) + "*");
-                                       cfundecl.add_parameter (cparam);
+                                       cparam_map.set (get_param_pos (get_ccode_delegate_target_pos (d) + 
0.01), cparam);
                                }
                        }
-               } else if (d.return_type.is_real_non_null_struct_type ()) {
-                       var cparam = new CCodeParameter ("result", "%s*".printf (get_ccode_name 
(d.return_type)));
-                       cfundecl.add_parameter (cparam);
                }
+
                if (d.has_target) {
                        var cparam = new CCodeParameter ("user_data", get_ccode_name (delegate_target_type));
-                       cfundecl.add_parameter (cparam);
+                       cparam_map.set (get_param_pos (get_ccode_instance_pos (d)), cparam);
                }
                if (d.tree_can_fail) {
                        var cparam = new CCodeParameter ("error", "GError**");
-                       cfundecl.add_parameter (cparam);
+                       cparam_map.set (get_param_pos (-1), cparam);
+               }
+
+               // append C parameters in the right order
+               int last_pos = -1;
+               int min_pos;
+               while (true) {
+                       min_pos = -1;
+                       foreach (int pos in cparam_map.get_keys ()) {
+                               if (pos > last_pos && (min_pos == -1 || pos < min_pos)) {
+                                       min_pos = pos;
+                               }
+                       }
+                       if (min_pos == -1) {
+                               break;
+                       }
+                       cfundecl.add_parameter (cparam_map.get (min_pos));
+                       last_pos = min_pos;
                }
 
                var ctypedef = new CCodeTypeDefinition (return_type_cname, cfundecl);


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