vala r983 - in trunk: . gobject tests vala vapi



Author: juergbi
Date: Wed Feb  6 23:18:01 2008
New Revision: 983
URL: http://svn.gnome.org/viewvc/vala?rev=983&view=rev

Log:
2008-02-07  Juerg Billeter  <j bitron ch>

	* vala/valasemanticanalyzer.vala, vala/valasignal.vala,
	  gobject/valaccodeassignmentbinding.vala,
	  gobject/valaccodegenerator.vala,
	  gobject/valaccodegeneratorinvocationexpression.vala,
	  gobject/valaccodegeneratorsourcefile.vala,
	  tests/classes-properties.vala, vapi/glib-2.0.vapi: create wrapper
	  functions for signal handlers to support public signal handlers,
	  fixes bug 508834


Modified:
   trunk/ChangeLog
   trunk/gobject/valaccodeassignmentbinding.vala
   trunk/gobject/valaccodegenerator.vala
   trunk/gobject/valaccodegeneratorinvocationexpression.vala
   trunk/gobject/valaccodegeneratorsourcefile.vala
   trunk/tests/classes-properties.vala
   trunk/vala/valasemanticanalyzer.vala
   trunk/vala/valasignal.vala
   trunk/vapi/glib-2.0.vapi

Modified: trunk/gobject/valaccodeassignmentbinding.vala
==============================================================================
--- trunk/gobject/valaccodeassignmentbinding.vala	(original)
+++ trunk/gobject/valaccodeassignmentbinding.vala	Wed Feb  6 23:18:01 2008
@@ -195,7 +195,7 @@
 		}
 
 		// third resp. sixth argument: handler
-		ccall.add_argument (new CCodeCastExpression (new CCodeIdentifier (m.get_cname ()), "GCallback"));
+		ccall.add_argument (new CCodeCastExpression (new CCodeIdentifier (generate_signal_handler_wrapper (m, sig)), "GCallback"));
 
 		if (m.instance) {
 			// g_signal_connect_object or g_signal_handlers_disconnect_matched
@@ -296,6 +296,109 @@
 		}
 	}
 
+	private string generate_signal_handler_wrapper (Method m, Signal sig) {
+		string wrapper_name = "_%s_%s%s".printf (m.get_cname (), sig.parent_symbol.get_lower_case_cprefix (), sig.get_cname ());
+
+		if (!codegen.add_wrapper (wrapper_name)) {
+			// wrapper already defined
+			return wrapper_name;
+		}
+
+		// declaration
+
+		var function = new CCodeFunction (wrapper_name, m.return_type.get_cname ());
+		function.modifiers = CCodeModifiers.STATIC;
+		m.ccodenode = function;
+
+		var cparam_map = new HashMap<int,CCodeFormalParameter> (direct_hash, direct_equal);
+
+		var cparam = new CCodeFormalParameter ("self", "gpointer");
+		cparam_map.set (codegen.get_param_pos (-1), cparam);
+
+		cparam = new CCodeFormalParameter ("sender", ((Typesymbol) sig.parent_symbol).get_cname () + "*");
+		cparam_map.set (codegen.get_param_pos (0), cparam);
+
+		var sig_params = sig.get_parameters ();
+		foreach (FormalParameter param in sig_params) {
+			// ensure that C code node has been generated
+			param.accept (codegen);
+
+			cparam_map.set (codegen.get_param_pos (param.cparameter_position), (CCodeFormalParameter) param.ccodenode);
+		}
+
+		// 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));
+			last_pos = min_pos;
+		}
+
+
+		// definition
+
+		var carg_map = new HashMap<int,CCodeExpression> (direct_hash, direct_equal);
+
+		if (m.instance) {
+			carg_map.set (codegen.get_param_pos (m.cinstance_parameter_position), new CCodeIdentifier ("self"));
+		}
+
+		int i = -1;
+		foreach (FormalParameter param in m.get_parameters ()) {
+			CCodeExpression arg;
+			if (i < 0) {
+				arg = new CCodeIdentifier ("sender");
+			} else {
+				arg = new CCodeIdentifier (sig_params.get (i).name);
+			}
+			carg_map.set (codegen.get_param_pos (param.cparameter_position), arg);
+			i++;
+		}
+
+		var ccall = new CCodeFunctionCall (new CCodeIdentifier (m.get_cname ()));
+
+		// append C arguments in the right order
+		last_pos = -1;
+		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;
+		}
+
+		var block = new CCodeBlock ();
+		if (m.return_type is VoidType) {
+			block.add_statement (new CCodeExpressionStatement (ccall));
+		} else {
+			block.add_statement (new CCodeReturnStatement (ccall));
+		}
+
+		// append to file
+
+		codegen.source_type_member_declaration.append (function.copy ());
+
+		function.block = block;
+		codegen.source_type_member_definition.append (function);
+
+		return wrapper_name;
+	}
+
 	private void emit_non_array_element_access () {
 		// custom element access
 		CCodeExpression rhs = (CCodeExpression) assignment.right.ccodenode;

Modified: trunk/gobject/valaccodegenerator.vala
==============================================================================
--- trunk/gobject/valaccodegenerator.vala	(original)
+++ trunk/gobject/valaccodegenerator.vala	Wed Feb  6 23:18:01 2008
@@ -45,9 +45,9 @@
 	CCodeFragment header_type_member_declaration;
 	CCodeFragment source_begin;
 	CCodeFragment source_include_directives;
-	CCodeFragment source_type_member_declaration;
+	public CCodeFragment source_type_member_declaration;
 	CCodeFragment source_signal_marshaller_declaration;
-	CCodeFragment source_type_member_definition;
+	public CCodeFragment source_type_member_definition;
 	CCodeFragment class_init_fragment;
 	CCodeFragment instance_init_fragment;
 	CCodeFragment instance_dispose_fragment;
@@ -121,6 +121,8 @@
 	private bool requires_array_move;
 	private bool requires_strcmp0;
 
+	private Set<string> wrappers;
+
 	public CCodeGenerator () {
 	}
 	
@@ -3108,6 +3110,10 @@
 		return ccomma;
 	}
 
