nitx: remove ModelView dependency
[nit.git] / src / doc / commands / commands_parser.nit
index af75cbe..920b2fa 100644 (file)
@@ -21,12 +21,17 @@ import commands::commands_model
 import commands::commands_graph
 import commands::commands_usage
 import commands::commands_catalog
+import commands::commands_ini
+import commands::commands_main
 
 # Parse string commands to create DocQueries
 class CommandParser
 
-       # ModelView used to retrieve mentities
-       var view: ModelView
+       # Model used to retrieve mentities
+       var model: Model
+
+       # Main module for linearization
+       var mainmodule: MModule
 
        # ModelBuilder used to retrieve AST nodes
        var modelbuilder: ModelBuilder
@@ -34,13 +39,67 @@ class CommandParser
        # Catalog used for catalog commands
        var catalog: nullable Catalog
 
+       # Filter to apply on model if any
+       var filter: nullable ModelFilter
+
        # List of allowed command names for this parser
        var allowed_commands: Array[String] = [
-       "doc", "code", "lin", "uml", "graph", "search",
+       "link", "doc", "code", "lin", "uml", "graph", "search",
        "parents", "ancestors", "children", "descendants",
        "param", "return", "new", "call", "defs", "list", "random",
+       "ini-desc", "ini-git", "ini-issues", "ini-maintainer", "ini-contributors", "ini-license",
+       "license-file", "contrib-file", "license-content", "contrib-content", "git-clone",
+       "mains", "main-compile", "main-run", "main-opts", "testing",
        "catalog", "stats", "tags", "tag", "person", "contrib", "maintain"] is writable
 
+       # List of commands usage and documentation
+       var commands_usage: Map[String, String] do
+               var usage = new ArrayMap[String, String]
+               usage["search: <string>"] = "list entities matching `string`"
+               usage["link: <name>"] = "display the link to `name`"
+               usage["doc: <name>"] = "display the documentation for `name`"
+               usage["defs: <name>"] = "list all definitions for `name`"
+               usage["code: <name>"] = "display the code for `name`"
+               usage["lin: <name>"] = "display the linearization for `name`"
+               usage["uml: <name>"] = "display the UML diagram for `name`"
+               usage["graph: <name>"] = "display the inheritance graph for `name`"
+               usage["parents: <name>"] = "list the direct parents of `name`"
+               usage["ancestors: <name>"] = "list all ancestors of `name`"
+               usage["children: <name>"] = "list direct children of `name`"
+               usage["descendants: <name>"] = "list all descendants of `name`"
+               usage["param: <type>"] = "list all methods accepting `type` as parameter"
+               usage["return: <type>"] = "list all methods returning `type`"
+               usage["new: <class>"] = "list all methods initializing `class`"
+               usage["call: <property>"] = "list all methods calling `property`"
+               usage["list: <kind>"] = "list all entities of `kind` from the model"
+               usage["random: <kind>"] = "list random entities of `kind` from the model"
+               usage["catalog:"] = "list packages from catalog"
+               usage["stats:"] = "display catalog statistics"
+               usage["tags:"] = "list all tabs from catalog"
+               usage["tag: <tag>"] = "list all packages with `tag`"
+               usage["maintain: <person>"] = "list all packages maintained by `person`"
+               usage["contrib: <person>"] = "list all packages contributed by `person`"
+               # Ini commands
+               usage["ini-desc: <package>"] = "display the description from the `package` ini file"
+               usage["ini-git: <package>"] = "display the git url from the `package` ini file"
+               usage["ini-issues: <package>"] = "display the issues url from the `package` ini file"
+               usage["ini-license: <package>"] = "display the license from the `package` ini file"
+               usage["ini-maintainer: <package>"] = "display the maintainer from the `package` ini file"
+               usage["ini-contributors: <package>"] = "display the contributors from the `package` ini file"
+               usage["license-file: <package>"] = "display the license file for the `package`"
+               usage["license-content: <package>"] = "display the license file content for the `package`"
+               usage["contrib-file: <package>"] = "display the contrib file for the `package`"
+               usage["contrib-content: <package>"] = "display the contrib file content for the `package`"
+               usage["git-clone: <package>"] = "display the git clone command for the `package`"
+               # Main
+               usage["mains: <name>"] = "display the list of main methods for `name`"
+               usage["main-compile: <name>"] = "display the nitc command to compile `name`"
+               usage["main-run: <name>"] = "display the command to run `name`"
+               usage["main-opts: <name>"] = "display the command options for `name`"
+               usage["testing: <name>"] = "display the nitunit command to test `name`"
+               return usage
+       end
+
        # Parse `string` as a DocCommand
        #
        # Returns `null` if the string cannot be parsed.
