Merge: nitrpg: Move `nitrpg` to its own repository
[nit.git] / src / doc / commands / commands_model.nit
index 1e88381..3a7215b 100644 (file)
 module commands_model
 
 import commands_base
-
-import model::model_collect
 import modelize
-import modelbuilder
-import htmlight
-import doc_down
 
 # Retrieve the MDoc related to a MEntity
 class CmdComment
@@ -47,7 +42,7 @@ class CmdComment
 
        # Format to render the comment
        #
-       # Can be one of `raw` or `html`.
+       # Can be one of `raw`, `html` or `md`.
        # Default is `raw`.
        var format = "raw" is optional, writable
 
@@ -70,14 +65,10 @@ class CmdComment
        end
 
        # Render `mdoc` depending on `full_doc` and `format`
-       fun render: nullable Writable do
+       fun render_comment: nullable Writable do
                var mdoc = self.mdoc
                if mdoc == null then return null
 
-               if format == "html" then
-                       if full_doc then return mdoc.html_documentation
-                       return mdoc.html_synopsis
-               end
                if full_doc then return mdoc.documentation
                return mdoc.synopsis
        end
@@ -93,11 +84,51 @@ class WarningNoMDoc
        redef fun to_s do return "No documentation for `{mentity.full_name}`."
 end
 
+# Get the link to a MEntity API documentation
+class CmdEntityLink
+       super CmdEntity
+
+       # The link text to display
+       var text: nullable String = null is optional, writable
+
+       # The link title to display when the link is hovered
+       var title: nullable String = null is optional, writable
+
+       redef fun init_command do
+               var res = super
+               if not res isa CmdSuccess then return res
+               var mentity = self.mentity.as(not null)
+
+               if text == null then
+                       text = mentity.name
+               end
+               if title == null then
+                       var mdoc = mentity.mdoc_or_fallback
+                       if mdoc != null then
+                               title = mdoc.synopsis
+                       end
+               end
+               return res
+       end
+end
+
+# An abstract inheritance command
+#
+# For things like ancestors, parents, children and descendants.
+abstract class CmdInheritance
+       super CmdEntityList
+
+       autoinit(model, mainmodule, filter, mentity, mentity_name, limit, page, count, max)
+
+       # Mainmodule for class linearization
+       var mainmodule: MModule
+end
+
 # MEntity ancestors command
 #
 # Retrieve all the ancestors (direct and indirect) of a MEntity.
 class CmdAncestors
-       super CmdEntityList
+       super CmdInheritance
 
        # Include direct parents in the ancestors list
        #
@@ -111,13 +142,13 @@ class CmdAncestors
                if not res isa CmdSuccess then return res
                var mentity = self.mentity.as(not null)
 
-               var ancestors = mentity.collect_ancestors(view).to_a
+               var ancestors = mentity.collect_ancestors(mainmodule, filter).to_a
                if parents then
                        results = ancestors
                        return res
                end
 
-               var parents = mentity.collect_parents(view)
+               var parents = mentity.collect_parents(mainmodule, filter)
                var mentities = new HashSet[MEntity]
                for ancestor in ancestors do
                        if not parents.has(ancestor) then mentities.add ancestor
@@ -129,7 +160,7 @@ end
 
 # MEntity parents command
 class CmdParents
-       super CmdEntityList
+       super CmdInheritance
 
        redef fun init_results do
                if results != null then return new CmdSuccess
@@ -138,14 +169,14 @@ class CmdParents
                if not res isa CmdSuccess then return res
                var mentity = self.mentity.as(not null)
 
-               results = mentity.collect_parents(view).to_a
+               results = mentity.collect_parents(mainmodule, filter).to_a
                return res
        end
 end
 
 # MEntity children command
 class CmdChildren
-       super CmdEntityList
+       super CmdInheritance
 
        redef fun init_results do
                if results != null then return new CmdSuccess
@@ -154,14 +185,14 @@ class CmdChildren
                if not res isa CmdSuccess then return res
                var mentity = self.mentity.as(not null)
 
-               results = mentity.collect_children(view).to_a
+               results = mentity.collect_children(mainmodule, filter).to_a
                return res
        end
 end
 
 # MEntity descendants command
 class CmdDescendants
-       super CmdEntityList
+       super CmdInheritance
 
        # Include direct children in the descendants list
        #
@@ -175,13 +206,13 @@ class CmdDescendants
                if not res isa CmdSuccess then return res
                var mentity = self.mentity.as(not null)
 
-               var descendants = mentity.collect_descendants(view).to_a
+               var descendants = mentity.collect_descendants(mainmodule, filter).to_a
                if children then
                        results = descendants
                        return res
                end
 
