]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
libvaladoc/html: Add "All known members inherited from "
authorFlorian Brosch <flo.brosch@gmail.com>
Thu, 9 Aug 2012 23:48:45 +0000 (01:48 +0200)
committerFlorian Brosch <flo.brosch@gmail.com>
Thu, 9 Aug 2012 23:48:45 +0000 (01:48 +0200)
src/libvaladoc/api/class.vala
src/libvaladoc/api/interface.vala
src/libvaladoc/api/node.vala
src/libvaladoc/html/basicdoclet.vala

index 6c19ea0786072dd2850e0d2ed544bfd50c6278c2..6eec1370d6cd95d8eb414a9568044222b1f3a268 100644 (file)
@@ -160,7 +160,7 @@ public class Valadoc.Api.Class : TypeSymbol {
         */
        public Collection<TypeReference> get_full_implemented_interface_list () {
                if (_full_implemented_interfaces == null) {
-                       _full_implemented_interfaces = new HashSet<TypeReference> ();
+                       _full_implemented_interfaces = new LinkedList<TypeReference> ();
                        _full_implemented_interfaces.add_all (this.interfaces);
 
                        if (base_type != null) {
index b8c339ee9a690fdfe5000c12f5a97e069d94ee34..51b6e00095a82b0f148af48340bf0c69c3884c24 100644 (file)
@@ -67,9 +67,10 @@ public class Valadoc.Api.Interface : TypeSymbol {
        /**
         * Returns a list of all preconditioned interfaces
         */
+       // TODO: rename to get_full_...
        public Collection<TypeReference> get_all_implemented_interface_list () {
                if (_full_implemented_interfaces == null) {
-                       _full_implemented_interfaces = new HashSet<TypeReference> ();
+                       _full_implemented_interfaces = new LinkedList<TypeReference> ();
                        _full_implemented_interfaces.add_all (this.interfaces);
 
                        if (base_type != null) {
index e28a898792cc6b2147b01178fa9736476bc96a5d..8c5345c8648f47fdcccbda5ceeff8fdcbe0c13cc 100644 (file)
@@ -144,6 +144,7 @@ public abstract class Valadoc.Api.Node : Item, Browsable, Documentation, Compara
        private Map<string,Node> per_name_children;
        private Map<NodeType?, Gee.List<Node>> per_type_children;
 
+
        public Node (Node? parent, SourceFile? file, string? name, void* data) {
                base (data);
 
@@ -165,6 +166,7 @@ public abstract class Valadoc.Api.Node : Item, Browsable, Documentation, Compara
        /**
         * {@inheritDoc}
         */
+       // TODO: rename to is_visible
        public abstract bool is_browsable (Settings settings);
 
        /**
@@ -210,13 +212,46 @@ public abstract class Valadoc.Api.Node : Item, Browsable, Documentation, Compara
                }
        }
 
+       /**
+        * Specifies whether this node has at least one visible child with the given type
+        *
+        * @param type a node type
+        */
+       public bool has_visible_children_by_type (NodeType type, Settings settings) {
+               Gee.List<Node>? all_children = per_type_children.get (type);
+               if (all_children != null) {
+                       foreach (Node node in all_children) {
+                               if (node.is_browsable (settings)) {
+                                       return true;
+                               }
+                       }
+               }
+
+               return false;
+       }
+
+       /**
+        * Specifies whether this node has at least one visible child with the given types
+        *
+        * @param types a list of node types
+        */
+       public bool has_visible_children_by_types (NodeType[] types, Settings settings) {
+               foreach (NodeType type in types) {
+                       if (has_visible_children_by_type (type, settings)) {
+                               return true;
+                       }
+               }
+
+               return false;
+       }
+
        /**
         * Specifies whether this node has at least one child with the given type
         *
         * @param type a node type
         */
        public bool has_children_by_type (NodeType type) {
-               Gee.List<Node> all_children = per_type_children.get (type);
+               Gee.List<Node>? all_children = per_type_children.get (type);
                return all_children != null && !all_children.is_empty;
        }
 
@@ -306,6 +341,7 @@ public abstract class Valadoc.Api.Node : Item, Browsable, Documentation, Compara
         * Visits all children of this node with the specified Visitor.
         *
         * @param visitor the visitor to be called while traversing
+        * @param filtered specifies whether nodes which are not browsable should appear in the list
         */
        public void accept_all_children (Visitor visitor, bool filtered = true) {
                foreach (Gee.List<Node> children in per_type_children.values) {
index 4f6d7c2b647e64a7f8ee5085df28f7f8a88a7f3c..c63edc7438bffd95de99dfbbcf3be3cc289a01af 100644 (file)
@@ -128,6 +128,25 @@ public abstract class Valadoc.Html.BasicDoclet : Api.Visitor, Doclet {
        }
 
 
+       private TypeSymbol? unpack_type_reference (TypeReference? type_reference) {
+               Api.Item pos = type_reference;
+
+               while (pos != null) {
+                       if (pos is TypeReference) {
+                               pos = ((TypeReference) pos).data_type;
+                       } else if (pos is Api.Array) {
+                               pos = ((Api.Array) pos).data_type;
+                       } else if (pos is Pointer) {
+                               pos = ((Pointer) pos).data_type;
+                       } else {
+                               assert (pos is TypeSymbol);
+                               return (TypeSymbol) pos;
+                       }
+               }
+
+               return null;
+       }
+
 
        protected void write_navi_entry_html_template (string style, string content, bool is_deprecated) {
                writer.start_tag ("li", {"class", style});
@@ -536,7 +555,7 @@ public abstract class Valadoc.Html.BasicDoclet : Api.Visitor, Doclet {
                return list;
        }
 
-       private void write_known_symbols_node (Gee.Collection<Api.Node> nodes2, Api.Node container, string headline) {
+       private void write_known_symbols_note (Gee.Collection<Api.Node> nodes2, Api.Node container, string headline) {
                var nodes = get_accessible_nodes_from_list (nodes2);
                if (nodes.size == 0) {
                        return ;
@@ -578,7 +597,12 @@ public abstract class Valadoc.Html.BasicDoclet : Api.Visitor, Doclet {
                        for (int p = 0; p < list_sizes[i] && iter.next (); p++) {
                                var node = iter.get ();
                                writer.start_tag ("li", {"class", cssresolver.resolve (node)});
-                               writer.link (get_link (node, container), node.name);
+                               string link = get_link (node, container);
+                               if (link == null) {
+                                       writer.text (node.name);
+                               } else {
+                                       writer.link (link, node.name);
+                               }
                                writer.end_tag ("li");
                        }
 
@@ -607,13 +631,15 @@ public abstract class Valadoc.Html.BasicDoclet : Api.Visitor, Doclet {
 
                if (node is Class) {
                        var cl = node as Class;
-                       write_known_symbols_node (cl.get_known_child_classes (), cl, "All known sub-classes:");
-                       write_known_symbols_node (cl.get_known_derived_interfaces (), cl, "Required by:");
+                       write_known_symbols_note (cl.get_known_child_classes (), cl, "All known sub-classes:");
+                       write_known_symbols_note (cl.get_known_derived_interfaces (), cl, "Required by:");
                } else if (node is Interface) {
                        var iface = node as Interface;
-                       write_known_symbols_node (iface.get_known_implementations (), iface, "All known implementing classes:");
-                       write_known_symbols_node (iface.get_known_related_interfaces (), iface, "All known sub-interfaces:");
+                       write_known_symbols_note (iface.get_known_implementations (), iface, "All known implementing classes:");
+                       write_known_symbols_note (iface.get_known_related_interfaces (), iface, "All known sub-interfaces:");
                }
+               // TODO: All known sub-structs
+
 
                if (node.parent is Namespace) {
                        writer.simple_tag ("br");
@@ -621,7 +647,9 @@ public abstract class Valadoc.Html.BasicDoclet : Api.Visitor, Doclet {
                        write_package_note (node);
                }
 
-               if (!(node is Method || node is Delegate || node is Api.Signal)) { // avoids exception listings & implementations
+               if (!(node is Method || node is Delegate || node is Api.Signal)) {
+                       // avoids exception listings & implementations
+
                        if (node.has_children ({
                                        Api.NodeType.ERROR_CODE,
                                        Api.NodeType.ENUM_VALUE,
@@ -653,9 +681,124 @@ public abstract class Valadoc.Html.BasicDoclet : Api.Visitor, Doclet {
                                write_children (node, Api.NodeType.FIELD, "Fields", node);
                        }
                }
+
+               if (node is Class) {
+                       write_inherited_symbols_note_for_class ((Class) node, node);
+               } else if (node is Interface) {
+                       write_inherited_symbols_note_for_interface ((Interface) node, node);
+               } else if (node is Struct) {
+                       write_inherited_symbols_note_for_struct ((Struct) node, node);
+               }
+
                writer.end_tag ("div");
        }
 
+       private static NodeType[] inheritable_members = {
+                       NodeType.CONSTANT,
+                       NodeType.PROPERTY,
+                       NodeType.DELEGATE,
+                       NodeType.STATIC_METHOD,
+                       NodeType.METHOD,
+                       NodeType.SIGNAL,
+                       NodeType.FIELD,
+               };
+
+       private inline bool has_visible_inheritable_children (TypeSymbol symbol) {
+               return symbol.has_visible_children_by_types (inheritable_members, _settings);
+       }
+
+       private void write_inherited_members_headline () {
+               writer.start_tag ("h3", {"class", css_title}).text ("Inherited Members:").end_tag ("h3");
+       }
+
+       private void write_inherited_symbols_note_for_class (Class cl, Api.Node container) {
+               bool headline_printed = false;
+
+               // class hierarchy:
+               Class base_class = unpack_type_reference (cl.base_type) as Class;
+               while (base_class != null) {
+                       if (!headline_printed && has_visible_inheritable_children (base_class)) {
+                               write_inherited_members_headline ();
+                               headline_printed = true;
+                       }
+
+                       write_inherited_symbols_note (base_class, "class", container);
+                       base_class = unpack_type_reference (base_class.base_type) as Class;
+               }
+
+
+               // implemented interfaces
+               Gee.LinkedList<Interface> printed_interfaces = new Gee.LinkedList<Interface> ();
+               foreach (TypeReference iface_ref in cl.get_full_implemented_interface_list ()) {
+                       Interface iface = (Interface) unpack_type_reference (iface_ref);
+
+                       if (!headline_printed && has_visible_inheritable_children (iface)) {
+                               write_inherited_members_headline ();
+                               headline_printed = true;
+                       } else if (printed_interfaces.contains (iface)) {
+                               continue ;
+                       }
+
+                       write_inherited_symbols_note (iface, "interface", container);
+                       printed_interfaces.add (iface);
+               }
+       }
+
+       private void write_inherited_symbols_note_for_interface (Interface iface, Api.Node container) {
+               bool headline_printed = false;
+
+               // class hierarchy:
+               Class base_class = unpack_type_reference (iface.base_type) as Class;
+               while (base_class != null) {
+                       if (!headline_printed && has_visible_inheritable_children (base_class)) {
+                               write_inherited_members_headline ();
+                               headline_printed = true;
+                       }
+
+                       write_inherited_symbols_note (base_class, "class", container);
+                       base_class = unpack_type_reference (base_class.base_type) as Class;
+               }
+
+
+               // interfaces:
+               Gee.LinkedList<Interface> printed_interfaces = new Gee.LinkedList<Interface> ();
+               foreach (TypeReference pre_ref in iface.get_all_implemented_interface_list ()) {
+                       Interface pre = (Interface) unpack_type_reference (pre_ref);
+
+                       if (!headline_printed && has_visible_inheritable_children (pre)) {
+                               write_inherited_members_headline ();
+                               headline_printed = true;
+                       } else if (printed_interfaces.contains (pre)) {
+                               continue ;
+                       }
+
+                       write_inherited_symbols_note (pre, "interface", container);
+                       printed_interfaces.add (pre);
+               }
+       }
+
+       private void write_inherited_symbols_note_for_struct (Struct str, Api.Node container) {
+               Struct base_struct = unpack_type_reference (str.base_type) as Struct;
+               if (base_struct != null && has_visible_inheritable_children (base_struct)) {
+                       write_inherited_members_headline ();
+                       write_inherited_symbols_note (base_struct, "struct", container);
+               }
+       }
+
+       private void write_inherited_symbols_note (TypeSymbol symbol, string type, Api.Node container) {
+               write_known_symbols_note (symbol.get_children_by_types (inheritable_members, false), container, "All known members inherited from %s %s".printf (type, symbol.get_full_name ()));
+
+               /*
+               write_known_symbols_note (symbol.get_children_by_type (NodeType.CONSTANT, false), container, "All known constants inherited from %s %s".printf (type, symbol.get_full_name ()));
+               write_known_symbols_note (symbol.get_children_by_type (NodeType.PROPERTY, false), container, "All known properties inherited from %s %s".printf (type, symbol.get_full_name ()));
+               write_known_symbols_note (symbol.get_children_by_type (NodeType.DELEGATE, false), container, "All known delegates inherited from %s %s".printf (type, symbol.get_full_name ()));
+               write_known_symbols_note (symbol.get_children_by_type (NodeType.STATIC_METHOD, false), container, "All known static methods inherited from %s %s".printf (type, symbol.get_full_name ()));
+               write_known_symbols_note (symbol.get_children_by_type (NodeType.METHOD, false), container, "All known methods inherited from %s %s".printf (type, symbol.get_full_name ()));
+               write_known_symbols_note (symbol.get_children_by_type (NodeType.SIGNAL, false), container, "All known signals inherited from %s %s".printf (type, symbol.get_full_name ()));
+               write_known_symbols_note (symbol.get_children_by_type (NodeType.FIELD, false), container, "All known fields inherited from  %s %s".printf (type, symbol.get_full_name ()));
+               */
+       }
+
        protected void write_child_namespaces (Api.Node node, Api.Node? parent) {
                Gee.ArrayList<Namespace> namespaces = new Gee.ArrayList<Namespace> ();
                this.fetch_subnamespace_names (node, namespaces);
@@ -698,7 +841,7 @@ public abstract class Valadoc.Html.BasicDoclet : Api.Visitor, Doclet {
        }
 
        protected void write_child_dependencies (Package package, Api.Node? parent) {
-               Gee.Collection<Package> deps = package.get_full_dependency_list ();
+               Gee.Collection<Package>? deps = package.get_full_dependency_list ();
                if (deps.size == 0) {
                        return;
                }
@@ -706,7 +849,7 @@ public abstract class Valadoc.Html.BasicDoclet : Api.Visitor, Doclet {
                writer.start_tag ("h2", {"class", css_title}).text ("Dependencies:").end_tag ("h2");
                writer.start_tag ("ul", {"class", css_inline_navigation});
                foreach (Package p in deps) {
-                       string link = this.get_link (p, parent);
+                       string? link = this.get_link (p, parent);
                        if (link == null) {
                                writer.start_tag ("li", {"class", cssresolver.resolve (p), "id", p.name}).text (p.name).end_tag ("li");
                        } else {