@@ -51,16 +110,25 @@ class CommandParser
                error = null
 
                # Parse command name
-               pos = string.read_until(tmp, pos, ':')
+               pos = string.read_until(tmp, pos, ':', '|')
                var name = tmp.write_to_string.trim
 
                # Check allowed commands
                if name.is_empty then
-                       error = new CmdParserError("empty command name", 0)
+                       error = new CmdParserError("Empty command name", 0)
                        return null
                end
-               if not allowed_commands.has(name) then
-                       error = new CmdParserError("unknown command name", 0)
+               # If the command name contains two consecutive colons or there is no colon in the name,
+               # we certainly have a wiki link to a mentity
+               var is_short_link = false
+               if (pos < string.length - 2 and string[pos] == ':' and string[pos + 1] == ':') or
+                  pos == string.length then
+                       is_short_link = true
+               else if pos < string.length - 1 and string[pos] == '|' then
+                       is_short_link = true
+                       pos -= 1
+               else if not allowed_commands.has(name) then
+                       error = new CmdParserError("Unknown command name `{name}`", 0)
                        return null
                end
 
@@ -68,6 +136,11 @@ class CommandParser
                tmp.clear
                pos = string.read_until(tmp, pos + 1, '|')
                var arg = tmp.write_to_string.trim
+               if is_short_link and not arg.is_empty then
+                       arg = "{name}:{arg}"
+               else if is_short_link then
+                       arg = name
+               end
 
                # Parse command options
                var opts = new HashMap[String, String]
@@ -88,9 +161,14 @@ class CommandParser
                end
 
                # Build the command
-               var command = new_command(name)
+               var command
+               if is_short_link then
+                       command = new CmdEntityLink(model, filter)
+               else
+                       command = new_command(name)
+               end
                if command == null then
-                       error = new CmdParserError("Unknown command name")
+                       error = new CmdParserError("Unknown command name `{name}`", 0)
                        return null
                end
 
@@ -106,37 +184,56 @@ class CommandParser
        # You must redefine this method to add new custom commands.
        fun new_command(name: String): nullable DocCommand do
                # CmdEntity
-               if name == "doc" then return new CmdComment(view)
-               if name == "code" then return new CmdCode(view, modelbuilder)
-               if name == "lin" then return new CmdLinearization(view)
-               if name == "defs" then return new CmdFeatures(view)
-               if name == "parents" then return new CmdParents(view)
-               if name == "ancestors" then return new CmdAncestors(view)
-               if name == "children" then return new CmdChildren(view)
-               if name == "descendants" then return new CmdDescendants(view)
-               if name == "param" then return new CmdParam(view)
-               if name == "return" then return new CmdReturn(view)
-               if name == "new" then return new CmdNew(view, modelbuilder)
-               if name == "call" then return new CmdCall(view, modelbuilder)
+               if name == "link" then return new CmdEntityLink(model, filter)
+               if name == "doc" then return new CmdComment(model, filter)
+               if name == "code" then return new CmdEntityCode(model, modelbuilder, filter)
+               if name == "lin" then return new CmdLinearization(model, mainmodule, filter)
+               if name == "defs" then return new CmdFeatures(model, filter)
+               if name == "parents" then return new CmdParents(model, mainmodule, filter)
+               if name == "ancestors" then return new CmdAncestors(model, mainmodule, filter)
+               if name == "children" then return new CmdChildren(model, mainmodule, filter)
+               if name == "descendants" then return new CmdDescendants(model, mainmodule, filter)
+               if name == "param" then return new CmdParam(model, filter)
+               if name == "return" then return new CmdReturn(model, filter)
+               if name == "new" then return new CmdNew(model, modelbuilder, filter)
+               if name == "call" then return new CmdCall(model, modelbuilder, filter)
                # CmdGraph
