From 2cd4ea1be4c3176b1054cd6ab61484382140986c Mon Sep 17 00:00:00 2001 From: Juerg Billeter Date: Wed, 6 Feb 2008 16:55:33 +0000 Subject: [PATCH] Support flexible position of array length and delegate target parameters, 2008-02-06 Juerg Billeter * 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 --- ChangeLog | 15 +++ .../valaccodegeneratorinvocationexpression.vala | 110 +++++++++++-------- gobject/valaccodegeneratormethod.vala | 121 ++++++++++++--------- vala/parser.y | 4 + vala/valaarrayresizemethod.vala | 6 +- vala/valaattribute.vala | 40 ++++++- vala/valaattributeprocessor.vala | 6 + vala/valacodecontext.vala | 2 +- vala/valadelegate.vala | 39 ++++++- vala/valaformalparameter.vala | 39 ++++++- vala/valainterfacewriter.vala | 41 +++++-- vala/valamethod.vala | 45 ++++++-- vala/valasemanticanalyzer.vala | 2 +- vapi/glib-2.0.vapi | 48 ++++---- 14 files changed, 378 insertions(+), 140 deletions(-) diff --git a/ChangeLog b/ChangeLog index a395574..4bb8dfe 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2008-02-06 Jürg Billeter + + * 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 * vala/valapointertype.vala: implement get_symbols method, diff --git a/gobject/valaccodegeneratorinvocationexpression.vala b/gobject/valaccodegeneratorinvocationexpression.vala index 6fea5ea..b38a82a 100644 --- a/gobject/valaccodegeneratorinvocationexpression.vala +++ b/gobject/valaccodegeneratorinvocationexpression.vala @@ -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 (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 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); + } + } + } } diff --git a/gobject/valaccodegeneratormethod.vala b/gobject/valaccodegeneratormethod.vala index ad1d951..2f7da2a 100644 --- a/gobject/valaccodegeneratormethod.vala +++ b/gobject/valaccodegeneratormethod.vala @@ -119,10 +119,10 @@ public class Vala.CCodeGenerator { function.modifiers |= CCodeModifiers.INLINE; } + var cparam_map = new HashMap (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 (direct_hash, direct_equal); + var carg_map = new HashMap (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); diff --git a/vala/parser.y b/vala/parser.y index 952bae3..eec9afd 100644 --- a/vala/parser.y +++ b/vala/parser.y @@ -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; } ; diff --git a/vala/valaarrayresizemethod.vala b/vala/valaarrayresizemethod.vala index 09babc9..96cedf3 100644 --- a/vala/valaarrayresizemethod.vala +++ b/vala/valaarrayresizemethod.vala @@ -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; + } } diff --git a/vala/valaattribute.vala b/vala/valaattribute.vala index cedf92c..cb3b462 100644 --- a/vala/valaattribute.vala +++ b/vala/valaattribute.vala @@ -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. * diff --git a/vala/valaattributeprocessor.vala b/vala/valaattributeprocessor.vala index 9d924a0..c2fb80a 100644 --- a/vala/valaattributeprocessor.vala +++ b/vala/valaattributeprocessor.vala @@ -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 (); } diff --git a/vala/valacodecontext.vala b/vala/valacodecontext.vala index 6414980..2ad5016 100644 --- a/vala/valacodecontext.vala +++ b/vala/valacodecontext.vala @@ -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) { diff --git a/vala/valadelegate.vala b/vala/valadelegate.vala index 87c4e39..39b8dc6 100644 --- a/vala/valadelegate.vala +++ b/vala/valadelegate.vala @@ -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 type_parameters = new ArrayList (); private Gee.List parameters = new ArrayList (); @@ -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"); + } } /** diff --git a/vala/valaformalparameter.vala b/vala/valaformalparameter.vala index b63bd5d..0643d19 100644 --- a/vala/valaformalparameter.vala +++ b/vala/valaformalparameter.vala @@ -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); + } + } + } } diff --git a/vala/valainterfacewriter.vala b/vala/valainterfacewriter.vala index 162c3ba..51269a4 100644 --- a/vala/valainterfacewriter.vala +++ b/vala/valainterfacewriter.vala @@ -413,12 +413,10 @@ public class Vala.InterfaceWriter : CodeVisitor { private void write_params (Collection 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 = ", "; diff --git a/vala/valamethod.vala b/vala/valamethod.vala index d94c335..d3c9f85 100644 --- a/vala/valamethod.vala +++ b/vala/valamethod.vala @@ -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") { diff --git a/vala/valasemanticanalyzer.vala b/vala/valasemanticanalyzer.vala index fc98116..7995452 100644 --- a/vala/valasemanticanalyzer.vala +++ b/vala/valasemanticanalyzer.vala @@ -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; diff --git a/vapi/glib-2.0.vapi b/vapi/glib-2.0.vapi index bf7ee3b..69d148e 100644 --- a/vapi/glib-2.0.vapi +++ b/vapi/glib-2.0.vapi @@ -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")] -- 2.7.4