From: Jürg Billeter Date: Tue, 28 Jul 2009 08:51:25 +0000 (+0200) Subject: Support delegate properties X-Git-Tag: 0.7.5~46 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=84ffdbd8ced058aa89be34bb134b12b21075a98f;p=thirdparty%2Fvala.git Support delegate properties Based on patch by Julien Fontanet, fixes bug 543879. --- diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala index 14b35f376..c44b5ecff 100644 --- a/codegen/valaccodebasemodule.vala +++ b/codegen/valaccodebasemodule.vala @@ -1221,6 +1221,8 @@ internal class Vala.CCodeBaseModule : CCodeModule { for (int dim = 1; dim <= array_type.rank; dim++) { function.add_parameter (new CCodeFormalParameter (head.get_array_length_cname (acc.readable ? "result" : "value", dim), length_ctype)); } + } else if ((acc.value_type is DelegateType) && ((DelegateType) acc.value_type).delegate_symbol.has_target) { + function.add_parameter (new CCodeFormalParameter (get_delegate_target_cname (acc.readable ? "result" : "value"), acc.readable ? "gpointer*" : "gpointer")); } if (prop.is_private_symbol () || (!acc.readable && !acc.writable) || acc.access == SymbolAccessibility.PRIVATE) { @@ -1303,6 +1305,8 @@ internal class Vala.CCodeBaseModule : CCodeModule { for (int dim = 1; dim <= array_type.rank; dim++) { function.add_parameter (new CCodeFormalParameter (head.get_array_length_cname (acc.readable ? "result" : "value", dim), length_ctype)); } + } else if ((acc.value_type is DelegateType) && ((DelegateType) acc.value_type).delegate_symbol.has_target) { + function.add_parameter (new CCodeFormalParameter (get_delegate_target_cname (acc.readable ? "result" : "value"), acc.readable ? "gpointer*" : "gpointer")); } if (prop.is_private_symbol () || !(acc.readable || acc.writable) || acc.access == SymbolAccessibility.PRIVATE) { @@ -1412,6 +1416,8 @@ internal class Vala.CCodeBaseModule : CCodeModule { for (int dim = 1; dim <= array_type.rank; dim++) { function.add_parameter (new CCodeFormalParameter (head.get_array_length_cname (acc.readable ? "result" : "value", dim), length_ctype)); } + } else if ((acc.value_type is DelegateType) && ((DelegateType) acc.value_type).delegate_symbol.has_target) { + function.add_parameter (new CCodeFormalParameter (get_delegate_target_cname (acc.readable ? "result" : "value"), acc.readable ? "gpointer*" : "gpointer")); } if (!is_virtual) { @@ -2482,6 +2488,23 @@ internal class Vala.CCodeBaseModule : CCodeModule { stmt.return_expression.ccodenode = ccomma; stmt.return_expression.temp_vars.add (return_expr_decl); + } else if ((current_method != null || current_property_accessor != null) && current_return_type is DelegateType) { + var delegate_type = (DelegateType) current_return_type; + if (delegate_type.delegate_symbol.has_target) { + var return_expr_decl = get_temp_variable (stmt.return_expression.value_type, true, stmt); + + var ccomma = new CCodeCommaExpression (); + ccomma.append_expression (new CCodeAssignment (get_variable_cexpression (return_expr_decl.name), (CCodeExpression) stmt.return_expression.ccodenode)); + + var len_l = new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier (get_delegate_target_cname ("result"))); + var len_r = get_delegate_target_cexpression (stmt.return_expression); + ccomma.append_expression (new CCodeAssignment (len_l, len_r)); + + ccomma.append_expression (get_variable_cexpression (return_expr_decl.name)); + + stmt.return_expression.ccodenode = ccomma; + stmt.return_expression.temp_vars.add (return_expr_decl); + } } var cfrag = new CCodeFragment (); @@ -3845,6 +3868,11 @@ internal class Vala.CCodeBaseModule : CCodeModule { for (int dim = 1; dim <= array_type.rank; dim++) { ccall.add_argument (head.get_array_length_cexpression (rhs, dim)); } + } else if (prop.property_type is DelegateType && rhs != null) { + var delegate_type = (DelegateType) prop.property_type; + if (delegate_type.delegate_symbol.has_target) { + ccall.add_argument (get_delegate_target_cexpression (rhs)); + } } if (prop.no_accessor_method) { diff --git a/codegen/valaccodedelegatemodule.vala b/codegen/valaccodedelegatemodule.vala index 05e5c311c..c45750a14 100644 --- a/codegen/valaccodedelegatemodule.vala +++ b/codegen/valaccodedelegatemodule.vala @@ -210,6 +210,8 @@ internal class Vala.CCodeDelegateModule : CCodeArrayModule { } else { return (CCodeExpression) get_ccodenode (ma.inner); } + } else if (delegate_expr.symbol_reference is Property) { + return delegate_expr.delegate_target; } } diff --git a/codegen/valaccodememberaccessmodule.vala b/codegen/valaccodememberaccessmodule.vala index a225c80ef..a87871cfd 100644 --- a/codegen/valaccodememberaccessmodule.vala +++ b/codegen/valaccodememberaccessmodule.vala @@ -223,7 +223,8 @@ internal class Vala.CCodeMemberAccessModule : CCodeControlFlowModule { if (prop.get_accessor.automatic_body && current_type_symbol == prop.parent_symbol && prop.base_property == null && - prop.base_interface_property == null) { + prop.base_interface_property == null && + !(prop.property_type is ArrayType || prop.property_type is DelegateType)) { CCodeExpression inst; inst = new CCodeMemberAccess.pointer (pub_inst, "priv"); expr.ccodenode = new CCodeMemberAccess.pointer (inst, prop.field.get_cname()); @@ -267,6 +268,15 @@ internal class Vala.CCodeMemberAccessModule : CCodeControlFlowModule { ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, ctemp)); expr.append_array_size (ctemp); } + } else { + var delegate_type = base_property.property_type as DelegateType; + if (delegate_type != null && delegate_type.delegate_symbol.has_target) { + var temp_var = get_temp_variable (new PointerType (new VoidType ())); + var ctemp = new CCodeIdentifier (temp_var.name); + temp_vars.add (temp_var); + ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, ctemp)); + expr.delegate_target = ctemp; + } } expr.ccodenode = ccall; diff --git a/codegen/valagobjectmodule.vala b/codegen/valagobjectmodule.vala index 700d5c1d6..ba0ad1f9b 100644 --- a/codegen/valagobjectmodule.vala +++ b/codegen/valagobjectmodule.vala @@ -692,6 +692,11 @@ internal class Vala.GObjectModule : GTypeModule { return false; } + var d = prop.property_type as DelegateType; + if (d != null && d.delegate_symbol.has_target) { + return false; + } + if (prop.base_interface_property != null) { var iface = (Interface) prop.base_interface_property.parent_symbol; if (!iface.is_subtype_of (gobject_type)) { diff --git a/vala/valaexpression.vala b/vala/valaexpression.vala index 3e458f5b8..431349972 100644 --- a/vala/valaexpression.vala +++ b/vala/valaexpression.vala @@ -66,6 +66,8 @@ public abstract class Vala.Expression : CodeNode { private Gee.List array_sizes = new ArrayList (); + public CCodeExpression delegate_target { get; set; } + /** * Returns whether this expression is constant, i.e. whether this * expression only consists of literals and other constants. diff --git a/vala/valamethodcall.vala b/vala/valamethodcall.vala index e1fa0c735..ff9443bab 100644 --- a/vala/valamethodcall.vala +++ b/vala/valamethodcall.vala @@ -38,8 +38,6 @@ public class Vala.MethodCall : Expression { } } - public CCodeExpression delegate_target { get; set; } - public Expression _call; private Gee.List argument_list = new ArrayList ();