vala r837 - in trunk: . gobject tests vala
- From: juergbi svn gnome org
- To: svn-commits-list gnome org
- Subject: vala r837 - in trunk: . gobject tests vala
- Date: Mon, 14 Jan 2008 20:47:21 +0000 (GMT)
Author: juergbi
Date: Mon Jan 14 20:47:21 2008
New Revision: 837
URL: http://svn.gnome.org/viewvc/vala?rev=837&view=rev
Log:
2008-01-14 Juerg Billeter <j bitron ch>
* vala/parser.y, vala/valainvocationexpression.vala,
gobject/valaccodegenerator.vala,
gobject/valaccodegeneratorinvocationexpression.vala,
gobject/valaccodegeneratormethod.vala: add support for instance
delegates, fixes bug 508734
* tests/delegates.exp, tests/delegates.vala: test instance delegates
Modified:
trunk/ChangeLog
trunk/gobject/valaccodegenerator.vala
trunk/gobject/valaccodegeneratorinvocationexpression.vala
trunk/gobject/valaccodegeneratormethod.vala
trunk/tests/delegates.exp
trunk/tests/delegates.vala
trunk/vala/parser.y
trunk/vala/valainvocationexpression.vala
Modified: trunk/gobject/valaccodegenerator.vala
==============================================================================
--- trunk/gobject/valaccodegenerator.vala (original)
+++ trunk/gobject/valaccodegenerator.vala Mon Jan 14 20:47:21 2008
@@ -298,17 +298,21 @@
}
}
- public override void visit_delegate (Delegate! cb) {
- cb.accept_children (this);
+ public override void visit_delegate (Delegate! d) {
+ d.accept_children (this);
- var cfundecl = new CCodeFunctionDeclarator (cb.get_cname ());
- foreach (FormalParameter param in cb.get_parameters ()) {
+ var cfundecl = new CCodeFunctionDeclarator (d.get_cname ());
+ foreach (FormalParameter param in d.get_parameters ()) {
cfundecl.add_parameter ((CCodeFormalParameter) param.ccodenode);
}
-
- var ctypedef = new CCodeTypeDefinition (cb.return_type.get_cname (), cfundecl);
-
- if (!cb.is_internal_symbol ()) {
+ if (d.instance) {
+ var cparam = new CCodeFormalParameter ("user_data", "void*");
+ cfundecl.add_parameter (cparam);
+ }
+
+ var ctypedef = new CCodeTypeDefinition (d.return_type.get_cname (), cfundecl);
+
+ if (!d.is_internal_symbol ()) {
header_type_definition.append (ctypedef);
} else {
source_type_member_declaration.append (ctypedef);
@@ -876,6 +880,16 @@
temp_vars.insert (0, len_decl);
}
+ } else if (decl.type_reference is DelegateType) {
+ var deleg_type = (DelegateType) decl.type_reference;
+ var d = deleg_type.delegate_symbol;
+ if (d.instance) {
+ // create variable to store delegate target
+ var target_decl = new VariableDeclarator (get_delegate_target_cname (decl.name));
+ target_decl.type_reference = new PointerType (new VoidType ());
+
+ temp_vars.insert (0, target_decl);
+ }
}
CCodeExpression rhs = null;
@@ -901,6 +915,24 @@
ccomma.append_expression (new CCodeIdentifier (temp_decl.name));
rhs = ccomma;
+ } else if (decl.type_reference is DelegateType) {
+ var deleg_type = (DelegateType) decl.type_reference;
+ var d = deleg_type.delegate_symbol;
+ if (d.instance) {
+ var ccomma = new CCodeCommaExpression ();
+
+ var temp_decl = get_temp_variable_declarator (decl.type_reference, true, decl);
+ temp_vars.insert (0, temp_decl);
+ ccomma.append_expression (new CCodeAssignment (new CCodeIdentifier (temp_decl.name), rhs));
+
+ var lhs_delegate_target = new CCodeIdentifier (get_delegate_target_cname (decl.name));
+ var rhs_delegate_target = get_delegate_target_cexpression (decl.initializer);
+ ccomma.append_expression (new CCodeAssignment (lhs_delegate_target, rhs_delegate_target));
+
+ ccomma.append_expression (new CCodeIdentifier (temp_decl.name));
+
+ rhs = ccomma;
+ }
}
} else if (decl.type_reference.data_type != null && decl.type_reference.data_type.is_reference_type ()) {
rhs = new CCodeConstant ("NULL");
@@ -2034,6 +2066,10 @@
visit_expression (expr);
}
+
+ private string! get_array_length_cname (string! array_cname, int dim) {
+ return "%s_length%d".printf (array_cname, dim);
+ }
public CCodeExpression! get_array_length_cexpression (Expression! array_expr, int dim) {
bool is_out = false;
@@ -2150,6 +2186,115 @@
return new CCodeConstant ("NULL");
}
}
+
+ private string! get_delegate_target_cname (string! delegate_cname) {
+ return "%s_target".printf (delegate_cname);
+ }
+
+ public CCodeExpression! get_delegate_target_cexpression (Expression! delegate_expr) {
+ bool is_out = false;
+
+ if (delegate_expr is UnaryExpression) {
+ var unary_expr = (UnaryExpression) delegate_expr;
+ if (unary_expr.operator == UnaryOperator.OUT || unary_expr.operator == UnaryOperator.REF) {
+ delegate_expr = unary_expr.inner;
+ is_out = true;
+ }
+ }
+
+ if (delegate_expr is InvocationExpression) {
+ var invocation_expr = (InvocationExpression) delegate_expr;
+ return invocation_expr.delegate_target;
+ } else if (delegate_expr.symbol_reference != null) {
+ if (delegate_expr.symbol_reference is FormalParameter) {
+ var param = (FormalParameter) delegate_expr.symbol_reference;
+ CCodeExpression target_expr = new CCodeIdentifier (get_delegate_target_cname (param.name));
+ if (param.type_reference.is_out || param.type_reference.is_ref) {
+ // accessing argument of out/ref param
+ target_expr = new CCodeParenthesizedExpression (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, target_expr));
+ }
+ if (is_out) {
+ // passing array as out/ref
+ return new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, target_expr);
+ } else {
+ return target_expr;
+ }
+ } else if (delegate_expr.symbol_reference is VariableDeclarator) {
+ var decl = (VariableDeclarator) delegate_expr.symbol_reference;
+ var target_expr = new CCodeIdentifier (get_delegate_target_cname (decl.name));
+ if (is_out) {
+ return new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, target_expr);
+ } else {
+ return target_expr;
+ }
+ } else if (delegate_expr.symbol_reference is Field) {
+ var field = (Field) delegate_expr.symbol_reference;
+ var target_cname = get_delegate_target_cname (field.name);
+
+ var ma = (MemberAccess) delegate_expr;
+
+ CCodeExpression pub_inst = null;
+ Typesymbol base_type = null;
+ CCodeExpression target_expr = null;
+
+ if (ma.inner == null) {
+ pub_inst = new CCodeIdentifier ("self");
+
+ if (current_type_symbol != null) {
+ /* base type is available if this is a type method */
+ base_type = (Typesymbol) current_type_symbol;
+ }
+ } else {
+ pub_inst = (CCodeExpression) ma.inner.ccodenode;
+
+ if (ma.inner.static_type != null) {
+ base_type = ma.inner.static_type.data_type;
+ }
+ }
+
+ if (field.instance) {
+ var instance_expression_type = new DataType ();
+ instance_expression_type.data_type = base_type;
+ var instance_target_type = new DataType ();
+ instance_target_type.data_type = (Typesymbol) field.parent_symbol;
+ CCodeExpression typed_inst = get_implicit_cast_expression (pub_inst, instance_expression_type, instance_target_type);
+
+ CCodeExpression inst;
+ if (field.access == SymbolAccessibility.PRIVATE) {
+ inst = new CCodeMemberAccess.pointer (typed_inst, "priv");
+ } else {
+ inst = typed_inst;
+ }
+ if (((Typesymbol) field.parent_symbol).is_reference_type ()) {
+ target_expr = new CCodeMemberAccess.pointer (inst, target_cname);
+ } else {
+ target_expr = new CCodeMemberAccess (inst, target_cname);
+ }
+ } else {
+ target_expr = new CCodeIdentifier (target_cname);
+ }
+
+ if (is_out) {
+ return new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, target_expr);
+ } else {
+ return target_expr;
+ }
+ } else if (delegate_expr.symbol_reference is Method) {
+ var ma = (MemberAccess) delegate_expr;
+ if (ma.inner == null) {
+ if (current_method != null && current_method.instance) {
+ return new CCodeIdentifier ("self");
+ } else {
+ return new CCodeConstant ("NULL");
+ }
+ } else {
+ return (CCodeExpression) ma.inner.ccodenode;
+ }
+ }
+ }
+
+ return new CCodeConstant ("NULL");
+ }
public override void visit_element_access (ElementAccess! expr) {
expr.code_binding.emit ();
Modified: trunk/gobject/valaccodegeneratorinvocationexpression.vala
==============================================================================
--- trunk/gobject/valaccodegeneratorinvocationexpression.vala (original)
+++ trunk/gobject/valaccodegeneratorinvocationexpression.vala Mon Jan 14 20:47:21 2008
@@ -221,6 +221,7 @@
}
CCodeExpression cexpr = (CCodeExpression) arg.ccodenode;
+ Gee.List<CCodeExpression> extra_args = new ArrayList<CCodeExpression> ();
if (params_it.next ()) {
var param = params_it.get ();
ellipsis = param.ellipsis;
@@ -233,6 +234,12 @@
for (int dim = 1; dim <= arr.rank; dim++) {
ccall.add_argument (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));
+ }
}
cexpr = get_implicit_cast_expression (cexpr, arg.static_type, param.type_reference);
@@ -287,6 +294,11 @@
}
ccall.add_argument (cexpr);
+
+ foreach (CCodeExpression extra_arg in extra_args) {
+ ccall.add_argument (extra_arg);
+ }
+
i++;
}
while (params_it.next ()) {
@@ -341,6 +353,19 @@
expr.append_array_size (new CCodeConstant ("-1"));
}
}
+ } else if (m != null && m.return_type is DelegateType) {
+ var deleg_type = (DelegateType) m.return_type;
+ var d = deleg_type.delegate_symbol;
+ if (d.instance) {
+ var temp_decl = get_temp_variable_declarator (new PointerType (new VoidType ()));
+ var temp_ref = new CCodeIdentifier (temp_decl.name);
+
+ temp_vars.insert (0, temp_decl);
+
+ ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, temp_ref));
+
+ expr.delegate_target = temp_ref;
+ }
}
if (connection_type != null && ma.inner != null && ma.inner.static_type != null && ma.inner.static_type.data_type == connection_type && m.name == "get_object") {
@@ -365,6 +390,12 @@
if ((m == null || !m.printf_format) && !(m is DBusMethod)) {
ccall.add_argument (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));
+ }
}
if (m != null && m.instance && m.returns_modified_pointer) {
Modified: trunk/gobject/valaccodegeneratormethod.vala
==============================================================================
--- trunk/gobject/valaccodegeneratormethod.vala (original)
+++ trunk/gobject/valaccodegeneratormethod.vala Mon Jan 14 20:47:21 2008
@@ -197,10 +197,22 @@
if (vdeclarator != null) {
vdeclarator.add_parameter ((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);
+ }
+ }
+ }
}
- // return array length if appropriate
if (!m.no_array_length && creturn_type.data_type is Array) {
+ // return array length if appropriate
var arr = (Array) creturn_type.data_type;
for (int dim = 1; dim <= arr.rank; dim++) {
@@ -210,6 +222,17 @@
vdeclarator.add_parameter (cparam);
}
}
+ } else if (creturn_type is DelegateType) {
+ // return delegate target if appropriate
+ var deleg_type = (DelegateType) creturn_type;
+ 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);
+ }
+ }
}
if (m.instance && m.instance_last) {
@@ -627,10 +650,6 @@
}
return null;
}
-
- private string! get_array_length_cname (string! array_cname, int dim) {
- return "%s_length%d".printf (array_cname, dim);
- }
public override void visit_creation_method (CreationMethod! m) {
if (m.body != null && current_type_symbol is Class && current_class.is_subtype_of (gobject_type)) {
Modified: trunk/tests/delegates.exp
==============================================================================
--- trunk/tests/delegates.exp (original)
+++ trunk/tests/delegates.exp Mon Jan 14 20:47:21 2008
@@ -1 +1 @@
-Delegate Test: 1 2 3 4 5
+Delegate Test: 1 2 3 4 5 6 7
Modified: trunk/tests/delegates.vala
==============================================================================
--- trunk/tests/delegates.vala (original)
+++ trunk/tests/delegates.vala Mon Jan 14 20:47:21 2008
@@ -4,7 +4,12 @@
public static delegate int Maman.ActionCallback ();
+public delegate void Maman.InstanceCallback ();
+
class Maman.Bar : Object {
+ public Bar () {
+ }
+
static void do_void_action () {
stdout.printf (" 2");
}
@@ -13,6 +18,14 @@
return 4;
}
+ void do_instance_action () {
+ stdout.printf (" 6");
+ }
+
+ static void call_instance_delegate (InstanceCallback instance_cb) {
+ instance_cb ();
+ }
+
static int main (string[] args) {
stdout.printf ("Delegate Test: 1");
@@ -25,9 +38,16 @@
ActionCallback cb = do_action;
stdout.printf (" %d", cb ());
-
- stdout.printf (" 5\n");
-
+
+ stdout.printf (" 5");
+
+ var bar = new Bar ();
+
+ InstanceCallback instance_cb = bar.do_instance_action;
+ call_instance_delegate (instance_cb);
+
+ stdout.printf (" 7\n");
+
return 0;
}
}
Modified: trunk/vala/parser.y
==============================================================================
--- trunk/vala/parser.y (original)
+++ trunk/vala/parser.y Mon Jan 14 20:47:21 2008
@@ -3797,7 +3797,10 @@
vala_symbol_set_access (VALA_SYMBOL (cb), $3);
}
VALA_CODE_NODE (cb)->attributes = $2;
-
+ if (($4 & VALA_MODIFIER_STATIC) == 0) {
+ vala_delegate_set_instance (cb, TRUE);
+ }
+
if ($9 != NULL) {
for (l = $9; l != NULL; l = l->next) {
vala_delegate_add_type_parameter (cb, l->data);
Modified: trunk/vala/valainvocationexpression.vala
==============================================================================
--- trunk/vala/valainvocationexpression.vala (original)
+++ trunk/vala/valainvocationexpression.vala Mon Jan 14 20:47:21 2008
@@ -1,6 +1,6 @@
/* valainvocationexpression.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
@@ -38,6 +38,8 @@
}
}
+ public CCodeExpression delegate_target { get; set; }
+
public Expression! _call;
private Gee.List<Expression> argument_list = new ArrayList<Expression> ();
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]