ni: moved comment faccilities to APropdef
[nit.git] / src / ni.nit
index 28a63a6..0826e46 100644 (file)
@@ -36,9 +36,10 @@ class NitIndex
        init(toolcontext: ToolContext) do
                # We need a model to collect stufs
                self.toolcontext = toolcontext
+               self.toolcontext.option_context.options.clear
                self.arguments = toolcontext.option_context.rest
 
-               if arguments.length > 2 then
+               if arguments.is_empty or arguments.length > 2 then
                        print "usage: ni path/to/module.nit [expression]"
                        toolcontext.option_context.usage
                        exit(1)
@@ -84,33 +85,50 @@ class NitIndex
        fun seek(entry: String) do
                if entry.is_empty then exit(0)
                var flag = false
-               # seek for modules
-               var mmatches = new List[MModule]
-               for m in model.mmodules do
-                       if m.name == entry then
+               # seek return types
+               if entry.has_prefix("return:") then
+                       var ret = entry.split_with(":")[1].replace(" ", "")
+                       var matches = seek_returns(ret)
+                       if not matches.is_empty then
                                flag = true
-                               mmatches.add(m)
+                               props_fulldoc(matches)
                        end
-               end
-               if not mmatches.is_empty then modules_fulldoc(mmatches)
-               # seek for classes
-               var cmatches = new List[MClass]
-               for c in model.mclasses do
-                       if c.name == entry then
+               else if entry.has_prefix("param:") then
+                       var param = entry.split_with(":")[1].replace(" ", "")
+                       var matches = seek_params(param)
+                       if not matches.is_empty then
                                flag = true
-                               cmatches.add(c)
+                               props_fulldoc(matches)
                        end
-               end
-               if not cmatches.is_empty then classes_fulldoc(cmatches)
-               # seek for properties
-               var matches = new List[MProperty]
-               for p in model.mproperties do
-                       if p.name == entry then
-                               flag = true
-                               matches.add(p)
+               else
+                       # seek for modules
+                       var mmatches = new List[MModule]
+                       for m in model.mmodules do
+                               if m.name == entry then
+                                       flag = true
+                                       mmatches.add(m)
+                               end
                        end
+                       if not mmatches.is_empty then modules_fulldoc(mmatches)
+                       # seek for classes
+                       var cmatches = new List[MClass]
+                       for c in model.mclasses do
+                               if c.name == entry then
+                                       flag = true
+                                       cmatches.add(c)
+                               end
+                       end
+                       if not cmatches.is_empty then classes_fulldoc(cmatches)
+                       # seek for properties
+                       var matches = new List[MProperty]
+                       for p in model.mproperties do
+                               if p.name == entry then
+                                       flag = true
+                                       matches.add(p)
+                               end
+                       end
+                       if not matches.is_empty then props_fulldoc(matches)
                end
-               if not matches.is_empty then props_fulldoc(matches)
                # no matches
                if not flag then print "Nothing known about '{entry}'"
                if arguments.length == 1 then prompt
@@ -134,12 +152,17 @@ class NitIndex
                        var cats = new HashMap[String, Collection[MClass]]
                        cats["introduced classes"] = mmodule.intro_mclasses
                        cats["refined classes"] = mmodule.redef_mclasses
-                       cats["inherited classes"] = mmodule.imported_mclasses
+                       cats["imported classes"] = mmodule.imported_mclasses
 
                        for cat, list in cats do
                                if not list.is_empty then
-                                       pager.add("# {cat}".bold)
-                                       for mclass in list do
+                                       pager.add("\n# {cat}".bold)
+                                       #sort list
+                                       var sorted = new Array[MClass]
+                                       sorted.add_all(list)
+                                       var sorter = new ComparableSorter[MClass]
+                                       sorter.sort(sorted)
+                                       for mclass in sorted do
                                                var nclass = mbuilder.mclassdef2nclassdef[mclass.intro].as(AStdClassdef)
                                                pager.add("")
                                                if not nclass.short_comment.is_empty then
@@ -150,7 +173,7 @@ class NitIndex
                                                else
                                                        pager.add("\t{mclass.short_doc}")
                                                end
-                                               if not mclass.intro_mmodule == mmodule then
+                                               if cat != "introduced classes" then
                                                        pager.add("\t\t" + "introduced in {mmodule.full_name}::{mclass}".gray)
                                                end
                                                for mclassdef in mclass.mclassdefs do
@@ -200,8 +223,13 @@ class NitIndex
 
                        for cat, list in cats do
                                if not list.is_empty then
+                                       #sort list
+                                       var sorted = new Array[MMethod]
+                                       sorted.add_all(list)
+                                       var sorter = new ComparableSorter[MMethod]
+                                       sorter.sort(sorted)
                                        pager.add("\n# {cat}".bold)
-                                       for mprop in list do
+                                       for mprop in sorted do
                                                pager.add("")
                                                method_fulldoc(pager, mprop)
                                        end
@@ -215,15 +243,25 @@ class NitIndex
        private fun props_fulldoc(raw_mprops: List[MProperty]) do
                var pager = new Pager
                # group by module
-               var cats = new HashMap[MModule, List[MProperty]]
+               var cats = new HashMap[MClass, Array[MProperty]]
                for mprop in raw_mprops do
