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)
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
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
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
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
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("")
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]
# 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
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 = ""
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
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}"
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
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