Support flexible position of array length and delegate target parameters,
authorJuerg Billeter <j@bitron.ch>
Wed, 6 Feb 2008 16:55:33 +0000 (16:55 +0000)
committerJürg Billeter <juergbi@src.gnome.org>
Wed, 6 Feb 2008 16:55:33 +0000 (16:55 +0000)
2008-02-06  Juerg Billeter  <j@bitron.ch>

* vala/parser.y, vala/valaarrayresizemethod.vala,
  vala/valaattribute.vala, vala/valaattributeprocessor.vala,
  vala/valacodecontext.vala, vala/valadelegate.vala,
  vala/valaformalparameter.vala, vala/valainterfacewriter.vala,
  vala/valamethod.vala, vala/valasemanticanalyzer.vala,
  gobject/valaccodegeneratorinvocationexpression.vala,
  gobject/valaccodegeneratormethod.vala:

  Support flexible position of array length and delegate target
  parameters, fixes bug 508831 and bug 513089

* vapi/glib-2.0.vapi: update

svn path=/trunk/; revision=982

14 files changed:
ChangeLog
gobject/valaccodegeneratorinvocationexpression.vala
gobject/valaccodegeneratormethod.vala
vala/parser.y
vala/valaarrayresizemethod.vala
vala/valaattribute.vala
vala/valaattributeprocessor.vala
vala/valacodecontext.vala
vala/valadelegate.vala
vala/valaformalparameter.vala
vala/valainterfacewriter.vala
vala/valamethod.vala
vala/valasemanticanalyzer.vala
vapi/glib-2.0.vapi

index a395574..4bb8dfe 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2008-02-06  Jürg Billeter  <j@bitron.ch>
+
+       * vala/parser.y, vala/valaarrayresizemethod.vala,
+         vala/valaattribute.vala, vala/valaattributeprocessor.vala,
+         vala/valacodecontext.vala, vala/valadelegate.vala,
+         vala/valaformalparameter.vala, vala/valainterfacewriter.vala,
+         vala/valamethod.vala, vala/valasemanticanalyzer.vala,
+         gobject/valaccodegeneratorinvocationexpression.vala,
+         gobject/valaccodegeneratormethod.vala:
+
+         Support flexible position of array length and delegate target
+         parameters, fixes bug 508831 and bug 513089
+
+       * vapi/glib-2.0.vapi: update
+
 2008-02-05  Jürg Billeter  <j@bitron.ch>
 
        * vala/valapointertype.vala: implement get_symbols method,
index 6fea5ea..b38a82a 100644 (file)
@@ -53,10 +53,12 @@ public class Vala.CCodeGenerator {
 
                // the complete call expression, might include casts, comma expressions, and/or assignments
                CCodeExpression ccall_expr = ccall;
-               
+
+               var carg_map = new HashMap<int,CCodeExpression> (direct_hash, direct_equal);
+
                if (m is ArrayResizeMethod) {
                        var array = (Array) m.parent_symbol;
-                       ccall.add_argument (new CCodeIdentifier (array.get_cname ()));
+                       carg_map.set (get_param_pos (0), new CCodeIdentifier (array.get_cname ()));
                } else if (m is ArrayMoveMethod) {
                        requires_array_move = true;
                }
@@ -91,16 +93,14 @@ public class Vala.CCodeGenerator {
                                instance = get_implicit_cast_expression (instance, instance_expression_type, instance_target_type);
                        }
 
-                       if (!m.instance_last) {
-                               ccall.add_argument (instance);
-                       }
+                       carg_map.set (get_param_pos (m.cinstance_parameter_position), instance);
                }
 
                if (m is ArrayMoveMethod) {
                        var array = (Array) m.parent_symbol;
                        var csizeof = new CCodeFunctionCall (new CCodeIdentifier ("sizeof"));
                        csizeof.add_argument (new CCodeIdentifier (array.get_cname ()));
-                       ccall.add_argument (csizeof);
+                       carg_map.set (get_param_pos (0.1), csizeof);
                } else if (m is DBusMethod) {
                        bool found_out = false;
                        Expression callback = null;
@@ -135,7 +135,7 @@ public class Vala.CCodeGenerator {
                                }
                        }
 
-                       ccall.add_argument (new CCodeConstant ("\"%s\"".printf (m.name)));
+                       carg_map.set (get_param_pos (0.1), new CCodeConstant ("\"%s\"".printf (m.name)));
 
                        if (callback != null) {
                                var reply_method = (Method) callback.symbol_reference;
@@ -192,15 +192,15 @@ public class Vala.CCodeGenerator {
                                cb_fun.block.add_statement (new CCodeExpressionStatement (creply_call));
                                source_type_member_definition.append (cb_fun);
 
-                               ccall.add_argument (new CCodeIdentifier (cb_fun.name));
-                               ccall.add_argument (new CCodeConstant ("self"));
-                               ccall.add_argument (new CCodeConstant ("NULL"));
+                               carg_map.set (get_param_pos (0.2), new CCodeIdentifier (cb_fun.name));
+                               carg_map.set (get_param_pos (0.3), new CCodeConstant ("self"));
+                               carg_map.set (get_param_pos (0.4), new CCodeConstant ("NULL"));
                        } else if (found_out || m.return_type.data_type != null) {
                                ccall.call = new CCodeIdentifier ("dbus_g_proxy_call");
 
                                // method can fail
                                current_method_inner_error = true;
-                               ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("inner_error")));
+                               carg_map.set (get_param_pos (0.2), new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("inner_error")));
                        } else {
                                ccall.call = new CCodeIdentifier ("dbus_g_proxy_call_no_reply");
                        }
