X-Git-Url: http://nitlanguage.org?ds=sidebyside diff --git a/src/ni.nit b/src/ni.nit index 32340af..e340415 100644 --- a/src/ni.nit +++ b/src/ni.nit @@ -84,33 +84,44 @@ 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 - flag = true - mmatches.add(m) + # 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 props_fulldoc(matches) + 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 props_fulldoc(matches) + 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 - 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) + 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 - 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) + 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 @@ -120,9 +131,13 @@ class NitIndex var pager = new Pager for mmodule in mmodules do var nmodule = mbuilder.mmodule2nmodule[mmodule] - pager.add("# module {mmodule.name}\n".bold) - pager.add("import {mmodule.in_importation.direct_greaters.join(", ")}") - #TODO add kmown clients + pager.add("# module {mmodule.namespace}\n".bold) + if not mmodule.in_importation.direct_greaters.is_empty then + pager.add("import ".bold + "{mmodule.in_importation.direct_greaters.join(", ")}\n") + end + if not mmodule.in_importation.direct_smallers.is_empty then + pager.add("known clients: ".bold + "{mmodule.in_importation.direct_smallers.join(", ")}\n") + end pager.add_rule pager.addn(nmodule.comment.green) pager.add_rule @@ -130,13 +145,19 @@ 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}\n".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 pager.add("\t# {nclass.short_comment}") end @@ -145,7 +166,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 @@ -153,7 +174,6 @@ class NitIndex pager.add("\t\t" + "refined in {mclassdef.namespace}".gray) end end - pager.add("") end end end @@ -167,24 +187,23 @@ class NitIndex for mclass in mclasses do var nclass = mbuilder.mclassdef2nclassdef[mclass.intro].as(AStdClassdef) - pager.add("# {mclass.intro_mmodule.public_owner.name}::{mclass.name}\n".bold) - pager.add("{mclass.short_doc} ") - #TODO add kmown subclasses + pager.add("# {mclass.namespace}\n".bold) + pager.add("{mclass.short_doc}") pager.add_rule pager.addn(nclass.comment.green) pager.add_rule if not mclass.parameter_types.is_empty then - pager.add("# formal types\n".bold) + pager.add("# formal types".bold) for ft, bound in mclass.parameter_types do - pager.add("\t{ft.to_s.green}: {bound}") pager.add("") + pager.add("\t{ft.to_s.green}: {bound}") end end if not mclass.virtual_types.is_empty then - pager.add("# virtual types\n".bold) + pager.add("# virtual types".bold) for vt in mclass.virtual_types do - vt_fulldoc(pager, vt) pager.add("") + vt_fulldoc(pager, vt) end end pager.add_rule @@ -197,10 +216,15 @@ class NitIndex for cat, list in cats do if not list.is_empty then - pager.add("# {cat}\n".bold) - for mprop in list do - method_fulldoc(pager, mprop) + #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 sorted do pager.add("") + method_fulldoc(pager, mprop) end end end @@ -209,34 +233,87 @@ class NitIndex pager.render end - private fun props_fulldoc(mprops: List[MProperty]) do + private fun props_fulldoc(raw_mprops: List[MProperty]) do var pager = new Pager - # TODO group by module - for mprop in mprops do - if mprop isa MMethod and mbuilder.mpropdef2npropdef.has_key(mprop.intro) then - method_fulldoc(pager, mprop) - pager.add_rule - else if mprop isa MVirtualTypeProp then - vt_fulldoc(pager, mprop) - pager.add_rule + # group by module + var cats = new HashMap[MModule, Array[MProperty]] + for mprop in raw_mprops do + var mmodule = mprop.intro_mclassdef.mmodule + if not cats.has_key(mmodule) then cats[mmodule] = new Array[MProperty] + cats[mmodule].add(mprop) + end + #sort groups + var sorter = new ComparableSorter[MModule] + var sorted = new Array[MModule] + sorted.add_all(cats.keys) + sorter.sort(sorted) + # display + for mmodule in sorted do + var mprops = cats[mmodule] + pager.add("# {mmodule.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("") + method_fulldoc(pager, mprop) + else if mprop isa MVirtualTypeProp then + pager.add("") + vt_fulldoc(pager, mprop) + end end + pager.add_rule end pager.render end - private fun method_fulldoc(pager: Pager, mmethod: MMethod) do - if mbuilder.mpropdef2npropdef.has_key(mmethod.intro) then - var nmethod = mbuilder.mpropdef2npropdef[mmethod.intro] - if nmethod isa AMethPropdef then - if not nmethod.short_comment.is_empty then - pager.add("\t# {nmethod.short_comment}") + 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 - pager.add("\t{nmethod}") - pager.add("\t\t" + "introduced in {mmethod.intro_mclassdef.namespace}".gray) - for mpropdef in mmethod.mpropdefs do - if mpropdef != mmethod.intro then - pager.add("\t\t" + "refined in {mpropdef.mclassdef.namespace}".gray) - 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] + if not nprop.short_comment.is_empty then + pager.add("\t# {nprop.short_comment}") + end + if nprop isa AAttrPropdef then + pager.add("\t{nprop.read_accessor}") + pager.add("\t{nprop.write_accessor}") + else if nprop isa AMethPropdef then + pager.add("\t{nprop}") + end + pager.add("\t\t" + "introduced in {mprop.intro_mclassdef.namespace}".gray) + for mpropdef in mprop.mpropdefs do + if mpropdef != mprop.intro then + pager.add("\t\t" + "refined in {mpropdef.mclassdef.namespace}".gray) end end end @@ -255,7 +332,20 @@ 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 @@ -274,9 +364,15 @@ redef class MClass if visibility.to_s == "public" then ret = "{ret}{to_s.green}" if visibility.to_s == "private" then ret = "{ret}{to_s.red}" if visibility.to_s == "protected" then ret = "{ret}{to_s.yellow}" - ret = "{ret} super {parents.join(", ")}" + if not parents.is_empty then + ret = "{ret} super {parents.join(", ")}" + end return ret end + + private fun namespace: String do + return "{intro_mmodule.public_owner.name}::{name}" + end end redef class MClassDef @@ -285,6 +381,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 = "" @@ -330,8 +432,52 @@ redef class AStdClassdef end end +redef class APropdef + private fun short_comment: String is abstract +end + +redef class AAttrPropdef + 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 + + 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}" + if mpropdef.mproperty.visibility.to_s == "protected" then ret = "{ret}{name.yellow}" + ret = "{ret}: {n_type.to_s}" + if n_kwredef != null then ret = "redef {ret}" + return ret + end + + private fun write_accessor: String do + var ret = "fun " + var name = "{mreadpropdef.mproperty.name}=" + if n_readable != null and n_readable.n_visibility != null then + if n_readable.n_visibility isa APublicVisibility then ret = "{ret}{name.green}" + if n_readable.n_visibility isa APrivateVisibility then ret = "{ret}{name.red}" + if n_readable.n_visibility isa AProtectedVisibility then ret = "{ret}{name.yellow}" + else + ret = "{ret}{name.red}" + end + ret = "{ret}({mreadpropdef.mproperty.name}: {n_type.to_s})" + if n_kwredef != null then ret = "redef {ret}" + return ret + end +end + redef class AMethPropdef - private fun short_comment: String do + redef fun short_comment do var ret = "" if n_doc != null then var txt = n_doc.n_comment.first.text @@ -440,10 +586,7 @@ toolcontext.process_options var ni = new NitIndex(toolcontext) ni.start -# TODO seek methods by return type : -# TODO seek methods by param type: () # TODO seek subclasses and super classes <. >. # TODO seek subclasses and super types <: >: -# TODO sort by alphabetic order # TODO seek with regexp -# TODO standardize namespaces +# TODO standardize namespaces with private option