[valadoc] libvala: Move tree creation out into a plugin



commit 9801f58f964bd87d9e3763fad150e9055e3a08a1
Author: Florian Brosch <flo brosch gmail com>
Date:   Thu Jul 21 03:16:59 2011 +0200

    libvala: Move tree creation out into a plugin

 configure.in                                       |    2 +
 src/Makefile.am                                    |    1 +
 src/doclets/devhelp/Makefile.am                    |    2 +-
 src/doclets/gtkdoc/Makefile.am                     |    2 +-
 src/doclets/htm/Makefile.am                        |    2 +-
 src/driver/0.13.x/Makefile.am                      |   62 ++
 src/driver/0.13.x/driver.vala                      |   52 +
 .../api => driver/0.13.x}/initializerbuilder.vala  |    4 +-
 .../api => driver/0.13.x}/symbolresolver.vala      |   36 +-
 src/driver/0.13.x/treebuilder.vala                 |  988 ++++++++++++++++++++
 src/driver/Makefile.am                             |   10 +
 src/libvaladoc/Makefile.am                         |    2 -
 src/libvaladoc/api/class.vala                      |    4 +-
 src/libvaladoc/api/driver.vala                     |  949 +-------------------
 src/libvaladoc/api/interface.vala                  |    4 +-
 src/libvaladoc/api/node.vala                       |    2 +-
 src/libvaladoc/api/signaturebuilder.vala           |   14 +
 src/libvaladoc/api/tree.vala                       |    5 +-
 src/libvaladoc/moduleloader.vala                   |   34 +-
 src/valadoc/Makefile.am                            |    2 +-
 src/valadoc/valadoc.vala                           |   89 ++-
 21 files changed, 1255 insertions(+), 1011 deletions(-)
