diff options
Diffstat (limited to 'libvaladoc/api/tree.vala')
-rw-r--r-- | libvaladoc/api/tree.vala | 350 |
1 files changed, 350 insertions, 0 deletions
diff --git a/libvaladoc/api/tree.vala b/libvaladoc/api/tree.vala new file mode 100644 index 000000000..4344c2e46 --- /dev/null +++ b/libvaladoc/api/tree.vala @@ -0,0 +1,350 @@ +/* tree.vala + * + * Copyright (C) 2008-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.Importer; + +/** + * The root of the code tree. + */ +public class Valadoc.Api.Tree { + private Vala.List<InheritDocContainer> inheritdocs = new Vala.ArrayList<InheritDocContainer> (); + private Vala.ArrayList<string> external_c_files = new Vala.ArrayList<string>(str_equal); + private Vala.ArrayList<Package> packages = new Vala.ArrayList<Package>(); + private Package source_package = null; + private Settings settings; + private ErrorReporter reporter; + private Highlighter.Highlighter _highlighter; + private CTypeResolver _cresolver = null; + private Package _source_package; + + + private class InheritDocContainer { + public unowned Taglets.InheritDoc taglet; + public unowned Api.Node taglet_container; + + public InheritDocContainer (Api.Node taglet_container, Taglets.InheritDoc taglet) { + this.taglet_container = taglet_container; + this.taglet = taglet; + } + } + + + public void add_package(Package package) { + this.packages.add (package); + } + + public void* data { + set; + get; + } + + public Highlighter.Highlighter highlighter { + get { + if (_highlighter == null) { + _highlighter = new Highlighter.Highlighter (); + } + + return _highlighter; + } + } + + /** + * The root of the wiki tree. + */ + public WikiPageTree? wikitree { + private set; + get; + } + + /** + * Returns a list of C source files. + * + * @return list of C source files + */ + public Vala.Collection<string> get_external_c_files () { + return external_c_files; + } + + public void add_external_c_files (string name) { + external_c_files.add (name); + } + + + /** + * Returns a list of all packages in the tree + * + * @return list of all packages + */ + public Vala.Collection<Package> get_package_list () { + return this.packages; + } + + private void add_dependencies_to_source_package () { + if ( this.source_package != null ) { + Vala.ArrayList<Package> deplst = new Vala.ArrayList<Package> (); + foreach (Package pkg in this.packages) { + if (pkg != this.source_package) { + deplst.add (pkg); + } + } + this.source_package.set_dependency_list (deplst); + } + } + + /** + * Visits this node with the specified Visitor. + * + * @param visitor the visitor to be called while traversing + */ + public void accept (Visitor visitor) { + visitor.visit_tree (this); + } + + /** + * Visits all children of this node with the given types with the specified Visitor. + * + * @param visitor the visitor to be called while traversing + */ + public void accept_children (Visitor visitor) { + foreach (Node node in packages) { + node.accept (visitor); + } + } + + private Node? search_relative_to (Node element, string[] path) { + Api.Node? node = element; + + foreach (string name in path) { + node = node.find_by_name (name); + if (node == null) { + break; + } + } + + if (node == null && element.parent != null) { + node = search_relative_to ((Node) element.parent, path); + } + + return node; + } + + public Node? search_symbol_path (Node? element, string[] path) { + Api.Node? node = null; + + // relative to element + if (element != null) { + node = search_relative_to (element, path); + if (node != null) { + return node; + } + } + + + // absolute + foreach (Package package in packages) { + // search in root namespace + + Node? global = package.find_by_name (""); + if (global != null) { + node = search_relative_to (global, path); + if (node != null) { + return node; + } + } + } + + return null; + } + + public TypeSymbol? search_symbol_type_cstr (string cname) { + if (_cresolver == null) { + _cresolver = new CTypeResolver (this); + } + + return _cresolver.resolve_symbol_type (cname); + } + + public Node? search_symbol_cstr (Node? element, string cname) { + if (_cresolver == null) { + _cresolver = new CTypeResolver (this); + } + + return _cresolver.resolve_symbol (element, cname); + } + + public Node? search_symbol_str (Node? element, string symname) { + string[] path = split_name (symname); + + var node = search_symbol_path (element, path); + if (node != null) { + return node; + } + + if (path.length >= 2 && path[path.length-2] == path[path.length-2]) { + path[path.length-2] = path[path.length-2]+"."+path[path.length-1]; + path.resize (path.length-1); + return search_symbol_path (element, path); + } + + return null; + } + + private string[] split_name (string full_name) { + string[] params = (full_name).split (".", -1); + int i = 0; while (params[i] != null) i++; + params.length = i; + return params; + } + + public Tree (ErrorReporter reporter, Settings settings, void* data = null) { + this.settings = settings; + this.reporter = reporter; + this.data = data; + } + + // copied from valacodecontext.vala + private string? get_file_path (string basename, string[] directories) { + string filename = null; + + if (directories != null) { + foreach (string dir in directories) { + filename = Path.build_filename (dir, basename); + if (FileUtils.test (filename, FileTest.EXISTS)) { + return filename; + } + } + } + + foreach (string dir in Environment.get_system_data_dirs ()) { + filename = Path.build_filename (dir, basename); + if (FileUtils.test (filename, FileTest.EXISTS)) { + return filename; + } + } + + return null; + } + + public bool create_tree ( ) { + this.add_dependencies_to_source_package (); + return true; + } + + private Package? get_source_package () { + if (_source_package == null) { + foreach (Package pkg in packages) { + if (!pkg.is_package) { + _source_package = pkg; + break; + } + } + } + + return _source_package; + } + + private void parse_wiki (DocumentationParser docparser) { + this.wikitree = new WikiPageTree (); + var pkg = get_source_package (); + if (pkg != null) { + wikitree.parse (settings, docparser, pkg, reporter); + } + } + + private void check_wiki (DocumentationParser docparser) { + Package pkg = get_source_package (); + if (pkg != null) { + wikitree.check (settings, docparser, pkg); + } + } + + public void parse_comments (DocumentationParser docparser) { + parse_wiki (docparser); + + foreach (Package pkg in this.packages) { + if (pkg.is_browsable (settings)) { + pkg.parse_comments (settings, docparser); + } + } + } + + public void check_comments (DocumentationParser docparser) { + check_wiki (docparser); + + foreach (Package pkg in this.packages) { + if (pkg.is_browsable (settings)) { + pkg.check_comments (settings, docparser); + postprocess_inheritdoc (docparser); + } + } + } + + internal void register_inheritdoc (Api.Node container, Taglets.InheritDoc taglet) { + inheritdocs.add (new InheritDocContainer (container, taglet)); + } + + private void postprocess_inheritdoc (DocumentationParser docparser) { + while (!this.inheritdocs.is_empty) { + InheritDocContainer container = this.inheritdocs.remove_at (0); + + docparser.transform_inheritdoc (container.taglet_container, container.taglet); + } + } + + + /** + * Import documentation from various sources + * + * @param importers a list of importers + * @param packages sources + * @param import_directories List of directories where to find the files + */ + public void import_comments (DocumentationImporter[] importers, string[] packages, + string[] import_directories) + { + Vala.HashSet<string> processed = new Vala.HashSet<string> (); + foreach (string pkg_name in packages) { + bool imported = false; + foreach (DocumentationImporter importer in importers) { + string? path = get_file_path ("%s.%s".printf (pkg_name, importer.file_extension), + import_directories); + if (path == null) { + continue; + } + + path = realpath (path); + imported = true; + + if (!processed.contains (path)) { + importer.process (path); + processed.add (path); + } + } + + if (imported == false) { + reporter.simple_error (null, "'%s' not found in specified import directories", pkg_name); + } + } + } +} + |