cmd/cmd_parser: parse filter options from cmd string
authorAlexandre Terrasa <alexandre@moz-code.org>
Tue, 15 May 2018 16:52:04 +0000 (12:52 -0400)
committerAlexandre Terrasa <alexandre@moz-code.org>
Thu, 21 Jun 2018 00:45:30 +0000 (20:45 -0400)
Signed-off-by: Alexandre Terrasa <alexandre@moz-code.org>

src/doc/commands/commands_base.nit
src/doc/commands/commands_parser.nit
src/doc/commands/tests/test_commands_parser.nit

index b1af0e1..822b509 100644 (file)
@@ -70,6 +70,13 @@ abstract class DocCommand
        #
        # Warnings are generally used to distinguish empty list or mdoc from no data at all.
        fun init_command: CmdMessage do return new CmdSuccess
+
+       # Return a new filter for that command execution.
+       fun cmd_filter: ModelFilter do
+               var filter = self.filter
+               if filter == null then return new ModelFilter
+               return new ModelFilter.from(filter)
+       end
 end
 
 # Command message
index 6678bfa..c3e5118 100644 (file)
@@ -256,6 +256,28 @@ redef class DocCommand
 
        # Initialize the command from the CommandParser data
        fun parser_init(arg: String, options: CmdOptions): CmdMessage do
+               var filter = cmd_filter
+               var opt_vis = options.opt_visibility("min-visibility")
+               if opt_vis != null then filter.min_visibility = opt_vis
+               var opt_fictive = options.opt_bool("no-fictive")
+               if opt_fictive != null then filter.accept_fictive = not opt_fictive
+               var opt_test = options.opt_bool("no-test")
+               if opt_test != null then filter.accept_test = not opt_test
+               var opt_redef = options.opt_bool("no-redef")
+               if opt_redef != null then filter.accept_redef = not opt_redef
+               var opt_extern = options.opt_bool("no-extern")
+               if opt_extern != null then filter.accept_extern = not opt_extern
+               var opt_example = options.opt_bool("no-example")
+               if opt_example != null then filter.accept_example = not opt_example
+               var opt_attr = options.opt_bool("no-attribute")
+               if opt_attr != null then filter.accept_attribute = not opt_attr
+               var opt_doc = options.opt_bool("no-empty-doc")
+               if opt_doc != null then filter.accept_empty_doc = not opt_doc
+               var opt_inh = options.opt_mentity(model, "inherit")
+               if opt_inh != null then filter.accept_inherited = opt_inh
+               var opt_match = options.opt_string("match")
+               if opt_match != null then filter.accept_full_name = opt_match
+               self.filter = filter
                return init_command
        end
 end
@@ -379,6 +401,15 @@ end
 class CmdOptions
        super HashMap[String,  String]
 
+       # Map String visiblity name to MVisibility object
+       var allowed_visibility: HashMap[String, MVisibility] is lazy do
+               var res = new HashMap[String, MVisibility]
+               res["public"] = public_visibility
+               res["protected"] = protected_visibility
+               res["private"] = private_visibility
+               return res
+       end
+
        # Get option value for `key` as String
        #
        # Return `null` if no option with that `key` or if value is empty.
@@ -411,6 +442,33 @@ class CmdOptions
                if value == "false" then return false
                return null
        end
+
+       # Get option as a MVisibility
+       #
+       # Return `null` if no option with that `key` or if the value is not in
+       # `allowed_visibility`.
+       fun opt_visibility(key: String): nullable MVisibility do
+               var value = opt_string(key)
+               if value == null then return null
+               if not allowed_visibility.keys.has(key) then return null
+               return allowed_visibility[value]
+       end
+
+       # Get option as a MEntity
+       #
+       # Lookup first by `MEntity::full_name` then by `MEntity::name`.
+       # Return `null` if the mentity name does not exist or return a conflict.
+       private fun opt_mentity(model: Model, key: String): nullable MEntity do
+               var value = opt_string(key)
+               if value == null or value.is_empty then return null
+
+               var mentity = model.mentity_by_full_name(value)
+               if mentity != null then return mentity
+
+               var mentities = model.mentities_by_name(value)
+               if mentities.is_empty or mentities.length > 1 then return null
+               return mentities.first
+       end
 end
 
 redef class Text
index d97e281..ea54a8b 100644 (file)
@@ -190,6 +190,14 @@ class TestCommandsParser
                assert cmd.results.as(not null).length == 9
        end
 
+       fun test_cmd_parser_ancestors_with_filter_match is test do
+               var parser = new CommandParser(test_model, test_main, test_builder, test_catalog)
+               var cmd = parser.parse("ancestors: test_prog::Warrior | match: Object")
+               assert cmd isa CmdAncestors
+               assert parser.error == null
+               assert cmd.results.as(not null).length == 1
+       end
+
        # CmdSearch
 
        fun test_cmd_parser_search is test do
@@ -226,6 +234,14 @@ class TestCommandsParser
                assert cmd.results.as(not null).length == 2
        end
 
+       fun test_cmd_parser_with_filter_inherited is test do
+               var parser = new CommandParser(test_model, test_main, test_builder, test_catalog)
+               var cmd = parser.parse("defs: test_prog::TestGame | inherited: TestGame")
+               assert cmd isa CmdFeatures
+               assert parser.error == null
+               assert cmd.results.as(not null).length == 3
+       end
+
        # CmdLinearization
 
        fun test_cmd_parser_lin is test do