---
diff --git a/configure.in b/configure.in
index d823949..2612193 100755
--- a/configure.in
+++ b/configure.in
@@ -64,6 +64,8 @@ AC_CONFIG_FILES([Makefile
                  icons/Makefile
                  doc/Makefile
                  src/libvaladoc/Makefile
+                 src/driver/Makefile
+                 src/driver/0.13.x/Makefile
                  src/doclets/Makefile
                  src/doclets/htm/Makefile
                  src/doclets/devhelp/Makefile
diff --git a/src/Makefile.am b/src/Makefile.am
index f9718b8..fcaf3a5 100755
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -7,6 +7,7 @@ SUBDIRS = \
 	libvaladoc \
 	valadoc \
 	doclets \
+	driver \
 	$(NULL)
 
 
diff --git a/src/doclets/devhelp/Makefile.am b/src/doclets/devhelp/Makefile.am
index 701fc17..af6aa5d 100755
--- a/src/doclets/devhelp/Makefile.am
+++ b/src/doclets/devhelp/Makefile.am
@@ -14,7 +14,7 @@ AM_CFLAGS =  -g \
 BUILT_SOURCES = libdoclet.vala.stamp
 
 
-docletdir = $(libdir)/valadoc/plugins/devhelp
+docletdir = $(libdir)/valadoc/doclets/devhelp
 
 
 libdoclet_la_LDFLAGS = -module -avoid-version -no-undefined
diff --git a/src/doclets/gtkdoc/Makefile.am b/src/doclets/gtkdoc/Makefile.am
index c985357..1f7e159 100755
--- a/src/doclets/gtkdoc/Makefile.am
+++ b/src/doclets/gtkdoc/Makefile.am
@@ -14,7 +14,7 @@ AM_CFLAGS =  -g \
 BUILT_SOURCES = libdoclet.vala.stamp
 
 
-docletdir = $(libdir)/valadoc/plugins/gtkdoc
+docletdir = $(libdir)/valadoc/doclets/gtkdoc
 
 
 libdoclet_la_LDFLAGS = -module -avoid-version -no-undefined
diff --git a/src/doclets/htm/Makefile.am b/src/doclets/htm/Makefile.am
index 12612a2..5af5092 100755
--- a/src/doclets/htm/Makefile.am
+++ b/src/doclets/htm/Makefile.am
@@ -14,7 +14,7 @@ AM_CFLAGS =  -g \
 BUILT_SOURCES = libdoclet.vala.stamp
 
 
-docletdir = $(libdir)/valadoc/plugins/html
+docletdir = $(libdir)/valadoc/doclets/html
 
 
 libdoclet_la_LDFLAGS = -module -avoid-version -no-undefined
diff --git a/src/driver/0.13.x/Makefile.am b/src/driver/0.13.x/Makefile.am
new file mode 100755
index 0000000..986dd79
--- /dev/null
+++ b/src/driver/0.13.x/Makefile.am
@@ -0,0 +1,62 @@
+NULL =
+
+
+AM_CFLAGS =  -g \
+	-DPACKAGE_ICONDIR=\"$(datadir)/valadoc/icons/\" \
+	-I ../../libvaladoc/ \
+	$(GLIB_CFLAGS) \
+	$(LIBGEE_CFLAGS) \
+	$(LIBVALA_CFLAGS) \
+	$(NULL)
+
+
+
+BUILT_SOURCES = libdriver.vala.stamp
+
+
+docletdir = $(libdir)/valadoc/drivers/0.13.x
+
+
+libdriver_la_LDFLAGS = -module -avoid-version -no-undefined
+
+
+doclet_LTLIBRARIES =  \
+	libdriver.la \
+	$(NULL)
+
+
+libdriver_la_VALASOURCES = \
+	initializerbuilder.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_PACKAGE) --pkg gee-1.0 --pkg valadoc-1.0 --basedir . $^
+	touch $@
+
+
+libdriver_la_LIBADD = \
+	../../libvaladoc/libvaladoc.la \
+	$(GLIB_LIBS) \
+	$(LIBVALA_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.13.x/driver.vala b/src/driver/0.13.x/driver.vala
new file mode 100755
index 0000000..d5e8e72
--- /dev/null
+++ b/src/driver/0.13.x/driver.vala
@@ -0,0 +1,52 @@
+/* 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);
+
+		return tree;
+	}
+}
+
+
+[ModuleInit]
+public Type register_plugin (GLib.TypeModule module) {
+	return typeof (Valadoc.Drivers.Driver);
+}
+
diff --git a/src/libvaladoc/api/initializerbuilder.vala b/src/driver/0.13.x/initializerbuilder.vala
similarity index 99%
rename from src/libvaladoc/api/initializerbuilder.vala
rename to src/driver/0.13.x/initializerbuilder.vala
index 3f580e1..70fd1d6 100644
--- a/src/libvaladoc/api/initializerbuilder.vala
+++ b/src/driver/0.13.x/initializerbuilder.vala
@@ -509,11 +509,9 @@ private class Valadoc.Api.InitializerBuilder : Vala.CodeVisitor {
 			first = false;
 		}
 
-		var run = new Run (Run.Style.ITALIC);
-		run.content.add (new Text (" [...] "));
 
 		signature.append (") => {", false);
-		signature.append_content (run, false);
+		signature.append_highlighted (" [...] ", false);
 		signature.append ("}", false);
 	}
 
diff --git a/src/libvaladoc/api/symbolresolver.vala b/src/driver/0.13.x/symbolresolver.vala
similarity index 90%
rename from src/libvaladoc/api/symbolresolver.vala
rename to src/driver/0.13.x/symbolresolver.vala
index 39d5a77..f227cd0 100644
--- a/src/libvaladoc/api/symbolresolver.vala
+++ b/src/driver/0.13.x/symbolresolver.vala
@@ -20,31 +20,32 @@
  * 	Florian Brosch <flo brosch gmail com>
  */
 
+using Valadoc.Api;
 using Gee;
 
 
-public class Valadoc.Api.SymbolResolver : Visitor {
+public class Valadoc.Drivers.SymbolResolver : Visitor {
 	private HashMap<Vala.Symbol, Symbol> symbol_map;
 	private Valadoc.Api.Class glib_error;
-	private Tree root;
+	private Api.Tree root;
 
-	public SymbolResolver (HashMap<Vala.Symbol, Symbol> symbol_map, Valadoc.Api.Class glib_error) {
-		this.symbol_map = symbol_map;
-		this.glib_error = glib_error;
+	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 (Array ptr) {
+	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 Array) {
-			resolve_array_type_references ((Array) data_type);
+		} 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 ((Pointer) data_type);
+			resolve_pointer_type_references ((Api.Pointer) data_type);
 		} else {
 			resolve_type_reference ((TypeReference) data_type);
 		}
@@ -54,8 +55,8 @@ public class Valadoc.Api.SymbolResolver : Visitor {
 		Api.Item type = ptr.data_type;
 		if (type == null) {
 			// void
-		} else if (type is Array) {
-			resolve_array_type_references ((Array) type);
+		} 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 {
@@ -87,15 +88,15 @@ public class Valadoc.Api.SymbolResolver : Visitor {
 
 		if (reference.data_type is Pointer) {
 			resolve_pointer_type_references ((Pointer)reference.data_type);
-		} else if (reference.data_type is Array) {
-			resolve_array_type_references ((Array)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 (Tree item) {
+	public override void visit_tree (Api.Tree item) {
 		this.root = item;
 		item.accept_children (this);
 		this.root = null;
@@ -217,7 +218,7 @@ public class Valadoc.Api.SymbolResolver : Visitor {
 	/**
 	 * { inheritDoc}
 	 */
-	public override void visit_signal (Signal item) {
+	public override void visit_signal (Api.Signal item) {
 		resolve_type_reference (item.return_type);
 
 		item.accept_all_children (this, false);
@@ -296,7 +297,7 @@ public class Valadoc.Api.SymbolResolver : Visitor {
 	/**
 	 * { inheritDoc}
 	 */
-	public override void visit_enum_value (EnumValue item) {
+	public override void visit_enum_value (Api.EnumValue item) {
 
 		if (((Vala.EnumValue) item.data).value != null) {
 			SignatureBuilder signature = new SignatureBuilder ();
@@ -308,3 +309,6 @@ public class Valadoc.Api.SymbolResolver : Visitor {
 		item.accept_all_children (this, false);
 	}
 }
+
+
+
diff --git a/src/driver/0.13.x/treebuilder.vala b/src/driver/0.13.x/treebuilder.vala
new file mode 100644
index 0000000..a4a05ec
--- /dev/null
+++ b/src/driver/0.13.x/treebuilder.vala
@@ -0,0 +1,988 @@
+/* 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.file_type == Vala.SourceFileType.SOURCE && !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 == Vala.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.Parameter) {
+			return (((Vala.Parameter)node).direction == Vala.ParameterDirection.IN &&
+				((Vala.Parameter)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.Parameter == 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.Parameter) {
+			if (((Vala.Parameter)parent).direction != Vala.ParameterDirection.IN) {
+				return false;
+			}
+			return ((Vala.Parameter)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.Parameter == 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.Parameter 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_vapi_path (pkg) ?? context.get_gir_path (pkg);
+		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, Vala.SourceFileType.PACKAGE, package_path);
+		context.add_source_file (vfile);
+		Package vdpkg = new Package (vfile, 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, Vala.SourceFileType.SOURCE, rpath);
+
+					if (source_package == null) {
+						source_package = register_package (new Package (source_file, 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, Vala.SourceFileType.PACKAGE, rpath);
+					Package vdpkg = new Package (vfile, file_name, true, null);
+					context.add_source_file (vfile);
+
+					register_source_file (register_package (vdpkg), 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.vapi_directories = settings.vapi_directories;
+		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);
+			}
+		}
+
+		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;
+		}
+
+
+		// parse vala-code:
+		Vala.Parser parser = new Vala.Parser ();
+
+		parser.parse (context);
+		if (context.report.get_errors () > 0) {
+			return context;
+		}
+
+
+		// check context:
+		context.check ();
+		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 {
+				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 == Vala.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 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 = (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.Parameter 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
new file mode 100755
index 0000000..5e22e88
--- /dev/null
+++ b/src/driver/Makefile.am
@@ -0,0 +1,10 @@
+# src/Makefile.am
+
+NULL =
+
+
+SUBDIRS = \
+	0.13.x \
+	$(NULL)
+
+
diff --git a/src/libvaladoc/Makefile.am b/src/libvaladoc/Makefile.am
index da6bf19..64c277b 100755
--- a/src/libvaladoc/Makefile.am
+++ b/src/libvaladoc/Makefile.am
@@ -43,7 +43,6 @@ libvaladoc_la_VALASOURCES = \
 	importer/valadocdocumentationimporter.vala \
 	importer/valadocdocumentationimporterscanner.vala \
 	api/symbolaccessibility.vala \
-	api/symbolresolver.vala \
 	api/sourcecomment.vala \
 	api/array.vala \
 	api/class.vala \
@@ -57,7 +56,6 @@ libvaladoc_la_VALASOURCES = \
 	api/formalparameter.vala \
 	api/formalparametertype.vala \
 	api/interface.vala \
-	api/initializerbuilder.vala \
 	api/item.vala \
 	api/member.vala \
 	api/method.vala \
diff --git a/src/libvaladoc/api/class.vala b/src/libvaladoc/api/class.vala
index 00441d6..a820d82 100755
--- a/src/libvaladoc/api/class.vala
+++ b/src/libvaladoc/api/class.vala
@@ -226,11 +226,11 @@ public class Valadoc.Api.Class : TypeSymbol {
 		return _known_derived_interfaces.read_only_view;
 	}
 
-	internal void register_derived_interface (Interface iface) {
+	public void register_derived_interface (Interface iface) {
 		_known_derived_interfaces.add (iface);
 	}
 
-	internal void register_child_class (Class cl) {
+	public void register_child_class (Class cl) {
 		if (this.base_type != null) {
 			((Class) this.base_type.data_type).register_child_class (cl);
 		}
diff --git a/src/libvaladoc/api/driver.vala b/src/libvaladoc/api/driver.vala
index c1376b1..0bcfc63 100755
--- a/src/libvaladoc/api/driver.vala
+++ b/src/libvaladoc/api/driver.vala
@@ -25,953 +25,18 @@ using Gee;
 
 
 /**
- * Creates an simpler, minimized, more abstract AST for valacs AST.
+ * A plugin register function for drivers
+ *
+ * @see ModuleLoader
  */
-public class Valadoc.Api.Driver : 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;
-
-
-	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.file_type == Vala.SourceFileType.SOURCE && !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 Array create_array (Vala.ArrayType vtyperef, Item parent) {
-		Array arr = new 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 == Vala.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.Parameter) {
-			return (((Vala.Parameter)node).direction == Vala.ParameterDirection.IN &&
-				((Vala.Parameter)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.Parameter == 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.Parameter) {
-			if (((Vala.Parameter)parent).direction != Vala.ParameterDirection.IN) {
-				return false;
-			}
-			return ((Vala.Parameter)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.Parameter == 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.Parameter 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_vapi_path (pkg) ?? context.get_gir_path (pkg);
-		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, Vala.SourceFileType.PACKAGE, package_path);
-		context.add_source_file (vfile);
-		Package vdpkg = new Package (vfile, 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, Vala.SourceFileType.SOURCE, rpath);
-
-					if (source_package == null) {
-						source_package = register_package (new Package (source_file, 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, Vala.SourceFileType.PACKAGE, rpath);
-					Package vdpkg = new Package (vfile, file_name, true, null);
-					context.add_source_file (vfile);
-
-					register_source_file (register_package (vdpkg), 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.vapi_directories = settings.vapi_directories;
-		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);
-			}
-		}
-
-		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;
-		}
-
-
-		// parse vala-code:
-		Vala.Parser parser = new Vala.Parser ();
-
-		parser.parse (context);
-		if (context.report.get_errors () > 0) {
-			return context;
-		}
-
-
-		// check context:
-		context.check ();
-		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 {
-				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 == Vala.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);
-
-		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 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 = (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.Parameter 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;
-		}
+[CCode (has_target = false)]
+public delegate Type Valadoc.DriverRegisterFunction (GLib.TypeModule module);
 
-		context.accept(this);
 
-		if (reporter.errors > 0) {
-			return null;
-		}
 
-		SymbolResolver resolver = new SymbolResolver (symbol_map, glib_error);
-		this.tree.accept (resolver);
+public interface Valadoc.Driver : Object {
 
-		return tree;
-	}
+	public abstract Api.Tree? build (Settings settings, ErrorReporter reporter);
 }
 
 
diff --git a/src/libvaladoc/api/interface.vala b/src/libvaladoc/api/interface.vala
index 236b14d..b8c339e 100755
--- a/src/libvaladoc/api/interface.vala
+++ b/src/libvaladoc/api/interface.vala
@@ -140,11 +140,11 @@ public class Valadoc.Api.Interface : TypeSymbol {
 		return _known_related_interfaces;
 	}
 
-	internal void register_related_interface (Interface iface) {
+	public void register_related_interface (Interface iface) {
 		_known_related_interfaces.add (iface);
 	}
 
-	internal void register_implementation (Class cl) {
+	public void register_implementation (Class cl) {
 		_known_implementations.add (cl);
 	}
 
diff --git a/src/libvaladoc/api/node.vala b/src/libvaladoc/api/node.vala
index 49671bc..48cb600 100755
--- a/src/libvaladoc/api/node.vala
+++ b/src/libvaladoc/api/node.vala
@@ -114,7 +114,7 @@ public abstract class Valadoc.Api.Node : Item, Browsable, Documentation, Compara
 		return file.relative_path;
 	}
 
-	internal void add_child (Symbol child) {
+	public void add_child (Symbol child) {
 		if (child.name != null) {
 			per_name_children.set (child.name, child);
 		} else {
diff --git a/src/libvaladoc/api/signaturebuilder.vala b/src/libvaladoc/api/signaturebuilder.vala
index 801afe0..f589a0b 100755
--- a/src/libvaladoc/api/signaturebuilder.vala
+++ b/src/libvaladoc/api/signaturebuilder.vala
@@ -59,6 +59,20 @@ public class Valadoc.Api.SignatureBuilder {
 	}
 
 	/**
+	 * Adds highlighted text onto the end of the builder. 
+	 *
+	 * @param literal a string
+	 * @param spaced add a space at the front of the string if necessary
+	 * @return this
+	 */
+	public SignatureBuilder append_highlighted (string text, bool spaced = true) {
+		string content = (last_appended != null && spaced ? " " : "") + text;
+		Run inner = new Run (Run.Style.ITALIC);
+		inner.content.add (new Text (content));
+		return append_content (inner, spaced);
+	}
+
+	/**
 	 * Adds a Inline onto the end of the builder. 
 	 *
 	 * @param literal a content
diff --git a/src/libvaladoc/api/tree.vala b/src/libvaladoc/api/tree.vala
index 8c28e66..c662058 100755
--- a/src/libvaladoc/api/tree.vala
+++ b/src/libvaladoc/api/tree.vala
@@ -40,8 +40,7 @@ public class Valadoc.Api.Tree {
 	private ErrorReporter reporter;
 	private CTypeResolver _cresolver = null;
 
-	// TODO schÃner machen
-	internal void add_package(Package package) {
+	public void add_package(Package package) {
 		this.packages.add (package);
 	}
 
@@ -67,7 +66,7 @@ public class Valadoc.Api.Tree {
 		return external_c_files.read_only_view;
 	}
 
-	internal void add_external_c_files (string name) {
+	public void add_external_c_files (string name) {
 		external_c_files.add (name);
 	}
 
diff --git a/src/libvaladoc/moduleloader.vala b/src/libvaladoc/moduleloader.vala
index 8743aec..72297a9 100755
--- a/src/libvaladoc/moduleloader.vala
+++ b/src/libvaladoc/moduleloader.vala
@@ -1,6 +1,7 @@
 /* moduleloader.vala
  *
  * Copyright (C) 2008-2009 Florian Brosch
+ * 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
@@ -24,16 +25,21 @@ using Gee;
 
 
 [CCode (has_target = false)]
-public delegate  void Valadoc.TagletRegisterFunction (ModuleLoader loader);
+public delegate void Valadoc.TagletRegisterFunction (ModuleLoader loader);
+
 
 
-public class Valadoc.ModuleLoader : TypeModule {
-	public Doclet doclet;
 
+public class Valadoc.ModuleLoader : TypeModule {
 	public HashMap<string, GLib.Type> taglets = new HashMap<string, Type> (GLib.str_hash, GLib.str_equal);
 
+	private Module drivermodule;
+	private Type drivertype;
+	public Driver driver;
+
 	private Module docletmodule;
 	private Type doclettype;
+	public Doclet doclet;
 
 	public ModuleLoader () {
 		Object ();
@@ -65,7 +71,27 @@ public class Valadoc.ModuleLoader : TypeModule {
 
 		Valadoc.DocletRegisterFunction doclet_register_function = (Valadoc.DocletRegisterFunction) function;
 		doclettype = doclet_register_function (this);
-		this.doclet = (Doclet)GLib.Object.new (doclettype);
+		this.doclet = (Doclet) GLib.Object.new (doclettype);
+		return true;
+	}
+
+
+	public bool load_driver (string path) {
+		void* function;
+
+		drivermodule = Module.open (Module.build_path (path, "libdriver"), ModuleFlags.BIND_LAZY | ModuleFlags.BIND_LOCAL);
+		if (drivermodule == null) {
+			return false;
+		}
+
+		drivermodule.symbol("register_plugin", out function);
+		if (function == null) {
+			return false;
+		}
+
+		Valadoc.DriverRegisterFunction driver_register_function = (Valadoc.DriverRegisterFunction) function;
+		drivertype = driver_register_function (this);
+		this.driver = (Driver) GLib.Object.new (drivertype);
 		return true;
 	}
 }
diff --git a/src/valadoc/Makefile.am b/src/valadoc/Makefile.am
index 67bae8b..8b34324 100755
--- a/src/valadoc/Makefile.am
+++ b/src/valadoc/Makefile.am
@@ -2,7 +2,7 @@ NULL =
 
 
 AM_CFLAGS =                             \
-	-DPACKAGE_DATADIR=\"$(libdir)/valadoc/plugins\" \
+	-DPACKAGE_DATADIR=\"$(libdir)/valadoc\" \
 	-DPACKAGE_VERSION=\"$(VERSION)\"    \
 	-I ../libvaladoc/                   \
 	$(GLIB_CFLAGS)                      \
diff --git a/src/valadoc/valadoc.vala b/src/valadoc/valadoc.vala
index 36235c6..02684b3 100755
--- a/src/valadoc/valadoc.vala
+++ b/src/valadoc/valadoc.vala
@@ -31,11 +31,12 @@ using Gee;
 public class ValaDoc : Object {
 	private static string wikidirectory = null;
 	private static string pkg_version = null;
-	private static string pluginpath = null;
+	private static string docletpath = null;
 	[CCode (array_length = false, array_null_terminated = true)]
 	private static string[] pluginargs;
 	private static string directory = null;
 	private static string pkg_name = null;
+	private static string driverpath = null;
 
 	private static bool add_inherited = false;
 	private static bool _protected = true;
@@ -71,7 +72,7 @@ public class ValaDoc : Object {
 		{ "vapidir", 0, 0, OptionArg.FILENAME_ARRAY, ref vapi_directories, "Look for package bindings in DIRECTORY", "DIRECTORY..." },
 		{ "importdir", 0, 0, OptionArg.FILENAME_ARRAY, ref import_directories, "Look for external documentation in DIRECTORY", "DIRECTORY..." },
 		{ "profile", 0, 0, OptionArg.STRING, ref profile, "Use the given profile instead of the default", "PROFILE" },
-		{ "version", 0, 0, OptionArg.NONE, ref version, "Display version number", null },
+		{ "driver", 0, 0, OptionArg.NONE, ref driverpath, "Display version number", null },
 
 		{ "pkg", 0, 0, OptionArg.STRING_ARRAY, ref packages, "Include binding for PACKAGE", "PACKAGE..." },
 		{ "import", 0, 0, OptionArg.STRING_ARRAY, ref import_packages, "Include binding for PACKAGE", "PACKAGE..." },
@@ -79,82 +80,106 @@ public class ValaDoc : Object {
 
 		{ "wiki", 0, 0, OptionArg.FILENAME, ref wikidirectory, "Wiki directory", "DIRECTORY" },
 		{ "deps", 0, 0, OptionArg.NONE, ref with_deps, "Adds packages to the documentation", null },
+
 		{ "doclet-arg", 'X', 0, OptionArg.STRING_ARRAY, ref pluginargs, "Pass arguments to the doclet", "ARG" },
-		{ "doclet", 0, 0, OptionArg.STRING, ref pluginpath, "Name of an included doclet or path to custom doclet", "PLUGIN"},
+		{ "doclet", 0, 0, OptionArg.STRING, ref docletpath, "Name of an included doclet or path to custom doclet", "PLUGIN"},
+
 		{ "no-protected", 0, OptionFlags.REVERSE, OptionArg.NONE, ref _protected, "Removes protected elements from documentation", null },
 		{ "internal", 0, 0, OptionArg.NONE, ref _internal, "Adds internal elements to documentation", null },
 		{ "private", 0, 0, OptionArg.NONE, ref _private, "Adds private elements to documentation", null },
 //		{ "inherit", 0, 0, OptionArg.NONE, ref add_inherited, "Adds inherited elements to a class", null },
+
 		{ "package-name", 0, 0, OptionArg.STRING, ref pkg_name, "package name", "NAME" },
 		{ "package-version", 0, 0, OptionArg.STRING, ref pkg_version, "package version", "VERSION" },
+
 		{ "force", 0, 0, OptionArg.NONE, ref force, "force", null },
 		{ "verbose", 0, 0, OptionArg.NONE, ref verbose, "Show all warnings", null },
 		{ "", 0, 0, OptionArg.FILENAME_ARRAY, ref tsources, null, "FILE..." },
+
 		{ null }
 	};
 
 	private static int quit (ErrorReporter reporter) {
-		if ( reporter.errors == 0) {
+		if (reporter.errors == 0) {
 			stdout.printf ("Succeeded - %d warning(s)\n", reporter.warnings);
 			return 0;
-		}
-		else {
+		} else {
 			stdout.printf ("Failed: %d error(s), %d warning(s)\n", reporter.errors, reporter.warnings);
 			return 1;
 		}
 	}
 
 	private static bool check_pkg_name () {
-		if (pkg_name == null)
+		if (pkg_name == null) {
 			return true;
+		}
 
-		if (pkg_name == "glib-2.0" || pkg_name == "gobject-2.0")
+		if (pkg_name == "glib-2.0" || pkg_name == "gobject-2.0") {
 			return false;
+		}
 
 		foreach (string package in tsources) {
-			if (pkg_name == package)
+			if (pkg_name == package) {
 				return false;
+			}
 		}
 		return true;
 	}
 
 	private string get_pkg_name () {
 		if (this.pkg_name == null) {
-			if (this.directory.has_suffix ("/"))
+			if (this.directory.has_suffix ("/")) {
 				this.pkg_name = GLib.Path.get_dirname (this.directory);
-			else
+			} else {
 				this.pkg_name = GLib.Path.get_basename (this.directory);
+			}
 		}
 
 		return this.pkg_name;
 	}
 
-	private ModuleLoader? create_module_loader (ErrorReporter reporter) {
-		string fulldirpath = "";
+	private string get_plugin_dir (string? pluginpath, string subdir, string default_pkg) {
 		if (pluginpath == null) {
-			fulldirpath = build_filename (Config.plugin_dir, "html");
-		} else if (is_absolute (pluginpath ) == false) {
+			return build_filename (Config.plugin_dir, subdir, default_pkg);
+		}
+
+		if (is_absolute (pluginpath) == false) {
 			// Test to see if the plugin exists in the expanded path and then fallback
 			// to using the configured plugin directory
 			string local_path = build_filename (Environment.get_current_dir(), pluginpath);
-			if ( FileUtils.test(local_path, FileTest.EXISTS)) {
-				fulldirpath = local_path;
+			if (FileUtils.test(local_path, FileTest.EXISTS)) {
+				return local_path;
 			} else {
-				fulldirpath = build_filename (Config.plugin_dir, pluginpath);
+				return build_filename (Config.plugin_dir, subdir, pluginpath);
 			}
-		} else {
-			fulldirpath = pluginpath;
 		}
 
+		return pluginpath;
+	}
 
+	private ModuleLoader? create_module_loader (ErrorReporter reporter) {
 		ModuleLoader modules = new ModuleLoader ();
 		Taglets.init (modules);
-		bool tmp = modules.load_doclet (fulldirpath);
+
+		// doclet:
+		string pluginpath = get_plugin_dir (docletpath, "doclets", "html");
+		bool tmp = modules.load_doclet (pluginpath);
 		if (tmp == false) {
-			reporter.simple_error ("failed to load plugin");
+			reporter.simple_error ("failed to load doclet");
 			return null;
 		}
 
+
+		// driver:
+		pluginpath = get_plugin_dir (driverpath, "drivers", "0.13.x");
+		tmp = modules.load_driver (pluginpath);
+		if (tmp == false) {
+			reporter.simple_error ("failed to load driver");
+			return null;
+		}
+
+		assert (modules.driver != null && modules.doclet != null);
+
 		return modules;
 	}
 
@@ -186,8 +211,15 @@ public class ValaDoc : Object {
 		settings.defines = defines;
 
 
+		// load plugins:
+		ModuleLoader? modules = create_module_loader (reporter);
+		if (reporter.errors > 0 || modules == null) {
+			return quit (reporter);
+		}
+
+
 		// Create tree:
-		Valadoc.Api.Driver driver = new Valadoc.Api.Driver ();
+		Valadoc.Driver driver = modules.driver;
 		Valadoc.Api.Tree doctree = driver.build (settings, reporter);
 
 		if (reporter.errors > 0) {
@@ -196,11 +228,6 @@ public class ValaDoc : Object {
 
 
 		// process documentation
-		ModuleLoader? modules = create_module_loader (reporter);
-		if (reporter.errors > 0 || modules == null) {
-			return quit (reporter);
-		}
-
 		Valadoc.DocumentationParser docparser = new Valadoc.DocumentationParser (settings, reporter, doctree, modules);
 		if (!doctree.create_tree()) {
 			return quit (reporter);
@@ -233,8 +260,7 @@ public class ValaDoc : Object {
 			opt_context.set_help_enabled (true);
 			opt_context.add_main_entries (options, null);
 			opt_context.parse (ref args);
-		}
-		catch (OptionError e) {
+		} catch (OptionError e) {
 			reporter.simple_error (e.message);
 			stdout.printf ("Run '%s --help' to see a full list of available command line options.\n", args[0]);
 			return quit (reporter);
@@ -262,8 +288,7 @@ public class ValaDoc : Object {
 					reporter.simple_error ("Can't remove directory.");
 					return quit (reporter);
 				}
-			}
-			else {
+			} else {
 				reporter.simple_error ("File already exists");
 				return quit (reporter);
 			}



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