[valadoc] drivers: Add 0.10.x driver



commit 79ff61a83b2a3b3d948b7ecdc28d441b8cd874f8
Author: Florian Brosch <flo brosch gmail com>
Date:   Sun Jul 24 10:41:09 2011 +0200

    drivers: Add 0.10.x driver

 configure.in                                |    8 +
 src/driver/0.10.x/Makefile.am               |   66 ++
 src/driver/0.10.x/childsymbolregistrar.vala |   95 +++
 src/driver/0.10.x/driver.vala               |   55 ++
 src/driver/0.10.x/initializerbuilder.vala   |  676 ++++++++++++++++++
 src/driver/0.10.x/symbolresolver.vala       |  309 ++++++++
 src/driver/0.10.x/treebuilder.vala          | 1029 +++++++++++++++++++++++++++
 src/driver/Makefile.am                      |    5 +
 8 files changed, 2243 insertions(+), 0 deletions(-)
---
diff --git a/configure.in b/configure.in
index a6ae2c6..68516ca 100755
--- a/configure.in
+++ b/configure.in
@@ -82,6 +82,13 @@ AC_SUBST(LIBVALA_0_11_0_CFLAGS)
 AC_SUBST(LIBVALA_0_11_0_LIBS)
 
 
+PKG_CHECK_MODULES(LIBVALA_0_10_X, vala-0.10 >= 0.10, have_libvala_0_10_x="yes", have_libvala_0_10_x="no")
+AM_CONDITIONAL(HAVE_LIBVALA_0_10_X, test "$have_libvala_0_10_x" = "yes")
+AC_SUBST(LIBVALA_0_10_X_CFLAGS)
+AC_SUBST(LIBVALA_0_10_X_LIBS)
+
+
+
 
 AC_CONFIG_FILES([Makefile
                  src/libvaladoc/valadoc-1.0.pc
@@ -91,6 +98,7 @@ AC_CONFIG_FILES([Makefile
                  doc/Makefile
                  src/libvaladoc/Makefile
                  src/driver/Makefile
+				 src/driver/0.10.x/Makefile
 				 src/driver/0.11.0/Makefile
 				 src/driver/0.11.x/Makefile
 				 src/driver/0.12.x/Makefile
diff --git a/src/driver/0.10.x/Makefile.am b/src/driver/0.10.x/Makefile.am
new file mode 100755
index 0000000..9c57051
--- /dev/null
+++ b/src/driver/0.10.x/Makefile.am
@@ -0,0 +1,66 @@
+NULL =
+
+
+VERSIONED_VAPI_DIR=`pkg-config vala-0.10 --variable vapidir`
+
+
+AM_CFLAGS =  -g \
+	-DPACKAGE_ICONDIR=\"$(datadir)/valadoc/icons/\" \
+	-I ../../libvaladoc/ \
+	$(GLIB_CFLAGS) \
+	$(LIBGEE_CFLAGS) \
+	$(LIBVALA_0_10_X_CFLAGS) \
+	$(NULL)
+
+
+
+BUILT_SOURCES = libdriver.vala.stamp
+
+
+driverdir = $(libdir)/valadoc/drivers/0.10.x
+
+
+libdriver_la_LDFLAGS = -module -avoid-version -no-undefined
+
+
+driver_LTLIBRARIES =  \
+	libdriver.la \
+	$(NULL)
+
+
+libdriver_la_VALASOURCES = \
+	initializerbuilder.vala \
+	childsymbolregistrar.vala \
+	symbolresolver.vala \
+	treebuilder.vala \
+	driver.vala \
+	$(NULL)
+
+
+libdriver_la_SOURCES =      \
+	libdriver.vala.stamp                 \
+	$(libdriver_la_VALASOURCES:.vala=.c) \
+	$(NULL)
+
+
+libdriver.vala.stamp: $(libdriver_la_VALASOURCES)
+	$(VALAC) -C --vapidir $(top_srcdir)/src/vapi --vapidir $(top_srcdir)/src/libvaladoc --pkg vala-0.10 --pkg gee-1.0 --pkg valadoc-1.0 --vapidir $(VERSIONED_VAPI_DIR) --basedir . $^
+	touch $@
+
+
+libdriver_la_LIBADD = \
+	../../libvaladoc/libvaladoc.la \
+	$(GLIB_LIBS) \
+	$(LIBVALA_0_10_X_LIBS) \
+	$(LIBGEE_LIBS) \
+	$(NULL)
+
+
+EXTRA_DIST = $(libdriver_la_VALASOURCES)  libdriver.vala.stamp 
+
+
+MAINTAINERCLEANFILES = \
+	$(libdriver_la_VALASOURCES:.vala=.c) \
+	$(NULL)
+
+
diff --git a/src/driver/0.10.x/childsymbolregistrar.vala b/src/driver/0.10.x/childsymbolregistrar.vala
new file mode 100644
index 0000000..2454242
--- /dev/null
+++ b/src/driver/0.10.x/childsymbolregistrar.vala
@@ -0,0 +1,95 @@
+/* childsymbolregistrar.vala
+ *
+ * Copyright (C) 2011  Florian Brosch
+ *
+ * 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:
+ * 	Florian Brosch <flo brosch gmail com>
+ */
+
+using Valadoc.Api;
+using Gee;
+
+
+public class Valadoc.Drivers.ChildSymbolRegistrar : Visitor {
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_tree (Api.Tree item) {
+		item.accept_children (this);			
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_package (Package item) {
+		item.accept_all_children (this);
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_namespace (Namespace item) {
+		item.accept_all_children (this);
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_interface (Interface item) {
+		Collection<TypeReference> interfaces = item.get_implemented_interface_list ();
+		foreach (var type_ref in interfaces) {
+			((Interface) type_ref.data_type).register_related_interface (item);
+		}
+
+		if (item.base_type != null) {
+			((Class) item.base_type.data_type).register_derived_interface (item);
+		}
+
+		item.accept_all_children (this);
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_class (Class item) {
+		Collection<TypeReference> interfaces = item.get_implemented_interface_list ();
+		foreach (TypeReference type_ref in interfaces) {
+			((Interface) type_ref.data_type).register_implementation (item);
+		}
+
+		if (item.base_type != null)	{
+			((Class) item.base_type.data_type).register_child_class (item);
+		}
+
+		item.accept_all_children (this);
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_struct (Struct item) {
+		item.accept_all_children (this);
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_property (Property item) {
+		item.accept_all_children (this);
+	}
+}
+
diff --git a/src/driver/0.10.x/driver.vala b/src/driver/0.10.x/driver.vala
new file mode 100755
index 0000000..4bbb940
--- /dev/null
+++ b/src/driver/0.10.x/driver.vala
@@ -0,0 +1,55 @@
+/* driver.vala
+ *
+ * Copyright (C) 2011  Florian Brosch
+ *
+ * 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:
+ * 	Florian Brosch <flo brosch gmail com>
+ */
+
+using Valadoc.Api;
+using Gee;
+
+
+
+/**
+ * Creates an simpler, minimized, more abstract AST for valacs AST.
+ */
+public class Valadoc.Drivers.Driver : Object, Valadoc.Driver {
+
+	public Api.Tree? build (Settings settings, ErrorReporter reporter) {
+		TreeBuilder builder = new TreeBuilder ();
+		Api.Tree? tree = builder.build (settings, reporter);
+		if (reporter.errors > 0) {
+			return null;
+		}
+
+		SymbolResolver resolver = new SymbolResolver (builder);
+		tree.accept (resolver);
+
+		ChildSymbolRegistrar registrar = new ChildSymbolRegistrar ();
+		tree.accept (registrar);
+
+		return tree;
+	}
+}
+
+
+[ModuleInit]
+public Type register_plugin (GLib.TypeModule module) {
+	return typeof (Valadoc.Drivers.Driver);
+}
+
diff --git a/src/driver/0.10.x/initializerbuilder.vala b/src/driver/0.10.x/initializerbuilder.vala
new file mode 100644
index 0000000..9138fd4
--- /dev/null
+++ b/src/driver/0.10.x/initializerbuilder.vala
@@ -0,0 +1,676 @@
+/* initializerbuilder.vala
+ *
+ * Copyright (C) 2011  Florian Brosch
+ *
+ * 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:
+ * 	Florian Brosch <flo brosch gmail com>
+ */
+
+
+using Valadoc.Content;
+using Gee;
+
+
+private class Valadoc.Api.InitializerBuilder : Vala.CodeVisitor {
+	private HashMap<Vala.Symbol, Symbol> symbol_map;
+	private SignatureBuilder signature;
+
+	private Symbol? resolve (Vala.Symbol symbol) {
+		return symbol_map.get (symbol);
+	}
+
+	private void write_node (Vala.Symbol vsymbol) {
+		signature.append_symbol (resolve (vsymbol));
+	}
+
+	private void write_type (Vala.DataType vsymbol) {
+		if (vsymbol.data_type != null) {
+			write_node (vsymbol.data_type);
+		} else {
+			signature.append_literal ("null");
+		}
+
+		var type_args = vsymbol.get_type_arguments ();
+		if (type_args.size > 0) {
+			signature.append ("<");
+			bool first = true;
+			foreach (Vala.DataType type_arg in type_args) {
+				if (!first) {
+					signature.append (",");
+				} else {
+					first = false;
+				}
+				if (!type_arg.value_owned) {
+					signature.append_keyword ("weak");
+				}
+				signature.append (type_arg.to_qualified_string (null));
+			}
+			signature.append (">");
+		}
+
+		if (vsymbol.nullable) {
+			signature.append ("?");
+		}
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_array_creation_expression (Vala.ArrayCreationExpression expr) {
+		signature.append_keyword ("new");
+		write_type (expr.element_type);
+		signature.append ("[", false);
+
+		bool first = true;
+		foreach (Vala.Expression size in expr.get_sizes ()) {
+			if (!first) {
+				signature.append (", ", false);
+			}
+			size.accept (this);
+			first = false;
+		}
+
+		signature.append ("]", false);
+
+		if (expr.initializer_list != null) {
+			signature.append (" ", false);
+			expr.initializer_list.accept (this);
+		}
+	}
+
+	public InitializerBuilder (SignatureBuilder signature, HashMap<Vala.Symbol, Symbol> symbol_map) {
+		this.symbol_map = symbol_map;
+		this.signature = signature;
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_binary_expression (Vala.BinaryExpression expr) {
+		expr.left.accept (this);
+
+		switch (expr.operator) {
+		case Vala.BinaryOperator.PLUS:
+			signature.append ("+ ");
+			break;
+
+		case Vala.BinaryOperator.MINUS:
+			signature.append ("- ");
+			break;
+
+		case Vala.BinaryOperator.MUL:
+			signature.append ("* ");
+			break;
+
+		case Vala.BinaryOperator.DIV:
+			signature.append ("/ ");
+			break;
+
+		case Vala.BinaryOperator.MOD:
+			signature.append ("% ");
+			break;
+
+		case Vala.BinaryOperator.SHIFT_LEFT:
+			signature.append ("<< ");
+			break;
+
+		case Vala.BinaryOperator.SHIFT_RIGHT:
+			signature.append (">> ");
+			break;
+
+		case Vala.BinaryOperator.LESS_THAN:
+			signature.append ("< ");
+			break;
+
+		case Vala.BinaryOperator.GREATER_THAN:
+			signature.append ("> ");
+			break;
+
+		case Vala.BinaryOperator.LESS_THAN_OR_EQUAL:
+			signature.append ("<= ");
+			break;
+
+		case Vala.BinaryOperator.GREATER_THAN_OR_EQUAL:
+			signature.append (">= ");
+			break;
+
+		case Vala.BinaryOperator.EQUALITY:
+			signature.append ("== ");
+			break;
+
+		case Vala.BinaryOperator.INEQUALITY:
+			signature.append ("!= ");
+			break;
+
+		case Vala.BinaryOperator.BITWISE_AND:
+			signature.append ("& ");
+			break;
+
+		case Vala.BinaryOperator.BITWISE_OR:
+			signature.append ("| ");
+			break;
+
+		case Vala.BinaryOperator.BITWISE_XOR:
+			signature.append ("^ ");
+			break;
+
+		case Vala.BinaryOperator.AND:
+			signature.append ("&& ");
+			break;
+
+		case Vala.BinaryOperator.OR:
+			signature.append ("|| ");
+			break;
+
+		case Vala.BinaryOperator.IN:
+			signature.append_keyword ("in");
+			signature.append (" ");
+			break;
+
+		case Vala.BinaryOperator.COALESCE:
+			signature.append ("?? ");
+			break;
+
+		default:
+			assert_not_reached ();
+		}
+
+		expr.right.accept (this);
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_unary_expression (Vala.UnaryExpression expr) {
+		switch (expr.operator) {
+		case Vala.UnaryOperator.PLUS:
+			signature.append ("+");
+			break;
+
+		case Vala.UnaryOperator.MINUS:
+			signature.append ("-");
+			break;
+
+		case Vala.UnaryOperator.LOGICAL_NEGATION:
+			signature.append ("!");
+			break;
+
+		case Vala.UnaryOperator.BITWISE_COMPLEMENT:
+			signature.append ("~");
+			break;
+
+		case Vala.UnaryOperator.INCREMENT:
+			signature.append ("++");
+			break;
+
+		case Vala.UnaryOperator.DECREMENT:
+			signature.append ("--");
+			break;
+
+		case Vala.UnaryOperator.REF:
+			signature.append_keyword ("ref");
+			break;
+
+		case Vala.UnaryOperator.OUT:
+			signature.append_keyword ("out");
+			break;
+
+		default:
+			assert_not_reached ();
+		}
+		expr.inner.accept (this);
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_assignment (Vala.Assignment a) {
+		a.left.accept (this);
+
+		switch (a.operator) {
+		case Vala.AssignmentOperator.SIMPLE:
+			signature.append ("=");
+			break;
+
+		case Vala.AssignmentOperator.BITWISE_OR:
+			signature.append ("|");
+			break;
+
+		case Vala.AssignmentOperator.BITWISE_AND:
+			signature.append ("&");
+			break;
+
+		case Vala.AssignmentOperator.BITWISE_XOR:
+			signature.append ("^");
+			break;
+
+		case Vala.AssignmentOperator.ADD:
+			signature.append ("+");
+			break;
+
+		case Vala.AssignmentOperator.SUB:
+			signature.append ("-");
+			break;
+
+		case Vala.AssignmentOperator.MUL:
+			signature.append ("*");
+			break;
+
+		case Vala.AssignmentOperator.DIV:
+			signature.append ("/");
+			break;
+
+		case Vala.AssignmentOperator.PERCENT:
+			signature.append ("%");
+			break;
+
+		case Vala.AssignmentOperator.SHIFT_LEFT:
+			signature.append ("<<");
+			break;
+
+		case Vala.AssignmentOperator.SHIFT_RIGHT:
+			signature.append (">>");
+			break;
+
+		default:
+			assert_not_reached ();
+		}
+
+		a.right.accept (this);
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_cast_expression (Vala.CastExpression expr) {
+		if (expr.is_non_null_cast) {
+			signature.append ("(!)");
+			expr.inner.accept (this);
+			return;
+		}
+
+		if (!expr.is_silent_cast) {
+			signature.append ("(", false);
+			write_type (expr.type_reference);
+			signature.append (")", false);
+		}
+
+		expr.inner.accept (this);
+
+		if (expr.is_silent_cast) {
+			signature.append_keyword ("as");
+			write_type (expr.type_reference);
+		}
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_initializer_list (Vala.InitializerList list) {
+		signature.append ("{", false);
+
+		bool first = true;
+		foreach (Vala.Expression initializer in list.get_initializers ()) {
+			if (!first) {
+				signature.append (", ", false);
+			}
+			first = false;
+			initializer.accept (this);
+		}
+
+		signature.append ("}", false);
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_member_access (Vala.MemberAccess expr) {
+		if (expr.symbol_reference != null) {
+			expr.symbol_reference.accept (this);
+		} else {
+			signature.append (expr.member_name);
+		}
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_element_access (Vala.ElementAccess expr) {
+		expr.container.accept (this);
+		signature.append ("[", false);
+
+		bool first = true;
+		foreach (Vala.Expression index in expr.get_indices ()) {
+			if (!first) {
+				signature.append (", ", false);
+			}
+			first = false;
+
+			index.accept (this);
+		}
+
+		signature.append ("]", false);
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_pointer_indirection (Vala.PointerIndirection expr) {
+		signature.append ("*", false);
+		expr.inner.accept (this);
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_addressof_expression (Vala.AddressofExpression expr) {
+		signature.append ("&", false);
+		expr.inner.accept (this);
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_reference_transfer_expression (Vala.ReferenceTransferExpression expr) {
+		signature.append ("(", false).append_keyword ("owned", false).append (")", false);
+		expr.inner.accept (this);
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_type_check (Vala.TypeCheck expr) {
+		expr.expression.accept (this);
+		signature.append_keyword ("is");
+		write_type (expr.type_reference);
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_method_call (Vala.MethodCall expr) {
+		// symbol-name:
+		expr.call.symbol_reference.accept (this);
+
+		// parameters:
+		signature.append (" (", false);
+		bool first = true;
+		foreach (Vala.Expression literal in expr.get_argument_list ()) {
+			if (!first) {
+				signature.append (", ", false);
+			}
+
+			literal.accept (this);
+			first = false;
+		}
+		signature.append (")", false);
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_slice_expression (Vala.SliceExpression expr) {
+		expr.container.accept (this);
+		signature.append ("[", false);
+		expr.start.accept (this);
+		signature.append (":", false);
+		expr.stop.accept (this);
+		signature.append ("]", false);
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_base_access (Vala.BaseAccess expr) {
+		signature.append_keyword ("base", false);
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_postfix_expression (Vala.PostfixExpression expr) {
+		expr.inner.accept (this);
+		if (expr.increment) {
+			signature.append ("++", false);
+		} else {
+			signature.append ("--", false);
+		}
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_object_creation_expression (Vala.ObjectCreationExpression expr) {
+		if (!expr.struct_creation) {
+			signature.append_keyword ("new");
+		}
+
+		signature.append_symbol (resolve (expr.symbol_reference));
+
+		signature.append (" (", false);
+
+		//TODO: rm conditional space
+		bool first = true;
+		foreach (Vala.Expression arg in expr.get_argument_list ()) {
+			if (!first) {
+				signature.append (", ", false);
+			}
+			arg.accept (this);
+			first = false;
+		}
+
+		signature.append (")", false);
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_sizeof_expression (Vala.SizeofExpression expr) {
+		signature.append_keyword ("sizeof", false).append (" (", false);
+		write_type (expr.type_reference);
+		signature.append (")", false);
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_typeof_expression (Vala.TypeofExpression expr) {
+		signature.append_keyword ("typeof", false).append (" (", false);
+		write_type (expr.type_reference);
+		signature.append (")", false);
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_lambda_expression (Vala.LambdaExpression expr) {
+		signature.append ("(", false);
+
+		bool first = true;
+		foreach (string param in expr.get_parameters ()) {
+			if (!first) {
+				signature.append (", ", false);
+			}
+			signature.append (param, false);
+			first = false;
+		}
+
+
+		signature.append (") => {", false);
+		signature.append_highlighted (" [...] ", false);
+		signature.append ("}", false);
+	}
+
+
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_boolean_literal (Vala.BooleanLiteral lit) {
+		signature.append_literal (lit.to_string (), false);
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_character_literal (Vala.CharacterLiteral lit) {
+		signature.append_literal (lit.to_string (), false);
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_integer_literal (Vala.IntegerLiteral lit) {
+		signature.append_literal (lit.to_string (), false);
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_real_literal (Vala.RealLiteral lit) {
+		signature.append_literal (lit.to_string (), false);
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_regex_literal (Vala.RegexLiteral lit) {
+		signature.append_literal (lit.to_string (), false);
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_string_literal (Vala.StringLiteral lit) {
+		signature.append_literal (lit.to_string (), false);
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_list_literal (Vala.ListLiteral lit) {
+		signature.append_literal (lit.to_string (), false);
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_null_literal (Vala.NullLiteral lit) {
+		signature.append_literal (lit.to_string (), false);
+	}
+
+
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_field (Vala.Field field) {
+		write_node (field);
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_constant (Vala.Constant constant) {
+		write_node (constant);
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_enum_value (Vala.EnumValue ev) {
+		write_node (ev);
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_error_code (Vala.ErrorCode ec) {
+		write_node (ec);
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_delegate (Vala.Delegate d) {
+		write_node (d);
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_method (Vala.Method m) {
+		write_node (m);
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_creation_method (Vala.CreationMethod m) {
+		write_node (m);
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_signal (Vala.Signal sig) {
+		write_node (sig);
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_class (Vala.Class c) {
+		write_node (c);
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_struct (Vala.Struct s) {
+		write_node (s);
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_interface (Vala.Interface i) {
+		write_node (i);
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_enum (Vala.Enum en) {
+		write_node (en);
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_error_domain (Vala.ErrorDomain ed) {
+		write_node (ed);
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_property (Vala.Property prop) {
+		write_node (prop);
+	}
+}
+
diff --git a/src/driver/0.10.x/symbolresolver.vala b/src/driver/0.10.x/symbolresolver.vala
new file mode 100644
index 0000000..ad63aea
--- /dev/null
+++ b/src/driver/0.10.x/symbolresolver.vala
@@ -0,0 +1,309 @@
+/* symbolresolver.vala
+ *
+ * Copyright (C) 2011  Florian Brosch
+ *
+ * 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:
+ * 	Florian Brosch <flo brosch gmail com>
+ */
+
+using Valadoc.Api;
+using Gee;
+
+
+public class Valadoc.Drivers.SymbolResolver : Visitor {
+	private HashMap<Vala.Symbol, Symbol> symbol_map;
+	private Valadoc.Api.Class glib_error;
+	private Api.Tree root;
+
+	public SymbolResolver (TreeBuilder builder) {
+		this.symbol_map = builder.get_symbol_map ();
+		this.glib_error = builder.get_glib_error ();
+	}
+
+	private Symbol? resolve (Vala.Symbol symbol) {
+		return symbol_map.get (symbol);
+	}
+
+	private void resolve_array_type_references (Api.Array ptr) {
+		Api.Item data_type = ptr.data_type;
+		if (data_type == null) {
+			// void
+		} else if (data_type is Api.Array) {
+			resolve_array_type_references ((Api.Array) data_type);
+		} else if (data_type is Pointer) {
+			resolve_pointer_type_references ((Api.Pointer) data_type);
+		} else {
+			resolve_type_reference ((TypeReference) data_type);
+		}
+	}
+
+	private void resolve_pointer_type_references (Pointer ptr) {
+		Api.Item type = ptr.data_type;
+		if (type == null) {
+			// void
+		} else if (type is Api.Array) {
+			resolve_array_type_references ((Api.Array) type);
+		} else if (type is Pointer) {
+			resolve_pointer_type_references ((Pointer) type);
+		} else {
+			resolve_type_reference ((TypeReference) type);
+		}
+	}
+
+	private void resolve_type_reference (TypeReference reference) {
+		Vala.DataType vtyperef = (Vala.DataType) reference.data;
+		if (vtyperef is Vala.GenericType) {
+			 reference.data_type = resolve (((Vala.GenericType) vtyperef).type_parameter);
+		} else if (vtyperef is Vala.ErrorType) {
+			Vala.ErrorDomain verrdom = ((Vala.ErrorType) vtyperef).error_domain;
+			if (verrdom != null) {
+				reference.data_type = resolve (verrdom);
+			} else {
+				reference.data_type = glib_error;
+			}
+		} else if (vtyperef is Vala.DelegateType) {
+			reference.data_type = resolve (((Vala.DelegateType) vtyperef).delegate_symbol);
+		} else if (vtyperef.data_type != null) {
+			reference.data_type = resolve (vtyperef.data_type);
+		}
+
+		// Type parameters:
+		foreach (TypeReference type_param_ref in reference.get_type_arguments ()) {
+			resolve_type_reference (type_param_ref);
+		}
+
+		if (reference.data_type is Pointer) {
+			resolve_pointer_type_references ((Pointer)reference.data_type);
+		} else if (reference.data_type is Api.Array) {
+			resolve_array_type_references ((Api.Array)reference.data_type);
+		}
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_tree (Api.Tree item) {
+		this.root = item;
+		item.accept_children (this);
+		this.root = null;
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_package (Package item) {
+		item.accept_all_children (this, false);
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_namespace (Namespace item) {
+		item.accept_all_children (this, false);
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_interface (Interface item) {
+		Collection<TypeReference> interfaces = item.get_implemented_interface_list ();
+		foreach (var type_ref in interfaces) {
+			resolve_type_reference (type_ref);
+		}
+
+		if (item.base_type != null) {
+			resolve_type_reference (item.base_type);
+		}
+
+		item.accept_all_children (this, false);
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_class (Class item) {
+		Collection<TypeReference> interfaces = item.get_implemented_interface_list ();
+		foreach (TypeReference type_ref in interfaces) {
+			resolve_type_reference (type_ref);
+		}
+
+		if (item.base_type != null)	{
+			resolve_type_reference (item.base_type);
+		}
+
+		item.accept_all_children (this, false);
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_struct (Struct item) {
+		if (item.base_type != null) {
+			resolve_type_reference (item.base_type);
+		}
+
+		item.accept_all_children (this, false);
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_property (Property item) {
+		Vala.Property vala_property = item.data as Vala.Property;
+		Vala.Property? base_vala_property = null;
+
+		if (vala_property.base_property != null) {
+			base_vala_property = vala_property.base_property;
+		} else if (vala_property.base_interface_property != null) {
+			base_vala_property = vala_property.base_interface_property;
+		}
+		if (base_vala_property == vala_property && vala_property.base_interface_property != null) {
+			base_vala_property = vala_property.base_interface_property;
+		}
+		if (base_vala_property != null) {
+			item.base_property = (Property?) resolve (base_vala_property);
+		}
+
+		resolve_type_reference (item.property_type);
+		
+		item.accept_all_children (this, false);
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_field (Field item) {
+		resolve_type_reference (item.field_type);
+
+		item.accept_all_children (this, false);
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_constant (Constant item) {
+		resolve_type_reference (item.constant_type);
+
+		item.accept_all_children (this, false);
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_delegate (Delegate item) {
+		resolve_type_reference (item.return_type);
+
+		item.accept_all_children (this, false);
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_signal (Api.Signal item) {
+		resolve_type_reference (item.return_type);
+
+		item.accept_all_children (this, false);
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_method (Method item) {
+		Vala.Method vala_method = item.data as Vala.Method;
+		Vala.Method? base_vala_method = null;
+		if (vala_method.base_method != null) {
+			base_vala_method = vala_method.base_method;
+		} else if (vala_method.base_interface_method != null) {
+			base_vala_method = vala_method.base_interface_method;
+		}
+		if (base_vala_method == vala_method && vala_method.base_interface_method != null) {
+			base_vala_method = vala_method.base_interface_method;
+		}
+		if (base_vala_method != null) {
+			item.base_method = (Method?) resolve (base_vala_method);
+		}
+
+		resolve_type_reference (item.return_type);
+
+		item.accept_all_children (this, false);
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_type_parameter (TypeParameter item) {
+		item.accept_all_children (this, false);
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_formal_parameter (FormalParameter item) {
+		if (item.ellipsis) {
+			return;
+		}
+
+		if (((Vala.FormalParameter) item.data).initializer != null) {
+			SignatureBuilder signature = new SignatureBuilder ();
+			InitializerBuilder ibuilder = new InitializerBuilder (signature, symbol_map);
+			((Vala.FormalParameter) item.data).initializer.accept (ibuilder);
+			item.default_value = signature.get ();
+		}
+
+		resolve_type_reference (item.parameter_type);
+		item.accept_all_children (this, false);
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_error_domain (ErrorDomain item) {
+		item.accept_all_children (this, false);
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_error_code (ErrorCode item) {
+		item.accept_all_children (this, false);
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_enum (Api.Enum item) {
+		item.accept_all_children (this, false);
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_enum_value (Api.EnumValue item) {
+
+		if (((Vala.EnumValue) item.data).value != null) {
+			SignatureBuilder signature = new SignatureBuilder ();
+			InitializerBuilder ibuilder = new InitializerBuilder (signature, symbol_map);
+			((Vala.EnumValue) item.data).value.accept (ibuilder);
+			item.default_value = signature.get ();
+		}
+
+		item.accept_all_children (this, false);
+	}
+}
+
+
+
diff --git a/src/driver/0.10.x/treebuilder.vala b/src/driver/0.10.x/treebuilder.vala
new file mode 100644
index 0000000..9150c7e
--- /dev/null
+++ b/src/driver/0.10.x/treebuilder.vala
@@ -0,0 +1,1029 @@
+/* treebuilder.vala
+ *
+ * Copyright (C) 2011  Florian Brosch
+ *
+ * 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:
+ * 	Florian Brosch <flo brosch gmail com>
+ */
+
+
+using Valadoc.Api;
+using Gee;
+
+
+/**
+ * Creates an simpler, minimized, more abstract AST for valacs AST.
+ */
+public class Valadoc.Drivers.TreeBuilder : Vala.CodeVisitor {
+	private ArrayList<PackageMetaData> packages = new ArrayList<PackageMetaData> ();
+	private PackageMetaData source_package;
+
+	private HashMap<Vala.SourceFile, SourceFile> files = new HashMap<Vala.SourceFile, SourceFile> ();
+	private HashMap<Vala.Symbol, Symbol> symbol_map = new HashMap<Vala.Symbol, Symbol> ();
+
+	private ErrorReporter reporter;
+	private Settings settings;
+
+	private Api.Node current_node;
+	private Api.Tree tree;
+
+	private Valadoc.Api.Class glib_error = null;
+
+
+	//
+	// Accessors
+	//
+
+	public Api.Class get_glib_error () {
+		return glib_error;
+	}
+
+	public HashMap<Vala.Symbol, Symbol> get_symbol_map () {
+		return symbol_map;
+	}
+
+
+	//
+	//
+	//
+
+	private class PackageMetaData {
+		public Package package;
+		public HashMap<Vala.Namespace, Namespace> namespaces = new HashMap<Vala.Namespace, Namespace> ();
+		public ArrayList<Vala.SourceFile> files = new ArrayList<Vala.SourceFile> ();
+
+		public PackageMetaData (Package package) {
+			this.package = package;
+		}
+
+		public Namespace get_namespace (Vala.Namespace vns, SourceFile? file) {
+			Namespace? ns = namespaces.get (vns);
+			if (ns != null) {
+				return ns;
+			}
+
+			// find documentation comment if existing:
+			SourceComment? comment = null;
+			if (vns.source_reference != null) {
+				foreach (Vala.Comment c in vns.get_comments()) {
+					if (c.source_reference.file == vns.source_reference.file) {
+						Vala.SourceReference pos = c.source_reference;
+						comment = new SourceComment (c.content, file, pos.first_line, pos.first_column, pos.last_line, pos.last_column);
+						break;
+					}
+				}
+			}
+
+			// find parent if existing
+			var parent_vns = vns.parent_symbol;
+
+			if (parent_vns == null) {
+				ns = new Namespace (package, file, vns.name, comment, vns);
+				package.add_child (ns);
+			} else {
+				Namespace parent_ns = get_namespace ((Vala.Namespace) parent_vns, file);
+				ns = new Namespace (parent_ns, file, vns.name, comment, vns);
+				parent_ns.add_child (ns);
+			}
+
+			namespaces.set (vns, ns);
+			return ns;
+		}
+
+		public void register_source_file (Vala.SourceFile file) {
+			files.add (file);
+		}
+
+		public bool is_package_for_file (Vala.SourceFile source_file) {
+			if (!source_file.external_package && !package.is_package) {
+				return true;
+			}
+
+			return files.contains (source_file);
+		}
+	}
+
+
+	//
+	// Type constructor translation helpers:
+	//
+
+	private Pointer create_pointer (Vala.PointerType vtyperef, Item parent) {
+		Pointer ptr = new Pointer (parent, vtyperef);
+
+		Vala.DataType vntype = vtyperef.base_type;
+		if (vntype is Vala.PointerType) {
+			ptr.data_type = create_pointer ((Vala.PointerType) vntype, ptr);
+		} else if (vntype is Vala.ArrayType) {
+			ptr.data_type = create_array ((Vala.ArrayType) vntype, ptr);
+		} else {
+			ptr.data_type = create_type_reference (vntype, ptr);
+		}
+
+		return ptr;
+	}
+
+	private Api.Array create_array (Vala.ArrayType vtyperef, Item parent) {
+		Api.Array arr = new Api.Array (parent, vtyperef);
+
+		Vala.DataType vntype = vtyperef.element_type;
+		if (vntype is Vala.ArrayType) {
+			arr.data_type = create_array ((Vala.ArrayType) vntype, arr);
+		} else {
+			arr.data_type = create_type_reference (vntype, arr);
+		}
+
+		return arr;
+	}
+
+	private TypeReference create_type_reference (Vala.DataType? vtyperef, Item parent) {
+		bool is_nullable = vtyperef != null && vtyperef.nullable && !(vtyperef is Vala.GenericType) && !(vtyperef is Vala.PointerType);
+		string? signature = (vtyperef != null && vtyperef.data_type != null)? Vala.GVariantModule.get_dbus_signature (vtyperef.data_type) : null;
+		bool pass_ownership = type_reference_pass_ownership (vtyperef);
+		Ownership ownership = get_type_reference_ownership (vtyperef);
+		bool is_dynamic = vtyperef != null && vtyperef.is_dynamic;
+
+		TypeReference type_ref = new TypeReference (parent, ownership, pass_ownership, is_dynamic, is_nullable, signature, vtyperef);
+
+		if (vtyperef is Vala.PointerType) {
+			type_ref.data_type = create_pointer ((Vala.PointerType) vtyperef,  type_ref);
+		} else if (vtyperef is Vala.ArrayType) {
+			type_ref.data_type = create_array ((Vala.ArrayType) vtyperef,  type_ref);
+		}
+
+		// type parameters:
+		if (vtyperef != null) {
+			foreach (Vala.DataType vdtype in vtyperef.get_type_arguments ()) {
+				var type_param = create_type_reference (vdtype, type_ref);
+				type_ref.add_type_argument (type_param);
+			}
+		}
+
+		return type_ref;
+	}
+
+
+
+	//
+	// Translation helpers:
+	//
+
+	private SourceComment? create_comment (Vala.Comment? comment) {
+		if (comment != null) {
+			Vala.SourceReference pos = comment.source_reference;
+			SourceFile file = files.get (pos.file);
+			return new SourceComment (comment.content, file, pos.first_line, pos.first_column, pos.last_line, pos.last_column);
+		}
+
+		return null;
+	}
+
+	private string get_method_name (Vala.Method element) {
+		if (element is Vala.CreationMethod) {
+			if (element.name == ".new") {
+				return element.parent_symbol.name;
+			} else {
+				return element.parent_symbol.name + "." + element.name;
+			}
+		}
+
+		return element.name;
+	}
+
+	private PackageMetaData? get_package_meta_data (Package pkg) {
+		foreach (PackageMetaData data in packages) {
+			if (data.package == pkg) {
+				return data;
+			}
+		}
+
+		return null;
+	}
+
+	private PackageMetaData register_package (Package package) {
+		PackageMetaData meta_data = new PackageMetaData (package);
+		tree.add_package (package);
+		packages.add (meta_data);
+		return meta_data;
+	}
+
+	private SourceFile register_source_file (PackageMetaData meta_data, Vala.SourceFile source_file) {
+		SourceFile file = new SourceFile (source_file.get_relative_filename (), source_file.get_csource_filename ());
+		files.set (source_file, file);
+
+		meta_data.register_source_file (source_file);
+		return file;
+	}
+
+	private SourceFile? get_source_file (Vala.Symbol symbol) {
+		Vala.SourceReference source_ref = symbol.source_reference;
+		if (source_ref == null) {
+			return null;
+		}
+
+		SourceFile file = files.get (source_ref.file);
+		assert (file != null);
+		return file;
+	}
+
+	private Package? find_package_for_file (Vala.SourceFile source_file) {
+		foreach (PackageMetaData pkg in this.packages) {
+			if (pkg.is_package_for_file (source_file)) {
+				return pkg.package;
+			}
+		}
+
+		return null;
+	}
+
+
+	private Namespace get_namespace (Package pkg, Vala.Symbol symbol, SourceFile? file) {
+		// Find the closest namespace in our vala-tree
+		Vala.Symbol namespace_symbol = symbol;
+		while (!(namespace_symbol is Vala.Namespace)) {
+			namespace_symbol = namespace_symbol.parent_symbol;
+		}
+
+		PackageMetaData? meta_data = get_package_meta_data (pkg);
+		assert (meta_data != null);
+
+		return meta_data.get_namespace ((Vala.Namespace) namespace_symbol, file);
+	}
+
+	private MethodBindingType get_method_binding_type (Vala.Method element) {
+		if (element.is_inline) {
+			return MethodBindingType.INLINE;
+		} else if (element.is_abstract) {
+			return MethodBindingType.ABSTRACT;
+		} else if (element.is_virtual) {
+			return MethodBindingType.VIRTUAL;
+		} else if (element.overrides) {
+			return MethodBindingType.OVERRIDE;
+		} else if (element.is_inline) {
+			return MethodBindingType.INLINE;
+		} else if (element.binding == MemberBinding.INSTANCE) {
+			return MethodBindingType.STATIC;
+		}
+		return MethodBindingType.UNMODIFIED;
+	}
+
+
+	private SymbolAccessibility get_access_modifier(Vala.Symbol symbol) {
+		switch (symbol.access) {
+		case Vala.SymbolAccessibility.PROTECTED:
+			return SymbolAccessibility.PROTECTED;
+
+		case Vala.SymbolAccessibility.INTERNAL:
+			return SymbolAccessibility.INTERNAL;
+
+		case Vala.SymbolAccessibility.PRIVATE:
+			return SymbolAccessibility.PRIVATE;
+
+		case Vala.SymbolAccessibility.PUBLIC:
+			return SymbolAccessibility.PUBLIC;
+
+		default:
+			error ("Unknown symbol accessibility modifier found");
+		}
+	}
+
+	private PropertyAccessorType get_property_accessor_type (Vala.PropertyAccessor element) {
+		if (element.construction) {
+			return PropertyAccessorType.CONSTRUCT;
+		} else if (element.writable) {
+			return PropertyAccessorType.SET;
+		} else if (element.readable) {
+			return PropertyAccessorType.GET;
+		}
+
+		error ("Unknown symbol accessibility type");
+	}
+
+	private bool type_reference_pass_ownership (Vala.DataType? element) {
+		if (element == null) {
+			return false;
+		}
+
+		Vala.CodeNode? node = element.parent_node;
+		if (node == null) {
+			return false;
+		}
+		if (node is Vala.FormalParameter) {
+			return (((Vala.FormalParameter)node).direction == Vala.ParameterDirection.IN &&
+				((Vala.FormalParameter)node).variable_type.value_owned);
+		}
+		if (node is Vala.Property) {
+			return ((Vala.Property)node).property_type.value_owned;
+		}
+
+		return false;
+	}
+
+	private bool is_type_reference_unowned (Vala.DataType? element) {
+			if (element == null) {
+				return false;
+			}
+
+			// non ref counted types are weak, not unowned
+			if (element.data_type is Vala.TypeSymbol && ((Vala.TypeSymbol) element.data_type).is_reference_counting () == true) {
+				return false;
+			}
+
+			// FormalParameters are weak by default
+			return (element.parent_node is Vala.FormalParameter == false)? element.is_weak () : false;
+	}
+
+	private bool is_type_reference_owned (Vala.DataType? element) {
+		if (element == null) {
+			return false;
+		}
+
+		Vala.CodeNode parent = element.parent_node;
+
+		// parameter:
+		if (parent is Vala.FormalParameter) {
+			if (((Vala.FormalParameter)parent).direction != Vala.ParameterDirection.IN) {
+				return false;
+			}
+			return ((Vala.FormalParameter)parent).variable_type.value_owned;
+		}
+
+		return false;
+	}
+
+	private bool is_type_reference_weak (Vala.DataType? element) {
+		if (element == null) {
+			return false;
+		}
+
+		// non ref counted types are unowned, not weak
+		if (element.data_type is Vala.TypeSymbol && ((Vala.TypeSymbol) element.data_type).is_reference_counting () == false) {
+			return false;
+		}
+
+		// FormalParameters are weak by default
+		return (element.parent_node is Vala.FormalParameter == false)? element.is_weak () : false;
+	}
+
+	private Ownership get_type_reference_ownership (Vala.DataType? element) {
+		if (is_type_reference_owned (element)) {
+			return Ownership.OWNED;
+		} else if (is_type_reference_weak (element)) {
+			return Ownership.WEAK;
+		} else if (is_type_reference_unowned (element)) {
+			return Ownership.UNOWNED;
+		}
+
+		return Ownership.DEFAULT;
+	}
+
+	private Ownership get_property_ownership (Vala.PropertyAccessor element) {
+		if (element.value_type.value_owned) {
+			return Ownership.OWNED;
+		}
+
+		// the exact type (weak, unowned) does not matter
+		return Ownership.UNOWNED;
+	}
+
+	private PropertyBindingType get_property_binding_type (Vala.Property element) {
+		if (element.is_abstract) {
+			return PropertyBindingType.ABSTRACT;
+		} else if (element.is_virtual) {
+			return PropertyBindingType.VIRTUAL;
+		} else if (element.overrides) {
+			return PropertyBindingType.OVERRIDE;
+		}
+
+		return PropertyBindingType.UNMODIFIED;
+	}
+
+	private FormalParameterType get_formal_parameter_type (Vala.FormalParameter element) {
+		if (element.direction == Vala.ParameterDirection.OUT) {
+			return FormalParameterType.OUT;
+		} else if (element.direction == Vala.ParameterDirection.REF) {
+			return FormalParameterType.REF;
+		} else if (element.direction == Vala.ParameterDirection.IN) {
+			return FormalParameterType.IN;
+		}
+
+		error ("Unknown formal parameter type");
+	}
+
+
+	//
+	// Vala tree creation:
+	//
+
+	private bool add_package (Vala.CodeContext context, string pkg) {
+		if (context.has_package (pkg)) {
+			// ignore multiple occurences of the same package
+			return true;
+		}
+
+
+		var package_path = context.get_package_path (pkg, settings.vapi_directories) ?? context.get_gir_path (pkg, settings.vapi_directories);
+		if (package_path == null) {
+			Vala.Report.error (null, "Package `%s' not found in specified Vala API directories or GObject-Introspection GIR directories".printf (pkg));
+			return false;
+		}
+
+		context.add_package (pkg);
+
+		var vfile = new Vala.SourceFile (context, package_path, true);
+		context.add_source_file (vfile);
+		Package vdpkg = new Package (pkg, true, null);
+		register_source_file (register_package (vdpkg), vfile);
+
+		add_deps (context, Path.build_filename (Path.get_dirname (package_path), "%s.deps".printf (pkg)), pkg);
+		return true;
+	}
+
+	private void add_deps (Vala.CodeContext context, string file_path, string pkg_name) {
+		if (FileUtils.test (file_path, FileTest.EXISTS)) {
+			try {
+				string deps_content;
+				ulong deps_len;
+				FileUtils.get_contents (file_path, out deps_content, out deps_len);
+				foreach (string dep in deps_content.split ("\n")) {
+					dep.strip ();
+					if (dep != "") {
+						if (!add_package (context, dep)) {
+							Vala.Report.error (null, "%s, dependency of %s, not found in specified Vala API directories".printf (dep, pkg_name));
+						}
+					}
+				}
+			} catch (FileError e) {
+				Vala.Report.error (null, "Unable to read dependency file: %s".printf (e.message));
+			}
+		}
+	}
+
+	/**
+	 * Adds the specified packages to the list of used packages.
+	 *
+	 * @param context The code context
+	 * @param packages a list of package names
+	 */
+	private void add_depencies (Vala.CodeContext context, string[] packages) {
+		foreach (string package in packages) {
+			if (!add_package (context, package)) {
+				Vala.Report.error (null, "Package `%s' not found in specified Vala API directories or GObject-Introspection GIR directories".printf (package));
+			}
+		}
+	}
+
+	/**
+	 * Add the specified source file to the context. Only .vala, .vapi, .gs,
+	 * and .c files are supported.
+	 */
+	private void add_documented_files (Vala.CodeContext context, string[] sources) {
+		if (sources == null) {
+			return;
+		}
+
+		foreach (string source in sources) {
+			if (FileUtils.test (source, FileTest.EXISTS)) {
+				var rpath = realpath (source);
+				if (source.has_suffix (".vala") || source.has_suffix (".gs")) {
+					var source_file = new Vala.SourceFile (context, rpath);
+
+					if (source_package == null) {
+						source_package = register_package (new Package (settings.pkg_name, false, null));
+					}
+
+					register_source_file (source_package, source_file);
+
+					if (context.profile == Vala.Profile.POSIX) {
+						// import the Posix namespace by default (namespace of backend-specific standard library)
+						var ns_ref = new Vala.UsingDirective (new Vala.UnresolvedSymbol (null, "Posix", null));
+						source_file.add_using_directive (ns_ref);
+						context.root.add_using_directive (ns_ref);
+					} else if (context.profile == Vala.Profile.GOBJECT) {
+						// import the GLib namespace by default (namespace of backend-specific standard library)
+						var ns_ref = new Vala.UsingDirective (new Vala.UnresolvedSymbol (null, "GLib", null));
+						source_file.add_using_directive (ns_ref);
+						context.root.add_using_directive (ns_ref);
+					}
+
+					context.add_source_file (source_file);
+				} else if (source.has_suffix (".vapi")) {
+					string file_name = Path.get_basename (source);
+					file_name = file_name.substring (0, file_name.length - ".vapi".length);
+
+					var vfile = new Vala.SourceFile (context, rpath, true);
+					context.add_source_file (vfile);
+
+					if (source_package == null) {
+						source_package = register_package (new Package (settings.pkg_name, false, null));
+					}
+
+					register_source_file (source_package, vfile);
+
+
+					add_deps (context, Path.build_filename (Path.get_dirname (source), "%s.deps".printf (file_name)), file_name);
+				} else if (source.has_suffix (".c")) {
+					context.add_c_source_file (rpath);
+					tree.add_external_c_files (rpath);
+				} else {
+					Vala.Report.error (null, "%s is not a supported source file type. Only .vala, .vapi, .gs, and .c files are supported.".printf (source));
+				}
+			} else {
+				Vala.Report.error (null, "%s not found".printf (source));
+			}
+		}
+	}
+
+	private Vala.CodeContext create_valac_tree (Settings settings) {
+		// init context:
+		var context = new Vala.CodeContext ();
+		Vala.CodeContext.push (context);
+
+
+		// settings:
+		context.experimental = settings.experimental;
+		context.experimental_non_null = settings.experimental || settings.experimental_non_null;
+		context.report.enable_warnings = settings.verbose;
+
+		if (settings.basedir == null) {
+			context.basedir = realpath (".");
+		} else {
+			context.basedir = realpath (settings.basedir);
+		}
+
+		if (settings.directory != null) {
+			context.directory = realpath (settings.directory);
+		} else {
+			context.directory = context.basedir;
+		}
+
+
+		// add default packages:
+		if (settings.profile == "gobject-2.0" || settings.profile == "gobject" || settings.profile == null) {
+			context.profile = Vala.Profile.GOBJECT;
+			context.add_define ("GOBJECT");
+		}
+
+
+		if (settings.defines != null) {
+			foreach (string define in settings.defines) {
+				context.add_define (define);
+			}
+		}
+
+		for (int i = 2; i <= 12; i += 2) {
+			context.add_define ("VALA_0_%d".printf (i));
+		}
+
+		if (context.profile == Vala.Profile.POSIX) {
+			// default package
+			if (!add_package (context, "posix")) {
+				Vala.Report.error (null, "posix not found in specified Vala API directories");
+			}
+		} else if (context.profile == Vala.Profile.GOBJECT) {
+			int glib_major = 2;
+			int glib_minor = 12;
+
+			context.target_glib_major = glib_major;
+			context.target_glib_minor = glib_minor;
+			if (context.target_glib_major != 2) {
+				Vala.Report.error (null, "This version of valac only supports GLib 2");
+			}
+
+			// default packages
+			if (!this.add_package (context, "glib-2.0")) { //
+				Vala.Report.error (null, "glib-2.0 not found in specified Vala API directories");
+			}
+
+			if (!this.add_package (context, "gobject-2.0")) { //
+				Vala.Report.error (null, "gobject-2.0 not found in specified Vala API directories");
+			}
+		}
+
+
+		// add user defined files:
+		add_depencies (context, settings.packages);
+		if (reporter.errors > 0) {
+			return context;
+		}
+
+		add_documented_files (context, settings.source_files);
+		if (reporter.errors > 0) {
+			return context;
+		}
+
+
+		// register modules
+		if (context.profile == Vala.Profile.GOBJECT) {
+			if (context.has_package ("dbus-glib-1")) {
+				context.codegen = new Vala.DBusServerModule ();
+			} else {
+				context.codegen = new Vala.GDBusServerModule ();
+			}
+		} else if (context.profile == Vala.Profile.DOVA) {
+			context.codegen = new Vala.DovaErrorModule ();
+		} else {
+			context.codegen = new Vala.CCodeDelegateModule ();
+		}
+
+
+		// parse vala-code:
+		Vala.Parser parser = new Vala.Parser ();
+
+		parser.parse (context);
+		if (context.report.get_errors () > 0) {
+			return context;
+		}
+
+
+		// check context:
+		var resolver = new Vala.SymbolResolver ();
+		resolver.resolve (context);
+
+		if (context.report.get_errors () > 0) {
+			return context;
+		}
+
+
+		var analyzer = new Vala.SemanticAnalyzer ();
+		analyzer.analyze (context);
+
+		if (context.report.get_errors () > 0) {
+			return context;
+		}
+
+
+		var flow_analyzer = new Vala.FlowAnalyzer ();
+		flow_analyzer.analyze (context);
+
+		if (context.report.get_errors () > 0) {
+			return context;
+		}
+
+
+		return context;
+	}
+
+
+
+	//
+	// Valadoc tree creation:
+	//
+
+	private void process_children (Api.Node node, Vala.Symbol element) {
+		Api.Node old_node = current_node;
+		current_node = node;
+		element.accept_children (this);
+		current_node = old_node;
+	}
+
+	private Api.Node get_parent_node_for (Vala.Symbol element) {
+		if (current_node != null) {
+			return current_node;
+		}
+
+		Vala.SourceFile vala_source_file = element.source_reference.file;
+		Package package = find_package_for_file (vala_source_file);
+		SourceFile? source_file = get_source_file (element);
+
+		return get_namespace (package, element, source_file);
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_namespace (Vala.Namespace element) {
+		element.accept_children (this);
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_class (Vala.Class element) {
+		Api.Node parent = get_parent_node_for (element);
+		SourceFile? file = get_source_file (element);
+		SourceComment? comment = create_comment (element.comment);
+
+		bool is_basic_type = element.base_class == null && element.name == "string";
+
+		Class node = new Class (parent, file, element.name, get_access_modifier(element), comment, element.get_cname (), Vala.GDBusModule.get_dbus_name (element), element.get_param_spec_function (), element.get_type_id (), element.get_ref_function (), element.get_unref_function (), element.get_take_value_function (), element.get_get_value_function (), element.get_set_value_function (), element.is_fundamental (), element.is_abstract, is_basic_type, element);
+		symbol_map.set (element, node);
+		parent.add_child (node);
+
+		// relations
+		foreach (Vala.DataType vala_type_ref in element.get_base_types ()) {
+			var type_ref = create_type_reference (vala_type_ref, node);
+
+			if (vala_type_ref.data_type is Vala.Interface) {
+				node.add_interface (type_ref);
+			} else if (vala_type_ref.data_type is Vala.Class) {
+				node.base_type = type_ref;
+			}
+		}
+
+		process_children (node, element);
+
+		// save GLib.Error
+		if (glib_error == null && node.get_full_name () == "GLib.Error") {
+			glib_error = node;
+		}
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_interface (Vala.Interface element) {
+		Api.Node parent = get_parent_node_for (element);
+		SourceFile? file = get_source_file (element);
+		SourceComment? comment = create_comment (element.comment);
+
+		Interface node = new Interface (parent, file, element.name, get_access_modifier(element), comment, element.get_cname (), Vala.GDBusModule.get_dbus_name (element), element);
+		symbol_map.set (element, node);
+		parent.add_child (node);
+
+		// prerequisites:
+		foreach (Vala.DataType vala_type_ref in element.get_prerequisites ()) {
+			TypeReference type_ref = create_type_reference (vala_type_ref, node);
+			if (vala_type_ref.data_type is Vala.Interface) {
+				node.add_interface (type_ref);
+			} else {
+				node.base_type = type_ref;
+			}
+		}
+
+		process_children (node, element);
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_struct (Vala.Struct element) {
+		Api.Node parent = get_parent_node_for (element);
+		SourceFile? file = get_source_file (element);
+		SourceComment? comment = create_comment (element.comment);
+
+		bool is_basic_type = element.base_type == null && (element.is_boolean_type () || element.is_floating_type () || element.is_integer_type ());
+
+		Struct node = new Struct (parent, file, element.name, get_access_modifier(element), comment, element.get_cname(), element.get_dup_function (), element.get_free_function (), is_basic_type, element);
+		symbol_map.set (element, node);
+		parent.add_child (node);
+
+		// parent type:
+		Vala.ValueType? basetype = element.base_type as Vala.ValueType;
+		if (basetype != null) {
+			node.base_type = create_type_reference (basetype, node);
+		}
+
+		process_children (node, element);
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_field (Vala.Field element) {
+		Api.Node parent = get_parent_node_for (element);
+		SourceFile? file = get_source_file (element);
+		SourceComment? comment = create_comment (element.comment);
+
+		Field node = new Field (parent, file, element.name, get_access_modifier(element), comment, element.get_cname (), element.binding == MemberBinding.STATIC, element.is_volatile, element);
+		node.field_type = create_type_reference (element.variable_type, node);
+		symbol_map.set (element, node);
+		parent.add_child (node);
+
+		process_children (node, element);
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_property (Vala.Property element) {
+		Api.Node parent = get_parent_node_for (element);
+		SourceFile? file = get_source_file (element);
+		SourceComment? comment = create_comment (element.comment);
+
+		Property node = new Property (parent, file, element.name, get_access_modifier(element), comment, element.nick, Vala.GDBusModule.get_dbus_name_for_member (element), Vala.GDBusServerModule.is_dbus_visible (element), get_property_binding_type (element), element);
+		node.property_type = create_type_reference (element.property_type, node);
+		symbol_map.set (element, node);
+		parent.add_child (node);
+
+		// Process property type
+		if (element.get_accessor != null) {
+			var accessor = element.get_accessor;
+			node.getter = new PropertyAccessor (node, file, element.name, get_access_modifier(element), accessor.get_cname(), get_property_accessor_type (accessor), get_property_ownership (accessor), accessor);
+		}
+
+		if (element.set_accessor != null) {
+			var accessor = element.set_accessor;
+			node.setter = new PropertyAccessor (node, file, element.name, get_access_modifier(element), accessor.get_cname(), get_property_accessor_type (accessor), get_property_ownership (accessor), accessor);
+		}
+
+		process_children (node, element);
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_creation_method (Vala.CreationMethod element) {
+		Api.Node parent = get_parent_node_for (element);
+		SourceFile? file = get_source_file (element);
+		SourceComment? comment = create_comment (element.comment);
+
+		Method node = new Method (parent, file, get_method_name (element), get_access_modifier(element), comment, element.get_cname (), Vala.GDBusModule.get_dbus_name_for_member (element), Vala.GDBusServerModule.dbus_result_name (element), (element.coroutine)? element.get_finish_cname () : null, get_method_binding_type (element), element.coroutine, Vala.GDBusServerModule.is_dbus_visible (element), element is Vala.CreationMethod, element);
+		node.return_type = create_type_reference (element.return_type, node);
+		symbol_map.set (element, node);
+		parent.add_child (node);
+
+		process_children (node, element);
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_method (Vala.Method element) {
+		Api.Node parent = get_parent_node_for (element);
+		SourceFile? file = get_source_file (element);
+		SourceComment? comment = create_comment (element.comment);
+
+		Method node = new Method (parent, file, get_method_name (element), get_access_modifier(element), comment, element.get_cname (), Vala.GDBusModule.get_dbus_name_for_member (element), Vala.GDBusServerModule.dbus_result_name (element), (element.coroutine)? element.get_finish_cname () : null, get_method_binding_type (element), element.coroutine, Vala.GDBusServerModule.is_dbus_visible (element), element is Vala.CreationMethod, element);
+		node.return_type = create_type_reference (element.return_type, node);
+		symbol_map.set (element, node);
+		parent.add_child (node);
+
+		process_children (node, element);
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_signal (Vala.Signal element) {
+		Api.Node parent = get_parent_node_for (element);
+		SourceFile? file = get_source_file (element);
+		SourceComment? comment = create_comment (element.comment);
+
+		Api.Signal node = new Api.Signal (parent, file, element.name, get_access_modifier(element), comment, element.get_cname(), Vala.GDBusModule.get_dbus_name_for_member (element), Vala.GDBusServerModule.is_dbus_visible (element), element.is_virtual, element);
+		node.return_type = create_type_reference (element.return_type, node);
+		symbol_map.set (element, node);
+		parent.add_child (node);
+
+		process_children (node, element);
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_delegate (Vala.Delegate element) {
+		Api.Node parent = get_parent_node_for (element);
+		SourceFile? file = get_source_file (element);
+		SourceComment? comment = create_comment (element.comment);
+
+		Delegate node = new Delegate (parent, file, element.name, get_access_modifier(element), comment, element.get_cname (), element.has_target, element);
+		node.return_type = create_type_reference (element.return_type, node);
+		symbol_map.set (element, node);
+		parent.add_child (node);
+
+		process_children (node, element);
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_enum (Vala.Enum element) {
+		Api.Node parent = get_parent_node_for (element);
+		SourceFile? file = get_source_file (element);
+		SourceComment? comment = create_comment (element.comment);
+
+		Symbol node = new Api.Enum (parent, file, element.name, get_access_modifier(element), comment, element.get_cname (), element);
+		symbol_map.set (element, node);
+		parent.add_child (node);
+
+		process_children (node, element);
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_enum_value (Vala.EnumValue element) {
+		Api.Enum parent = (Api.Enum) get_parent_node_for (element);
+		SourceFile? file = get_source_file (element);
+		SourceComment? comment = create_comment (element.comment);
+
+		Symbol node = new Api.EnumValue (parent, file, element.name, comment, element.get_cname (), element);
+		symbol_map.set (element, node);
+		parent.add_child (node);
+
+		process_children (node, element);
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_constant (Vala.Constant element) {
+		Api.Node parent = get_parent_node_for (element);
+		SourceFile? file = get_source_file (element);
+		SourceComment? comment = create_comment (element.comment);
+
+		Constant node = new Constant (parent, file, element.name, get_access_modifier(element), comment, element.get_cname (), element);
+		node.constant_type = create_type_reference (element.type_reference, node);
+		symbol_map.set (element, node);
+		parent.add_child (node);
+
+		process_children (node, element);
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_error_domain (Vala.ErrorDomain element) {
+		Api.Node parent = get_parent_node_for (element);
+		SourceFile? file = get_source_file (element);
+		SourceComment? comment = create_comment (element.comment);
+
+		Symbol node = new ErrorDomain (parent, file, element.name, get_access_modifier(element), comment, element.get_cname(), Vala.GDBusModule.get_dbus_name (element), element);
+		symbol_map.set (element, node);
+		parent.add_child (node);
+
+		process_children (node, element);
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_error_code (Vala.ErrorCode element) {
+		Api.ErrorDomain parent = (ErrorDomain) get_parent_node_for (element);
+		SourceFile? file = get_source_file (element);
+		SourceComment? comment = create_comment (element.comment);
+
+		Symbol node = new Api.ErrorCode (parent, file, element.name, comment, element.get_cname (), Vala.GDBusModule.get_dbus_name_for_member (element), element);
+		symbol_map.set (element, node);
+		parent.add_child (node);
+
+		process_children (node, element);
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_type_parameter (Vala.TypeParameter element) {
+		Api.Node parent = get_parent_node_for (element);
+		SourceFile? file = get_source_file (element);
+
+		Symbol node = new TypeParameter (parent, file, element.name, element);
+		parent.add_child (node);
+
+		process_children (node, element);
+	}
+
+	/**
+	 * { inheritDoc}
+	 */
+	public override void visit_formal_parameter (Vala.FormalParameter element) {
+		Api.Node parent = get_parent_node_for (element);
+		SourceFile? file = get_source_file (element);
+
+		FormalParameter node = new FormalParameter (parent, file, element.name, get_access_modifier(element), get_formal_parameter_type (element), element.ellipsis, element);
+		node.parameter_type = create_type_reference (element.variable_type, node);
+		parent.add_child (node);
+
+		process_children (node, element);
+	}	
+
+
+	//
+	// startpoint:
+	//
+
+	public Api.Tree? build (Settings settings, ErrorReporter reporter) {
+		this.tree = new Api.Tree (reporter, settings);
+		this.settings = settings;
+		this.reporter = reporter;
+
+		var context = create_valac_tree (settings);
+
+		reporter.warnings_offset = context.report.get_warnings ();
+		reporter.errors_offset = context.report.get_errors ();
+
+		if (context == null) {
+			return null;
+		}
+
+		context.accept(this);
+
+		return (reporter.errors == 0)? tree : null;
+	}
+}
+
+
diff --git a/src/driver/Makefile.am b/src/driver/Makefile.am
index 89faeab..50a9981 100755
--- a/src/driver/Makefile.am
+++ b/src/driver/Makefile.am
@@ -2,6 +2,10 @@
 
 NULL =
 
+if HAVE_LIBVALA_0_10_X
+DRIVER_0_10_X_DIR = 0.10.x
+endif
+
 if HAVE_LIBVALA_0_11_0
 DRIVER_0_11_0_DIR = 0.11.0
 endif
@@ -19,6 +23,7 @@ DRIVER_0_13_X_DIR = 0.13.x
 endif
 
 SUBDIRS = \
+	$(DRIVER_0_10_X_DIR) \
 	$(DRIVER_0_11_0_DIR) \
 	$(DRIVER_0_11_X_DIR) \
 	$(DRIVER_0_12_X_DIR) \



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