fun seek(entry: String) do
if entry.is_empty then exit(0)
- var flag = false
+ var pager = new Pager
# 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
- props_fulldoc(matches)
- end
+ props_fulldoc(pager, 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
- flag = true
- props_fulldoc(matches)
- end
+ props_fulldoc(pager, 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
+ if m.name == entry then mmatches.add(m)
end
- if not mmatches.is_empty then modules_fulldoc(mmatches)
+ if not mmatches.is_empty then modules_fulldoc(pager, 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
+ if c.name == entry then cmatches.add(c)
end
- if not cmatches.is_empty then classes_fulldoc(cmatches)
+ if not cmatches.is_empty then classes_fulldoc(pager, 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
+ if p.name == entry then matches.add(p)
end
- if not matches.is_empty then props_fulldoc(matches)
+ if not matches.is_empty then props_fulldoc(pager, matches)
end
# no matches
- if not flag then print "Nothing known about '{entry}'"
+ if pager.content.is_empty then
+ print "Nothing known about '{entry}'"
+ else
+ pager.render
+ end
if arguments.length == 1 then prompt
end
- private fun modules_fulldoc(mmodules: List[MModule]) do
- var pager = new Pager
+ private fun modules_fulldoc(pager: Pager, mmodules: List[MModule]) do
for mmodule in mmodules do
# name and prototype
pager.add("# {mmodule.namespace}\n".bold)
for comment in nmodule.n_moduledecl.n_doc.comment do pager.add(comment.green)
end
end
- pager.add("{mmodule.prototype}")
- pager.add_rule
+ pager.add("{mmodule.prototype}\n")
# imports
var msorter = new MModuleNameSorter
var ms = mmodule.in_importation.greaters.to_a
if ms.length > 1 then
msorter.sort(ms)
- pager.add("# imported modules".bold)
+ pager.add("## imported modules".bold)
pager.addn("\t")
for i in [0..ms.length[ do
if ms[i] == mmodule then continue
ms = mmodule.in_importation.smallers.to_a
if ms.length > 1 then
msorter.sort(ms)
- pager.add("# known modules".bold)
+ pager.add("## known modules".bold)
pager.addn("\t")
for i in [0..ms.length[ do
if ms[i] == mmodule then continue
# intro
if not intro_mclassdefs.is_empty then
sorter.sort(intro_mclassdefs)
- pager.add("\n# introduced classes".bold)
+ pager.add("\n## introduced classes".bold)
for mclassdef in intro_mclassdefs do
pager.add("")
var nclass = mbuilder.mclassdef2nclassdef[mclassdef]
# redefs
if not redef_mclassdefs.is_empty then
sorter.sort(redef_mclassdefs)
- pager.add("\n# refined classes".bold)
+ pager.add("\n## refined classes".bold)
for mclassdef in redef_mclassdefs do
pager.add("")
#TODO intro comment?
end
end
#TODO add inherited classes?
+ pager.add_rule
end
- pager.render
end
- private fun classes_fulldoc(mclasses: List[MClass]) do
- var pager = new Pager
+ private fun classes_fulldoc(pager: Pager, mclasses: List[MClass]) do
for mclass in mclasses do
- var nclass = mbuilder.mclassdef2nclassdef[mclass.intro].as(AStdClassdef)
-
+ # title
pager.add("# {mclass.namespace}\n".bold)
- pager.add("{mclass.prototype}")
- if not nclass.n_doc == null then
- pager.add_rule
- pager.addn(nclass.n_doc.comment.green)
+ # comment
+ if mbuilder.mclassdef2nclassdef.has_key(mclass.intro) then
+ var nclass = mbuilder.mclassdef2nclassdef[mclass.intro]
+ if nclass isa AStdClassdef and not nclass.n_doc == null then
+ for comment in nclass.n_doc.comment do pager.add(comment.green)
+ end
end
- pager.add_rule
+ pager.addn("{mclass.prototype}")
+ if mclass.in_hierarchy(mainmodule).direct_greaters.length > 1 then
+ var supers = mclass.in_hierarchy(mainmodule).direct_greaters.to_a
+ pager.addn(" super ")
+ for i in [0..supers.length[ do
+ if supers[i] == mclass then continue
+ pager.addn(supers[i].name)
+ if i < mclass.in_hierarchy(mainmodule).direct_greaters.length -1 then pager.addn(", ")
+ end
+ pager.add("\n")
+ end
+ # formal types
if not mclass.parameter_types.is_empty then
- pager.add("# formal types".bold)
+ pager.add("## formal types".bold)
for ft, bound in mclass.parameter_types do
pager.add("")
pager.add("\t{ft.to_s.green}: {bound}")
end
+ pager.add("")
end
- if not mclass.virtual_types.is_empty then
- pager.add("# virtual types".bold)
- for vt in mclass.virtual_types do
- pager.add("")
- mpropdef_fulldoc(pager, vt.intro)
+ # get properties
+ var cats = new ArrayMap[String, Set[MPropDef]]
+ cats["virtual types"] = new HashSet[MPropDef]
+ cats["constructors"] = new HashSet[MPropDef]
+ cats["introduced methods"] = new HashSet[MPropDef]
+ cats["refined methods"] = new HashSet[MPropDef]
+
+ for mclassdef in mclass.mclassdefs do
+ for mpropdef in mclassdef.mpropdefs do
+ if mpropdef isa MAttributeDef then continue
+ if mpropdef isa MVirtualTypeDef then cats["virtual types"].add(mpropdef)
+ if mpropdef isa MMethodDef then
+ if mpropdef.mproperty.is_init then
+ cats["constructors"].add(mpropdef)
+ else if mpropdef.is_intro then
+ cats["introduced methods"].add(mpropdef)
+ else
+ cats["refined methods"].add(mpropdef)
+ end
+ end
end
end
- pager.add_rule
-
- var cats = new HashMap[String, Collection[MMethod]]
- cats["constructors"] = mclass.constructors
- cats["introduced methods"] = mclass.intro_methods
- cats["refined methods"] = mclass.redef_methods
- cats["inherited methods"] = mclass.inherited_methods
-
+ # local mproperties
for cat, list in cats do
if not list.is_empty then
#sort list
- var sorted = new Array[MMethod]
+ var sorted = new Array[MPropDef]
sorted.add_all(list)
- var sorter = new MPropertyNameSorter
+ var sorter = new MPropDefNameSorter
sorter.sort(sorted)
- pager.add("\n# {cat}".bold)
- for mprop in sorted do
+ pager.add("## {cat}".bold)
+ for mpropdef in sorted do
pager.add("")
- mpropdef_fulldoc(pager, mprop.intro)
+ if mbuilder.mpropdef2npropdef.has_key(mpropdef) then
+ var nprop = mbuilder.mpropdef2npropdef[mpropdef]
+ if not nprop.n_doc == null and not nprop.n_doc.comment.is_empty then
+ for comment in nprop.n_doc.comment do pager.add("\t{comment.green}")
+ else
+ nprop = mbuilder.mpropdef2npropdef[mpropdef.mproperty.intro]
+ if not nprop.n_doc == null and not nprop.n_doc.comment.is_empty then
+ for comment in nprop.n_doc.comment do pager.add("\t{comment.green}")
+ end
+ end
+ end
+ pager.add("\t{mpropdef}")
+ mainmodule.linearize_mpropdefs(mpropdef.mproperty.mpropdefs)
+ var previous_defs = new Array[MPropDef]
+ for def in mpropdef.mproperty.mpropdefs do
+ if def == mpropdef then continue
+ if def.is_intro then continue
+ if mclass.in_hierarchy(mainmodule) < def.mclassdef.mclass then
+ previous_defs.add(def)
+ end
+ end
+ if not mpropdef.is_intro then
+ pager.add("\t\t" + "introduced by {mpropdef.mproperty.intro.mclassdef.namespace.bold}".gray)
+ end
+ if not previous_defs.is_empty then
+ for def in previous_defs do pager.add("\t\t" + "inherited from {def.mclassdef.namespace.bold}".gray)
+ end
end
+ pager.add("")
+ end
+ end
+ # inherited mproperties
+ var inhs = new ArrayMap[MClass, Array[MProperty]]
+ var ancestors = mclass.in_hierarchy(mainmodule).greaters.to_a
+ mainmodule.linearize_mclasses(ancestors)
+ for a in ancestors do
+ if a == mclass then continue
+ for c in a.mclassdefs do
+ for p in c.intro_mproperties do
+ if p.intro_mclassdef == c then
+ if not inhs.has_key(a) then inhs[a] = new Array[MProperty]
+ inhs[a].add(p)
+ end
+ end
+ end
+ end
+ if not inhs.is_empty then
+ pager.add("## inherited properties".bold)
+ for a, ps in inhs do
+ pager.add("\n\tfrom {a.namespace.bold}: {ps.join(", ")}")
end
end
pager.add_rule
end
- pager.render
end
- private fun props_fulldoc(raw_mprops: List[MProperty]) do
- var pager = new Pager
+ private fun props_fulldoc(pager: Pager, raw_mprops: List[MProperty]) do
# group by module
- var cats = new HashMap[MClass, Array[MProperty]]
+ var cats = new HashMap[MModule, Array[MProperty]]
for mprop in raw_mprops do
- 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)
+ var key = mprop.intro.mclassdef.mmodule
+ if not cats.has_key(key) then cats[key] = new Array[MProperty]
+ cats[key].add(mprop)
end
#sort groups
- var sorter = new MClassNameSorter
- var sorted = new Array[MClass]
+ var sorter = new MModuleNameSorter
+ var sorted = new Array[MModule]
sorted.add_all(cats.keys)
sorter.sort(sorted)
# display
- for mclass in sorted do
- var mprops = cats[mclass]
- pager.add("# {mclass.namespace}".bold)
+ for mmodule in sorted do
+ var mprops = cats[mmodule]
+ pager.add("# matches in module {mmodule.namespace.bold}")
var sorterp = new MPropertyNameSorter
sorterp.sort(mprops)
for mprop in mprops do
pager.add("")
- mpropdef_fulldoc(pager, mprop.intro)
+ if mbuilder.mpropdef2npropdef.has_key(mprop.intro) then
+ var nprop = mbuilder.mpropdef2npropdef[mprop.intro]
+ if not nprop.n_doc == null and not nprop.n_doc.comment.is_empty then
+ for comment in nprop.n_doc.comment do pager.add("\t{comment.green}")
+ end
+ end
+ pager.add("\t{mprop.intro}")
+ pager.add("\t\t" + "introduced in {mprop.intro_mclassdef.namespace.bold}".gray)
+ var mpropdefs = mprop.mpropdefs
+ mainmodule.linearize_mpropdefs(mpropdefs)
+ for mpdef in mpropdefs do
+ if not mpdef.is_intro then
+ pager.add("\t\t" + "refined in {mpdef.mclassdef.namespace.bold}".gray)
+ end
+ end
end
pager.add_rule
end
- pager.render
end
private fun seek_returns(entry: String): List[MProperty] do
end
return matches
end
-
- private fun mpropdef_fulldoc(pager: Pager, mpropdef: MPropDef) do
- if mbuilder.mpropdef2npropdef.has_key(mpropdef) then
- var nprop = mbuilder.mpropdef2npropdef[mpropdef]
- if not nprop.n_doc == null and not nprop.n_doc.short_comment.is_empty then
- pager.add("\t# {nprop.n_doc.short_comment}")
- end
- end
- pager.add("\t{mpropdef}")
- pager.add("\t\t" + "introduced in {mpropdef.mproperty.intro_mclassdef.namespace}".gray)
- for mpdef in mpropdef.mproperty.mpropdefs do
- if not mpdef.is_intro then
- pager.add("\t\t" + "refined in {mpdef.mclassdef.namespace}".gray)
- end
- end
- end
end
# Printing facilities
end
private fun namespace: String do
- if not intro_mmodule.public_owner == null then
- return "{intro_mmodule.public_owner.name}::{name}"
- else
- return "{intro_mmodule.name}::{name}"
- end
+ return "{intro_mmodule.namespace}::{name}"
end
end
end
end
+redef class MProperty
+ redef fun to_s do
+ if visibility.to_s == "public" then return name.green
+ if visibility.to_s == "private" then return name.red
+ if visibility.to_s == "protected" then return name.yellow
+ return name.bold
+ end
+end
+
redef class MMethodDef
redef fun to_s do
var res = new Buffer
if not is_intro then res.append("redef ")
if not mproperty.is_init then res.append("fun ")
- if mproperty.visibility.to_s == "public" then res.append(mproperty.name.green)
- if mproperty.visibility.to_s == "private" then res.append(mproperty.name.red)
- if mproperty.visibility.to_s == "protected" then res.append(mproperty.name.yellow)
+ res.append(mproperty.to_s.bold)
if msignature != null then res.append(msignature.to_s)
# FIXME: modifiers should be accessible via the model
#if self isa ADeferredMethPropdef then ret = "{ret} is abstract"
redef class MVirtualTypeDef
redef fun to_s do
var res = new Buffer
- if mproperty.visibility.to_s == "public" then res.append(mproperty.name.green)
- if mproperty.visibility.to_s == "private" then res.append(mproperty.name.red)
- if mproperty.visibility.to_s == "protected" then res.append(mproperty.name.yellow)
+ res.append("type ")
+ res.append(mproperty.to_s.bold)
res.append(": {bound.to_s}")
return res.to_s
end