+ private fun class_doc do
+ # title
+ append("<h1>{mclass.signature}</h1>")
+ append("<div class='subtitle info'>")
+ mclass.html_full_signature(self)
+ append("</div>")
+ # comment
+ var nclass = ctx.mbuilder.mclassdef2nclassdef[mclass.intro]
+ append("<section class='description'>")
+ process_generate_dot
+ append("</section>")
+ # concerns
+ var concern2meths = new ArrayMap[MModule, Array[MMethodDef]]
+ var sorted_meths = new Array[MMethodDef]
+ var sorted = new Array[MModule]
+ sorted_meths.add_all(meths)
+ ctx.mainmodule.linearize_mpropdefs(sorted_meths)
+ for meth in meths do
+ if inherited.has(meth) then continue
+ var mmodule = meth.mclassdef.mmodule
+ if not concern2meths.has_key(mmodule) then
+ sorted.add(mmodule)
+ concern2meths[mmodule] = new Array[MMethodDef]
+ end
+ concern2meths[mmodule].add(meth)
+ end
+ var sections = new ArrayMap[MModule, Array[MModule]]
+ for mmodule in concern2meths.keys do
+ var owner = mmodule.public_owner
+ if owner == null then owner = mmodule
+ if not sections.has_key(owner) then sections[owner] = new Array[MModule]
+ if owner != mmodule then sections[owner].add(mmodule)
+ end
+ append("<section class='concerns'>")
+ append("<h2 class='section-header'>Concerns</h2>")
+ append("<ul>")
+ for owner, mmodules in sections do
+ var nowner = ctx.mbuilder.mmodule2nmodule[owner]
+ append("<li>")
+ if nowner.short_comment.is_empty then
+ append("<a href=\"#{owner.anchor}\">{owner.name}</a>")
+ else
+ append("<a href=\"#{owner.anchor}\">{owner.name}</a>: {nowner.short_comment}")
+ end
+ if not mmodules.is_empty then
+ append("<ul>")
+ for mmodule in mmodules do
+ var nmodule = ctx.mbuilder.mmodule2nmodule[mmodule]
+ if nmodule.short_comment.is_empty then
+ append("<li><a href=\"#{mmodule.anchor}\">{mmodule.name}</a></li>")
+ else
+ append("<li><a href=\"#{mmodule.anchor}\">{mmodule.name}</a>: {nmodule.short_comment}</li>")
+ end
+ end
+ append("</ul>")
+ end
+ append("</li>")
+ end
+ append("</ul>")
+ append("</section>")
+ # properties
+ var prop_sorter = new MPropDefNameSorter
+ var lmmodule = new List[MModule]
+ # virtual and formal types
+ var local_vtypes = new Array[MVirtualTypeDef]
+ for vt in vtypes do if not inherited.has(vt) then local_vtypes.add(vt)
+ if local_vtypes.length > 0 or mclass.arity > 0 then
+ append("<section class='types'>")
+ append("<h2>Formal and Virtual Types</h2>")
+ # formal types
+ if mclass.arity > 0 and nclass isa AStdClassdef then
+ for ft, bound in mclass.parameter_types do
+ append("<article id='FT_{ft}'>")
+ append("<h3 class='signature'>{ft}: ")
+ bound.html_link(self)
+ append("</h3>")
+ append("<div class=\"info\">formal generic type</div>")
+ append("</article>")
+ end
+ end
+ # virtual types
+ prop_sorter.sort(local_vtypes)
+ for prop in local_vtypes do prop.html_full_desc(self)
+ append("</section>")
+ end
+ # constructors
+ var local_consts = new Array[MMethodDef]
+ for const in consts do if not inherited.has(const) then local_consts.add(const)
+ prop_sorter.sort(local_consts)
+ if local_consts.length > 0 then
+ append("<section class='constructors'>")
+ append("<h2 class='section-header'>Constructors</h2>")
+ for prop in local_consts do prop.html_full_desc(self)
+ append("</section>")
+ end
+ # methods
+ if not concern2meths.is_empty then
+ append("<section class='methods'>")
+ append("<h2 class='section-header'>Methods</h2>")
+ for owner, mmodules in sections do
+ append("<a id=\"{owner.anchor}\"></a>")
+ if owner != mclass.intro_mmodule and owner != mclass.public_owner then
+ var nowner = ctx.mbuilder.mmodule2nmodule[owner]
+ append("<h3 class=\"concern-toplevel\">Methods refined in ")
+ owner.html_link(self)
+ append("</h3>")
+ append("<p class=\"concern-doc\">")
+ owner.html_link(self)
+ if not nowner.short_comment.is_empty then
+ append(": {nowner.short_comment}")
+ end
+ append("</p>")
+ end
+ if concern2meths.has_key(owner) then
+ var mmethods = concern2meths[owner]
+ prop_sorter.sort(mmethods)
+ for prop in mmethods do prop.html_full_desc(self)
+ end
+ for mmodule in mmodules do
+ append("<a id=\"{mmodule.anchor}\"></a>")
+ var nmodule = ctx.mbuilder.mmodule2nmodule[mmodule]
+ if mmodule != mclass.intro_mmodule and mmodule != mclass.public_owner then
+ append("<p class=\"concern-doc\">")
+ mmodule.html_link(self)
+ if not nmodule.short_comment.is_empty then
+ append(": {nmodule.short_comment}")
+ end
+ append("</p>")
+ end
+ var mmethods = concern2meths[mmodule]
+ prop_sorter.sort(mmethods)
+ for prop in mmethods do prop.html_full_desc(self)
+ end
+ end
+ end
+ # inherited properties
+ if inherited.length > 0 then
+ var sorted_inherited = new Array[MPropDef]
+ sorted_inherited.add_all(inherited)
+ ctx.mainmodule.linearize_mpropdefs(sorted_inherited)
+ var classes = new ArrayMap[MClass, Array[MPropDef]]
+ for mmethod in sorted_inherited.reversed do
+ var mclass = mmethod.mclassdef.mclass
+ if not classes.has_key(mclass) then classes[mclass] = new Array[MPropDef]
+ classes[mclass].add(mmethod)
+ end
+ append("<h3>Inherited Properties</h3>")
+ for c, mmethods in classes do
+ prop_sorter.sort(mmethods)
+ append("<p>Defined in ")
+ c.html_link(self)
+ append(": ")
+ for i in [0..mmethods.length[ do
+ var mmethod = mmethods[i]
+ mmethod.html_link(self)
+ if i <= mmethods.length - 1 then append(", ")
+ end
+ append("</p>")
+ end
+ end
+ append("</section>")
+ end
+
+ private fun process_generate_dot do
+ var pe = ctx.class_hierarchy[mclass]
+ var cla = new HashSet[MClass]
+ var sm = new HashSet[MClass]
+ var sm2 = new HashSet[MClass]
+ sm.add(mclass)
+ while cla.length + sm.length < 10 and sm.length > 0 do
+ cla.add_all(sm)
+ sm2.clear
+ for x in sm do
+ sm2.add_all(pe.poset[x].direct_smallers)
+ end
+ var t = sm
+ sm = sm2
+ sm2 = t
+ end
+ cla.add_all(pe.greaters)
+
+ var op = new Buffer
+ var name = "dep_{mclass.name}"
+ op.append("digraph {name} \{ rankdir=BT; node[shape=none,margin=0,width=0,height=0,fontsize=10]; edge[dir=none,color=gray]; ranksep=0.2; nodesep=0.1;\n")
+ for c in cla do
+ if c == mclass then
+ op.append("\"{c.name}\"[shape=box,margin=0.03];\n")
+ else
+ op.append("\"{c.name}\"[URL=\"{c.url}\"];\n")
+ end
+ for c2 in pe.poset[c].direct_greaters do
+ if not cla.has(c2) then continue
+ op.append("\"{c.name}\"->\"{c2.name}\";\n")
+ end
+ if not pe.poset[c].direct_smallers.is_empty then
+ var others = true
+ for c2 in pe.poset[c].direct_smallers do
+ if cla.has(c2) then others = false
+ end
+ if others then
+ op.append("\"{c.name}...\"[label=\"\"];\n")
+ op.append("\"{c.name}...\"->\"{c.name}\"[style=dotted];\n")
+ end
+ end
+ end
+ op.append("\}\n")
+ generate_dot(op.to_s, name, "Dependency graph for class {mclass.name}")
+ end