Merge: nitx: add hierarchy lookup commands
authorJean Privat <jean@pryen.org>
Tue, 2 Jun 2015 10:42:59 +0000 (06:42 -0400)
committerJean Privat <jean@pryen.org>
Tue, 2 Jun 2015 10:42:59 +0000 (06:42 -0400)
This PR introduce 4 commands to explore class hierarchies:

* `parents:` for direct parents
* `ancestors`: for all inherited classes
* `children:` for known direct children
* `descendants:` for all the known descandants classes

Also fixes #1420

Pull-Request: #1421
Reviewed-by: Jean Privat <jean@pryen.org>

src/doc/console_templates/console_model.nit
src/doc/console_templates/console_templates.nit
src/doc/doc_phases/doc_console.nit
src/nitx.nit

index dee8a74..5d693b1 100644 (file)
@@ -94,7 +94,10 @@ redef class MEntity
                return mdoc.cs_short_comment
        end
 
-       # Returns 1self` as a list element that can be displayed in console.
+       # Returns `self` as a list element that can be displayed in console.
+       #
+       # Displays `cs_icon`, `cs_name`, `cs_short_comment, `cs_namespace`,
+       # `cs_declaration` and `cs_location`.
        fun cs_list_item: String do
                var tpl = new FlatBuffer
                tpl.append " {cs_visibility_color(cs_icon).bold} {cs_name.blue.bold}"
@@ -111,6 +114,18 @@ redef class MEntity
                return tpl.write_to_string
        end
 
+       # Returns `self` as a short list element that can be displayed in console.
+       # Displays `cs_icon`, `cs_name`, and `cs_short_comment.
+       fun cs_short_list_item: String do
+               var tpl = new FlatBuffer
+               tpl.append " {cs_visibility_color(cs_icon).bold} {cs_name.blue.bold}"
+               var comment = cs_short_comment
+               if comment != null then
+                       tpl.append " # {comment}".green
+               end
+               return tpl.write_to_string
+       end
+
        # ASCII icon to be displayed in front of the list item.
        fun cs_icon: String do return "*"
 
index e94a388..6e8f03e 100644 (file)
@@ -35,7 +35,7 @@ redef class DocComposite
        # Title that can be decorated for console display.
        #
        # Set as `null` if you don't want to display a title.
-       var cs_title: nullable String is noinit, writable
+       var cs_title: nullable String is writable, lazy do return title
 
        # Subtitle that can be decorated for console display.
        #
@@ -87,9 +87,6 @@ redef class MEntityComposite
 end
 
 redef class IntroArticle
-       redef var cs_title = null
-       redef var cs_subtitle = null
-
        redef fun render_body do
                addn "    {mentity.cs_declaration.bold}"
                addn "    {mentity.cs_location.gray.bold}"
@@ -104,9 +101,6 @@ redef class IntroArticle
 end
 
 redef class ConcernsArticle
-       redef var cs_title = "Concerns"
-       redef var cs_subtitle = null
-
        redef fun render_body do
                var w = new StringWriter
                concerns.write_to(w)
@@ -135,3 +129,11 @@ redef class DefinitionArticle
                super
        end
 end
+
+redef class MEntitiesListArticle
+       redef fun render_body do
+               for mentity in mentities do
+                       addn mentity.cs_short_list_item
+               end
+       end
+end
index 4c0c193..b6d08dc 100644 (file)
@@ -20,6 +20,7 @@ module doc_console
 
 import semantize
 import doc_extract
+import doc_poset
 import doc::console_templates
 
 # Nitx handles console I/O.
@@ -58,16 +59,24 @@ class Nitx
 
        # Displays the list of available commands.
        fun help do
-               print "\nCommands:"
-               print "\tname\t\tlookup module, class and property with the corresponding 'name'"
+               print "\nCommands:\n"
+               print "\tname\t\t\tlookup module, class and property with the corresponding 'name'"
                print "\tdoc: <name::space>\tdisplay the documentation page of 'namespace'"