-               if name == "uml" then return new CmdUML(view)
-               if name == "graph" then return new CmdInheritanceGraph(view)
+               if name == "uml" then return new CmdUML(model, mainmodule, filter)
+               if name == "graph" then return new CmdInheritanceGraph(model, mainmodule, filter)
                # CmdModel
-               if name == "list" then return new CmdModelEntities(view)
-               if name == "random" then return new CmdRandomEntities(view)
+               if name == "list" then return new CmdModelEntities(model, filter)
+               if name == "random" then return new CmdRandomEntities(model, filter)
+               # Ini
+               if name == "ini-desc" then return new CmdIniDescription(model, filter)
+               if name == "ini-git" then return new CmdIniGitUrl(model, filter)
+               if name == "ini-issues" then return new CmdIniIssuesUrl(model, filter)
+               if name == "ini-license" then return new CmdIniLicense(model, filter)
+               if name == "ini-maintainer" then return new CmdIniMaintainer(model, filter)
+               if name == "ini-contributors" then return new CmdIniContributors(model, filter)
+               if name == "license-file" then return new CmdLicenseFile(model, filter)
+               if name == "license-content" then return new CmdLicenseFileContent(model, filter)
+               if name == "contrib-file" then return new CmdContribFile(model, filter)
+               if name == "contrib-content" then return new CmdContribFileContent(model, filter)
+               if name == "git-clone" then return new CmdIniCloneCommand(model, filter)
+               # CmdMain
+               if name == "mains" then return new CmdMains(model, filter)
+               if name == "main-compile" then return new CmdMainCompile(model, filter)
+               if name == "main-run" then return new CmdManSynopsis(model, filter)
+               if name == "main-opts" then return new CmdManOptions(model, filter)
+               if name == "testing" then return new CmdTesting(model, filter)
                # CmdCatalog
                var catalog = self.catalog
                if catalog != null then
-                       if name == "catalog" then return new CmdCatalogPackages(view, catalog)
-                       if name == "stats" then return new CmdCatalogStats(view, catalog)
-                       if name == "tags" then return new CmdCatalogTags(view, catalog)
-                       if name == "tag" then return new CmdCatalogTag(view, catalog)
-                       if name == "person" then return new CmdCatalogPerson(view, catalog)
-                       if name == "contrib" then return new CmdCatalogContributing(view, catalog)
-                       if name == "maintain" then return new CmdCatalogMaintaining(view, catalog)
-                       if name == "search" then return new CmdCatalogSearch(view, catalog)
+                       if name == "catalog" then return new CmdCatalogPackages(model, catalog, filter)
+                       if name == "stats" then return new CmdCatalogStats(model, catalog, filter)
+                       if name == "tags" then return new CmdCatalogTags(model, catalog, filter)
+                       if name == "tag" then return new CmdCatalogTag(model, catalog, filter)
+                       if name == "person" then return new CmdCatalogPerson(model, catalog, filter)
+                       if name == "contrib" then return new CmdCatalogContributing(model, catalog, filter)
+                       if name == "maintain" then return new CmdCatalogMaintaining(model, catalog, filter)
+                       if name == "search" then return new CmdCatalogSearch(model, catalog, filter)
                else
-                       if name == "search" then return new CmdSearch(view)
+                       if name == "search" then return new CmdSearch(model, filter)
                end
                return null
        end
@@ -191,6 +288,14 @@ redef class CmdComment
        end
 end
 
+redef class CmdEntityLink
+       redef fun parser_init(mentity_name, options) do
+               if options.has_key("text") then text = options["text"]
+               if options.has_key("title") then title = options["title"]
+               return super
+       end
+end
+
 redef class CmdCode
        redef fun parser_init(mentity_name, options) do
                if options.has_key("format") then format = options["format"]