-               var children = mentity.collect_children(view)
+               var children = mentity.collect_children(mainmodule, filter)
                var mentities = new HashSet[MEntity]
                for descendant in descendants do
                        if not children.has(descendant) then mentities.add descendant
@@ -195,7 +226,7 @@ end
 #
 # Collects and linearizes definitions about an MEntity.
 class CmdLinearization
-       super CmdEntityList
+       super CmdInheritance
 
        # Same states than `CmdEntity::init_mentity`
        #
@@ -209,7 +240,7 @@ class CmdLinearization
                var mentity = self.mentity.as(not null)
 
                sorter = null
-               results = mentity.collect_linearization(view.mainmodule)
+               results = mentity.collect_linearization(mainmodule)
                if results == null then return new WarningNoLinearization(mentity)
                return res
        end
@@ -244,7 +275,7 @@ class CmdSearch
                var query = self.query
                if query == null then return new ErrorNoQuery
                sorter = null
-               results = view.find(query)
+               results = model.find(query)
                return res
        end
 end
@@ -274,21 +305,21 @@ class CmdFeatures
 
                var mentities = new Array[MEntity]
                if mentity isa MPackage then
-                       mentities.add_all mentity.collect_mgroups(view)
-                       mentities.add_all mentity.collect_mmodules(view)
+                       mentities.add_all mentity.collect_mgroups(filter)
+                       mentities.add_all mentity.collect_mmodules(filter)
                else if mentity isa MGroup then
-                       mentities.add_all mentity.collect_mgroups(view)
-                       mentities.add_all mentity.collect_mmodules(view)
+                       mentities.add_all mentity.collect_mgroups(filter)
+                       mentities.add_all mentity.collect_mmodules(filter)
                else if mentity isa MModule then
-                       mentities.add_all mentity.collect_local_mclassdefs(view)
+                       mentities.add_all mentity.collect_local_mclassdefs(filter)
                else if mentity isa MClass then
-                       mentities.add_all mentity.collect_intro_mproperties(view)
-                       mentities.add_all mentity.collect_redef_mpropdefs(view)
+                       mentities.add_all mentity.collect_intro_mproperties(filter)
+                       mentities.add_all mentity.collect_redef_mpropdefs(filter)
                else if mentity isa MClassDef then
-                       mentities.add_all mentity.collect_intro_mpropdefs(view)
-                       mentities.add_all mentity.collect_redef_mpropdefs(view)
+                       mentities.add_all mentity.collect_intro_mpropdefs(filter)
+                       mentities.add_all mentity.collect_redef_mpropdefs(filter)
                else if mentity isa MProperty then
-                       mentities.add_all mentity.collect_mpropdefs(view)
+                       mentities.add_all mentity.collect_mpropdefs(filter)
                else
                        return new WarningNoFeatures(mentity)
                end
@@ -299,7 +330,7 @@ end
 
 # TODO remove once the filters/sorters are merged
 class CmdIntros
-       super CmdEntityList
+       super CmdInheritance
 
        redef fun init_results do
                if results != null then return new CmdSuccess
@@ -309,14 +340,14 @@ class CmdIntros
                var mentity = self.mentity.as(not null)
 
                if mentity isa MModule then
-                       var mentities = mentity.collect_intro_mclasses(view).to_a
+                       var mentities = mentity.collect_intro_mclasses(filter).to_a
                        self.results = mentities
                else if mentity isa MClass then
-                       var mentities = mentity.collect_intro_mproperties(view).to_a
+                       var mentities = mentity.collect_intro_mproperties(filter).to_a
                        self.results = mentities
                else if mentity isa MClassDef then
-                       var mentities = mentity.collect_intro_mpropdefs(view).to_a
-                       view.mainmodule.linearize_mpropdefs(mentities)
+                       var mentities = mentity.collect_intro_mpropdefs(filter).to_a
+                       mainmodule.linearize_mpropdefs(mentities)
                        self.results = mentities
                else
                        return new WarningNoFeatures(mentity)
@@ -327,9 +358,9 @@ end
 
 # TODO remove once the filters/sorters are merged
 class CmdRedefs
-       super CmdEntityList
+       super CmdInheritance
 
-       redef fun init_command do
+       redef fun init_results do
                if results != null then return new CmdSuccess
 
                var res = super
@@ -337,14 +368,14 @@ class CmdRedefs
                var mentity = self.mentity.as(not null)
 
                if mentity isa MModule then
-                       var mentities = mentity.collect_redef_mclasses(view).to_a
+                       var mentities = mentity.collect_redef_mclassdefs(filter).to_a
                        self.results = mentities
                else if mentity isa MClass then
