vala r1122 - in trunk: . compiler gobject



Author: juergbi
Date: Tue Mar 11 13:25:53 2008
New Revision: 1122
URL: http://svn.gnome.org/viewvc/vala?rev=1122&view=rev

Log:
2008-03-11  Juerg Billeter  <j bitron ch>

	* gobject/Makefile.am, gobject/valagidlwriter.vala,
	  compiler/valacompiler.vala: add GIdlWriter to generate .gidl files
	  when building libraries


Added:
   trunk/gobject/valagidlwriter.vala
Modified:
   trunk/ChangeLog
   trunk/compiler/valacompiler.vala
   trunk/gobject/Makefile.am

Modified: trunk/compiler/valacompiler.vala
==============================================================================
--- trunk/compiler/valacompiler.vala	(original)
+++ trunk/compiler/valacompiler.vala	Tue Mar 11 13:25:53 2008
@@ -269,7 +269,19 @@
 			}
 
 			interface_writer.write_file (context, vapi_filename);
-			
+
+
+			var gidl_writer = new GIdlWriter ();
+			string gidl_filename = "%s.gidl".printf (library);
+
+			// put .gidl file in current directory unless -d has been explicitly specified
+			if (directory != null) {
+				gidl_filename = "%s/%s".printf (context.directory, gidl_filename);
+			}
+
+			gidl_writer.write_file (context, gidl_filename);
+
+
 			library = null;
 		}
 

Modified: trunk/gobject/Makefile.am
==============================================================================
--- trunk/gobject/Makefile.am	(original)
+++ trunk/gobject/Makefile.am	Tue Mar 11 13:25:53 2008
@@ -32,6 +32,7 @@
 	valadbusbindingprovider.vala \
 	valadbusmethod.vala \
 	valadbussignal.vala \
+	valagidlwriter.vala \
 	valainterfaceregisterfunction.vala \
 	valatyperegisterfunction.vala \
 	$(NULL)

