[Vala] [PATCH] Belongs_to and is_instance for vapigen



Hello vala developers!

I updated my old patch adding belongs_to and is_instance options to
vapigen, and I was wondering if I could get them included in vapigen.
They are quite useful in wrapping not-entirely-glib libraries.

Thanks,
Sam
>From e6a676f1ef6c37f9fab8b008ef7ae11559ea1ffc Mon Sep 17 00:00:00 2001
From: Sam Wilson <tecywiz121 hotmail com>
Date: Mon, 27 Sep 2010 16:59:32 -0400
Subject: [PATCH] Added belongs_to and is_instance options to vapigen

---
 vapigen/valagidlparser.vala |  133 +++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 129 insertions(+), 4 deletions(-)

diff --git a/vapigen/valagidlparser.vala b/vapigen/valagidlparser.vala
index 438a8c7..54b2484 100644
--- a/vapigen/valagidlparser.vala
+++ b/vapigen/valagidlparser.vala
@@ -24,6 +24,18 @@
 
 using GLib;
 
+private class Vala.DelayedAdd
+{
+	public DelayedAdd(Symbol sym, string target)
+	{
+		symbol = sym;
+		this.target = target;
+	}
+
+	public Symbol symbol { get; private set; }
+	public string target { get; private set; }
+}
+
 /**
  * Code visitor parsing all GIDL files.
  */
@@ -41,6 +53,8 @@ public class Vala.GIdlParser : CodeVisitor {
 	private Set<string> current_type_symbol_set;
 
 	private Map<string,TypeSymbol> cname_type_map;
+	
+	private ArrayList<DelayedAdd> delayed_nodes;
 
 	/**
 	 * Parse all source files in the specified code context and build a
@@ -140,7 +154,9 @@ public class Vala.GIdlParser : CodeVisitor {
 			current_source_reference = new SourceReference (source_file);
 			
 			foreach (weak IdlModule module in modules) {
+				delayed_nodes = new ArrayList<DelayedAdd>();
 				var ns = parse_module (module);
+				process_delayed_symbols();
 				if (ns != null) {
 					context.root.add_namespace (ns);
 				}
@@ -1859,6 +1875,10 @@ public class Vala.GIdlParser : CodeVisitor {
 		bool add_ellipsis = false;
 		bool suppress_throws = false;
 		string? error_types = null;
+		
+		string? super_class = null;
+		bool clear_data_type = false;
+		bool is_instance = false;
 
 		var attributes = get_attributes (symbol);
 		if (attributes != null) {
@@ -1959,7 +1979,29 @@ public class Vala.GIdlParser : CodeVisitor {
 						m.set_cname (m.name);
 						m.name = symbol.offset (prefix.length);
 					}
-				}
+				} else if (nv[0] == "belongs_to") {
+					super_class = eval (nv[1]);
+					if (current_data_type == null)
+					{
+						clear_data_type = true;
+						current_data_type = new Struct(super_class,
+														current_source_reference,
+														new Comment("Fake reference",
+														current_source_reference));
+						((Struct)current_data_type).set_cname(super_class);
+						
+						if (m.name.has_prefix(super_class))
+						{
+							m.set_cname(m.name);
+							m.name = m.name.substring(super_class.length);
+						}
+					}
+				} else if (nv[0] == "is_instance") {
+					if (eval (nv[1]) == "1")
+					{
+						is_instance = true;
+					}
+ 				}
 			}
 		}
 		
@@ -1973,7 +2015,11 @@ public class Vala.GIdlParser : CodeVisitor {
 			
 			if (first) {
 				first = false;
-				if (!(m is CreationMethod) &&
+				if (is_instance)
+				{
+					m.binding = MemberBinding.INSTANCE;
+					continue;   // Force instance even if its not
+				} else if (!(m is CreationMethod) &&
 				    current_data_type != null &&
 				    param.type.is_interface &&
 				    (param_node.name == "self" ||
@@ -2204,9 +2250,88 @@ public class Vala.GIdlParser : CodeVisitor {
 			m.add_parameter (new FormalParameter.with_ellipsis ());
 		}
 		
-		return m;
+		if (super_class == null)
+			return m;
+		
+		else
+		{
+			delay_symbol(m, super_class);
+			
+			if (clear_data_type)
+				current_data_type = null;
+			
+			return null;
+		}
 	}
-
+	
+	private void delay_symbol(Symbol m, string new_class)
+	{
+		stdout.printf("Delaying: %s.%s\n", new_class, m.name);
+		delayed_nodes.add(new DelayedAdd(m, new_class));
+	}
+	
+	private void process_delayed_symbols()
+	{
+		foreach (DelayedAdd add in delayed_nodes)
+		{
+			TypeSymbol? sym = cname_type_map[add.target];
+			
+			if (sym == null)
+			{
+				stdout.printf("WARNING: Could not find type '%s' for belongs_to of '%s'\n", add.target, add.symbol.name);
+				continue;
+			}
+				
+				
+			if (sym is Class)
+			{
+				add_symbol_class((Class)sym, add.symbol);
+			}
+			if (sym is Struct)
+			{
+				add_symbol_struct((Struct)sym, add.symbol);
+			}
+		}
+		
+		delayed_nodes.clear();
+	}
+	
+	private void add_symbol_class(Class c, Symbol s)
+	{
+		if (s is Method) {
+			c.add_method((Method)s);
+		} else if (s is Class) {
+			c.add_class((Class)s);
+		} else if (s is Constant) {
+			c.add_constant((Constant)s);
+		} else if (s is Delegate) {
+			c.add_delegate((Delegate)s);
+		} else if (s is Enum) {
+			c.add_enum((Enum)s);
+		} else if (s is Field) {
+			c.add_field((Field)s);
+		} else if (s is Property) {
+			c.add_property((Property)s);
+		} else if (s is Signal) {
+			c.add_signal((Signal)s);
+		} else if (s is Struct) {
+			c.add_struct((Struct)s);
+		}
+	}
+	
+	private void add_symbol_struct(Struct c, Symbol s)
+	{
+		if (s is Method) {
+			c.add_method((Method)s);
+		} else if (s is Constant) {
+			c.add_constant((Constant)s);
+		} else if (s is Field) {
+			c.add_field((Field)s);
+		} else if (s is Property) {
+			c.add_property((Property)s);
+		}
+	}
+	
 	private bool param_is_exception (IdlNodeParam param) {
 		if (!param.type.is_error) {
 			return false;
-- 
1.7.0.4



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