-                       var mentities = mentity.collect_redef_mproperties(view).to_a
+                       var mentities = mentity.collect_redef_mpropdefs(filter).to_a
                        self.results = mentities
                else if mentity isa MClassDef then
-                       var mentities = mentity.collect_redef_mpropdefs(view).to_a
-                       view.mainmodule.linearize_mpropdefs(mentities)
+                       var mentities = mentity.collect_redef_mpropdefs(filter).to_a
+                       mainmodule.linearize_mpropdefs(mentities)
                        self.results = mentities
                else
                        return new WarningNoFeatures(mentity)
@@ -355,7 +386,7 @@ end
 
 # TODO remove once the filters/sorters are merged
 class CmdAllProps
-       super CmdEntityList
+       super CmdInheritance
 
        redef fun init_results do
                if results != null then return new CmdSuccess
@@ -365,7 +396,7 @@ class CmdAllProps
                var mentity = self.mentity.as(not null)
 
                if mentity isa MClass then
-                       results = mentity.collect_accessible_mproperties(view).to_a
+                       results = mentity.collect_accessible_mproperties(mainmodule, filter).to_a
                else
                        return new WarningNoFeatures(mentity)
                end
@@ -383,16 +414,13 @@ class WarningNoFeatures
        redef fun to_s do return "No features for `{mentity.full_name}`"
 end
 
-# Cmd that finds the source code related to an `mentity`
-class CmdCode
-       super CmdEntity
-
-       autoinit(view, modelbuilder, mentity, mentity_name, format)
+# Abstract command that returns source-code pieces
+abstract class CmdCode
+       super DocCommand
 
-       # ModelBuilder used to get AST nodes
-       var modelbuilder: ModelBuilder
+       autoinit(model, filter, node, format)
 
-       # AST node to return
+       # AST node to display code from
        var node: nullable ANode = null is optional, writable
 
        # Rendering format
@@ -406,6 +434,22 @@ class CmdCode
        # Another example is to render raw format to put into a HTML code tag.
        var format = "raw" is optional, writable
 
+       # Render `node` depending on the selected `format`
+       fun render_code(node: ANode): Writable do
+               return node.location.text
+       end
+end
+
+# Cmd that finds the source code related to an `mentity`
+class CmdEntityCode
+       super CmdEntity
+       super CmdCode
+
+       autoinit(model, modelbuilder, filter, mentity, mentity_name, format)
+
+       # ModelBuilder used to get AST nodes from entities
+       var modelbuilder: ModelBuilder
+
        # Same as `CmdEntity::init_mentity`
        #
        # Plus `WarningNoCode` if no code/AST node is found for `mentity`.
@@ -422,24 +466,6 @@ class CmdCode
                if node == null then return new WarningNoCode(mentity)
                return res
        end
-
-       # Render `node` depending on the selected `format`
-       fun render: nullable Writable do
-               var node = self.node
-               if node == null then return null
-               if format == "html" then
-                       var hl = new HtmlightVisitor
-                       hl.highlight_node node
-                       return hl.html
-               else if format == "ansi" then
-                       var hl = new AnsiHighlightVisitor
-                       hl.highlight_node node
-                       return hl.result
-               end
-               var mentity = self.mentity
-               if mentity == null then return null
-               return mentity.location.text
-       end
 end
 
 # No code for `mentity`
@@ -477,21 +503,21 @@ class CmdModelEntities
 
                var mentities = new Array[MEntity]
                if kind == "packages" then
-                       mentities = view.mpackages.to_a
+                       mentities = model.collect_mpackages(filter).to_a
                else if kind == "groups" then
-                       mentities = view.mgroups.to_a
+                       mentities = model.collect_mgroups(filter).to_a
                else if kind == "modules" then
-                       mentities = view.mmodules.to_a
+                       mentities = model.collect_mmodules(filter).to_a
                else if kind == "classes" then
-                       mentities = view.mclasses.to_a
+                       mentities = model.collect_mclasses(filter).to_a
                else if kind == "classdefs" then
-                       mentities = view.mclassdefs.to_a
+                       mentities = model.collect_mclassdefs(filter).to_a
                else if kind == "properties" then
-                       mentities = view.mproperties.to_a
+                       mentities = model.collect_mproperties(filter).to_a
                else if kind == "propdefs" then
-                       mentities = view.mpropdefs.to_a
+                       mentities = model.collect_mpropdefs(filter).to_a
                else
-                       mentities = view.mentities.to_a
+                       mentities = model.collect_mentities(filter).to_a
                end
                results = mentities
                return res