@@ -208,7 +208,8 @@ public class Vala.CCodeGenerator {
 
                bool ellipsis = false;
                
-               var i = 1;
+               int i = 1;
+               int arg_pos;
                Iterator<FormalParameter> params_it = params.iterator ();
                foreach (Expression arg in expr.get_argument_list ()) {
                        if (m is DBusMethod) {
@@ -217,7 +218,7 @@ public class Vala.CCodeGenerator {
                                        break;
                                }
                                
-                               ccall.add_argument (new CCodeIdentifier (arg.static_type.data_type.get_type_id ()));
+                               carg_map.set (get_param_pos (i - 0.1), new CCodeIdentifier (arg.static_type.data_type.get_type_id ()));
                        }
 
                        CCodeExpression cexpr = (CCodeExpression) arg.ccodenode;
@@ -232,13 +233,13 @@ public class Vala.CCodeGenerator {
                                                if (!param.no_array_length && param.type_reference is ArrayType) {
                                                        var array_type = (ArrayType) param.type_reference;
                                                        for (int dim = 1; dim <= array_type.rank; dim++) {
-                                                               ccall.add_argument (get_array_length_cexpression (arg, dim));
+                                                               carg_map.set (get_param_pos (param.carray_length_parameter_position + 0.01 * dim), get_array_length_cexpression (arg, dim));
                                                        }
                                                } else if (param.type_reference is DelegateType) {
                                                        var deleg_type = (DelegateType) param.type_reference;
                                                        var d = deleg_type.delegate_symbol;
                                                        if (d.instance) {
-                                                               extra_args.add (get_delegate_target_cexpression (arg));
+                                                               carg_map.set (get_param_pos (param.cdelegate_target_parameter_position), get_delegate_target_cexpression (arg));
                                                        }
                                                }
                                                cexpr = get_implicit_cast_expression (cexpr, arg.static_type, param.type_reference);
@@ -286,18 +287,14 @@ public class Vala.CCodeGenerator {
                                                        ccall_expr = ccomma;
                                                }
                                        }
-                               } else if (expr.can_fail && !(m is DBusMethod)) {
-                                       // method can fail
-                                       current_method_inner_error = true;
-                                       ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("inner_error")));
                                }
+                               arg_pos = get_param_pos (param.cparameter_position, ellipsis);
+                       } else {
+                               // default argument position
+                               arg_pos = get_param_pos (i, ellipsis);
                        }
-                                       
-                       ccall.add_argument (cexpr);
 
-                       foreach (CCodeExpression extra_arg in extra_args) {
-                               ccall.add_argument (extra_arg);
-                       }
+                       carg_map.set (arg_pos, cexpr);
 
                        i++;
                }
@@ -306,11 +303,6 @@ public class Vala.CCodeGenerator {
                        
                        if (param.ellipsis) {
                                ellipsis = true;
-                               if (expr.can_fail && !(m is DBusMethod)) {
-                                       // method can fail
-                                       current_method_inner_error = true;
-                                       ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("inner_error")));
-                               }
                                break;
                        }
                        
@@ -328,11 +320,11 @@ public class Vala.CCodeGenerator {
                            param.type_reference is ArrayType) {
                                var array_type = (ArrayType) param.type_reference;
                                for (int dim = 1; dim <= array_type.rank; dim++) {
-                                       ccall.add_argument (get_array_length_cexpression (param.default_expression, dim));
+                                       carg_map.set (get_param_pos (param.carray_length_parameter_position + 0.01 * dim), get_array_length_cexpression (param.default_expression, dim));
                                }
                        }
 
-                       ccall.add_argument ((CCodeExpression) param.default_expression.ccodenode);
+                       carg_map.set (get_param_pos (param.cparameter_position), (CCodeExpression) param.default_expression.ccodenode);
                        i++;
                }
 
@@ -346,7 +338,7 @@ public class Vala.CCodeGenerator {
 
                                        temp_vars.insert (0, temp_decl);
 
-                                       ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, temp_ref));
+                                       carg_map.set (get_param_pos (m.carray_length_parameter_position + 0.01 * dim), new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, temp_ref));
 
                                        expr.append_array_size (temp_ref);
                                } else {
@@ -362,7 +354,7 @@ public class Vala.CCodeGenerator {
 
                                temp_vars.insert (0, temp_decl);
 
-                               ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, temp_ref));
+                               carg_map.set (get_param_pos (m.cdelegate_target_parameter_position), new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, temp_ref));
 
                                expr.delegate_target = temp_ref;
                        }
@@ -371,33 +363,49 @@ public class Vala.CCodeGenerator {
                if (connection_type != null && ma.inner != null && ma.inner.static_type != null && ma.inner.static_type.data_type == connection_type && m.name == "get_object") {
                        var dbus_iface = (Interface) m.return_type.data_type;
                        var dbus_attr = dbus_iface.get_attribute ("DBusInterface");
-                       ccall.add_argument (new CCodeConstant ("\"%s\"".printf (dbus_attr.get_string ("name"))));
+                       carg_map.set (get_param_pos (-1), new CCodeConstant ("\"%s\"".printf (dbus_attr.get_string ("name"))));
                } else if (m is DBusMethod) {
-                       ccall.add_argument (new CCodeIdentifier ("G_TYPE_INVALID"));
+                       carg_map.set (get_param_pos (-1), new CCodeIdentifier ("G_TYPE_INVALID"));
                }
 
-               if (!ellipsis && expr.can_fail && !(m is DBusMethod)) {
+               if (expr.can_fail && !(m is DBusMethod)) {
                        // method can fail
                        current_method_inner_error = true;
-                       ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("inner_error")));
+                       // add &inner_error before the ellipsis arguments
+                       carg_map.set (get_param_pos (-2), new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("inner_error")));
                }
 
