[valadoc] libvala: Move tree creation out into a plugin
- From: Florian Brosch <flobrosch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [valadoc] libvala: Move tree creation out into a plugin
- Date: Fri, 29 Jul 2011 00:59:13 +0000 (UTC)
commit 9801f58f964bd87d9e3763fad150e9055e3a08a1
Author: Florian Brosch <flo brosch gmail com>
Date: Thu Jul 21 03:16:59 2011 +0200
libvala: Move tree creation out into a plugin
configure.in | 2 +
src/Makefile.am | 1 +
src/doclets/devhelp/Makefile.am | 2 +-
src/doclets/gtkdoc/Makefile.am | 2 +-
src/doclets/htm/Makefile.am | 2 +-
src/driver/0.13.x/Makefile.am | 62 ++
src/driver/0.13.x/driver.vala | 52 +
.../api => driver/0.13.x}/initializerbuilder.vala | 4 +-
.../api => driver/0.13.x}/symbolresolver.vala | 36 +-
src/driver/0.13.x/treebuilder.vala | 988 ++++++++++++++++++++
src/driver/Makefile.am | 10 +
src/libvaladoc/Makefile.am | 2 -
src/libvaladoc/api/class.vala | 4 +-
src/libvaladoc/api/driver.vala | 949 +-------------------
src/libvaladoc/api/interface.vala | 4 +-
src/libvaladoc/api/node.vala | 2 +-
src/libvaladoc/api/signaturebuilder.vala | 14 +
src/libvaladoc/api/tree.vala | 5 +-
src/libvaladoc/moduleloader.vala | 34 +-
src/valadoc/Makefile.am | 2 +-
src/valadoc/valadoc.vala | 89 ++-
21 files changed, 1255 insertions(+), 1011 deletions(-)
---
diff --git a/configure.in b/configure.in
index d823949..2612193 100755
--- a/configure.in
+++ b/configure.in
@@ -64,6 +64,8 @@ AC_CONFIG_FILES([Makefile
icons/Makefile
doc/Makefile
src/libvaladoc/Makefile
+ src/driver/Makefile
+ src/driver/0.13.x/Makefile
src/doclets/Makefile
src/doclets/htm/Makefile
src/doclets/devhelp/Makefile
diff --git a/src/Makefile.am b/src/Makefile.am
index f9718b8..fcaf3a5 100755
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -7,6 +7,7 @@ SUBDIRS = \
libvaladoc \
valadoc \
doclets \
+ driver \
$(NULL)
diff --git a/src/doclets/devhelp/Makefile.am b/src/doclets/devhelp/Makefile.am
index 701fc17..af6aa5d 100755
--- a/src/doclets/devhelp/Makefile.am
+++ b/src/doclets/devhelp/Makefile.am
@@ -14,7 +14,7 @@ AM_CFLAGS = -g \
BUILT_SOURCES = libdoclet.vala.stamp
-docletdir = $(libdir)/valadoc/plugins/devhelp
+docletdir = $(libdir)/valadoc/doclets/devhelp
libdoclet_la_LDFLAGS = -module -avoid-version -no-undefined
diff --git a/src/doclets/gtkdoc/Makefile.am b/src/doclets/gtkdoc/Makefile.am
index c985357..1f7e159 100755
--- a/src/doclets/gtkdoc/Makefile.am
+++ b/src/doclets/gtkdoc/Makefile.am
@@ -14,7 +14,7 @@ AM_CFLAGS = -g \
BUILT_SOURCES = libdoclet.vala.stamp
-docletdir = $(libdir)/valadoc/plugins/gtkdoc
+docletdir = $(libdir)/valadoc/doclets/gtkdoc
libdoclet_la_LDFLAGS = -module -avoid-version -no-undefined
diff --git a/src/doclets/htm/Makefile.am b/src/doclets/htm/Makefile.am
index 12612a2..5af5092 100755
--- a/src/doclets/htm/Makefile.am
+++ b/src/doclets/htm/Makefile.am
@@ -14,7 +14,7 @@ AM_CFLAGS = -g \
BUILT_SOURCES = libdoclet.vala.stamp
-docletdir = $(libdir)/valadoc/plugins/html
+docletdir = $(libdir)/valadoc/doclets/html
libdoclet_la_LDFLAGS = -module -avoid-version -no-undefined
diff --git a/src/driver/0.13.x/Makefile.am b/src/driver/0.13.x/Makefile.am
new file mode 100755
index 0000000..986dd79
--- /dev/null
+++ b/src/driver/0.13.x/Makefile.am
@@ -0,0 +1,62 @@
+NULL =
+
+
+AM_CFLAGS = -g \
+ -DPACKAGE_ICONDIR=\"$(datadir)/valadoc/icons/\" \
+ -I ../../libvaladoc/ \
+ $(GLIB_CFLAGS) \
+ $(LIBGEE_CFLAGS) \
+ $(LIBVALA_CFLAGS) \
+ $(NULL)
+
+
+
+BUILT_SOURCES = libdriver.vala.stamp
+
+
+docletdir = $(libdir)/valadoc/drivers/0.13.x
+
+
+libdriver_la_LDFLAGS = -module -avoid-version -no-undefined
+
+
+doclet_LTLIBRARIES = \
+ libdriver.la \
+ $(NULL)
+
+
+libdriver_la_VALASOURCES = \
+ initializerbuilder.vala \
+ symbolresolver.vala \
+ treebuilder.vala \
+ driver.vala \
+ $(NULL)
+
+
+libdriver_la_SOURCES = \
+ libdriver.vala.stamp \
+ $(libdriver_la_VALASOURCES:.vala=.c) \
+ $(NULL)
+
+
+libdriver.vala.stamp: $(libdriver_la_VALASOURCES)
+ $(VALAC) -C --vapidir $(top_srcdir)/src/vapi --vapidir $(top_srcdir)/src/libvaladoc --pkg $(VALA_PACKAGE) --pkg gee-1.0 --pkg valadoc-1.0 --basedir . $^
+ touch $@
+
+
+libdriver_la_LIBADD = \
+ ../../libvaladoc/libvaladoc.la \
+ $(GLIB_LIBS) \
+ $(LIBVALA_LIBS) \
+ $(LIBGEE_LIBS) \
+ $(NULL)
+
+
+EXTRA_DIST = $(libdriver_la_VALASOURCES) libdriver.vala.stamp
+
+
+MAINTAINERCLEANFILES = \
+ $(libdriver_la_VALASOURCES:.vala=.c) \
+ $(NULL)
+
+
diff --git a/src/driver/0.13.x/driver.vala b/src/driver/0.13.x/driver.vala
new file mode 100755
index 0000000..d5e8e72
--- /dev/null
+++ b/src/driver/0.13.x/driver.vala
@@ -0,0 +1,52 @@
+/* driver.vala
+ *
+ * Copyright (C) 2011 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Florian Brosch <flo brosch gmail com>
+ */
+
+using Valadoc.Api;
+using Gee;
+
+
+
+/**
+ * Creates an simpler, minimized, more abstract AST for valacs AST.
+ */
+public class Valadoc.Drivers.Driver : Object, Valadoc.Driver {
+
+ public Api.Tree? build (Settings settings, ErrorReporter reporter) {
+ TreeBuilder builder = new TreeBuilder ();
+ Api.Tree? tree = builder.build (settings, reporter);
+ if (reporter.errors > 0) {
+ return null;
+ }
+
+ SymbolResolver resolver = new SymbolResolver (builder);
+ tree.accept (resolver);
+
+ return tree;
+ }
+}
+
+
+[ModuleInit]
+public Type register_plugin (GLib.TypeModule module) {
+ return typeof (Valadoc.Drivers.Driver);
+}
+
diff --git a/src/libvaladoc/api/initializerbuilder.vala b/src/driver/0.13.x/initializerbuilder.vala
similarity index 99%
rename from src/libvaladoc/api/initializerbuilder.vala
rename to src/driver/0.13.x/initializerbuilder.vala
index 3f580e1..70fd1d6 100644
--- a/src/libvaladoc/api/initializerbuilder.vala
+++ b/src/driver/0.13.x/initializerbuilder.vala
@@ -509,11 +509,9 @@ private class Valadoc.Api.InitializerBuilder : Vala.CodeVisitor {
first = false;
}
- var run = new Run (Run.Style.ITALIC);
- run.content.add (new Text (" [...] "));
signature.append (") => {", false);
- signature.append_content (run, false);
+ signature.append_highlighted (" [...] ", false);
signature.append ("}", false);
}
diff --git a/src/libvaladoc/api/symbolresolver.vala b/src/driver/0.13.x/symbolresolver.vala
similarity index 90%
rename from src/libvaladoc/api/symbolresolver.vala
rename to src/driver/0.13.x/symbolresolver.vala
index 39d5a77..f227cd0 100644
--- a/src/libvaladoc/api/symbolresolver.vala
+++ b/src/driver/0.13.x/symbolresolver.vala
@@ -20,31 +20,32 @@
* Florian Brosch <flo brosch gmail com>
*/
+using Valadoc.Api;
using Gee;
-public class Valadoc.Api.SymbolResolver : Visitor {
+public class Valadoc.Drivers.SymbolResolver : Visitor {
private HashMap<Vala.Symbol, Symbol> symbol_map;
private Valadoc.Api.Class glib_error;
- private Tree root;
+ private Api.Tree root;
- public SymbolResolver (HashMap<Vala.Symbol, Symbol> symbol_map, Valadoc.Api.Class glib_error) {
- this.symbol_map = symbol_map;
- this.glib_error = glib_error;
+ public SymbolResolver (TreeBuilder builder) {
+ this.symbol_map = builder.get_symbol_map ();
+ this.glib_error = builder.get_glib_error ();
}
private Symbol? resolve (Vala.Symbol symbol) {
return symbol_map.get (symbol);
}
- private void resolve_array_type_references (Array ptr) {
+ private void resolve_array_type_references (Api.Array ptr) {
Api.Item data_type = ptr.data_type;
if (data_type == null) {
// void
- } else if (data_type is Array) {
- resolve_array_type_references ((Array) data_type);
+ } else if (data_type is Api.Array) {
+ resolve_array_type_references ((Api.Array) data_type);
} else if (data_type is Pointer) {
- resolve_pointer_type_references ((Pointer) data_type);
+ resolve_pointer_type_references ((Api.Pointer) data_type);
} else {
resolve_type_reference ((TypeReference) data_type);
}
@@ -54,8 +55,8 @@ public class Valadoc.Api.SymbolResolver : Visitor {
Api.Item type = ptr.data_type;
if (type == null) {
// void
- } else if (type is Array) {
- resolve_array_type_references ((Array) type);
+ } else if (type is Api.Array) {
+ resolve_array_type_references ((Api.Array) type);
} else if (type is Pointer) {
resolve_pointer_type_references ((Pointer) type);
} else {
@@ -87,15 +88,15 @@ public class Valadoc.Api.SymbolResolver : Visitor {
if (reference.data_type is Pointer) {
resolve_pointer_type_references ((Pointer)reference.data_type);
- } else if (reference.data_type is Array) {
- resolve_array_type_references ((Array)reference.data_type);
+ } else if (reference.data_type is Api.Array) {
+ resolve_array_type_references ((Api.Array)reference.data_type);
}
}
/**
* { inheritDoc}
*/
- public override void visit_tree (Tree item) {
+ public override void visit_tree (Api.Tree item) {
this.root = item;
item.accept_children (this);
this.root = null;
@@ -217,7 +218,7 @@ public class Valadoc.Api.SymbolResolver : Visitor {
/**
* { inheritDoc}
*/
- public override void visit_signal (Signal item) {
+ public override void visit_signal (Api.Signal item) {
resolve_type_reference (item.return_type);
item.accept_all_children (this, false);
@@ -296,7 +297,7 @@ public class Valadoc.Api.SymbolResolver : Visitor {
/**
* { inheritDoc}
*/
- public override void visit_enum_value (EnumValue item) {
+ public override void visit_enum_value (Api.EnumValue item) {
if (((Vala.EnumValue) item.data).value != null) {
SignatureBuilder signature = new SignatureBuilder ();
@@ -308,3 +309,6 @@ public class Valadoc.Api.SymbolResolver : Visitor {
item.accept_all_children (this, false);
}
}
+
+
+
diff --git a/src/driver/0.13.x/treebuilder.vala b/src/driver/0.13.x/treebuilder.vala
new file mode 100644
index 0000000..a4a05ec
--- /dev/null
+++ b/src/driver/0.13.x/treebuilder.vala
@@ -0,0 +1,988 @@
+/* treebuilder.vala
+ *
+ * Copyright (C) 2011 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Florian Brosch <flo brosch gmail com>
+ */
+
+
+using Valadoc.Api;
+using Gee;
+
+
+/**
+ * Creates an simpler, minimized, more abstract AST for valacs AST.
+ */
+public class Valadoc.Drivers.TreeBuilder : Vala.CodeVisitor {
+ private ArrayList<PackageMetaData> packages = new ArrayList<PackageMetaData> ();
+ private PackageMetaData source_package;
+
+ private HashMap<Vala.SourceFile, SourceFile> files = new HashMap<Vala.SourceFile, SourceFile> ();
+ private HashMap<Vala.Symbol, Symbol> symbol_map = new HashMap<Vala.Symbol, Symbol> ();
+
+ private ErrorReporter reporter;
+ private Settings settings;
+
+ private Api.Node current_node;
+ private Api.Tree tree;
+
+ private Valadoc.Api.Class glib_error = null;
+
+
+ //
+ // Accessors
+ //
+
+ public Api.Class get_glib_error () {
+ return glib_error;
+ }
+
+ public HashMap<Vala.Symbol, Symbol> get_symbol_map () {
+ return symbol_map;
+ }
+
+
+ //
+ //
+ //
+
+ private class PackageMetaData {
+ public Package package;
+ public HashMap<Vala.Namespace, Namespace> namespaces = new HashMap<Vala.Namespace, Namespace> ();
+ public ArrayList<Vala.SourceFile> files = new ArrayList<Vala.SourceFile> ();
+
+ public PackageMetaData (Package package) {
+ this.package = package;
+ }
+
+ public Namespace get_namespace (Vala.Namespace vns, SourceFile? file) {
+ Namespace? ns = namespaces.get (vns);
+ if (ns != null) {
+ return ns;
+ }
+
+ // find documentation comment if existing:
+ SourceComment? comment = null;
+ if (vns.source_reference != null) {
+ foreach (Vala.Comment c in vns.get_comments()) {
+ if (c.source_reference.file == vns.source_reference.file) {
+ Vala.SourceReference pos = c.source_reference;
+ comment = new SourceComment (c.content, file, pos.first_line, pos.first_column, pos.last_line, pos.last_column);
+ break;
+ }
+ }
+ }
+
+ // find parent if existing
+ var parent_vns = vns.parent_symbol;
+
+ if (parent_vns == null) {
+ ns = new Namespace (package, file, vns.name, comment, vns);
+ package.add_child (ns);
+ } else {
+ Namespace parent_ns = get_namespace ((Vala.Namespace) parent_vns, file);
+ ns = new Namespace (parent_ns, file, vns.name, comment, vns);
+ parent_ns.add_child (ns);
+ }
+
+ namespaces.set (vns, ns);
+ return ns;
+ }
+
+ public void register_source_file (Vala.SourceFile file) {
+ files.add (file);
+ }
+
+ public bool is_package_for_file (Vala.SourceFile source_file) {
+ if (source_file.file_type == Vala.SourceFileType.SOURCE && !package.is_package) {
+ return true;
+ }
+
+ return files.contains (source_file);
+ }
+ }
+
+
+ //
+ // Type constructor translation helpers:
+ //
+
+ private Pointer create_pointer (Vala.PointerType vtyperef, Item parent) {
+ Pointer ptr = new Pointer (parent, vtyperef);
+
+ Vala.DataType vntype = vtyperef.base_type;
+ if (vntype is Vala.PointerType) {
+ ptr.data_type = create_pointer ((Vala.PointerType) vntype, ptr);
+ } else if (vntype is Vala.ArrayType) {
+ ptr.data_type = create_array ((Vala.ArrayType) vntype, ptr);
+ } else {
+ ptr.data_type = create_type_reference (vntype, ptr);
+ }
+
+ return ptr;
+ }
+
+ private Api.Array create_array (Vala.ArrayType vtyperef, Item parent) {
+ Api.Array arr = new Api.Array (parent, vtyperef);
+
+ Vala.DataType vntype = vtyperef.element_type;
+ if (vntype is Vala.ArrayType) {
+ arr.data_type = create_array ((Vala.ArrayType) vntype, arr);
+ } else {
+ arr.data_type = create_type_reference (vntype, arr);
+ }
+
+ return arr;
+ }
+
+ private TypeReference create_type_reference (Vala.DataType? vtyperef, Item parent) {
+ bool is_nullable = vtyperef != null && vtyperef.nullable && !(vtyperef is Vala.GenericType) && !(vtyperef is Vala.PointerType);
+ string? signature = (vtyperef != null && vtyperef.data_type != null)? Vala.GVariantModule.get_dbus_signature (vtyperef.data_type) : null;
+ bool pass_ownership = type_reference_pass_ownership (vtyperef);
+ Ownership ownership = get_type_reference_ownership (vtyperef);
+ bool is_dynamic = vtyperef != null && vtyperef.is_dynamic;
+
+ TypeReference type_ref = new TypeReference (parent, ownership, pass_ownership, is_dynamic, is_nullable, signature, vtyperef);
+
+ if (vtyperef is Vala.PointerType) {
+ type_ref.data_type = create_pointer ((Vala.PointerType) vtyperef, type_ref);
+ } else if (vtyperef is Vala.ArrayType) {
+ type_ref.data_type = create_array ((Vala.ArrayType) vtyperef, type_ref);
+ }
+
+ // type parameters:
+ if (vtyperef != null) {
+ foreach (Vala.DataType vdtype in vtyperef.get_type_arguments ()) {
+ var type_param = create_type_reference (vdtype, type_ref);
+ type_ref.add_type_argument (type_param);
+ }
+ }
+
+ return type_ref;
+ }
+
+
+
+ //
+ // Translation helpers:
+ //
+
+ private SourceComment? create_comment (Vala.Comment? comment) {
+ if (comment != null) {
+ Vala.SourceReference pos = comment.source_reference;
+ SourceFile file = files.get (pos.file);
+ return new SourceComment (comment.content, file, pos.first_line, pos.first_column, pos.last_line, pos.last_column);
+ }
+
+ return null;
+ }
+
+ private string get_method_name (Vala.Method element) {
+ if (element is Vala.CreationMethod) {
+ if (element.name == ".new") {
+ return element.parent_symbol.name;
+ } else {
+ return element.parent_symbol.name + "." + element.name;
+ }
+ }
+
+ return element.name;
+ }
+
+ private PackageMetaData? get_package_meta_data (Package pkg) {
+ foreach (PackageMetaData data in packages) {
+ if (data.package == pkg) {
+ return data;
+ }
+ }
+
+ return null;
+ }
+
+ private PackageMetaData register_package (Package package) {
+ PackageMetaData meta_data = new PackageMetaData (package);
+ tree.add_package (package);
+ packages.add (meta_data);
+ return meta_data;
+ }
+
+ private SourceFile register_source_file (PackageMetaData meta_data, Vala.SourceFile source_file) {
+ SourceFile file = new SourceFile (source_file.get_relative_filename (), source_file.get_csource_filename ());
+ files.set (source_file, file);
+
+ meta_data.register_source_file (source_file);
+ return file;
+ }
+
+ private SourceFile? get_source_file (Vala.Symbol symbol) {
+ Vala.SourceReference source_ref = symbol.source_reference;
+ if (source_ref == null) {
+ return null;
+ }
+
+ SourceFile file = files.get (source_ref.file);
+ assert (file != null);
+ return file;
+ }
+
+ private Package? find_package_for_file (Vala.SourceFile source_file) {
+ foreach (PackageMetaData pkg in this.packages) {
+ if (pkg.is_package_for_file (source_file)) {
+ return pkg.package;
+ }
+ }
+
+ return null;
+ }
+
+
+ private Namespace get_namespace (Package pkg, Vala.Symbol symbol, SourceFile? file) {
+ // Find the closest namespace in our vala-tree
+ Vala.Symbol namespace_symbol = symbol;
+ while (!(namespace_symbol is Vala.Namespace)) {
+ namespace_symbol = namespace_symbol.parent_symbol;
+ }
+
+ PackageMetaData? meta_data = get_package_meta_data (pkg);
+ assert (meta_data != null);
+
+ return meta_data.get_namespace ((Vala.Namespace) namespace_symbol, file);
+ }
+
+ private MethodBindingType get_method_binding_type (Vala.Method element) {
+ if (element.is_inline) {
+ return MethodBindingType.INLINE;
+ } else if (element.is_abstract) {
+ return MethodBindingType.ABSTRACT;
+ } else if (element.is_virtual) {
+ return MethodBindingType.VIRTUAL;
+ } else if (element.overrides) {
+ return MethodBindingType.OVERRIDE;
+ } else if (element.is_inline) {
+ return MethodBindingType.INLINE;
+ } else if (element.binding == Vala.MemberBinding.INSTANCE) {
+ return MethodBindingType.STATIC;
+ }
+ return MethodBindingType.UNMODIFIED;
+ }
+
+
+ private SymbolAccessibility get_access_modifier(Vala.Symbol symbol) {
+ switch (symbol.access) {
+ case Vala.SymbolAccessibility.PROTECTED:
+ return SymbolAccessibility.PROTECTED;
+
+ case Vala.SymbolAccessibility.INTERNAL:
+ return SymbolAccessibility.INTERNAL;
+
+ case Vala.SymbolAccessibility.PRIVATE:
+ return SymbolAccessibility.PRIVATE;
+
+ case Vala.SymbolAccessibility.PUBLIC:
+ return SymbolAccessibility.PUBLIC;
+
+ default:
+ error ("Unknown symbol accessibility modifier found");
+ }
+ }
+
+ private PropertyAccessorType get_property_accessor_type (Vala.PropertyAccessor element) {
+ if (element.construction) {
+ return PropertyAccessorType.CONSTRUCT;
+ } else if (element.writable) {
+ return PropertyAccessorType.SET;
+ } else if (element.readable) {
+ return PropertyAccessorType.GET;
+ }
+
+ error ("Unknown symbol accessibility type");
+ }
+
+ private bool type_reference_pass_ownership (Vala.DataType? element) {
+ if (element == null) {
+ return false;
+ }
+
+ Vala.CodeNode? node = element.parent_node;
+ if (node == null) {
+ return false;
+ }
+ if (node is Vala.Parameter) {
+ return (((Vala.Parameter)node).direction == Vala.ParameterDirection.IN &&
+ ((Vala.Parameter)node).variable_type.value_owned);
+ }
+ if (node is Vala.Property) {
+ return ((Vala.Property)node).property_type.value_owned;
+ }
+
+ return false;
+ }
+
+ private bool is_type_reference_unowned (Vala.DataType? element) {
+ if (element == null) {
+ return false;
+ }
+
+ // non ref counted types are weak, not unowned
+ if (element.data_type is Vala.TypeSymbol && ((Vala.TypeSymbol) element.data_type).is_reference_counting () == true) {
+ return false;
+ }
+
+ // FormalParameters are weak by default
+ return (element.parent_node is Vala.Parameter == false)? element.is_weak () : false;
+ }
+
+ private bool is_type_reference_owned (Vala.DataType? element) {
+ if (element == null) {
+ return false;
+ }
+
+ Vala.CodeNode parent = element.parent_node;
+
+ // parameter:
+ if (parent is Vala.Parameter) {
+ if (((Vala.Parameter)parent).direction != Vala.ParameterDirection.IN) {
+ return false;
+ }
+ return ((Vala.Parameter)parent).variable_type.value_owned;
+ }
+
+ return false;
+ }
+
+ private bool is_type_reference_weak (Vala.DataType? element) {
+ if (element == null) {
+ return false;
+ }
+
+ // non ref counted types are unowned, not weak
+ if (element.data_type is Vala.TypeSymbol && ((Vala.TypeSymbol) element.data_type).is_reference_counting () == false) {
+ return false;
+ }
+
+ // FormalParameters are weak by default
+ return (element.parent_node is Vala.Parameter == false)? element.is_weak () : false;
+ }
+
+ private Ownership get_type_reference_ownership (Vala.DataType? element) {
+ if (is_type_reference_owned (element)) {
+ return Ownership.OWNED;
+ } else if (is_type_reference_weak (element)) {
+ return Ownership.WEAK;
+ } else if (is_type_reference_unowned (element)) {
+ return Ownership.UNOWNED;
+ }
+
+ return Ownership.DEFAULT;
+ }
+
+ private Ownership get_property_ownership (Vala.PropertyAccessor element) {
+ if (element.value_type.value_owned) {
+ return Ownership.OWNED;
+ }
+
+ // the exact type (weak, unowned) does not matter
+ return Ownership.UNOWNED;
+ }
+
+ private PropertyBindingType get_property_binding_type (Vala.Property element) {
+ if (element.is_abstract) {
+ return PropertyBindingType.ABSTRACT;
+ } else if (element.is_virtual) {
+ return PropertyBindingType.VIRTUAL;
+ } else if (element.overrides) {
+ return PropertyBindingType.OVERRIDE;
+ }
+
+ return PropertyBindingType.UNMODIFIED;
+ }
+
+ private FormalParameterType get_formal_parameter_type (Vala.Parameter element) {
+ if (element.direction == Vala.ParameterDirection.OUT) {
+ return FormalParameterType.OUT;
+ } else if (element.direction == Vala.ParameterDirection.REF) {
+ return FormalParameterType.REF;
+ } else if (element.direction == Vala.ParameterDirection.IN) {
+ return FormalParameterType.IN;
+ }
+
+ error ("Unknown formal parameter type");
+ }
+
+
+ //
+ // Vala tree creation:
+ //
+
+ private bool add_package (Vala.CodeContext context, string pkg) {
+ if (context.has_package (pkg)) {
+ // ignore multiple occurences of the same package
+ return true;
+ }
+
+ var package_path = context.get_vapi_path (pkg) ?? context.get_gir_path (pkg);
+ if (package_path == null) {
+ Vala.Report.error (null, "Package `%s' not found in specified Vala API directories or GObject-Introspection GIR directories".printf (pkg));
+ return false;
+ }
+
+ context.add_package (pkg);
+
+ var vfile = new Vala.SourceFile (context, Vala.SourceFileType.PACKAGE, package_path);
+ context.add_source_file (vfile);
+ Package vdpkg = new Package (vfile, pkg, true, null);
+ register_source_file (register_package (vdpkg), vfile);
+
+ add_deps (context, Path.build_filename (Path.get_dirname (package_path), "%s.deps".printf (pkg)), pkg);
+ return true;
+ }
+
+ private void add_deps (Vala.CodeContext context, string file_path, string pkg_name) {
+ if (FileUtils.test (file_path, FileTest.EXISTS)) {
+ try {
+ string deps_content;
+ ulong deps_len;
+ FileUtils.get_contents (file_path, out deps_content, out deps_len);
+ foreach (string dep in deps_content.split ("\n")) {
+ dep.strip ();
+ if (dep != "") {
+ if (!add_package (context, dep)) {
+ Vala.Report.error (null, "%s, dependency of %s, not found in specified Vala API directories".printf (dep, pkg_name));
+ }
+ }
+ }
+ } catch (FileError e) {
+ Vala.Report.error (null, "Unable to read dependency file: %s".printf (e.message));
+ }
+ }
+ }
+
+ /**
+ * Adds the specified packages to the list of used packages.
+ *
+ * @param context The code context
+ * @param packages a list of package names
+ */
+ private void add_depencies (Vala.CodeContext context, string[] packages) {
+ foreach (string package in packages) {
+ if (!add_package (context, package)) {
+ Vala.Report.error (null, "Package `%s' not found in specified Vala API directories or GObject-Introspection GIR directories".printf (package));
+ }
+ }
+ }
+
+ /**
+ * Add the specified source file to the context. Only .vala, .vapi, .gs,
+ * and .c files are supported.
+ */
+ private void add_documented_files (Vala.CodeContext context, string[] sources) {
+ if (sources == null) {
+ return;
+ }
+
+ foreach (string source in sources) {
+ if (FileUtils.test (source, FileTest.EXISTS)) {
+ var rpath = realpath (source);
+ if (source.has_suffix (".vala") || source.has_suffix (".gs")) {
+ var source_file = new Vala.SourceFile (context, Vala.SourceFileType.SOURCE, rpath);
+
+ if (source_package == null) {
+ source_package = register_package (new Package (source_file, settings.pkg_name, false, null));
+ }
+
+ register_source_file (source_package, source_file);
+
+ if (context.profile == Vala.Profile.POSIX) {
+ // import the Posix namespace by default (namespace of backend-specific standard library)
+ var ns_ref = new Vala.UsingDirective (new Vala.UnresolvedSymbol (null, "Posix", null));
+ source_file.add_using_directive (ns_ref);
+ context.root.add_using_directive (ns_ref);
+ } else if (context.profile == Vala.Profile.GOBJECT) {
+ // import the GLib namespace by default (namespace of backend-specific standard library)
+ var ns_ref = new Vala.UsingDirective (new Vala.UnresolvedSymbol (null, "GLib", null));
+ source_file.add_using_directive (ns_ref);
+ context.root.add_using_directive (ns_ref);
+ }
+
+ context.add_source_file (source_file);
+ } else if (source.has_suffix (".vapi")) {
+ string file_name = Path.get_basename (source);
+ file_name = file_name.substring (0, file_name.length - ".vapi".length);
+
+ var vfile = new Vala.SourceFile (context, Vala.SourceFileType.PACKAGE, rpath);
+ Package vdpkg = new Package (vfile, file_name, true, null);
+ context.add_source_file (vfile);
+
+ register_source_file (register_package (vdpkg), vfile);
+
+ add_deps (context, Path.build_filename (Path.get_dirname (source), "%s.deps".printf (file_name)), file_name);
+ } else if (source.has_suffix (".c")) {
+ context.add_c_source_file (rpath);
+ tree.add_external_c_files (rpath);
+ } else {
+ Vala.Report.error (null, "%s is not a supported source file type. Only .vala, .vapi, .gs, and .c files are supported.".printf (source));
+ }
+ } else {
+ Vala.Report.error (null, "%s not found".printf (source));
+ }
+ }
+ }
+
+ private Vala.CodeContext create_valac_tree (Settings settings) {
+ // init context:
+ var context = new Vala.CodeContext ();
+ Vala.CodeContext.push (context);
+
+
+ // settings:
+ context.experimental = settings.experimental;
+ context.experimental_non_null = settings.experimental || settings.experimental_non_null;
+ context.vapi_directories = settings.vapi_directories;
+ context.report.enable_warnings = settings.verbose;
+
+ if (settings.basedir == null) {
+ context.basedir = realpath (".");
+ } else {
+ context.basedir = realpath (settings.basedir);
+ }
+
+ if (settings.directory != null) {
+ context.directory = realpath (settings.directory);
+ } else {
+ context.directory = context.basedir;
+ }
+
+
+ // add default packages:
+ if (settings.profile == "gobject-2.0" || settings.profile == "gobject" || settings.profile == null) {
+ context.profile = Vala.Profile.GOBJECT;
+ context.add_define ("GOBJECT");
+ }
+
+
+ if (settings.defines != null) {
+ foreach (string define in settings.defines) {
+ context.add_define (define);
+ }
+ }
+
+ if (context.profile == Vala.Profile.POSIX) {
+ // default package
+ if (!add_package (context, "posix")) {
+ Vala.Report.error (null, "posix not found in specified Vala API directories");
+ }
+ } else if (context.profile == Vala.Profile.GOBJECT) {
+ int glib_major = 2;
+ int glib_minor = 12;
+
+ context.target_glib_major = glib_major;
+ context.target_glib_minor = glib_minor;
+ if (context.target_glib_major != 2) {
+ Vala.Report.error (null, "This version of valac only supports GLib 2");
+ }
+
+ // default packages
+ if (!this.add_package (context, "glib-2.0")) { //
+ Vala.Report.error (null, "glib-2.0 not found in specified Vala API directories");
+ }
+
+ if (!this.add_package (context, "gobject-2.0")) { //
+ Vala.Report.error (null, "gobject-2.0 not found in specified Vala API directories");
+ }
+ }
+
+
+ // add user defined files:
+ add_depencies (context, settings.packages);
+ if (reporter.errors > 0) {
+ return context;
+ }
+
+ add_documented_files (context, settings.source_files);
+ if (reporter.errors > 0) {
+ return context;
+ }
+
+
+ // parse vala-code:
+ Vala.Parser parser = new Vala.Parser ();
+
+ parser.parse (context);
+ if (context.report.get_errors () > 0) {
+ return context;
+ }
+
+
+ // check context:
+ context.check ();
+ if (context.report.get_errors () > 0) {
+ return context;
+ }
+
+ return context;
+ }
+
+
+
+ //
+ // Valadoc tree creation:
+ //
+
+ private void process_children (Api.Node node, Vala.Symbol element) {
+ Api.Node old_node = current_node;
+ current_node = node;
+ element.accept_children (this);
+ current_node = old_node;
+ }
+
+ private Api.Node get_parent_node_for (Vala.Symbol element) {
+ if (current_node != null) {
+ return current_node;
+ }
+
+ Vala.SourceFile vala_source_file = element.source_reference.file;
+ Package package = find_package_for_file (vala_source_file);
+ SourceFile? source_file = get_source_file (element);
+
+ return get_namespace (package, element, source_file);
+ }
+
+ /**
+ * { inheritDoc}
+ */
+ public override void visit_namespace (Vala.Namespace element) {
+ element.accept_children (this);
+ }
+
+ /**
+ * { inheritDoc}
+ */
+ public override void visit_class (Vala.Class element) {
+ Api.Node parent = get_parent_node_for (element);
+ SourceFile? file = get_source_file (element);
+ SourceComment? comment = create_comment (element.comment);
+
+ bool is_basic_type = element.base_class == null && element.name == "string";
+
+ Class node = new Class (parent, file, element.name, get_access_modifier(element), comment, element.get_cname (), Vala.GDBusModule.get_dbus_name (element), element.get_param_spec_function (), element.get_type_id (), element.get_ref_function (), element.get_unref_function (), element.get_take_value_function (), element.get_get_value_function (), element.get_set_value_function (), element.is_fundamental (), element.is_abstract, is_basic_type, element);
+ symbol_map.set (element, node);
+ parent.add_child (node);
+
+ // relations
+ foreach (Vala.DataType vala_type_ref in element.get_base_types ()) {
+ var type_ref = create_type_reference (vala_type_ref, node);
+
+ if (vala_type_ref.data_type is Vala.Interface) {
+ node.add_interface (type_ref);
+ } else {
+ node.base_type = type_ref;
+ }
+ }
+
+ process_children (node, element);
+
+ // save GLib.Error
+ if (glib_error == null && node.get_full_name () == "GLib.Error") {
+ glib_error = node;
+ }
+ }
+
+ /**
+ * { inheritDoc}
+ */
+ public override void visit_interface (Vala.Interface element) {
+ Api.Node parent = get_parent_node_for (element);
+ SourceFile? file = get_source_file (element);
+ SourceComment? comment = create_comment (element.comment);
+
+ Interface node = new Interface (parent, file, element.name, get_access_modifier(element), comment, element.get_cname (), Vala.GDBusModule.get_dbus_name (element), element);
+ symbol_map.set (element, node);
+ parent.add_child (node);
+
+ // prerequisites:
+ foreach (Vala.DataType vala_type_ref in element.get_prerequisites ()) {
+ TypeReference type_ref = create_type_reference (vala_type_ref, node);
+ if (vala_type_ref.data_type is Vala.Interface) {
+ node.add_interface (type_ref);
+ } else {
+ node.base_type = type_ref;
+ }
+ }
+
+ process_children (node, element);
+ }
+
+ /**
+ * { inheritDoc}
+ */
+ public override void visit_struct (Vala.Struct element) {
+ Api.Node parent = get_parent_node_for (element);
+ SourceFile? file = get_source_file (element);
+ SourceComment? comment = create_comment (element.comment);
+
+ bool is_basic_type = element.base_type == null && (element.is_boolean_type () || element.is_floating_type () || element.is_integer_type ());
+
+ Struct node = new Struct (parent, file, element.name, get_access_modifier(element), comment, element.get_cname(), element.get_dup_function (), element.get_free_function (), is_basic_type, element);
+ symbol_map.set (element, node);
+ parent.add_child (node);
+
+ // parent type:
+ Vala.ValueType? basetype = element.base_type as Vala.ValueType;
+ if (basetype != null) {
+ node.base_type = create_type_reference (basetype, node);
+ }
+
+ process_children (node, element);
+ }
+
+ /**
+ * { inheritDoc}
+ */
+ public override void visit_field (Vala.Field element) {
+ Api.Node parent = get_parent_node_for (element);
+ SourceFile? file = get_source_file (element);
+ SourceComment? comment = create_comment (element.comment);
+
+ Field node = new Field (parent, file, element.name, get_access_modifier(element), comment, element.get_cname (), element.binding == Vala.MemberBinding.STATIC, element.is_volatile, element);
+ node.field_type = create_type_reference (element.variable_type, node);
+ symbol_map.set (element, node);
+ parent.add_child (node);
+
+ process_children (node, element);
+ }
+
+ /**
+ * { inheritDoc}
+ */
+ public override void visit_property (Vala.Property element) {
+ Api.Node parent = get_parent_node_for (element);
+ SourceFile? file = get_source_file (element);
+ SourceComment? comment = create_comment (element.comment);
+
+ Property node = new Property (parent, file, element.name, get_access_modifier(element), comment, element.nick, Vala.GDBusModule.get_dbus_name_for_member (element), Vala.GDBusServerModule.is_dbus_visible (element), get_property_binding_type (element), element);
+ node.property_type = create_type_reference (element.property_type, node);
+ symbol_map.set (element, node);
+ parent.add_child (node);
+
+ // Process property type
+ if (element.get_accessor != null) {
+ var accessor = element.get_accessor;
+ node.getter = new PropertyAccessor (node, file, element.name, get_access_modifier(element), accessor.get_cname(), get_property_accessor_type (accessor), get_property_ownership (accessor), accessor);
+ }
+
+ if (element.set_accessor != null) {
+ var accessor = element.set_accessor;
+ node.setter = new PropertyAccessor (node, file, element.name, get_access_modifier(element), accessor.get_cname(), get_property_accessor_type (accessor), get_property_ownership (accessor), accessor);
+ }
+
+ process_children (node, element);
+ }
+
+ /**
+ * { inheritDoc}
+ */
+ public override void visit_creation_method (Vala.CreationMethod element) {
+ Api.Node parent = get_parent_node_for (element);
+ SourceFile? file = get_source_file (element);
+ SourceComment? comment = create_comment (element.comment);
+
+ Method node = new Method (parent, file, get_method_name (element), get_access_modifier(element), comment, element.get_cname (), Vala.GDBusModule.get_dbus_name_for_member (element), Vala.GDBusServerModule.dbus_result_name (element), (element.coroutine)? element.get_finish_cname () : null, get_method_binding_type (element), element.coroutine, Vala.GDBusServerModule.is_dbus_visible (element), element is Vala.CreationMethod, element);
+ node.return_type = create_type_reference (element.return_type, node);
+ symbol_map.set (element, node);
+ parent.add_child (node);
+
+ process_children (node, element);
+ }
+
+ /**
+ * { inheritDoc}
+ */
+ public override void visit_method (Vala.Method element) {
+ Api.Node parent = get_parent_node_for (element);
+ SourceFile? file = get_source_file (element);
+ SourceComment? comment = create_comment (element.comment);
+
+ Method node = new Method (parent, file, get_method_name (element), get_access_modifier(element), comment, element.get_cname (), Vala.GDBusModule.get_dbus_name_for_member (element), Vala.GDBusServerModule.dbus_result_name (element), (element.coroutine)? element.get_finish_cname () : null, get_method_binding_type (element), element.coroutine, Vala.GDBusServerModule.is_dbus_visible (element), element is Vala.CreationMethod, element);
+ node.return_type = create_type_reference (element.return_type, node);
+ symbol_map.set (element, node);
+ parent.add_child (node);
+
+ process_children (node, element);
+ }
+
+ /**
+ * { inheritDoc}
+ */
+ public override void visit_signal (Vala.Signal element) {
+ Api.Node parent = get_parent_node_for (element);
+ SourceFile? file = get_source_file (element);
+ SourceComment? comment = create_comment (element.comment);
+
+ Api.Signal node = new Api.Signal (parent, file, element.name, get_access_modifier(element), comment, element.get_cname(), Vala.GDBusModule.get_dbus_name_for_member (element), Vala.GDBusServerModule.is_dbus_visible (element), element.is_virtual, element);
+ node.return_type = create_type_reference (element.return_type, node);
+ symbol_map.set (element, node);
+ parent.add_child (node);
+
+ process_children (node, element);
+ }
+
+ /**
+ * { inheritDoc}
+ */
+ public override void visit_delegate (Vala.Delegate element) {
+ Api.Node parent = get_parent_node_for (element);
+ SourceFile? file = get_source_file (element);
+ SourceComment? comment = create_comment (element.comment);
+
+ Delegate node = new Delegate (parent, file, element.name, get_access_modifier(element), comment, element.get_cname (), element.has_target, element);
+ node.return_type = create_type_reference (element.return_type, node);
+ symbol_map.set (element, node);
+ parent.add_child (node);
+
+ process_children (node, element);
+ }
+
+ /**
+ * { inheritDoc}
+ */
+ public override void visit_enum (Vala.Enum element) {
+ Api.Node parent = get_parent_node_for (element);
+ SourceFile? file = get_source_file (element);
+ SourceComment? comment = create_comment (element.comment);
+
+ Symbol node = new Enum (parent, file, element.name, get_access_modifier(element), comment, element.get_cname (), element);
+ symbol_map.set (element, node);
+ parent.add_child (node);
+
+ process_children (node, element);
+ }
+
+ /**
+ * { inheritDoc}
+ */
+ public override void visit_enum_value (Vala.EnumValue element) {
+ Api.Enum parent = (Enum) get_parent_node_for (element);
+ SourceFile? file = get_source_file (element);
+ SourceComment? comment = create_comment (element.comment);
+
+ Symbol node = new Api.EnumValue (parent, file, element.name, comment, element.get_cname (), element);
+ symbol_map.set (element, node);
+ parent.add_child (node);
+
+ process_children (node, element);
+ }
+
+ /**
+ * { inheritDoc}
+ */
+ public override void visit_constant (Vala.Constant element) {
+ Api.Node parent = get_parent_node_for (element);
+ SourceFile? file = get_source_file (element);
+ SourceComment? comment = create_comment (element.comment);
+
+ Constant node = new Constant (parent, file, element.name, get_access_modifier(element), comment, element.get_cname (), element);
+ node.constant_type = create_type_reference (element.type_reference, node);
+ symbol_map.set (element, node);
+ parent.add_child (node);
+
+ process_children (node, element);
+ }
+
+ /**
+ * { inheritDoc}
+ */
+ public override void visit_error_domain (Vala.ErrorDomain element) {
+ Api.Node parent = get_parent_node_for (element);
+ SourceFile? file = get_source_file (element);
+ SourceComment? comment = create_comment (element.comment);
+
+ Symbol node = new ErrorDomain (parent, file, element.name, get_access_modifier(element), comment, element.get_cname(), Vala.GDBusModule.get_dbus_name (element), element);
+ symbol_map.set (element, node);
+ parent.add_child (node);
+
+ process_children (node, element);
+ }
+
+ /**
+ * { inheritDoc}
+ */
+ public override void visit_error_code (Vala.ErrorCode element) {
+ Api.ErrorDomain parent = (ErrorDomain) get_parent_node_for (element);
+ SourceFile? file = get_source_file (element);
+ SourceComment? comment = create_comment (element.comment);
+
+ Symbol node = new Api.ErrorCode (parent, file, element.name, comment, element.get_cname (), Vala.GDBusModule.get_dbus_name_for_member (element), element);
+ symbol_map.set (element, node);
+ parent.add_child (node);
+
+ process_children (node, element);
+ }
+
+ /**
+ * { inheritDoc}
+ */
+ public override void visit_type_parameter (Vala.TypeParameter element) {
+ Api.Node parent = get_parent_node_for (element);
+ SourceFile? file = get_source_file (element);
+
+ Symbol node = new TypeParameter (parent, file, element.name, element);
+ parent.add_child (node);
+
+ process_children (node, element);
+ }
+
+ /**
+ * { inheritDoc}
+ */
+ public override void visit_formal_parameter (Vala.Parameter element) {
+ Api.Node parent = get_parent_node_for (element);
+ SourceFile? file = get_source_file (element);
+
+ FormalParameter node = new FormalParameter (parent, file, element.name, get_access_modifier(element), get_formal_parameter_type (element), element.ellipsis, element);
+ node.parameter_type = create_type_reference (element.variable_type, node);
+ parent.add_child (node);
+
+ process_children (node, element);
+ }
+
+
+ //
+ // startpoint:
+ //
+
+ public Api.Tree? build (Settings settings, ErrorReporter reporter) {
+ this.tree = new Api.Tree (reporter, settings);
+ this.settings = settings;
+ this.reporter = reporter;
+
+ var context = create_valac_tree (settings);
+
+ reporter.warnings_offset = context.report.get_warnings ();
+ reporter.errors_offset = context.report.get_errors ();
+
+ if (context == null) {
+ return null;
+ }
+
+ context.accept(this);
+
+ return (reporter.errors == 0)? tree : null;
+ }
+}
+
+
diff --git a/src/driver/Makefile.am b/src/driver/Makefile.am
new file mode 100755
index 0000000..5e22e88
--- /dev/null
+++ b/src/driver/Makefile.am
@@ -0,0 +1,10 @@
+# src/Makefile.am
+
+NULL =
+
+
+SUBDIRS = \
+ 0.13.x \
+ $(NULL)
+
+
diff --git a/src/libvaladoc/Makefile.am b/src/libvaladoc/Makefile.am
index da6bf19..64c277b 100755
--- a/src/libvaladoc/Makefile.am
+++ b/src/libvaladoc/Makefile.am
@@ -43,7 +43,6 @@ libvaladoc_la_VALASOURCES = \
importer/valadocdocumentationimporter.vala \
importer/valadocdocumentationimporterscanner.vala \
api/symbolaccessibility.vala \
- api/symbolresolver.vala \
api/sourcecomment.vala \
api/array.vala \
api/class.vala \
@@ -57,7 +56,6 @@ libvaladoc_la_VALASOURCES = \
api/formalparameter.vala \
api/formalparametertype.vala \
api/interface.vala \
- api/initializerbuilder.vala \
api/item.vala \
api/member.vala \
api/method.vala \
diff --git a/src/libvaladoc/api/class.vala b/src/libvaladoc/api/class.vala
index 00441d6..a820d82 100755
--- a/src/libvaladoc/api/class.vala
+++ b/src/libvaladoc/api/class.vala
@@ -226,11 +226,11 @@ public class Valadoc.Api.Class : TypeSymbol {
return _known_derived_interfaces.read_only_view;
}
- internal void register_derived_interface (Interface iface) {
+ public void register_derived_interface (Interface iface) {
_known_derived_interfaces.add (iface);
}
- internal void register_child_class (Class cl) {
+ public void register_child_class (Class cl) {
if (this.base_type != null) {
((Class) this.base_type.data_type).register_child_class (cl);
}
diff --git a/src/libvaladoc/api/driver.vala b/src/libvaladoc/api/driver.vala
index c1376b1..0bcfc63 100755
--- a/src/libvaladoc/api/driver.vala
+++ b/src/libvaladoc/api/driver.vala
@@ -25,953 +25,18 @@ using Gee;
/**
- * Creates an simpler, minimized, more abstract AST for valacs AST.
+ * A plugin register function for drivers
+ *
+ * @see ModuleLoader
*/
-public class Valadoc.Api.Driver : Vala.CodeVisitor {
- private ArrayList<PackageMetaData> packages = new ArrayList<PackageMetaData> ();
- private PackageMetaData source_package;
-
- private HashMap<Vala.SourceFile, SourceFile> files = new HashMap<Vala.SourceFile, SourceFile> ();
- private HashMap<Vala.Symbol, Symbol> symbol_map = new HashMap<Vala.Symbol, Symbol> ();
-
- private ErrorReporter reporter;
- private Settings settings;
-
- private Api.Node current_node;
- private Api.Tree tree;
-
- private Valadoc.Api.Class glib_error = null;
-
-
- private class PackageMetaData {
- public Package package;
- public HashMap<Vala.Namespace, Namespace> namespaces = new HashMap<Vala.Namespace, Namespace> ();
- public ArrayList<Vala.SourceFile> files = new ArrayList<Vala.SourceFile> ();
-
- public PackageMetaData (Package package) {
- this.package = package;
- }
-
- public Namespace get_namespace (Vala.Namespace vns, SourceFile? file) {
- Namespace? ns = namespaces.get (vns);
- if (ns != null) {
- return ns;
- }
-
- // find documentation comment if existing:
- SourceComment? comment = null;
- if (vns.source_reference != null) {
- foreach (Vala.Comment c in vns.get_comments()) {
- if (c.source_reference.file == vns.source_reference.file) {
- Vala.SourceReference pos = c.source_reference;
- comment = new SourceComment (c.content, file, pos.first_line, pos.first_column, pos.last_line, pos.last_column);
- break;
- }
- }
- }
-
- // find parent if existing
- var parent_vns = vns.parent_symbol;
-
- if (parent_vns == null) {
- ns = new Namespace (package, file, vns.name, comment, vns);
- package.add_child (ns);
- } else {
- Namespace parent_ns = get_namespace ((Vala.Namespace) parent_vns, file);
- ns = new Namespace (parent_ns, file, vns.name, comment, vns);
- parent_ns.add_child (ns);
- }
-
- namespaces.set (vns, ns);
- return ns;
- }
-
- public void register_source_file (Vala.SourceFile file) {
- files.add (file);
- }
-
- public bool is_package_for_file (Vala.SourceFile source_file) {
- if (source_file.file_type == Vala.SourceFileType.SOURCE && !package.is_package) {
- return true;
- }
-
- return files.contains (source_file);
- }
- }
-
-
- //
- // Type constructor translation helpers:
- //
-
- private Pointer create_pointer (Vala.PointerType vtyperef, Item parent) {
- Pointer ptr = new Pointer (parent, vtyperef);
-
- Vala.DataType vntype = vtyperef.base_type;
- if (vntype is Vala.PointerType) {
- ptr.data_type = create_pointer ((Vala.PointerType) vntype, ptr);
- } else if (vntype is Vala.ArrayType) {
- ptr.data_type = create_array ((Vala.ArrayType) vntype, ptr);
- } else {
- ptr.data_type = create_type_reference (vntype, ptr);
- }
-
- return ptr;
- }
-
- private Array create_array (Vala.ArrayType vtyperef, Item parent) {
- Array arr = new Array (parent, vtyperef);
-
- Vala.DataType vntype = vtyperef.element_type;
- if (vntype is Vala.ArrayType) {
- arr.data_type = create_array ((Vala.ArrayType) vntype, arr);
- } else {
- arr.data_type = create_type_reference (vntype, arr);
- }
-
- return arr;
- }
-
- private TypeReference create_type_reference (Vala.DataType? vtyperef, Item parent) {
- bool is_nullable = vtyperef != null && vtyperef.nullable && !(vtyperef is Vala.GenericType) && !(vtyperef is Vala.PointerType);
- string? signature = (vtyperef != null && vtyperef.data_type != null)? Vala.GVariantModule.get_dbus_signature (vtyperef.data_type) : null;
- bool pass_ownership = type_reference_pass_ownership (vtyperef);
- Ownership ownership = get_type_reference_ownership (vtyperef);
- bool is_dynamic = vtyperef != null && vtyperef.is_dynamic;
-
- TypeReference type_ref = new TypeReference (parent, ownership, pass_ownership, is_dynamic, is_nullable, signature, vtyperef);
-
- if (vtyperef is Vala.PointerType) {
- type_ref.data_type = create_pointer ((Vala.PointerType) vtyperef, type_ref);
- } else if (vtyperef is Vala.ArrayType) {
- type_ref.data_type = create_array ((Vala.ArrayType) vtyperef, type_ref);
- }
-
- // type parameters:
- if (vtyperef != null) {
- foreach (Vala.DataType vdtype in vtyperef.get_type_arguments ()) {
- var type_param = create_type_reference (vdtype, type_ref);
- type_ref.add_type_argument (type_param);
- }
- }
-
- return type_ref;
- }
-
-
-
- //
- // Translation helpers:
- //
-
- private SourceComment? create_comment (Vala.Comment? comment) {
- if (comment != null) {
- Vala.SourceReference pos = comment.source_reference;
- SourceFile file = files.get (pos.file);
- return new SourceComment (comment.content, file, pos.first_line, pos.first_column, pos.last_line, pos.last_column);
- }
-
- return null;
- }
-
- private string get_method_name (Vala.Method element) {
- if (element is Vala.CreationMethod) {
- if (element.name == ".new") {
- return element.parent_symbol.name;
- } else {
- return element.parent_symbol.name + "." + element.name;
- }
- }
-
- return element.name;
- }
-
- private PackageMetaData? get_package_meta_data (Package pkg) {
- foreach (PackageMetaData data in packages) {
- if (data.package == pkg) {
- return data;
- }
- }
-
- return null;
- }
-
- private PackageMetaData register_package (Package package) {
- PackageMetaData meta_data = new PackageMetaData (package);
- tree.add_package (package);
- packages.add (meta_data);
- return meta_data;
- }
-
- private SourceFile register_source_file (PackageMetaData meta_data, Vala.SourceFile source_file) {
- SourceFile file = new SourceFile (source_file.get_relative_filename (), source_file.get_csource_filename ());
- files.set (source_file, file);
-
- meta_data.register_source_file (source_file);
- return file;
- }
-
- private SourceFile? get_source_file (Vala.Symbol symbol) {
- Vala.SourceReference source_ref = symbol.source_reference;
- if (source_ref == null) {
- return null;
- }
-
- SourceFile file = files.get (source_ref.file);
- assert (file != null);
- return file;
- }
-
- private Package? find_package_for_file (Vala.SourceFile source_file) {
- foreach (PackageMetaData pkg in this.packages) {
- if (pkg.is_package_for_file (source_file)) {
- return pkg.package;
- }
- }
-
- return null;
- }
-
-
- private Namespace get_namespace (Package pkg, Vala.Symbol symbol, SourceFile? file) {
- // Find the closest namespace in our vala-tree
- Vala.Symbol namespace_symbol = symbol;
- while (!(namespace_symbol is Vala.Namespace)) {
- namespace_symbol = namespace_symbol.parent_symbol;
- }
-
- PackageMetaData? meta_data = get_package_meta_data (pkg);
- assert (meta_data != null);
-
- return meta_data.get_namespace ((Vala.Namespace) namespace_symbol, file);
- }
-
- private MethodBindingType get_method_binding_type (Vala.Method element) {
- if (element.is_inline) {
- return MethodBindingType.INLINE;
- } else if (element.is_abstract) {
- return MethodBindingType.ABSTRACT;
- } else if (element.is_virtual) {
- return MethodBindingType.VIRTUAL;
- } else if (element.overrides) {
- return MethodBindingType.OVERRIDE;
- } else if (element.is_inline) {
- return MethodBindingType.INLINE;
- } else if (element.binding == Vala.MemberBinding.INSTANCE) {
- return MethodBindingType.STATIC;
- }
- return MethodBindingType.UNMODIFIED;
- }
-
-
- private SymbolAccessibility get_access_modifier(Vala.Symbol symbol) {
- switch (symbol.access) {
- case Vala.SymbolAccessibility.PROTECTED:
- return SymbolAccessibility.PROTECTED;
-
- case Vala.SymbolAccessibility.INTERNAL:
- return SymbolAccessibility.INTERNAL;
-
- case Vala.SymbolAccessibility.PRIVATE:
- return SymbolAccessibility.PRIVATE;
-
- case Vala.SymbolAccessibility.PUBLIC:
- return SymbolAccessibility.PUBLIC;
-
- default:
- error ("Unknown symbol accessibility modifier found");
- }
- }
-
- private PropertyAccessorType get_property_accessor_type (Vala.PropertyAccessor element) {
- if (element.construction) {
- return PropertyAccessorType.CONSTRUCT;
- } else if (element.writable) {
- return PropertyAccessorType.SET;
- } else if (element.readable) {
- return PropertyAccessorType.GET;
- }
-
- error ("Unknown symbol accessibility type");
- }
-
- private bool type_reference_pass_ownership (Vala.DataType? element) {
- if (element == null) {
- return false;
- }
-
- Vala.CodeNode? node = element.parent_node;
- if (node == null) {
- return false;
- }
- if (node is Vala.Parameter) {
- return (((Vala.Parameter)node).direction == Vala.ParameterDirection.IN &&
- ((Vala.Parameter)node).variable_type.value_owned);
- }
- if (node is Vala.Property) {
- return ((Vala.Property)node).property_type.value_owned;
- }
-
- return false;
- }
-
- private bool is_type_reference_unowned (Vala.DataType? element) {
- if (element == null) {
- return false;
- }
-
- // non ref counted types are weak, not unowned
- if (element.data_type is Vala.TypeSymbol && ((Vala.TypeSymbol) element.data_type).is_reference_counting () == true) {
- return false;
- }
-
- // FormalParameters are weak by default
- return (element.parent_node is Vala.Parameter == false)? element.is_weak () : false;
- }
-
- private bool is_type_reference_owned (Vala.DataType? element) {
- if (element == null) {
- return false;
- }
-
- Vala.CodeNode parent = element.parent_node;
-
- // parameter:
- if (parent is Vala.Parameter) {
- if (((Vala.Parameter)parent).direction != Vala.ParameterDirection.IN) {
- return false;
- }
- return ((Vala.Parameter)parent).variable_type.value_owned;
- }
-
- return false;
- }
-
- private bool is_type_reference_weak (Vala.DataType? element) {
- if (element == null) {
- return false;
- }
-
- // non ref counted types are unowned, not weak
- if (element.data_type is Vala.TypeSymbol && ((Vala.TypeSymbol) element.data_type).is_reference_counting () == false) {
- return false;
- }
-
- // FormalParameters are weak by default
- return (element.parent_node is Vala.Parameter == false)? element.is_weak () : false;
- }
-
- private Ownership get_type_reference_ownership (Vala.DataType? element) {
- if (is_type_reference_owned (element)) {
- return Ownership.OWNED;
- } else if (is_type_reference_weak (element)) {
- return Ownership.WEAK;
- } else if (is_type_reference_unowned (element)) {
- return Ownership.UNOWNED;
- }
-
- return Ownership.DEFAULT;
- }
-
- private Ownership get_property_ownership (Vala.PropertyAccessor element) {
- if (element.value_type.value_owned) {
- return Ownership.OWNED;
- }
-
- // the exact type (weak, unowned) does not matter
- return Ownership.UNOWNED;
- }
-
- private PropertyBindingType get_property_binding_type (Vala.Property element) {
- if (element.is_abstract) {
- return PropertyBindingType.ABSTRACT;
- } else if (element.is_virtual) {
- return PropertyBindingType.VIRTUAL;
- } else if (element.overrides) {
- return PropertyBindingType.OVERRIDE;
- }
-
- return PropertyBindingType.UNMODIFIED;
- }
-
- private FormalParameterType get_formal_parameter_type (Vala.Parameter element) {
- if (element.direction == Vala.ParameterDirection.OUT) {
- return FormalParameterType.OUT;
- } else if (element.direction == Vala.ParameterDirection.REF) {
- return FormalParameterType.REF;
- } else if (element.direction == Vala.ParameterDirection.IN) {
- return FormalParameterType.IN;
- }
-
- error ("Unknown formal parameter type");
- }
-
-
- //
- // Vala tree creation:
- //
-
- private bool add_package (Vala.CodeContext context, string pkg) {
- if (context.has_package (pkg)) {
- // ignore multiple occurences of the same package
- return true;
- }
-
- var package_path = context.get_vapi_path (pkg) ?? context.get_gir_path (pkg);
- if (package_path == null) {
- Vala.Report.error (null, "Package `%s' not found in specified Vala API directories or GObject-Introspection GIR directories".printf (pkg));
- return false;
- }
-
- context.add_package (pkg);
-
- var vfile = new Vala.SourceFile (context, Vala.SourceFileType.PACKAGE, package_path);
- context.add_source_file (vfile);
- Package vdpkg = new Package (vfile, pkg, true, null);
- register_source_file (register_package (vdpkg), vfile);
-
- add_deps (context, Path.build_filename (Path.get_dirname (package_path), "%s.deps".printf (pkg)), pkg);
- return true;
- }
-
- private void add_deps (Vala.CodeContext context, string file_path, string pkg_name) {
- if (FileUtils.test (file_path, FileTest.EXISTS)) {
- try {
- string deps_content;
- ulong deps_len;
- FileUtils.get_contents (file_path, out deps_content, out deps_len);
- foreach (string dep in deps_content.split ("\n")) {
- dep.strip ();
- if (dep != "") {
- if (!add_package (context, dep)) {
- Vala.Report.error (null, "%s, dependency of %s, not found in specified Vala API directories".printf (dep, pkg_name));
- }
- }
- }
- } catch (FileError e) {
- Vala.Report.error (null, "Unable to read dependency file: %s".printf (e.message));
- }
- }
- }
-
- /**
- * Adds the specified packages to the list of used packages.
- *
- * @param context The code context
- * @param packages a list of package names
- */
- private void add_depencies (Vala.CodeContext context, string[] packages) {
- foreach (string package in packages) {
- if (!add_package (context, package)) {
- Vala.Report.error (null, "Package `%s' not found in specified Vala API directories or GObject-Introspection GIR directories".printf (package));
- }
- }
- }
-
- /**
- * Add the specified source file to the context. Only .vala, .vapi, .gs,
- * and .c files are supported.
- */
- private void add_documented_files (Vala.CodeContext context, string[] sources) {
- if (sources == null) {
- return;
- }
-
- foreach (string source in sources) {
- if (FileUtils.test (source, FileTest.EXISTS)) {
- var rpath = realpath (source);
- if (source.has_suffix (".vala") || source.has_suffix (".gs")) {
- var source_file = new Vala.SourceFile (context, Vala.SourceFileType.SOURCE, rpath);
-
- if (source_package == null) {
- source_package = register_package (new Package (source_file, settings.pkg_name, false, null));
- }
-
- register_source_file (source_package, source_file);
-
- if (context.profile == Vala.Profile.POSIX) {
- // import the Posix namespace by default (namespace of backend-specific standard library)
- var ns_ref = new Vala.UsingDirective (new Vala.UnresolvedSymbol (null, "Posix", null));
- source_file.add_using_directive (ns_ref);
- context.root.add_using_directive (ns_ref);
- } else if (context.profile == Vala.Profile.GOBJECT) {
- // import the GLib namespace by default (namespace of backend-specific standard library)
- var ns_ref = new Vala.UsingDirective (new Vala.UnresolvedSymbol (null, "GLib", null));
- source_file.add_using_directive (ns_ref);
- context.root.add_using_directive (ns_ref);
- }
-
- context.add_source_file (source_file);
- } else if (source.has_suffix (".vapi")) {
- string file_name = Path.get_basename (source);
- file_name = file_name.substring (0, file_name.length - ".vapi".length);
-
- var vfile = new Vala.SourceFile (context, Vala.SourceFileType.PACKAGE, rpath);
- Package vdpkg = new Package (vfile, file_name, true, null);
- context.add_source_file (vfile);
-
- register_source_file (register_package (vdpkg), vfile);
-
- add_deps (context, Path.build_filename (Path.get_dirname (source), "%s.deps".printf (file_name)), file_name);
- } else if (source.has_suffix (".c")) {
- context.add_c_source_file (rpath);
- tree.add_external_c_files (rpath);
- } else {
- Vala.Report.error (null, "%s is not a supported source file type. Only .vala, .vapi, .gs, and .c files are supported.".printf (source));
- }
- } else {
- Vala.Report.error (null, "%s not found".printf (source));
- }
- }
- }
-
- private Vala.CodeContext create_valac_tree (Settings settings) {
- // init context:
- var context = new Vala.CodeContext ();
- Vala.CodeContext.push (context);
-
-
- // settings:
- context.experimental = settings.experimental;
- context.experimental_non_null = settings.experimental || settings.experimental_non_null;
- context.vapi_directories = settings.vapi_directories;
- context.report.enable_warnings = settings.verbose;
-
- if (settings.basedir == null) {
- context.basedir = realpath (".");
- } else {
- context.basedir = realpath (settings.basedir);
- }
-
- if (settings.directory != null) {
- context.directory = realpath (settings.directory);
- } else {
- context.directory = context.basedir;
- }
-
-
- // add default packages:
- if (settings.profile == "gobject-2.0" || settings.profile == "gobject" || settings.profile == null) {
- context.profile = Vala.Profile.GOBJECT;
- context.add_define ("GOBJECT");
- }
-
-
- if (settings.defines != null) {
- foreach (string define in settings.defines) {
- context.add_define (define);
- }
- }
-
- if (context.profile == Vala.Profile.POSIX) {
- // default package
- if (!add_package (context, "posix")) {
- Vala.Report.error (null, "posix not found in specified Vala API directories");
- }
- } else if (context.profile == Vala.Profile.GOBJECT) {
- int glib_major = 2;
- int glib_minor = 12;
-
- context.target_glib_major = glib_major;
- context.target_glib_minor = glib_minor;
- if (context.target_glib_major != 2) {
- Vala.Report.error (null, "This version of valac only supports GLib 2");
- }
-
- // default packages
- if (!this.add_package (context, "glib-2.0")) { //
- Vala.Report.error (null, "glib-2.0 not found in specified Vala API directories");
- }
-
- if (!this.add_package (context, "gobject-2.0")) { //
- Vala.Report.error (null, "gobject-2.0 not found in specified Vala API directories");
- }
- }
-
-
- // add user defined files:
- add_depencies (context, settings.packages);
- if (reporter.errors > 0) {
- return context;
- }
-
- add_documented_files (context, settings.source_files);
- if (reporter.errors > 0) {
- return context;
- }
-
-
- // parse vala-code:
- Vala.Parser parser = new Vala.Parser ();
-
- parser.parse (context);
- if (context.report.get_errors () > 0) {
- return context;
- }
-
-
- // check context:
- context.check ();
- if (context.report.get_errors () > 0) {
- return context;
- }
-
- return context;
- }
-
-
-
- //
- // Valadoc tree creation:
- //
-
- private void process_children (Api.Node node, Vala.Symbol element) {
- Api.Node old_node = current_node;
- current_node = node;
- element.accept_children (this);
- current_node = old_node;
- }
-
- private Api.Node get_parent_node_for (Vala.Symbol element) {
- if (current_node != null) {
- return current_node;
- }
-
- Vala.SourceFile vala_source_file = element.source_reference.file;
- Package package = find_package_for_file (vala_source_file);
- SourceFile? source_file = get_source_file (element);
-
- return get_namespace (package, element, source_file);
- }
-
- /**
- * { inheritDoc}
- */
- public override void visit_namespace (Vala.Namespace element) {
- element.accept_children (this);
- }
-
- /**
- * { inheritDoc}
- */
- public override void visit_class (Vala.Class element) {
- Api.Node parent = get_parent_node_for (element);
- SourceFile? file = get_source_file (element);
- SourceComment? comment = create_comment (element.comment);
-
- bool is_basic_type = element.base_class == null && element.name == "string";
-
- Class node = new Class (parent, file, element.name, get_access_modifier(element), comment, element.get_cname (), Vala.GDBusModule.get_dbus_name (element), element.get_param_spec_function (), element.get_type_id (), element.get_ref_function (), element.get_unref_function (), element.get_take_value_function (), element.get_get_value_function (), element.get_set_value_function (), element.is_fundamental (), element.is_abstract, is_basic_type, element);
- symbol_map.set (element, node);
- parent.add_child (node);
-
- // relations
- foreach (Vala.DataType vala_type_ref in element.get_base_types ()) {
- var type_ref = create_type_reference (vala_type_ref, node);
-
- if (vala_type_ref.data_type is Vala.Interface) {
- node.add_interface (type_ref);
- } else {
- node.base_type = type_ref;
- }
- }
-
- process_children (node, element);
-
- // save GLib.Error
- if (glib_error == null && node.get_full_name () == "GLib.Error") {
- glib_error = node;
- }
- }
-
- /**
- * { inheritDoc}
- */
- public override void visit_interface (Vala.Interface element) {
- Api.Node parent = get_parent_node_for (element);
- SourceFile? file = get_source_file (element);
- SourceComment? comment = create_comment (element.comment);
-
- Interface node = new Interface (parent, file, element.name, get_access_modifier(element), comment, element.get_cname (), Vala.GDBusModule.get_dbus_name (element), element);
- symbol_map.set (element, node);
- parent.add_child (node);
-
- // prerequisites:
- foreach (Vala.DataType vala_type_ref in element.get_prerequisites ()) {
- TypeReference type_ref = create_type_reference (vala_type_ref, node);
- if (vala_type_ref.data_type is Vala.Interface) {
- node.add_interface (type_ref);
- } else {
- node.base_type = type_ref;
- }
- }
-
- process_children (node, element);
- }
-
- /**
- * { inheritDoc}
- */
- public override void visit_struct (Vala.Struct element) {
- Api.Node parent = get_parent_node_for (element);
- SourceFile? file = get_source_file (element);
- SourceComment? comment = create_comment (element.comment);
-
- bool is_basic_type = element.base_type == null && (element.is_boolean_type () || element.is_floating_type () || element.is_integer_type ());
-
- Struct node = new Struct (parent, file, element.name, get_access_modifier(element), comment, element.get_cname(), element.get_dup_function (), element.get_free_function (), is_basic_type, element);
- symbol_map.set (element, node);
- parent.add_child (node);
-
- // parent type:
- Vala.ValueType? basetype = element.base_type as Vala.ValueType;
- if (basetype != null) {
- node.base_type = create_type_reference (basetype, node);
- }
-
- process_children (node, element);
- }
-
- /**
- * { inheritDoc}
- */
- public override void visit_field (Vala.Field element) {
- Api.Node parent = get_parent_node_for (element);
- SourceFile? file = get_source_file (element);
- SourceComment? comment = create_comment (element.comment);
-
- Field node = new Field (parent, file, element.name, get_access_modifier(element), comment, element.get_cname (), element.binding == Vala.MemberBinding.STATIC, element.is_volatile, element);
- node.field_type = create_type_reference (element.variable_type, node);
- symbol_map.set (element, node);
- parent.add_child (node);
-
- process_children (node, element);
- }
-
- /**
- * { inheritDoc}
- */
- public override void visit_property (Vala.Property element) {
- Api.Node parent = get_parent_node_for (element);
- SourceFile? file = get_source_file (element);
- SourceComment? comment = create_comment (element.comment);
-
- Property node = new Property (parent, file, element.name, get_access_modifier(element), comment, element.nick, Vala.GDBusModule.get_dbus_name_for_member (element), Vala.GDBusServerModule.is_dbus_visible (element), get_property_binding_type (element), element);
- node.property_type = create_type_reference (element.property_type, node);
- symbol_map.set (element, node);
- parent.add_child (node);
-
- // Process property type
- if (element.get_accessor != null) {
- var accessor = element.get_accessor;
- node.getter = new PropertyAccessor (node, file, element.name, get_access_modifier(element), accessor.get_cname(), get_property_accessor_type (accessor), get_property_ownership (accessor), accessor);
- }
-
- if (element.set_accessor != null) {
- var accessor = element.set_accessor;
- node.setter = new PropertyAccessor (node, file, element.name, get_access_modifier(element), accessor.get_cname(), get_property_accessor_type (accessor), get_property_ownership (accessor), accessor);
- }
-
- process_children (node, element);
- }
-
- /**
- * { inheritDoc}
- */
- public override void visit_creation_method (Vala.CreationMethod element) {
- Api.Node parent = get_parent_node_for (element);
- SourceFile? file = get_source_file (element);
- SourceComment? comment = create_comment (element.comment);
-
- Method node = new Method (parent, file, get_method_name (element), get_access_modifier(element), comment, element.get_cname (), Vala.GDBusModule.get_dbus_name_for_member (element), Vala.GDBusServerModule.dbus_result_name (element), (element.coroutine)? element.get_finish_cname () : null, get_method_binding_type (element), element.coroutine, Vala.GDBusServerModule.is_dbus_visible (element), element is Vala.CreationMethod, element);
- node.return_type = create_type_reference (element.return_type, node);
- symbol_map.set (element, node);
- parent.add_child (node);
-
- process_children (node, element);
- }
-
- /**
- * { inheritDoc}
- */
- public override void visit_method (Vala.Method element) {
- Api.Node parent = get_parent_node_for (element);
- SourceFile? file = get_source_file (element);
- SourceComment? comment = create_comment (element.comment);
-
- Method node = new Method (parent, file, get_method_name (element), get_access_modifier(element), comment, element.get_cname (), Vala.GDBusModule.get_dbus_name_for_member (element), Vala.GDBusServerModule.dbus_result_name (element), (element.coroutine)? element.get_finish_cname () : null, get_method_binding_type (element), element.coroutine, Vala.GDBusServerModule.is_dbus_visible (element), element is Vala.CreationMethod, element);
- node.return_type = create_type_reference (element.return_type, node);
- symbol_map.set (element, node);
- parent.add_child (node);
-
- process_children (node, element);
- }
-
- /**
- * { inheritDoc}
- */
- public override void visit_signal (Vala.Signal element) {
- Api.Node parent = get_parent_node_for (element);
- SourceFile? file = get_source_file (element);
- SourceComment? comment = create_comment (element.comment);
-
- Signal node = new Api.Signal (parent, file, element.name, get_access_modifier(element), comment, element.get_cname(), Vala.GDBusModule.get_dbus_name_for_member (element), Vala.GDBusServerModule.is_dbus_visible (element), element.is_virtual, element);
- node.return_type = create_type_reference (element.return_type, node);
- symbol_map.set (element, node);
- parent.add_child (node);
-
- process_children (node, element);
- }
-
- /**
- * { inheritDoc}
- */
- public override void visit_delegate (Vala.Delegate element) {
- Api.Node parent = get_parent_node_for (element);
- SourceFile? file = get_source_file (element);
- SourceComment? comment = create_comment (element.comment);
-
- Delegate node = new Delegate (parent, file, element.name, get_access_modifier(element), comment, element.get_cname (), element.has_target, element);
- node.return_type = create_type_reference (element.return_type, node);
- symbol_map.set (element, node);
- parent.add_child (node);
-
- process_children (node, element);
- }
-
- /**
- * { inheritDoc}
- */
- public override void visit_enum (Vala.Enum element) {
- Api.Node parent = get_parent_node_for (element);
- SourceFile? file = get_source_file (element);
- SourceComment? comment = create_comment (element.comment);
-
- Symbol node = new Enum (parent, file, element.name, get_access_modifier(element), comment, element.get_cname (), element);
- symbol_map.set (element, node);
- parent.add_child (node);
-
- process_children (node, element);
- }
-
- /**
- * { inheritDoc}
- */
- public override void visit_enum_value (Vala.EnumValue element) {
- Api.Enum parent = (Enum) get_parent_node_for (element);
- SourceFile? file = get_source_file (element);
- SourceComment? comment = create_comment (element.comment);
-
- Symbol node = new Api.EnumValue (parent, file, element.name, comment, element.get_cname (), element);
- symbol_map.set (element, node);
- parent.add_child (node);
-
- process_children (node, element);
- }
-
- /**
- * { inheritDoc}
- */
- public override void visit_constant (Vala.Constant element) {
- Api.Node parent = get_parent_node_for (element);
- SourceFile? file = get_source_file (element);
- SourceComment? comment = create_comment (element.comment);
-
- Constant node = new Constant (parent, file, element.name, get_access_modifier(element), comment, element.get_cname (), element);
- node.constant_type = create_type_reference (element.type_reference, node);
- symbol_map.set (element, node);
- parent.add_child (node);
-
- process_children (node, element);
- }
-
- /**
- * { inheritDoc}
- */
- public override void visit_error_domain (Vala.ErrorDomain element) {
- Api.Node parent = get_parent_node_for (element);
- SourceFile? file = get_source_file (element);
- SourceComment? comment = create_comment (element.comment);
-
- Symbol node = new ErrorDomain (parent, file, element.name, get_access_modifier(element), comment, element.get_cname(), Vala.GDBusModule.get_dbus_name (element), element);
- symbol_map.set (element, node);
- parent.add_child (node);
-
- process_children (node, element);
- }
-
- /**
- * { inheritDoc}
- */
- public override void visit_error_code (Vala.ErrorCode element) {
- Api.ErrorDomain parent = (ErrorDomain) get_parent_node_for (element);
- SourceFile? file = get_source_file (element);
- SourceComment? comment = create_comment (element.comment);
-
- Symbol node = new Api.ErrorCode (parent, file, element.name, comment, element.get_cname (), Vala.GDBusModule.get_dbus_name_for_member (element), element);
- symbol_map.set (element, node);
- parent.add_child (node);
-
- process_children (node, element);
- }
-
- /**
- * { inheritDoc}
- */
- public override void visit_type_parameter (Vala.TypeParameter element) {
- Api.Node parent = get_parent_node_for (element);
- SourceFile? file = get_source_file (element);
-
- Symbol node = new TypeParameter (parent, file, element.name, element);
- parent.add_child (node);
-
- process_children (node, element);
- }
-
- /**
- * { inheritDoc}
- */
- public override void visit_formal_parameter (Vala.Parameter element) {
- Api.Node parent = get_parent_node_for (element);
- SourceFile? file = get_source_file (element);
-
- FormalParameter node = new FormalParameter (parent, file, element.name, get_access_modifier(element), get_formal_parameter_type (element), element.ellipsis, element);
- node.parameter_type = create_type_reference (element.variable_type, node);
- parent.add_child (node);
-
- process_children (node, element);
- }
-
-
- //
- // startpoint:
- //
-
- public Api.Tree? build (Settings settings, ErrorReporter reporter) {
- this.tree = new Api.Tree (reporter, settings);
- this.settings = settings;
- this.reporter = reporter;
-
- var context = create_valac_tree (settings);
-
- reporter.warnings_offset = context.report.get_warnings ();
- reporter.errors_offset = context.report.get_errors ();
-
- if (context == null) {
- return null;
- }
+[CCode (has_target = false)]
+public delegate Type Valadoc.DriverRegisterFunction (GLib.TypeModule module);
- context.accept(this);
- if (reporter.errors > 0) {
- return null;
- }
- SymbolResolver resolver = new SymbolResolver (symbol_map, glib_error);
- this.tree.accept (resolver);
+public interface Valadoc.Driver : Object {
- return tree;
- }
+ public abstract Api.Tree? build (Settings settings, ErrorReporter reporter);
}
diff --git a/src/libvaladoc/api/interface.vala b/src/libvaladoc/api/interface.vala
index 236b14d..b8c339e 100755
--- a/src/libvaladoc/api/interface.vala
+++ b/src/libvaladoc/api/interface.vala
@@ -140,11 +140,11 @@ public class Valadoc.Api.Interface : TypeSymbol {
return _known_related_interfaces;
}
- internal void register_related_interface (Interface iface) {
+ public void register_related_interface (Interface iface) {
_known_related_interfaces.add (iface);
}
- internal void register_implementation (Class cl) {
+ public void register_implementation (Class cl) {
_known_implementations.add (cl);
}
diff --git a/src/libvaladoc/api/node.vala b/src/libvaladoc/api/node.vala
index 49671bc..48cb600 100755
--- a/src/libvaladoc/api/node.vala
+++ b/src/libvaladoc/api/node.vala
@@ -114,7 +114,7 @@ public abstract class Valadoc.Api.Node : Item, Browsable, Documentation, Compara
return file.relative_path;
}
- internal void add_child (Symbol child) {
+ public void add_child (Symbol child) {
if (child.name != null) {
per_name_children.set (child.name, child);
} else {
diff --git a/src/libvaladoc/api/signaturebuilder.vala b/src/libvaladoc/api/signaturebuilder.vala
index 801afe0..f589a0b 100755
--- a/src/libvaladoc/api/signaturebuilder.vala
+++ b/src/libvaladoc/api/signaturebuilder.vala
@@ -59,6 +59,20 @@ public class Valadoc.Api.SignatureBuilder {
}
/**
+ * Adds highlighted text onto the end of the builder.
+ *
+ * @param literal a string
+ * @param spaced add a space at the front of the string if necessary
+ * @return this
+ */
+ public SignatureBuilder append_highlighted (string text, bool spaced = true) {
+ string content = (last_appended != null && spaced ? " " : "") + text;
+ Run inner = new Run (Run.Style.ITALIC);
+ inner.content.add (new Text (content));
+ return append_content (inner, spaced);
+ }
+
+ /**
* Adds a Inline onto the end of the builder.
*
* @param literal a content
diff --git a/src/libvaladoc/api/tree.vala b/src/libvaladoc/api/tree.vala
index 8c28e66..c662058 100755
--- a/src/libvaladoc/api/tree.vala
+++ b/src/libvaladoc/api/tree.vala
@@ -40,8 +40,7 @@ public class Valadoc.Api.Tree {
private ErrorReporter reporter;
private CTypeResolver _cresolver = null;
- // TODO schÃner machen
- internal void add_package(Package package) {
+ public void add_package(Package package) {
this.packages.add (package);
}
@@ -67,7 +66,7 @@ public class Valadoc.Api.Tree {
return external_c_files.read_only_view;
}
- internal void add_external_c_files (string name) {
+ public void add_external_c_files (string name) {
external_c_files.add (name);
}
diff --git a/src/libvaladoc/moduleloader.vala b/src/libvaladoc/moduleloader.vala
index 8743aec..72297a9 100755
--- a/src/libvaladoc/moduleloader.vala
+++ b/src/libvaladoc/moduleloader.vala
@@ -1,6 +1,7 @@
/* moduleloader.vala
*
* Copyright (C) 2008-2009 Florian Brosch
+ * Copyright (C) 2011 Florian Brosch
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -24,16 +25,21 @@ using Gee;
[CCode (has_target = false)]
-public delegate void Valadoc.TagletRegisterFunction (ModuleLoader loader);
+public delegate void Valadoc.TagletRegisterFunction (ModuleLoader loader);
+
-public class Valadoc.ModuleLoader : TypeModule {
- public Doclet doclet;
+public class Valadoc.ModuleLoader : TypeModule {
public HashMap<string, GLib.Type> taglets = new HashMap<string, Type> (GLib.str_hash, GLib.str_equal);
+ private Module drivermodule;
+ private Type drivertype;
+ public Driver driver;
+
private Module docletmodule;
private Type doclettype;
+ public Doclet doclet;
public ModuleLoader () {
Object ();
@@ -65,7 +71,27 @@ public class Valadoc.ModuleLoader : TypeModule {
Valadoc.DocletRegisterFunction doclet_register_function = (Valadoc.DocletRegisterFunction) function;
doclettype = doclet_register_function (this);
- this.doclet = (Doclet)GLib.Object.new (doclettype);
+ this.doclet = (Doclet) GLib.Object.new (doclettype);
+ return true;
+ }
+
+
+ public bool load_driver (string path) {
+ void* function;
+
+ drivermodule = Module.open (Module.build_path (path, "libdriver"), ModuleFlags.BIND_LAZY | ModuleFlags.BIND_LOCAL);
+ if (drivermodule == null) {
+ return false;
+ }
+
+ drivermodule.symbol("register_plugin", out function);
+ if (function == null) {
+ return false;
+ }
+
+ Valadoc.DriverRegisterFunction driver_register_function = (Valadoc.DriverRegisterFunction) function;
+ drivertype = driver_register_function (this);
+ this.driver = (Driver) GLib.Object.new (drivertype);
return true;
}
}
diff --git a/src/valadoc/Makefile.am b/src/valadoc/Makefile.am
index 67bae8b..8b34324 100755
--- a/src/valadoc/Makefile.am
+++ b/src/valadoc/Makefile.am
@@ -2,7 +2,7 @@ NULL =
AM_CFLAGS = \
- -DPACKAGE_DATADIR=\"$(libdir)/valadoc/plugins\" \
+ -DPACKAGE_DATADIR=\"$(libdir)/valadoc\" \
-DPACKAGE_VERSION=\"$(VERSION)\" \
-I ../libvaladoc/ \
$(GLIB_CFLAGS) \
diff --git a/src/valadoc/valadoc.vala b/src/valadoc/valadoc.vala
index 36235c6..02684b3 100755
--- a/src/valadoc/valadoc.vala
+++ b/src/valadoc/valadoc.vala
@@ -31,11 +31,12 @@ using Gee;
public class ValaDoc : Object {
private static string wikidirectory = null;
private static string pkg_version = null;
- private static string pluginpath = null;
+ private static string docletpath = null;
[CCode (array_length = false, array_null_terminated = true)]
private static string[] pluginargs;
private static string directory = null;
private static string pkg_name = null;
+ private static string driverpath = null;
private static bool add_inherited = false;
private static bool _protected = true;
@@ -71,7 +72,7 @@ public class ValaDoc : Object {
{ "vapidir", 0, 0, OptionArg.FILENAME_ARRAY, ref vapi_directories, "Look for package bindings in DIRECTORY", "DIRECTORY..." },
{ "importdir", 0, 0, OptionArg.FILENAME_ARRAY, ref import_directories, "Look for external documentation in DIRECTORY", "DIRECTORY..." },
{ "profile", 0, 0, OptionArg.STRING, ref profile, "Use the given profile instead of the default", "PROFILE" },
- { "version", 0, 0, OptionArg.NONE, ref version, "Display version number", null },
+ { "driver", 0, 0, OptionArg.NONE, ref driverpath, "Display version number", null },
{ "pkg", 0, 0, OptionArg.STRING_ARRAY, ref packages, "Include binding for PACKAGE", "PACKAGE..." },
{ "import", 0, 0, OptionArg.STRING_ARRAY, ref import_packages, "Include binding for PACKAGE", "PACKAGE..." },
@@ -79,82 +80,106 @@ public class ValaDoc : Object {
{ "wiki", 0, 0, OptionArg.FILENAME, ref wikidirectory, "Wiki directory", "DIRECTORY" },
{ "deps", 0, 0, OptionArg.NONE, ref with_deps, "Adds packages to the documentation", null },
+
{ "doclet-arg", 'X', 0, OptionArg.STRING_ARRAY, ref pluginargs, "Pass arguments to the doclet", "ARG" },
- { "doclet", 0, 0, OptionArg.STRING, ref pluginpath, "Name of an included doclet or path to custom doclet", "PLUGIN"},
+ { "doclet", 0, 0, OptionArg.STRING, ref docletpath, "Name of an included doclet or path to custom doclet", "PLUGIN"},
+
{ "no-protected", 0, OptionFlags.REVERSE, OptionArg.NONE, ref _protected, "Removes protected elements from documentation", null },
{ "internal", 0, 0, OptionArg.NONE, ref _internal, "Adds internal elements to documentation", null },
{ "private", 0, 0, OptionArg.NONE, ref _private, "Adds private elements to documentation", null },
// { "inherit", 0, 0, OptionArg.NONE, ref add_inherited, "Adds inherited elements to a class", null },
+
{ "package-name", 0, 0, OptionArg.STRING, ref pkg_name, "package name", "NAME" },
{ "package-version", 0, 0, OptionArg.STRING, ref pkg_version, "package version", "VERSION" },
+
{ "force", 0, 0, OptionArg.NONE, ref force, "force", null },
{ "verbose", 0, 0, OptionArg.NONE, ref verbose, "Show all warnings", null },
{ "", 0, 0, OptionArg.FILENAME_ARRAY, ref tsources, null, "FILE..." },
+
{ null }
};
private static int quit (ErrorReporter reporter) {
- if ( reporter.errors == 0) {
+ if (reporter.errors == 0) {
stdout.printf ("Succeeded - %d warning(s)\n", reporter.warnings);
return 0;
- }
- else {
+ } else {
stdout.printf ("Failed: %d error(s), %d warning(s)\n", reporter.errors, reporter.warnings);
return 1;
}
}
private static bool check_pkg_name () {
- if (pkg_name == null)
+ if (pkg_name == null) {
return true;
+ }
- if (pkg_name == "glib-2.0" || pkg_name == "gobject-2.0")
+ if (pkg_name == "glib-2.0" || pkg_name == "gobject-2.0") {
return false;
+ }
foreach (string package in tsources) {
- if (pkg_name == package)
+ if (pkg_name == package) {
return false;
+ }
}
return true;
}
private string get_pkg_name () {
if (this.pkg_name == null) {
- if (this.directory.has_suffix ("/"))
+ if (this.directory.has_suffix ("/")) {
this.pkg_name = GLib.Path.get_dirname (this.directory);
- else
+ } else {
this.pkg_name = GLib.Path.get_basename (this.directory);
+ }
}
return this.pkg_name;
}
- private ModuleLoader? create_module_loader (ErrorReporter reporter) {
- string fulldirpath = "";
+ private string get_plugin_dir (string? pluginpath, string subdir, string default_pkg) {
if (pluginpath == null) {
- fulldirpath = build_filename (Config.plugin_dir, "html");
- } else if (is_absolute (pluginpath ) == false) {
+ return build_filename (Config.plugin_dir, subdir, default_pkg);
+ }
+
+ if (is_absolute (pluginpath) == false) {
// Test to see if the plugin exists in the expanded path and then fallback
// to using the configured plugin directory
string local_path = build_filename (Environment.get_current_dir(), pluginpath);
- if ( FileUtils.test(local_path, FileTest.EXISTS)) {
- fulldirpath = local_path;
+ if (FileUtils.test(local_path, FileTest.EXISTS)) {
+ return local_path;
} else {
- fulldirpath = build_filename (Config.plugin_dir, pluginpath);
+ return build_filename (Config.plugin_dir, subdir, pluginpath);
}
- } else {
- fulldirpath = pluginpath;
}
+ return pluginpath;
+ }
+ private ModuleLoader? create_module_loader (ErrorReporter reporter) {
ModuleLoader modules = new ModuleLoader ();
Taglets.init (modules);
- bool tmp = modules.load_doclet (fulldirpath);
+
+ // doclet:
+ string pluginpath = get_plugin_dir (docletpath, "doclets", "html");
+ bool tmp = modules.load_doclet (pluginpath);
if (tmp == false) {
- reporter.simple_error ("failed to load plugin");
+ reporter.simple_error ("failed to load doclet");
return null;
}
+
+ // driver:
+ pluginpath = get_plugin_dir (driverpath, "drivers", "0.13.x");
+ tmp = modules.load_driver (pluginpath);
+ if (tmp == false) {
+ reporter.simple_error ("failed to load driver");
+ return null;
+ }
+
+ assert (modules.driver != null && modules.doclet != null);
+
return modules;
}
@@ -186,8 +211,15 @@ public class ValaDoc : Object {
settings.defines = defines;
+ // load plugins:
+ ModuleLoader? modules = create_module_loader (reporter);
+ if (reporter.errors > 0 || modules == null) {
+ return quit (reporter);
+ }
+
+
// Create tree:
- Valadoc.Api.Driver driver = new Valadoc.Api.Driver ();
+ Valadoc.Driver driver = modules.driver;
Valadoc.Api.Tree doctree = driver.build (settings, reporter);
if (reporter.errors > 0) {
@@ -196,11 +228,6 @@ public class ValaDoc : Object {
// process documentation
- ModuleLoader? modules = create_module_loader (reporter);
- if (reporter.errors > 0 || modules == null) {
- return quit (reporter);
- }
-
Valadoc.DocumentationParser docparser = new Valadoc.DocumentationParser (settings, reporter, doctree, modules);
if (!doctree.create_tree()) {
return quit (reporter);
@@ -233,8 +260,7 @@ public class ValaDoc : Object {
opt_context.set_help_enabled (true);
opt_context.add_main_entries (options, null);
opt_context.parse (ref args);
- }
- catch (OptionError e) {
+ } catch (OptionError e) {
reporter.simple_error (e.message);
stdout.printf ("Run '%s --help' to see a full list of available command line options.\n", args[0]);
return quit (reporter);
@@ -262,8 +288,7 @@ public class ValaDoc : Object {
reporter.simple_error ("Can't remove directory.");
return quit (reporter);
}
- }
- else {
+ } else {
reporter.simple_error ("File already exists");
return quit (reporter);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]