Added: trunk/gobject/valagidlwriter.vala
==============================================================================
--- (empty file)
+++ trunk/gobject/valagidlwriter.vala	Tue Mar 11 13:25:53 2008
@@ -0,0 +1,489 @@
+/* valagidlwriter.vala
+ *
+ * Copyright (C) 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
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
+ *
+ * Author:
+ * 	JÃrg Billeter <j bitron ch>
+ */
+
+using GLib;
+using Gee;
+
+/**
+ * Code visitor generating .gidl file for the public interface.
+ */
+public class Vala.GIdlWriter : CodeVisitor {
+	private CodeContext context;
+	
+	FileStream stream;
+	
+	int indent;
+
+	private Typesymbol gobject_type;
+
+	/**
+	 * Writes the public interface of the specified code context into the
+	 * specified file.
+	 *
+	 * @param context  a code context
+	 * @param filename a relative or absolute filename
+	 */
+	public void write_file (CodeContext! context, string! filename) {
+		this.context = context;
+
+		var root_symbol = context.root;
+		var glib_ns = root_symbol.scope.lookup ("GLib");
+		gobject_type = (Typesymbol) glib_ns.scope.lookup ("Object");
+
+		stream = FileStream.open (filename, "w");
+
+		stream.printf ("<?xml version=\"1.0\"?>\n");
+
+		stream.printf ("<api version=\"1.0\">\n");
+
+		context.accept (this);
+
+		stream.printf ("</api>\n");
+
+		stream = null;
+	}
+
+	public override void visit_namespace (Namespace! ns) {
+		if (ns.pkg) {
+			return;
+		}
+
+		if (ns.name == null)  {
+			// global namespace
+			ns.accept_children (this);
+			return;
+		}
+
+		write_indent ();
+		stream.printf ("<namespace name=\"%s\">\n", ns.name);
+		indent++;
+
+		ns.accept_children (this);
+
+		indent--;
+		write_indent ();
+		stream.printf ("</namespace>\n");
+	}
+
+	public override void visit_class (Class! cl) {
+		if (cl.source_reference != null && cl.source_reference.file.pkg) {
+			return;
+		}
+
+		if (!check_accessibility (cl)) {
+			return;
+		}
+
+		if (cl.is_subtype_of (gobject_type)) {
+			write_indent ();
+			stream.printf ("<object name=\"%s\"", cl.name);
+			stream.printf (" parent=\"%s\"", cl.base_class.get_full_name ());
+			stream.printf (" type-name=\"%s\"", cl.get_cname ());
+			stream.printf (" get-type=\"%sget_type\"", cl.get_lower_case_cprefix ());
+			stream.printf (">\n");
+			indent++;
+
+			// write implemented interfaces
+			bool first = true;
+			foreach (DataType base_type in cl.get_base_types ()) {
+				var iface_type = base_type as InterfaceType;
+				if (iface_type != null) {
+					if (first) {
+						write_indent ();
+						stream.printf ("<implements>\n");
+						indent++;
+						first = false;
+					}
+					write_indent ();
+					stream.printf ("<interface name=\"%s\"/>\n", iface_type.interface_symbol.get_full_name ());
+				}
+			}
+			if (!first) {
+				indent--;
+				write_indent ();
+				stream.printf ("</implements>\n");
+			}
+
+			cl.accept_children (this);
+
+			indent--;
+			write_indent ();
+			stream.printf ("</object>\n");
+		} else {
+			write_indent ();
+			stream.printf ("<struct name=\"%s\"", cl.name);
+			stream.printf (">\n");
+			indent++;
+
+			cl.accept_children (this);
+
+			indent--;
+			write_indent ();
+			stream.printf ("</struct>\n");
+		}
+	}
+
+	public override void visit_struct (Struct! st) {
+		if (st.source_reference != null && st.source_reference.file.pkg) {
+			return;
+		}
+
+		if (!check_accessibility (st)) {
+			return;
+		}
+
+		write_indent ();
+		stream.printf ("<struct name=\"%s\"", st.get_cname ());
+		stream.printf (">\n");
+		indent++;
+
+		st.accept_children (this);
+
+		indent--;
+		write_indent ();
+		stream.printf ("</struct>\n");
+	}
+
+	public override void visit_interface (Interface! iface) {
+		if (iface.source_reference != null && iface.source_reference.file.pkg) {
+			return;
+		}
+
+		if (!check_accessibility (iface)) {
+			return;
+		}
+
+		write_indent ();
+		stream.printf ("<interface name=\"%s\"", iface.get_cname ());
+		stream.printf (" get-type=\"%sget_type\"", iface.get_lower_case_cprefix ());
+		stream.printf (">\n");
+		indent++;
+
+		// write prerequisites
+		if (iface.get_prerequisites ().size > 0) {
+			write_indent ();
+			stream.printf ("<requires>\n");
+			indent++;
+
+			foreach (DataType base_type in iface.get_prerequisites ()) {
+				var class_type = base_type as ClassType;
+				var iface_type = base_type as InterfaceType;
+				if (class_type != null) {
+					write_indent ();
+					stream.printf ("<object name=\"%s\"/>\n", class_type.class_symbol.get_full_name ());
+				} else if (iface_type != null) {
+					write_indent ();
+					stream.printf ("<interface name=\"%s\"/>\n", iface_type.interface_symbol.get_full_name ());
+				} else {
+					assert_not_reached ();
+				}
+			}
+
+			indent--;
+			write_indent ();
+			stream.printf ("</requires>\n");
+		}
+
+		iface.accept_children (this);
+
+		indent--;
+		write_indent ();
+		stream.printf ("</interface>\n");
+	}
+
+	public override void visit_enum (Enum! en) {
+		if (en.source_reference != null && en.source_reference.file.pkg) {
+			return;
+		}
+
+		if (!check_accessibility (en)) {
+			return;
+		}
+
+		write_indent ();
+		stream.printf ("<enum name=\"%s\"", en.get_cname ());
+		stream.printf (" get-type=\"%sget_type\"", en.get_lower_case_cprefix ());
+		stream.printf (">\n");
+		indent++;
+
+		en.accept_children (this);
+
+		indent--;
+		write_indent ();
+		stream.printf ("</enum>\n");
+	}
+
+	public override void visit_enum_value (EnumValue! ev) {
+		write_indent ();
+		stream.printf ("<member name=\"%s\"/>\n", ev.get_cname ());
+	}
+
+	public override void visit_error_domain (ErrorDomain edomain) {
+		if (edomain.source_reference != null && edomain.source_reference.file.pkg) {
+			return;
+		}
+
+		if (!check_accessibility (edomain)) {
+			return;
+		}
+
+		write_indent ();
+		stream.printf ("<errordomain name=\"%s\"", edomain.get_cname ());
+		stream.printf (">\n");
+		indent++;
+
+		edomain.accept_children (this);
+
+		indent--;
+		write_indent ();
+		stream.printf ("</errordomain>\n");
+	}
+
+	public override void visit_error_code (ErrorCode ecode) {
+		write_indent ();
+		stream.printf ("<member name=\"%s\"/>\n", ecode.get_cname ());
+	}
+
+	public override void visit_constant (Constant! c) {
+		if (c.source_reference != null && c.source_reference.file.pkg) {
+			return;
+		}
+
+		if (!check_accessibility (c)) {
+			return;
+		}
+
+		write_indent ();
+		stream.printf ("<constant name=\"%s\"/>\n", c.get_cname ());
+	}
+
+	public override void visit_field (Field! f) {
+		if (f.source_reference != null && f.source_reference.file.pkg) {
+			return;
+		}
+
+		if (!check_accessibility (f)) {
+			return;
+		}
+
+		write_indent ();
+		stream.printf ("<field name=\"%s\"/>\n", f.get_cname ());
+	}
+
+	private string get_gidl_type_name (DataType type) {
+		// workaround to get GIDL-specific type name
+		string gidl_type = type.get_cname ();
+		if (type.data_type != null) {
+			string cname = type.data_type.get_cname ();
+			if (gidl_type.has_prefix (cname)) {
+				gidl_type = type.data_type.get_full_name () + gidl_type.substring (cname.len (), gidl_type.len () - cname.len ());
+			}
+		} else if (type is DelegateType) {
+			var dt = (DelegateType) type;
+			string cname = dt.get_cname ();
+			if (gidl_type.has_prefix (cname)) {
+				gidl_type = dt.delegate_symbol.get_full_name () + gidl_type.substring (cname.len (), gidl_type.len () - cname.len ());
+			}
+		}
+		return gidl_type;
+	}
+
+	private void write_params (Collection<FormalParameter> params, DataType? instance_type = null) {
+		write_indent ();
+		stream.printf ("<parameters>\n");
+		indent++;
+
+		if (instance_type != null) {
+			write_indent ();
+			stream.printf ("<parameter name=\"self\" type=\"%s\"/>\n", get_gidl_type_name (instance_type));
+		}
+
+		foreach (FormalParameter param in params) {
+			write_indent ();
+			stream.printf ("<parameter name=\"%s\" type=\"%s\"", param.name, get_gidl_type_name (param.type_reference));
+			if (param.type_reference.is_ref) {
+				stream.printf (" direction=\"inout\"");
+				// in/out paramter
+				if (param.type_reference.takes_ownership) {
+					stream.printf (" transfer=\"full\"");
+				}
+			} else if (param.type_reference.is_out) {
+				// out paramter
+				stream.printf (" direction=\"out\"");
+				if (param.type_reference.takes_ownership) {
+					stream.printf (" transfer=\"full\"");
+				}
+			} else {
+				// normal in paramter
+				if (param.type_reference.transfers_ownership) {
+					stream.printf (" transfer=\"full\"");
+				}
+			}
+			stream.printf ("/>\n");
+		}
+
+		indent--;
+		write_indent ();
+		stream.printf ("</parameters>\n");
+	}
+
+	public override void visit_delegate (Delegate! cb) {
+		if (cb.source_reference != null && cb.source_reference.file.pkg) {
+			return;
+		}
+
+		if (!check_accessibility (cb)) {
+			return;
+		}
+
+		write_indent ();
+		stream.printf ("<callback name=\"%s\"", cb.get_cname ());
+		stream.printf (">\n");
+		indent++;
+
+		write_params (cb.get_parameters ());
+
+		write_return_type (cb.return_type);
+
+		indent--;
+		write_indent ();
+		stream.printf ("</callback>\n");
+	}
+
+	public override void visit_method (Method! m) {
+		if (m.source_reference != null && m.source_reference.file.pkg) {
+			return;
+		}
+
+		// don't write interface implementation unless it's an abstract or virtual method
+		if (!check_accessibility (m) || m.overrides || (m.base_interface_method != null && !m.is_abstract && !m.is_virtual)) {
+			return;
+		}
+
+		write_indent ();
+		stream.printf ("<method name=\"%s\" symbol=\"%s\"", m.name, m.get_cname ());
+		stream.printf (">\n");
+		indent++;
+
+		DataType instance_type = null;
+		if (m.instance) {
+			instance_type = CCodeGenerator.get_data_type_for_symbol ((Typesymbol) m.parent_symbol);
+		}
+
+		write_params (m.get_parameters (), instance_type);
+
+		write_return_type (m.return_type);
+
+		indent--;
+		write_indent ();
+		stream.printf ("</method>\n");
+	}
+	
+	public override void visit_creation_method (CreationMethod! m) {
+		if (m.source_reference != null && m.source_reference.file.pkg) {
+			return;
+		}
+
+		if (!check_accessibility (m)) {
+			return;
+		}
+
+		string name = "new";
+		if (m.name.has_prefix (".new.")) {
+			name = m.name.substring (5, m.name.len () - 5);
+		}
+
+		write_indent ();
+		stream.printf ("<constructor name=\"%s\" symbol=\"%s\"", name, m.get_cname ());
+		stream.printf (">\n");
+		indent++;
+
+		write_params (m.get_parameters ());
+
+		write_return_type (CCodeGenerator.get_data_type_for_symbol ((Typesymbol) m.parent_symbol));
+
+		indent--;
+		write_indent ();
+		stream.printf ("</constructor>\n");
+	}
+
+	public override void visit_property (Property! prop) {
+		if (!check_accessibility (prop) || prop.overrides || prop.base_interface_property != null) {
+			return;
+		}
+
+		write_indent ();
+		stream.printf ("<property name=\"%s\" type=\"%s\"", prop.name, get_gidl_type_name (prop.type_reference));
+		if (prop.get_accessor != null) {
+			stream.printf (" readable=\"1\"");
+		}
+		if (prop.set_accessor != null) {
+			stream.printf (" writable=\"1\"");
+		}
+		stream.printf ("/>\n");
+	}
+
+	public override void visit_signal (Signal! sig) {
+		if (!check_accessibility (sig)) {
+			return;
+		}
+		
+		write_indent ();
+		stream.printf ("<signal name=\"%s\"", sig.get_cname ());
+		stream.printf (">\n");
+		indent++;
+
+		write_params (sig.get_parameters ());
+
+		write_return_type (sig.return_type);
+
+		indent--;
+		write_indent ();
+		stream.printf ("</signal>\n");
+	}
+
+	private void write_indent () {
+		int i;
+		
+		for (i = 0; i < indent; i++) {
+			stream.putc ('\t');
+		}
+	}
+
+	private void write_return_type (DataType! type) {
+		write_indent ();
+		stream.printf ("<return-type type=\"%s\"", get_gidl_type_name (type));
+		if (type.transfers_ownership) {
+			stream.printf (" transfer=\"full\"");
+		}
+		stream.printf ("/>\n");
+	}
+
+	private bool check_accessibility (Symbol! sym) {
+		if (sym.access == SymbolAccessibility.PUBLIC ||
+		    sym.access == SymbolAccessibility.PROTECTED) {
+			return true;
+		}
+
+		return false;
+	}
+}



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