-               if (m != null && m.instance && m.instance_last) {
-                       ccall.add_argument (instance);
-               } else if (ellipsis) {
+               if (ellipsis) {
                        /* ensure variable argument list ends with NULL
                         * except when using printf-style arguments */
                        if ((m == null || !m.printf_format) && !(m is DBusMethod)) {
-                               ccall.add_argument (new CCodeConstant (m.sentinel));
+                               carg_map.set (get_param_pos (-1, true), new CCodeConstant (m.sentinel));
                        }
                } else if (itype is DelegateType) {
                        var deleg_type = (DelegateType) itype;
                        var d = deleg_type.delegate_symbol;
                        if (d.instance) {
-                               ccall.add_argument (get_delegate_target_cexpression (expr.call));
+                               carg_map.set (get_param_pos (d.cinstance_parameter_position), get_delegate_target_cexpression (expr.call));
                        }
                }
-               
+
+               // append C arguments in the right order
+               int last_pos = -1;
+               int min_pos;
+               while (true) {
+                       min_pos = -1;
+                       foreach (int pos in carg_map.get_keys ()) {
+                               if (pos > last_pos && (min_pos == -1 || pos < min_pos)) {
+                                       min_pos = pos;
+                               }
+                       }
+                       if (min_pos == -1) {
+                               break;
+                       }
+                       ccall.add_argument (carg_map.get (min_pos));
+                       last_pos = min_pos;
+               }
+
                if (m != null && m.instance && m.returns_modified_pointer) {
                        expr.ccodenode = new CCodeAssignment (instance, ccall_expr);
                } else {
@@ -530,5 +538,21 @@ public class Vala.CCodeGenerator {
                carray_type.add_argument (new CCodeIdentifier (array_type.element_type.data_type.get_type_id ()));
                return carray_type;
        }
+
+       private int get_param_pos (double param_pos, bool ellipsis = false) {
+               if (!ellipsis) {
+                       if (param_pos >= 0) {
+                               return (int) (param_pos * 1000);
+                       } else {
+                               return (int) ((100 + param_pos) * 1000);
+                       }
+               } else {
+                       if (param_pos >= 0) {
+                               return (int) ((100 + param_pos) * 1000);
+                       } else {
+                               return (int) ((200 + param_pos) * 1000);
+                       }
+               }
+       }
 }
 
index ad1d951..2f7da2a 100644 (file)
@@ -119,10 +119,10 @@ public class Vala.CCodeGenerator {
                        function.modifiers |= CCodeModifiers.INLINE;
                }
 
+               var cparam_map = new HashMap<int,CCodeFormalParameter> (direct_hash, direct_equal);
+
                CCodeFunctionDeclarator vdeclarator = null;
-               
-               CCodeFormalParameter instance_param = null;
-               
+
                if (m.instance || (m.parent_symbol is Struct && m is CreationMethod)) {
                        Typesymbol parent_type = find_parent_type (m);
                        DataType this_type;
@@ -134,6 +134,7 @@ public class Vala.CCodeGenerator {
                                this_type = new ValueType (parent_type);
                        }
 
+                       CCodeFormalParameter instance_param = null;
                        if (m.base_interface_method != null && !m.is_abstract && !m.is_virtual) {
                                var base_type = new InterfaceType ((Interface) m.base_interface_method.parent_symbol);
                                instance_param = new CCodeFormalParameter ("base", base_type.get_cname ());
@@ -147,30 +148,28 @@ public class Vala.CCodeGenerator {
                                        instance_param = new CCodeFormalParameter ("self", this_type.get_cname ());
                                }
                        }
-                       if (!m.instance_last) {
-                               function.add_parameter (instance_param);
-                       }
-                       
+                       cparam_map.set (get_param_pos (m.cinstance_parameter_position), instance_param);
+
                        if (m.is_abstract || m.is_virtual) {
                                var vdecl = new CCodeDeclaration (creturn_type.get_cname ());
                                vdeclarator = new CCodeFunctionDeclarator (m.vfunc_name);
                                vdecl.add_declarator (vdeclarator);
                                type_struct.add_declaration (vdecl);
-
-                               vdeclarator.add_parameter (instance_param);
                        }
                }
 
                if (in_fundamental_creation_method) {
-                       function.add_parameter (new CCodeFormalParameter ("type", "GType"));
+                       cparam_map.set (get_param_pos (0.1), new CCodeFormalParameter ("type", "GType"));
                }
 
                if (in_gobject_creation_method) {
                        // memory management for generic types
+                       int type_param_index = 0;
                        foreach (TypeParameter type_param in current_class.get_type_parameters ()) {
-                               function.add_parameter (new CCodeFormalParameter ("%s_type".printf (type_param.name.down ()), "GType"));
-                               function.add_parameter (new CCodeFormalParameter ("%s_dup_func".printf (type_param.name.down ()), "GBoxedCopyFunc"));
-                               function.add_parameter (new CCodeFormalParameter ("%s_destroy_func".printf (type_param.name.down ()), "GDestroyNotify"));
+                               cparam_map.set (get_param_pos (0.1 * type_param_index + 0.01), new CCodeFormalParameter ("%s_type".printf (type_param.name.down ()), "GType"));
+                               cparam_map.set (get_param_pos (0.1 * type_param_index + 0.02), new CCodeFormalParameter ("%s_dup_func".printf (type_param.name.down ()), "GBoxedCopyFunc"));
+                               cparam_map.set (get_param_pos (0.1 * type_param_index + 0.03), new CCodeFormalParameter ("%s_destroy_func".printf (type_param.name.down ()), "GDestroyNotify"));
+                               type_param_index++;
                        }
                }
 
@@ -186,27 +185,18 @@ public class Vala.CCodeGenerator {
                                
                                for (int dim = 1; dim <= array_type.rank; dim++) {
                                        var cparam = new CCodeFormalParameter (get_array_length_cname (param.name, dim), length_ctype);
-                                       function.add_parameter (cparam);
-                                       if (vdeclarator != null) {
-                                               vdeclarator.add_parameter (cparam);
-                                       }
+                                       cparam_map.set (get_param_pos (param.carray_length_parameter_position + 0.01 * dim), cparam);
                                }
                        }
-               
-                       function.add_parameter ((CCodeFormalParameter) param.ccodenode);
-                       if (vdeclarator != null) {
-                               vdeclarator.add_parameter ((CCodeFormalParameter) param.ccodenode);
-                       }
+
+                       cparam_map.set (get_param_pos (param.cparameter_position), (CCodeFormalParameter) param.ccodenode);
 
                        if (param.type_reference is DelegateType) {
                                var deleg_type = (DelegateType) param.type_reference;
                                var d = deleg_type.delegate_symbol;
                                if (d.instance) {
                                        var cparam = new CCodeFormalParameter (get_delegate_target_cname (param.name), "void*");
-                                       function.add_parameter (cparam);
-                                       if (vdeclarator != null) {
-                                               vdeclarator.add_parameter (cparam);
-                                       }
+                                       cparam_map.set (get_param_pos (param.cdelegate_target_parameter_position), cparam);
                                }
                        }
                }