-                       var mmodule = mprop.intro_mclassdef.mmodule
-                       if not cats.has_key(mmodule) then cats[mmodule] = new List[MProperty]
-                       cats[mmodule].add(mprop)
+                       if not mbuilder.mpropdef2npropdef.has_key(mprop.intro) then continue
+                       if mprop isa MAttribute then continue
+                       var mclass = mprop.intro_mclassdef.mclass
+                       if not cats.has_key(mclass) then cats[mclass] = new Array[MProperty]
+                       cats[mclass].add(mprop)
                end
+               #sort groups
+               var sorter = new ComparableSorter[MClass]
+               var sorted = new Array[MClass]
+               sorted.add_all(cats.keys)
+               sorter.sort(sorted)
                # display
-               for mmodule, mprops in cats do
-                       pager.add("# {mmodule.namespace}".bold)
+               for mclass in sorted do
+                       var mprops = cats[mclass]
+                       pager.add("# {mclass.namespace}".bold)
+                       var sorterp = new ComparableSorter[MProperty]
+                       sorterp.sort(mprops)
                        for mprop in mprops do
                                if mprop isa MMethod and mbuilder.mpropdef2npropdef.has_key(mprop.intro) then
                                        pager.add("")
@@ -238,6 +276,37 @@ class NitIndex
                pager.render
        end
 
+       private fun seek_returns(entry: String): List[MProperty] do
+               # TODO how to match with generic types?
+               var matches = new List[MProperty]
+               for mprop in model.mproperties do
+                       var intro = mprop.intro
+                       if intro isa MMethodDef then
+                               if intro.msignature.return_mtype != null and intro.msignature.return_mtype.to_s == entry then matches.add(mprop)
+                       else if intro isa MAttributeDef then
+                               if intro.static_mtype.to_s == entry then matches.add(mprop)
+                       end
+               end
+               return matches
+       end
+
+       private fun seek_params(entry: String): List[MProperty] do
+               # TODO how to match with generic types?
+               var matches = new List[MProperty]
+               for mprop in model.mproperties do
+                       var intro = mprop.intro
+                       if intro isa MMethodDef then
+                               var mparameters = intro.msignature.mparameters
+                               for mparameter in mparameters do
+                                       if mparameter.mtype.to_s == entry then matches.add(mprop)
+                               end
+                       else if intro isa MAttributeDef then
+                               if intro.static_mtype.to_s == entry then matches.add(mprop)
+                       end
+               end
+               return matches
+       end
+
        private fun method_fulldoc(pager: Pager, mprop: MMethod) do
                if mbuilder.mpropdef2npropdef.has_key(mprop.intro) then
                        var nprop = mbuilder.mpropdef2npropdef[mprop.intro]
@@ -273,12 +342,19 @@ end
 # Printing facilities
 
 redef class MModule
+       super Comparable
+       redef type OTHER: MModule
+       redef fun <(other: OTHER): Bool do return self.name < other.name
+
        private fun namespace: String do
                return full_name
        end
 end
 
 redef class MClass
+       super Comparable
+       redef type OTHER: MClass
+       redef fun <(other: OTHER): Bool do return self.name < other.name
 
        redef fun to_s: String do
                if arity > 0 then
@@ -314,6 +390,12 @@ redef class MClassDef
        end
 end
 
+redef class MProperty
+       super Comparable
+       redef type OTHER: MProperty
+       redef fun <(other: OTHER): Bool do return self.name < other.name
+end
+
 redef class MVirtualTypeProp
        private fun short_doc: String do
                var ret = ""
@@ -360,11 +442,19 @@ redef class AStdClassdef
 end
 
 redef class APropdef
-       private fun short_comment: String is abstract
-end
+       private fun comment: String do
+               var ret = ""
+               if n_doc != null then
+                       for t in n_doc.n_comment do
+                               var txt = t.text.replace("# ", "")
+                               txt = txt.replace("#", "")
+                               ret += "{txt}"
+                       end
+               end
+               return ret
+       end
 
-redef class AAttrPropdef
-       redef fun short_comment do
+       private fun short_comment: String do
                var ret = ""
                if n_doc != null then
                        var txt = n_doc.n_comment.first.text
@@ -374,9 +464,12 @@ redef class AAttrPropdef
                end
                return ret
        end
+end
 
+redef class AAttrPropdef
        private fun read_accessor: String do
                var ret = "fun "
+               #FIXME bug with standard::stream::FDStream::fd
                var name = mreadpropdef.mproperty.name
                if mpropdef.mproperty.visibility.to_s == "public" then ret = "{ret}{name.green}"
                if mpropdef.mproperty.visibility.to_s == "private" then ret = "{ret}{name.red}"
@@ -403,17 +496,6 @@ redef class AAttrPropdef
 end
 
 redef class AMethPropdef
-       redef fun short_comment do
-               var ret = ""
-               if n_doc != null then
-                       var txt = n_doc.n_comment.first.text
-                       txt = txt.replace("# ", "")
-                       txt = txt.replace("\n", "")
-                       ret += txt
-               end
-               return ret
-       end
-
        redef fun to_s do
                var ret = ""
                if not mpropdef.mproperty.is_init then
@@ -512,10 +594,7 @@ toolcontext.process_options
 var ni = new NitIndex(toolcontext)
 ni.start
 
-# TODO seek methods by return type :<type>
-# TODO seek methods by param type: (<type>)
 # TODO seek subclasses and super classes <.<class> >.<class>
 # TODO seek subclasses and super types <:<type> >:<type>
-# TODO sort by alphabetic order
 # TODO seek with regexp
 # TODO standardize namespaces with private option