+	public bool add_wrapper (string wrapper_name) {
+		return wrappers.add (wrapper_name);
+	}
+
 	public override CodeBinding create_namespace_binding (Namespace! node) {
 		return null;
 	}

Modified: trunk/gobject/valaccodegeneratorinvocationexpression.vala
==============================================================================
--- trunk/gobject/valaccodegeneratorinvocationexpression.vala	(original)
+++ trunk/gobject/valaccodegeneratorinvocationexpression.vala	Wed Feb  6 23:18:01 2008
@@ -539,7 +539,7 @@
 		return carray_type;
 	}
 
-	private int get_param_pos (double param_pos, bool ellipsis = false) {
+	public int get_param_pos (double param_pos, bool ellipsis = false) {
 		if (!ellipsis) {
 			if (param_pos >= 0) {
 				return (int) (param_pos * 1000);

Modified: trunk/gobject/valaccodegeneratorsourcefile.vala
==============================================================================
--- trunk/gobject/valaccodegeneratorsourcefile.vala	(original)
+++ trunk/gobject/valaccodegeneratorsourcefile.vala	Wed Feb  6 23:18:01 2008
@@ -193,7 +193,9 @@
 		requires_array_free = false;
 		requires_array_move = false;
 		requires_strcmp0 = false;
-		
+
+		wrappers = new HashSet<string> (str_hash, str_equal);
+
 		header_begin.append (new CCodeIncludeDirective ("glib.h"));
 		header_begin.append (new CCodeIncludeDirective ("glib-object.h"));
 		if (context.basedir != null || context.library != null) {

Modified: trunk/tests/classes-properties.vala
==============================================================================
--- trunk/tests/classes-properties.vala	(original)
+++ trunk/tests/classes-properties.vala	Wed Feb  6 23:18:01 2008
@@ -1,18 +1,13 @@
 using GLib;
 
 public class Sample : Object {
-	private string automatic {
-		get; set;
-	}
+	private string automatic { get; set; }
 
 	private string _name;
+	[Notify]
 	public string name {
 		get { return _name; }
-
-		set {
-			_name = value;
-			notify("name");
-		}
+		set { _name = value; }
 	}
 
 	private string _read_only;
@@ -30,12 +25,8 @@
 
 	public void run() {
 		notify += (s, p) => {
-			/* FIXME Cast needed as signatures conflict for the 
-			 * notify method and the notify signal of GObject.
-			 * See Bug 473804.
-			 */
 			stdout.printf("property `%s' has changed!\n",
-				      ((ParamSpec) p).name);
+				      p.name);
 		};
 
 

Modified: trunk/vala/valasemanticanalyzer.vala
==============================================================================
--- trunk/vala/valasemanticanalyzer.vala	(original)
+++ trunk/vala/valasemanticanalyzer.vala	Wed Feb  6 23:18:01 2008
@@ -2768,26 +2768,6 @@
 					Report.error (a.right.source_reference, "unsupported expression for signal handler");
 					return;
 				}
-
-				var m = (Method) a.right.symbol_reference;
-
-				if (m.instance && m.access != SymbolAccessibility.PRIVATE) {
-					/* TODO: generate wrapper function */
-
-					ma.error = true;
-					Report.error (a.right.source_reference, "public instance methods not yet supported as signal handlers");
-					return;
-				}
-
-				if (m.instance) {
-					/* instance signal handlers must have the self
-					 * parameter at the end
-					 * do not use G_CONNECT_SWAPPED as this would
-					 * rearrange the parameters for instance
-					 * methods and non-instance methods
-					 */
-					m.cinstance_parameter_position = -1;
-				}
 			} else if (ma.symbol_reference is Property) {
 				var prop = (Property) ma.symbol_reference;
 

Modified: trunk/vala/valasignal.vala
==============================================================================
--- trunk/vala/valasignal.vala	(original)
+++ trunk/vala/valasignal.vala	Wed Feb  6 23:18:01 2008
@@ -69,12 +69,15 @@
 	 * @param param a formal parameter
 	 */
 	public void add_parameter (FormalParameter! param) {
+		// default C parameter position
+		param.cparameter_position = parameters.size + 1;
+
 		parameters.add (param);
 		scope.add (param.name, param);
 	}
 
-	public Collection<FormalParameter> get_parameters () {
-		return new ReadOnlyCollection<FormalParameter> (parameters);
+	public Gee.List<FormalParameter> get_parameters () {
+		return new ReadOnlyList<FormalParameter> (parameters);
 	}
 
 	/**

Modified: trunk/vapi/glib-2.0.vapi
==============================================================================
--- trunk/vapi/glib-2.0.vapi	(original)
+++ trunk/vapi/glib-2.0.vapi	Wed Feb  6 23:18:01 2008
@@ -735,13 +735,7 @@
 		public virtual void finalize ();
 		public virtual void constructed ();
 
-		/* FIXME The notify passes a ParamSpec where the
-		 * wrapper expects a string. Fortunatly Vala doesn't
-		 * verify signatures of signal handlers yet.
-		 * See Bug 473804.
-		 */
-		[HasEmitter]
-		public signal void notify(string! property_name);
+		public signal void notify (ParamSpec pspec);
 
 		public weak Object connect (string! signal_spec, ...);
 	}



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