@@ -217,10 +207,7 @@ public class Vala.CCodeGenerator {
 
                        for (int dim = 1; dim <= array_type.rank; dim++) {
                                var cparam = new CCodeFormalParameter (get_array_length_cname ("result", dim), "int*");
-                               function.add_parameter (cparam);
-                               if (vdeclarator != null) {
-                                       vdeclarator.add_parameter (cparam);
-                               }
+                               cparam_map.set (get_param_pos (m.carray_length_parameter_position + 0.01 * dim), cparam);
                        }
                } else if (creturn_type is DelegateType) {
                        // return delegate target if appropriate
@@ -228,23 +215,33 @@ public class Vala.CCodeGenerator {
                        var d = deleg_type.delegate_symbol;
                        if (d.instance) {
                                var cparam = new CCodeFormalParameter (get_delegate_target_cname ("result"), "void*");
-                               function.add_parameter (cparam);
-                               if (vdeclarator != null) {
-                                       vdeclarator.add_parameter (cparam);
-                               }
+                               cparam_map.set (get_param_pos (m.cdelegate_target_parameter_position), cparam);
                        }
                }
 
-               if (m.instance && m.instance_last) {
-                       function.add_parameter (instance_param);
-               }
-
                if (m.get_error_domains ().size > 0) {
                        var cparam = new CCodeFormalParameter ("error", "GError**");
-                       function.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;
+                       }
+                       function.add_parameter (cparam_map.get (min_pos));
                        if (vdeclarator != null) {
-                               vdeclarator.add_parameter (cparam);
+                               vdeclarator.add_parameter (cparam_map.get (min_pos));
                        }
+                       last_pos = min_pos;
                }
 
                bool visible = !m.is_internal_symbol ();
@@ -436,8 +433,11 @@ public class Vala.CCodeGenerator {
                                this_type = new InterfaceType ((Interface) m.parent_symbol);
                        }
 
+                       cparam_map = new HashMap<int,CCodeFormalParameter> (direct_hash, direct_equal);
+                       var carg_map = new HashMap<int,CCodeExpression> (direct_hash, direct_equal);
+
                        var cparam = new CCodeFormalParameter ("self", this_type.get_cname ());
-                       vfunc.add_parameter (cparam);
+                       cparam_map.set (get_param_pos (m.cinstance_parameter_position), cparam);
                        
                        var vblock = new CCodeBlock ();
 
@@ -458,7 +458,7 @@ public class Vala.CCodeGenerator {
                        vcast.add_argument (new CCodeIdentifier ("self"));
                
                        var vcall = new CCodeFunctionCall (new CCodeMemberAccess.pointer (vcast, m.vfunc_name));
-                       vcall.add_argument (new CCodeIdentifier ("self"));
+                       carg_map.set (get_param_pos (m.cinstance_parameter_position), new CCodeIdentifier ("self"));
                
                        var params = m.get_parameters ();
                        foreach (FormalParameter param in params) {
@@ -472,13 +472,13 @@ public class Vala.CCodeGenerator {
                                        
                                        for (int dim = 1; dim <= array_type.rank; dim++) {
                                                var cparam = new CCodeFormalParameter (get_array_length_cname (param.name, dim), length_ctype);
-                                               vfunc.add_parameter (cparam);
-                                               vcall.add_argument (new CCodeIdentifier (cparam.name));
+                                               cparam_map.set (get_param_pos (param.carray_length_parameter_position + 0.01 * dim), cparam);
+                                               carg_map.set (get_param_pos (param.carray_length_parameter_position + 0.01 * dim), new CCodeIdentifier (cparam.name));
                                        }
                                }
 
-                               vfunc.add_parameter ((CCodeFormalParameter) param.ccodenode);
-                               vcall.add_argument (new CCodeIdentifier (param.name));
+                               cparam_map.set (get_param_pos (param.cparameter_position), (CCodeFormalParameter) param.ccodenode);
+                               carg_map.set (get_param_pos (param.cparameter_position), new CCodeIdentifier (param.name));
                        }
 
                        // return array length if appropriate
@@ -487,15 +487,34 @@ public class Vala.CCodeGenerator {
 
                                for (int dim = 1; dim <= array_type.rank; dim++) {
                                        var cparam = new CCodeFormalParameter (get_array_length_cname ("result", dim), "int*");
-                                       vfunc.add_parameter (cparam);
-                                       vcall.add_argument (new CCodeIdentifier (cparam.name));
+                                       cparam_map.set (get_param_pos (m.carray_length_parameter_position), cparam);
+                                       carg_map.set (get_param_pos (m.carray_length_parameter_position), new CCodeIdentifier (cparam.name));
                                }
                        }
 
                        if (m.get_error_domains ().size > 0) {
                                var cparam = new CCodeFormalParameter ("error", "GError**");
-                               vfunc.add_parameter (cparam);
-                               vcall.add_argument (new CCodeIdentifier (cparam.name));
+                               cparam_map.set (get_param_pos (-1), cparam);
+                               carg_map.set (get_param_pos (-1), new CCodeIdentifier (cparam.name));
+                       }
+
+
+                       // append C parameters and arguments 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;
+                               }
+                               vfunc.add_parameter (cparam_map.get (min_pos));
+                               vcall.add_argument (carg_map.get (min_pos));
+                               last_pos = min_pos;
                        }
 
                        CCodeStatement cstmt;