-               print "\tparam: <Type>\tlookup methods using the corresponding 'Type' as parameter"
-               print "\treturn: <Type>\tlookup methods returning the corresponding 'Type'"
-               print "\tnew: <Type>\tlookup methods creating new instances of 'Type'"
-               print "\tcall: <name>\tlookup methods calling 'name'"
-               print "\tcode: <name>\tdisplay the source code associated to the 'name' entity"
-               print "\t:h\t\tdisplay this help message"
-               print "\t:q\t\tquit interactive mode"
+               print "\nType lookup:"
+               print "\tparam: <Type>\t\tlookup methods using the corresponding 'Type' as parameter"
+               print "\treturn: <Type>\t\tlookup methods returning the corresponding 'Type'"
+               print "\tnew: <Type>\t\tlookup methods creating new instances of 'Type'"
+               print "\tcall: <name>\t\tlookup methods calling 'name'"
+               print "\nHierarchy lookup:"
+               print "\tparents: <Class>\tlist direct parents of 'Class'"
+               print "\tancestors: <Class>\tlist all ancestors of 'Class'"
+               print "\tchildren: <Class>\tlist direct children of 'Class'"
+               print "\tdescendants: <Class>\tlist all descendants of 'Class'"
+               print "\nCode lookup:"
+               print "\tcode: <name>\t\tdisplay the source code associated to the 'name' entity"
+               print "\n"
+               print "\t:h\t\t\tdisplay this help message"
+               print "\t:q\t\t\tquit interactive mode"
                print ""
        end
 
@@ -80,19 +89,14 @@ class Nitx
 
        # Processes the query string and performs it.
        fun do_query(str: String) do
-               var query = parse_query(str)
-               var res = query.perform(self, doc)
-               var page = query.make_results(self, res)
-               print page.write_to_string
-       end
-
-       # Returns an `NitxQuery` from a raw query string.
-       fun parse_query(str: String): NitxQuery do
                var query = new NitxQuery(str)
                if query isa NitxCommand then
                        query.execute(self)
+                       return
                end
-               return query
+               var res = query.perform(self, doc)
+               var page = query.make_results(self, res)
+               print page.write_to_string
        end
 end
 
@@ -129,7 +133,14 @@ interface NitxQuery
                        return new CallQuery(query_string)
                else if query_string.has_prefix("code:") then
                        return new CodeQuery(query_string)
-
+               else if query_string.has_prefix("parents:") then
+                       return new ParentsQuery(query_string)
+               else if query_string.has_prefix("ancestors:") then
+                       return new AncestorsQuery(query_string)
+               else if query_string.has_prefix("children:") then
+                       return new ChildrenQuery(query_string)
+               else if query_string.has_prefix("descendants:") then
+                       return new DescendantsQuery(query_string)
                end
                return new CommentQuery("comment: {query_string}")
        end
@@ -361,6 +372,76 @@ class PageMatch
        end
 end
 
+# Search in class or module hierarchy of a `MEntity`.
+#
+# It actually searches for pages about the mentity and extracts the
+# pre-calculated hierarchies by the `doc_post` phase.
+abstract class HierarchiesQuery
+       super DocQuery
+
+       redef fun make_results(nitx, results) do
+               var page = new DocPage("hierarchy", "Hierarchy")
+               for result in results do
+                       if not result isa PageMatch then continue
+                       var rpage = result.page
+                       if not rpage isa MClassPage then continue
+                       page.root.add_child build_article(rpage)
+               end
+               return page
+       end
+
+       # Build an article containing the hierarchy list depending on subclasses.
+       private fun build_article(page: MClassPage): DocArticle is abstract
+end
+
+# List all parents of a `MClass`.
+class AncestorsQuery
+       super HierarchiesQuery
+
+       redef fun build_article(page) do
+               return new MEntitiesListArticle(
+                       "ancerstors",
+                       "Ancestors for {page.mentity.name}",
+                       page.ancestors.to_a)
+       end
+end
+
+# List direct parents of a `MClass`.
+class ParentsQuery
+       super HierarchiesQuery
+
+       redef fun build_article(page) do
+               return new MEntitiesListArticle(
+                       "parents",
+                       "Parents for {page.mentity.name}",
+                       page.parents.to_a)
+       end
+end
+
+# List direct children of a `MClass`.
+class ChildrenQuery
+       super HierarchiesQuery
+
+       redef fun build_article(page) do
+               return new MEntitiesListArticle(
+                       "children",
+                       "Children for {page.mentity.name}",
+                       page.children.to_a)
+       end
+end
+
+# List all descendants of a `MClass`.
+class DescendantsQuery
+       super HierarchiesQuery
+
+       redef fun build_article(page) do
+               return new MEntitiesListArticle(
+                       "descendants",
+                       "Descendants for {page.mentity.name}",
+                       page.children.to_a)
+       end
+end
+
 # A query to search source code from a file name.
 class CodeQuery
        super MetaQuery
index 23490a8..cf5ab95 100644 (file)
@@ -48,7 +48,8 @@ private class NitxPhase
                        new ExtractionPhase(toolcontext, doc),
                        new MakePagePhase(toolcontext, doc),
                        new ConcernsPhase(toolcontext, doc),
-                       new StructurePhase(toolcontext, doc): DocPhase]
+                       new StructurePhase(toolcontext, doc),
+                       new POSetPhase(toolcontext, doc): DocPhase]
 
                for phase in phases do
                        toolcontext.info("# {phase.class_name}", 1)