]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
libvala: Move tree creation out into a plugin
authorFlorian Brosch <flo.brosch@gmail.com>
Thu, 21 Jul 2011 01:16:59 +0000 (03:16 +0200)
committerFlorian Brosch <flo.brosch@gmail.com>
Fri, 29 Jul 2011 00:45:25 +0000 (02:45 +0200)
21 files changed:
configure.in
src/Makefile.am
src/doclets/devhelp/Makefile.am
src/doclets/gtkdoc/Makefile.am
src/doclets/htm/Makefile.am
src/driver/0.13.x/Makefile.am [new file with mode: 0755]
src/driver/0.13.x/driver.vala [new file with mode: 0755]
src/driver/0.13.x/initializerbuilder.vala [moved from src/libvaladoc/api/initializerbuilder.vala with 99% similarity]
src/driver/0.13.x/symbolresolver.vala [moved from src/libvaladoc/api/symbolresolver.vala with 90% similarity]
src/driver/0.13.x/treebuilder.vala [new file with mode: 0644]
src/driver/Makefile.am [new file with mode: 0755]
src/libvaladoc/Makefile.am
src/libvaladoc/api/class.vala
src/libvaladoc/api/driver.vala
src/libvaladoc/api/interface.vala
src/libvaladoc/api/node.vala
src/libvaladoc/api/signaturebuilder.vala
src/libvaladoc/api/tree.vala
src/libvaladoc/moduleloader.vala
src/valadoc/Makefile.am
src/valadoc/valadoc.vala

index d823949409928fb3a7f88f7e467fb73d02be09b7..2612193b6b076e787719f7d3db17212919da4d8a 100755 (executable)
@@ -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
index f9718b8ea4803d2093f0e076c8a67831f22e626e..fcaf3a5a861a7631af2bd1b7a2ac1b6ad1ac9b2b 100755 (executable)
@@ -7,6 +7,7 @@ SUBDIRS = \
        libvaladoc \
        valadoc \
        doclets \
+       driver \
        $(NULL)
 
 
index 701fc17d8ca219c2c47fd9ee7d002375600a1699..af6aa5d0e896fcca7bbd3220cfad088d7ccfc361 100755 (executable)
@@ -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
index c985357ad8e0aa3600c22abe46503fe6edcd5435..1f7e159bec11648e74af56b52dd8ce8af59051ce 100755 (executable)
@@ -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
index 12612a246fb72d94a11d92ad274233e29fb83bc8..5af5092db4d9531616f5e08367e5131db5af9453 100755 (executable)
@@ -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 (executable)
index 0000000..986dd79
--- /dev/null
@@ -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 (executable)
index 0000000..d5e8e72
--- /dev/null
@@ -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);
+}
+
similarity index 99%
rename from src/libvaladoc/api/initializerbuilder.vala
rename to src/driver/0.13.x/initializerbuilder.vala
index 3f580e178015bb0856ea8eac1636c8cc0b89d344..70fd1d6bb9fc9bc2b23dc1e4bb941e17bafc3c3f 100644 (file)
@@ -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);
        }
 
similarity index 90%
rename from src/libvaladoc/api/symbolresolver.vala
rename to src/driver/0.13.x/symbolresolver.vala
index 39d5a77b337604c2fbd538eb1458325a4c5e1686..f227cd0b1a5c3a895c4b0de6a0beba7d1c75eb80 100644 (file)
  *     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 (file)
index 0000000..a4a05ec
--- /dev/null
@@ -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 (executable)
index 0000000..5e22e88
--- /dev/null
@@ -0,0 +1,10 @@
+# src/Makefile.am
+
+NULL =
+
+
+SUBDIRS = \
+       0.13.x \
+       $(NULL)
+
+
index da6bf19464c5d9ac00c2f8344a23bc6bb8670617..64c277bca5236b1f21653689f1bebce079749579 100755 (executable)
@@ -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 \
index 00441d6382549ade1b7dfa6cdcc125788881386e..a820d8286662e9e649d6e9699a1637c87c5d7f3a 100755 (executable)
@@ -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);
                }
index c1376b176c1fe5797a00692b48762f405a3bc4af..0bcfc63e57a19e7ae75791fc4f8545d84e129273 100755 (executable)
@@ -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);
 }
 
 
index 236b14d1508f5fdeae1384fa6e5e689c6421df4b..b8c339ee9a690fdfe5000c12f5a97e069d94ee34 100755 (executable)
@@ -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);
        }
 
index 49671bc4e0ad6fe6610975a5eea6310f4bb09f3d..48cb6009cdb82225aeb57ebf803f1c7ccfd1c88a 100755 (executable)
@@ -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 {
index 801afe07267aaa159478b5450befb9d5becbda18..f589a0b6a12588fb4247dd7aa493be91fb79fa1d 100755 (executable)
@@ -58,6 +58,20 @@ public class Valadoc.Api.SignatureBuilder {
                return this;
        }
 
+       /**
+        * 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. 
         *
index 8c28e66fb36d0cb98a5a6d8412c69b30752f1f9b..c662058345b368b3ecfa34d28e2d4f5e100141b7 100755 (executable)
@@ -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);
        }
 
index 8743aecb0dd61a1523ac02ad5ef08819744b806f..72297a9ea94e70c6130b490d0b8ee1825bbaaf6e 100755 (executable)
@@ -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;
        }
 }
index 67bae8b9a59da1d1364fc87f761c1da2519f8cfe..8b34324fbdc5fa66fb8d61919681ebcbee691f78 100755 (executable)
@@ -2,7 +2,7 @@ NULL =
 
 
 AM_CFLAGS =                             \
-       -DPACKAGE_DATADIR=\"$(libdir)/valadoc/plugins\" \
+       -DPACKAGE_DATADIR=\"$(libdir)/valadoc\" \
        -DPACKAGE_VERSION=\"$(VERSION)\"    \
        -I ../libvaladoc/                   \
        $(GLIB_CFLAGS)                      \
index 36235c6948fb6ca51a9913b38c30e0707417685f..02684b3e27136724c02af7ec8523dead755df222 100755 (executable)
@@ -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);
                        }