@@ -585,8 +604,8 @@ public class Vala.CCodeGenerator {
 
                        var main_call = new CCodeFunctionCall (new CCodeIdentifier (function.name));
                        if (args_parameter) {
-                               main_call.add_argument (new CCodeIdentifier ("argc"));
                                main_call.add_argument (new CCodeIdentifier ("argv"));
+                               main_call.add_argument (new CCodeIdentifier ("argc"));
                        }
                        if (return_value) {
                                var main_stmt = new CCodeReturnStatement (main_call);
index 952bae3..eec9afd 100644 (file)
@@ -3236,6 +3236,8 @@ fixed_parameter
                vala_formal_parameter_set_construct_parameter ($$, $2);
                g_object_unref ($3);
                g_free ($4);
+
+               VALA_CODE_NODE($$)->attributes = $1;
          }
        | opt_attributes opt_construct type identifier ASSIGN expression
          {
@@ -3262,6 +3264,8 @@ fixed_parameter
                g_object_unref ($3);
                g_free ($4);
                g_object_unref ($6);
+
+               VALA_CODE_NODE($$)->attributes = $1;
          }
        ;
 
index 09babc9..96cedf3 100644 (file)
@@ -1,6 +1,6 @@
 /* valaarrayresizemethod.vala
  *
- * Copyright (C) 2007  Jürg Billeter
+ * Copyright (C) 2007-2008  Jürg Billeter
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -34,4 +34,8 @@ public class Vala.ArrayResizeMethod : Method {
        public ArrayResizeMethod (construct SourceReference source_reference) {
                name = "resize";
        }
+
+       construct {
+               cinstance_parameter_position = 0.1;
+       }
 }
index cedf92c..cb3b462 100644 (file)
@@ -1,6 +1,6 @@
 /* valaattribute.vala
  *
- * Copyright (C) 2006-2007  Jürg Billeter
+ * Copyright (C) 2006-2008  Jürg Billeter
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -116,7 +116,43 @@ public class Vala.Attribute : CodeNode {
                
                return 0;
        }
-       
+
+       /**
+        * Returns the double value of the specified named argument.
+        *
+        * @param name argument name
+        * @return     double value
+        */
+       public double get_double (string! name) {
+               // FIXME: use hash table
+               foreach (NamedArgument arg in args) {
+                       if (arg.name == name) {
+                               if (arg.argument is LiteralExpression) {
+                                       var lit = ((LiteralExpression) arg.argument).literal;
+                                       if (lit is RealLiteral) {
+                                               return ((RealLiteral) lit).value.to_double ();
+                                       } else if (lit is IntegerLiteral) {
+                                               return ((IntegerLiteral) lit).value.to_int ();
+                                       }
+                               } else if (arg.argument is UnaryExpression) {
+                                       var unary = (UnaryExpression) arg.argument;
+                                       if (unary.operator == UnaryOperator.MINUS) {
+                                               if (unary.inner is LiteralExpression) {
+                                                       var lit = ((LiteralExpression) unary.inner).literal;
+                                                       if (lit is RealLiteral) {
+                                                               return -((RealLiteral) lit).value.to_double ();
+                                                       } else if (lit is IntegerLiteral) {
+                                                               return -((IntegerLiteral) lit).value.to_int ();
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               }
+               
+               return 0;
+       }
+
        /**
         * Returns the boolean value of the specified named argument.
         *
index 9d924a0..c2fb80a 100644 (file)
@@ -72,12 +72,18 @@ public class Vala.AttributeProcessor : CodeVisitor {
 
        public override void visit_method (Method! m) {
                m.process_attributes ();
+
+               m.accept_children (this);
        }
        
        public override void visit_creation_method (CreationMethod! m) {
                m.process_attributes ();
        }
 
+       public override void visit_formal_parameter (FormalParameter! p) {
+               p.process_attributes ();
+       }
+
        public override void visit_property (Property! prop) {
                prop.process_attributes ();
        }
index 6414980..2ad5016 100644 (file)
@@ -385,7 +385,7 @@ public class Vala.CodeContext : Object {
                }
        }
 
-       public string get_package_path (string! pkg, string[] vapi_directories) {
+       public string get_package_path (string! pkg, [CCode (array_length_pos = 1.9)] string[] vapi_directories) {
                string basename = "%s.vapi".printf (pkg);
 
                if (vapi_directories != null) {
index 87c4e39..39b8dc6 100644 (file)
@@ -44,7 +44,24 @@ public class Vala.Delegate : Typesymbol {
         * the argument list in the generated C code.
         */
        public bool instance { get; set; }
-       
+
+       /**
+        * Specifies the position of the instance parameter in the C function.
+        */
+       public double cinstance_parameter_position { get; set; }
+
+       /**
+        * Specifies the position of the array length out parameter in the C
+        * function.
+        */
+       public double carray_length_parameter_position { get; set; }
+
+       /**
+        * Specifies the position of the delegate target out parameter in the C
+        * function.
+        */
+       public double cdelegate_target_parameter_position { get; set; }
+
        private Gee.List<TypeParameter> type_parameters = new ArrayList<TypeParameter> ();
 
        private Gee.List<FormalParameter> parameters = new ArrayList<FormalParameter> ();
@@ -63,6 +80,12 @@ public class Vala.Delegate : Typesymbol {
        public Delegate (construct string name, construct DataType return_type, construct SourceReference source_reference = null) {
        }
 
+       construct {
+               cinstance_parameter_position = -1;
+               carray_length_parameter_position = -3;
+               cdelegate_target_parameter_position = -3;
+       }
+
        /**
         * Appends the specified parameter to the list of type parameters.
         *
@@ -80,6 +103,11 @@ public class Vala.Delegate : Typesymbol {
         * @param param a formal parameter
         */
        public void add_parameter (FormalParameter! param) {
+               // default C parameter position
+               param.cparameter_position = parameters.size + 1;
+               param.carray_length_parameter_position = param.cparameter_position + 0.1;
+               param.cdelegate_target_parameter_position = param.cparameter_position + 0.1;
+
                parameters.add (param);
                scope.add (param.name, param);
        }
@@ -173,6 +201,15 @@ public class Vala.Delegate : Typesymbol {
                if (a.has_argument ("cname")) {
                        set_cname (a.get_string ("cname"));
                }
+               if (a.has_argument ("instance_pos")) {
+                       cinstance_parameter_position = a.get_double ("instance_pos");
+               }
+               if (a.has_argument ("array_length_pos")) {
+                       carray_length_parameter_position = a.get_double ("array_length_pos");
+               }
+               if (a.has_argument ("delegate_target_pos")) {
+                       cdelegate_target_parameter_position = a.get_double ("delegate_target_pos");
+               }
        }
        
        /**
index b63bd5d..0643d19 100644 (file)
@@ -1,6 +1,6 @@
 /* valaformalparameter.vala
  *
- * Copyright (C) 2006-2007  Jürg Billeter, Raffaele Sandrini
+ * Copyright (C) 2006-2008  Jürg Billeter, Raffaele Sandrini
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -63,6 +63,23 @@ public class Vala.FormalParameter : Symbol {
         */
        public bool construct_parameter { get; set; }
 
+       /**
+        * Specifies the position of the parameter in the C function.
+        */
+       public double cparameter_position { get; set; }
+
+       /**
+        * Specifies the position of the array length parameter in the C
+        * function.
+        */
+       public double carray_length_parameter_position { get; set; }
+
+       /**
+        * Specifies the position of the delegate target parameter in the C
+        * function.
+        */
+       public double cdelegate_target_parameter_position { get; set; }
+
        private DataType _data_type;
 
        /**
@@ -111,4 +128,24 @@ public class Vala.FormalParameter : Symbol {
                        type_reference = new_type;
                }
        }
+
+       private void process_ccode_attribute (Attribute a) {
+               if (a.has_argument ("array_length_pos")) {
+                       carray_length_parameter_position = a.get_double ("array_length_pos");
+               }
+               if (a.has_argument ("delegate_target_pos")) {
+                       cdelegate_target_parameter_position = a.get_double ("delegate_target_pos");
+               }
+       }
+
+       /**
+        * Process all associated attributes.
+        */
+       public void process_attributes () {
+               foreach (Attribute a in attributes) {
+                       if (a.name == "CCode") {
+                               process_ccode_attribute (a);
+                       }
+               }
+       }
 }
index 162c3ba..51269a4 100644 (file)
@@ -413,12 +413,10 @@ public class Vala.InterfaceWriter : CodeVisitor {
        private void write_params (Collection<FormalParameter> params) {
                write_string ("(");
 
-               bool first = true;
+               int i = 1;
                foreach (FormalParameter param in params) {
-                       if (!first) {
+                       if (i > 1) {
                                write_string (", ");
-                       } else {
-                               first = false;
                        }
                        
                        if (param.ellipsis) {
@@ -426,6 +424,23 @@ public class Vala.InterfaceWriter : CodeVisitor {
                                continue;
                        }
                        
+
+                       var ccode_params = new String ();
+                       var separator = "";
+
+                       if (param.carray_length_parameter_position != i + 0.1) {
+                               ccode_params.append_printf ("%sarray_length_pos = %g", separator, param.carray_length_parameter_position);
+                               separator = ", ";
+                       }
+                       if (param.cdelegate_target_parameter_position != i + 0.1) {
+                               ccode_params.append_printf ("%sdelegate_target_pos = %g", separator, param.cdelegate_target_parameter_position);
+                               separator = ", ";
+                       }
+
+                       if (ccode_params.len > 0) {
+                               write_string ("[CCode (%s)] ".printf (ccode_params.str));
+                       }
+
                        if (param.type_reference.is_ref || param.type_reference.is_out) {
                                if (param.type_reference.is_ref) {
                                        write_string ("ref ");
@@ -450,6 +465,8 @@ public class Vala.InterfaceWriter : CodeVisitor {
                                write_string (" = ");
                                write_string (param.default_expression.to_string ());
                        }
+
+                       i++;
                }
 
                write_string (")");
@@ -508,10 +525,6 @@ public class Vala.InterfaceWriter : CodeVisitor {
                                write_string ("[NoArrayLength]");
                        }
                }
-               if (m.instance_last) {
-                       write_indent ();
-                       write_string ("[InstanceLast]");
-               }
 
                var ccode_params = new String ();
                var separator = "";
@@ -520,6 +533,18 @@ public class Vala.InterfaceWriter : CodeVisitor {
                        ccode_params.append_printf ("%scname = \"%s\"", separator, m.get_cname ());
                        separator = ", ";
                }
+               if (m.cinstance_parameter_position != 0) {
+                       ccode_params.append_printf ("%sinstance_pos = %g", separator, m.cinstance_parameter_position);
+                       separator = ", ";
+               }
+               if (m.carray_length_parameter_position != -3) {
+                       ccode_params.append_printf ("%sarray_length_pos = %g", separator, m.carray_length_parameter_position);
+                       separator = ", ";
+               }
+               if (m.cdelegate_target_parameter_position != -3) {
+                       ccode_params.append_printf ("%sdelegate_target_pos = %g", separator, m.cdelegate_target_parameter_position);
+                       separator = ", ";
+               }
                if (m.sentinel != m.DEFAULT_SENTINEL) {
                        ccode_params.append_printf ("%ssentinel = \"%s\"", separator, m.sentinel);
                        separator = ", ";
index d94c335..d3c9f85 100644 (file)
@@ -122,12 +122,6 @@ public class Vala.Method : Member {
         * imported methods.
         */
        public bool returns_modified_pointer { get; set; }
-       
-       /**
-        * Specifies whether the instance pointer should be passed as the first
-        * or as the last argument in C code. Defaults to first.
-        */
-       public bool instance_last { get; set; }
 
        /**
         * Specifies the virtual or abstract method this method overrides.
@@ -152,6 +146,23 @@ public class Vala.Method : Member {
        public VariableDeclarator result_var { get; set; }
 
        /**
+        * Specifies the position of the instance parameter in the C function.
+        */
+       public double cinstance_parameter_position { get; set; }
+
+       /**
+        * Specifies the position of the array length out parameter in the C
+        * function.
+        */
+       public double carray_length_parameter_position { get; set; }
+
+       /**
+        * Specifies the position of the delegate target out parameter in the C
+        * function.
+        */
+       public double cdelegate_target_parameter_position { get; set; }
+
+       /**
         * Specifies whether the array length should implicitly be passed
         * if the parameter type is an array.
         */
@@ -194,6 +205,11 @@ public class Vala.Method : Member {
        public Method (construct string name, construct DataType return_type, construct SourceReference source_reference = null) {
        }
 
+       construct {
+               carray_length_parameter_position = -3;
+               cdelegate_target_parameter_position = -3;
+       }
+
        /**
         * Appends parameter to this method.
         *
@@ -203,7 +219,11 @@ public class Vala.Method : Member {
                if (no_array_length) {
                        param.no_array_length = true;
                }
-               
+               // default C parameter position
+               param.cparameter_position = parameters.size + 1;
+               param.carray_length_parameter_position = param.cparameter_position + 0.1;
+               param.cdelegate_target_parameter_position = param.cparameter_position + 0.1;
+
                parameters.add (param);
                if (!param.ellipsis) {
                        scope.add (param.name, param);
@@ -313,6 +333,15 @@ public class Vala.Method : Member {
                if (a.has_argument ("sentinel")) {
                        this.sentinel = a.get_string ("sentinel");
                }
+               if (a.has_argument ("instance_pos")) {
+                       cinstance_parameter_position = a.get_double ("instance_pos");
+               }
+               if (a.has_argument ("array_length_pos")) {
+                       carray_length_parameter_position = a.get_double ("array_length_pos");
+               }
+               if (a.has_argument ("delegate_target_pos")) {
+                       cdelegate_target_parameter_position = a.get_double ("delegate_target_pos");
+               }
        }
        
        /**
@@ -324,8 +353,6 @@ public class Vala.Method : Member {
                                process_ccode_attribute (a);
                        } else if (a.name == "ReturnsModifiedPointer") {
                                returns_modified_pointer = true;
-                       } else if (a.name == "InstanceLast") {
-                               instance_last = true;
                        } else if (a.name == "FloatingReference") {
                                return_type.floating_reference = true;
                        } else if (a.name == "NoArrayLength") {
index fc98116..7995452 100644 (file)
@@ -2786,7 +2786,7 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
                                         * rearrange the parameters for instance
                                         * methods and non-instance methods
                                         */
-                                       m.instance_last = true;
+                                       m.cinstance_parameter_position = -1;
                                }
                        } else if (ma.symbol_reference is Property) {
                                var prop = (Property) ma.symbol_reference;
index bf7ee3b..69d148e 100644 (file)
@@ -50,7 +50,7 @@ public struct constpointer {
 [IntegerType (rank = 2, min = 0, max = 127)]
 public struct char {
        [InstanceLast ()]
-       [CCode (cname = "g_strdup_printf")]
+       [CCode (cname = "g_strdup_printf", instance_pos = -1)]
        public string! to_string (string! format = "%hhi");
        public bool isalnum ();
        public bool isalpha ();
@@ -74,7 +74,7 @@ public struct char {
 [IntegerType (rank = 3, min = 0, max = 255)]
 public struct uchar {
        [InstanceLast ()]
-       [CCode (cname = "g_strdup_printf")]
+       [CCode (cname = "g_strdup_printf", instance_pos = -1)]
        public string! to_string (string! format = "%hhu");
 }
 
@@ -88,7 +88,7 @@ public struct int {
        public static int MAX;
 
        [InstanceLast ()]
-       [CCode (cname = "g_strdup_printf")]
+       [CCode (cname = "g_strdup_printf", instance_pos = -1)]
        public string! to_string (string! format = "%i");
 
        [CCode (cname = "CLAMP")]
@@ -108,7 +108,7 @@ public struct uint {
        public static uint MAX;
 
        [InstanceLast ()]
-       [CCode (cname = "g_strdup_printf")]
+       [CCode (cname = "g_strdup_printf", instance_pos = -1)]
        public string! to_string (string! format = "%u");
 
        [CCode (cname = "CLAMP")]
@@ -128,7 +128,7 @@ public struct short {
        public static short MAX;
 
        [InstanceLast ()]
-       [CCode (cname = "g_strdup_printf")]
+       [CCode (cname = "g_strdup_printf", instance_pos = -1)]
        public string! to_string (string! format = "%hi");
 }
 
@@ -142,7 +142,7 @@ public struct ushort {
        public static ushort MAX;
 
        [InstanceLast ()]
-       [CCode (cname = "g_strdup_printf")]
+       [CCode (cname = "g_strdup_printf", instance_pos = -1)]
        public string! to_string (string! format = "%hu");
 }
 
@@ -156,7 +156,7 @@ public struct long {
        public static long MAX;
 
        [InstanceLast ()]
-       [CCode (cname = "g_strdup_printf")]
+       [CCode (cname = "g_strdup_printf", instance_pos = -1)]
        public string! to_string (string! format = "%li");
 }
 
@@ -170,7 +170,7 @@ public struct ulong {
        public static ulong MAX;
 
        [InstanceLast ()]
-       [CCode (cname = "g_strdup_printf")]
+       [CCode (cname = "g_strdup_printf", instance_pos = -1)]
        public string! to_string (string! format = "%lu");
 }
 
@@ -184,7 +184,7 @@ public struct size_t {
        public static ulong MAX;
 
        [InstanceLast]
-       [CCode (cname = "g_strdup_printf")]
+       [CCode (cname = "g_strdup_printf", instance_pos = -1)]
        public string! to_string (string! format = "%zu");
 
        [CCode (cname = "GSIZE_TO_POINTER")]
@@ -201,7 +201,7 @@ public struct ssize_t {
        public static long MAX;
 
        [InstanceLast]
-       [CCode (cname = "g_strdup_printf")]
+       [CCode (cname = "g_strdup_printf", instance_pos = -1)]
        public string! to_string (string! format = "%zi");
 }
 
@@ -214,7 +214,7 @@ public struct int8 {
        [CCode (cname = "G_MAXINT8")]
        public static int8 MAX;
 
-       [CCode (cname = "g_strdup_printf"), InstanceLast]
+       [CCode (cname = "g_strdup_printf", instance_pos = -1), InstanceLast]
        public string! to_string (string! format = "%hhi");
 }
 
@@ -227,7 +227,7 @@ public struct uint8 {
        [CCode (cname = "G_MAXUINT8")]
        public static uint8 MAX;
 
-       [CCode (cname = "g_strdup_printf"), InstanceLast]
+       [CCode (cname = "g_strdup_printf", instance_pos = -1), InstanceLast]
        public string! to_string (string! format = "%hhu");
 }
 
@@ -240,7 +240,7 @@ public struct int16 {
        [CCode (cname = "G_MAXINT16")]
        public static int16 MAX;
 
-       [CCode (cname = "g_strdup_printf"), InstanceLast]
+       [CCode (cname = "g_strdup_printf", instance_pos = -1), InstanceLast]
        public string! to_string (string! format = "%hi");
 }
 
@@ -253,7 +253,7 @@ public struct uint16 {
        [CCode (cname = "G_MAXUINT16")]
        public static uint16 MAX;
 
-       [CCode (cname = "g_strdup_printf"), InstanceLast]
+       [CCode (cname = "g_strdup_printf", instance_pos = -1), InstanceLast]
        public string! to_string (string! format = "%hu");
 }
 
@@ -266,7 +266,7 @@ public struct int32 {
        [CCode (cname = "G_MAXINT32")]
        public static int32 MAX;
 
-       [CCode (cname = "g_strdup_printf"), InstanceLast]
+       [CCode (cname = "g_strdup_printf", instance_pos = -1), InstanceLast]
        public string! to_string (string! format = "%i");
 }
 
@@ -280,7 +280,7 @@ public struct uint32 {
        public static uint32 MAX;
 
        [InstanceLast ()]
-       [CCode (cname = "g_strdup_printf")]
+       [CCode (cname = "g_strdup_printf", instance_pos = -1)]
        public string! to_string (string! format = "%u");
 }
 
@@ -294,7 +294,7 @@ public struct int64 {
        public static int64 MAX;
 
        [InstanceLast ()]
-       [CCode (cname = "g_strdup_printf")]
+       [CCode (cname = "g_strdup_printf", instance_pos = -1)]
        public string! to_string (string! format = "%lli");
 }
 
@@ -308,7 +308,7 @@ public struct uint64 {
        public static uint64 MAX;
 
        [InstanceLast ()]
-       [CCode (cname = "g_strdup_printf")]
+       [CCode (cname = "g_strdup_printf", instance_pos = -1)]
        public string! to_string (string! format = "%llu");
 }
 
@@ -352,7 +352,7 @@ public struct float {
        [CCode (cname = "isinf")]
        public int is_infinity ();
 
-       [CCode (cname = "g_strdup_printf"), InstanceLast]
+       [CCode (cname = "g_strdup_printf", instance_pos = -1), InstanceLast]
        public string! to_string (string! format = "%g");
 }
 
@@ -396,7 +396,7 @@ public struct double {
        [CCode (cname = "isinf")]
        public int is_infinity ();
 
-       [CCode (cname = "g_strdup_printf"), InstanceLast]
+       [CCode (cname = "g_strdup_printf", instance_pos = -1), InstanceLast]
        public string! to_string (string! format = "%g");
 }
 
@@ -1990,7 +1990,7 @@ namespace GLib {
                [PrintfFormat ()]
                public void printf (string format, ...);
                [InstanceLast ()]
-               [CCode (cname = "fputc")]
+               [CCode (cname = "fputc", instance_pos = -1)]
                public void putc (char c);
                [InstanceLast ()]
                [CCode (cname = "fputs")]
@@ -2112,7 +2112,7 @@ namespace GLib {
                public void get_description ();
                public void set_translate_func (TranslateFunc func, DestroyNotify destroy_notify);
                public void set_translation_domain (string domain);
-               public bool parse (ref string[] argv) throws OptionError;
+               public bool parse ([CCode (array_length_pos = 0.9)] ref string[] argv) throws OptionError;
                public void set_help_enabled (bool help_enabled);
                public bool get_help_enabled ();
                public void set_ignore_unknown_options (bool ignore_unknown);
@@ -2699,6 +2699,10 @@ namespace GLib {
        public static GLib.HashFunc direct_hash;
        [CCode (cname = "g_direct_equal")]
        public static GLib.EqualFunc direct_equal;
+       [CCode (cname = "g_int_hash")]
+       public static GLib.HashFunc int_hash;
+       [CCode (cname = "g_int_equal")]
+       public static GLib.EqualFunc int_equal;
        [CCode (cname = "g_str_hash")]
        public static GLib.HashFunc str_hash;
        [CCode (cname = "g_str_equal")]