# This file is part of NIT ( http://www.nitlanguage.org ).
#
-# Copyright 2008 Jean Privat <jean@pryen.org>
-#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# See the License for the specific language governing permissions and
# limitations under the License.
+# Documentation generator for the nit language.
+# Generate API documentation in HTML format from nit source code.
module ni_nitdoc
import model_utils
-import abstract_compiler
# The NitdocContext contains all the knowledge used for doc generation
class NitdocContext
mbuilder = new ModelBuilder(model, self)
# Here we load an process all modules passed on the command line
var mmodules = mbuilder.parse_and_build(arguments)
- mbuilder.full_propdef_semantic_analysis
if mmodules.is_empty then return
if mmodules.length == 1 then
end
end
# sort modules
- var sorter = new ComparableSorter[MModule]
+ var sorter = new MModuleNameSorter
self.mmodules.add_all(mmodules)
sorter.sort(self.mmodules)
end
# Add to content modules column
private fun module_column do
var sorted = ctx.mbuilder.model.mmodule_importation_hierarchy.to_a
- var sorter = new ComparableSorter[MModule]
+ var sorter = new MModuleNameSorter
sorter.sort(sorted)
append("<article class='modules filterable'>")
append("<h2>Modules</h2>")
# Add to content classes modules
private fun classes_column do
var sorted = ctx.mbuilder.model.mclasses
- var sorter = new ComparableSorter[MClass]
+ var sorter = new MClassNameSorter
sorter.sort(sorted)
append("<article class='modules filterable'>")
append("<h2>Classes</h2>")
# Insert the properties column of fullindex page
private fun properties_column do
var sorted = ctx.mbuilder.model.mproperties
- var sorter = new ComparableSorter[MProperty]
+ var sorter = new MPropertyNameSorter
sorter.sort(sorted)
append("<article class='modules filterable'>")
append("<h2>Properties</h2>")
end
var clients = new Array[MModule]
for dep in mmodule.in_importation.smallers do
+ if dep.name == "<main>" then continue
if dep == mmodule or dep.public_owner != null then continue
clients.add(dep)
end
display_module_list(clients)
end
append("</nav>")
- if mmodule.in_nesting.direct_greaters.length > 0 then
- append("<nav>")
- append("<h3>Nested Modules</h3>")
- display_module_list(mmodule.in_nesting.direct_greaters.to_a)
- append("</nav>")
+ if ctx.min_visibility < protected_visibility then
+ if mmodule.in_nesting.direct_greaters.length > 0 then
+ append("<nav>")
+ append("<h3>Nested Modules</h3>")
+ display_module_list(mmodule.in_nesting.direct_greaters.to_a)
+ append("</nav>")
+ end
end
append("</div>")
end
private fun display_module_list(list: Array[MModule]) do
append("<ul>")
- var sorter = new ComparableSorter[MModule]
+ var sorter = new MModuleNameSorter
sorter.sort(list)
for m in list do
append("<li>")
var sorted = new Array[MClass]
sorted.add_all(all_mclasses)
- var sorter = new ComparableSorter[MClass]
+ var sorter = new MClassNameSorter
sorter.sort(sorted)
append("<div class='module'>")
append("<article class='classes filterable'>")
end
for c in mmodule.mclassdefs do mpropdefs.add_all(c.mpropdefs)
var sorted = mpropdefs.to_a
- var sorter = new ComparableSorter[MPropDef]
+ var sorter = new MPropDefNameSorter
sorter.sort(sorted)
# display properties in one column
append("<article class='properties filterable'>")
end
private fun properties_column do
- var sorter = new ComparableSorter[MPropDef]
+ var sorter = new MPropDefNameSorter
append("<nav class='properties filterable'>")
append("<h3>Properties</h3>")
# virtual types
private fun inheritance_column do
var sorted = new Array[MClass]
- var sorterp = new ComparableSorter[MClass]
+ var sorterp = new MClassNameSorter
append("<nav>")
append("<h3>Inheritance</h3>")
var greaters = mclass.in_hierarchy(ctx.mainmodule).greaters.to_a
append("</ul>")
append("</section>")
# properties
- var prop_sorter = new ComparableSorter[MPropDef]
- var sorterprop = new ComparableSorter[MProperty]
- var sorterc = new ComparableSorter[MClass]
+ var prop_sorter = new MPropDefNameSorter
var lmmodule = new List[MModule]
# virtual and formal types
var local_vtypes = new Array[MVirtualTypeDef]
prop_sorter.sort(mmethods)
append("<p>Defined in ")
c.html_link(self)
- append("}: ")
+ append(": ")
for i in [0..mmethods.length[ do
var mmethod = mmethods[i]
mmethod.html_link(self)
#
redef class MModule
- super Comparable
- redef type OTHER: MModule
- redef fun <(other: OTHER): Bool do return self.name < other.name
-
- # Get the list of all methods in a module
- fun imported_methods: Set[MMethod] do
- var methods = new HashSet[MMethod]
- for mclass in imported_mclasses do
- for method in mclass.intro_methods do
- methods.add(method)
- end
- end
- return methods
- end
-
- # Get the list aof all refined methods in a module
- fun redef_methods: Set[MMethod] do
- var methods = new HashSet[MMethod]
- for mclass in redef_mclasses do
- for method in mclass.intro_methods do
- methods.add(method)
- end
- end
- return methods
- end
-
# URL to nitdoc page
fun url: String do
var res = new Buffer
end
redef class MClass
- super Comparable
- redef type OTHER: MClass
- redef fun <(other: OTHER): Bool do return self.name < other.name
-
# Return the module signature decorated with html
fun html_full_signature(page: NitdocPage) do
if visibility < public_visibility then page.append("{visibility.to_s} ")
end
fun url: String do
- return "class_{public_owner}_{c_name}.html"
+ return "class_{public_owner}_{name}.html"
end
# Escape name for html output
end
redef class MProperty
- super Comparable
- redef type OTHER: MProperty
- redef fun <(other: OTHER): Bool do return self.name < other.name
-
# Return the property namespace decorated with html
fun html_namespace(page: NitdocPage) do
intro_mclassdef.mclass.html_namespace(page)
end
redef class MPropDef
- super Comparable
- redef type OTHER: MPropDef
- redef fun <(other: OTHER): Bool do return self.mproperty.name < other.mproperty.name
-
fun url: String do return "{mclassdef.mclass.url}#{anchor}"
- fun anchor: String do return "PROP_{mclassdef.mclass.public_owner.name}_{c_name}"
+ fun anchor: String do return "PROP_{mclassdef.mclass.public_owner.name}_{mproperty.name}"
# Return a link (html a tag) to the nitdoc class page
fun html_link(page: NitdocPage) do
end
# Return a list item for the mpropdef
- fun html_list_item(page: NitdocPage) do
+ private fun html_list_item(page: NitdocPage) do
if is_intro then
page.append("<li class='intro'>")
page.append("<span title='introduction'>I</span> ")
end
# Return a list item for the mpropdef
- fun html_sidebar_item(page: NitdocClass) do
+ private fun html_sidebar_item(page: NitdocClass) do
if is_intro and mclassdef.mclass == page.mclass then
page.append("<li class='intro'>")
page.append("<span title='Introduced'>I</span>")
page.append("</li>")
end
- fun html_full_desc(page: NitdocClass) is abstract
- fun html_info(page: NitdocClass) is abstract
+ private fun html_full_desc(page: NitdocClass) is abstract
+ private fun html_info(page: NitdocClass) is abstract
fun full_name: String do
return "{mclassdef.mclass.public_owner.name}::{mclassdef.mclass.name}::{mproperty.name}"
end
- fun html_inheritance(page: NitdocClass) do
+ private fun html_inheritance(page: NitdocClass) do
# definitions block
page.append("<p class='info'>")
page.ctx.mainmodule.linearize_mpropdefs(mproperty.mpropdefs)
end
page.append(".</p>")
end
-end
-redef class MMethodDef
- redef fun html_full_desc(page) do
+ private fun html_comment(page: NitdocClass) do
if not page.ctx.mbuilder.mpropdef2npropdef.has_key(self) then return
var nprop = page.ctx.mbuilder.mpropdef2npropdef[self]
- var classes = new Array[String]
- var is_redef = mproperty.intro_mclassdef.mclass != page.mclass
- classes.add("fun")
- if mproperty.is_init then classes.add("init")
- if is_redef then classes.add("redef")
- classes.add(mproperty.visibility.to_s)
- page.append("<article class='{classes.join(" ")}' id='{anchor}'>")
- if nprop isa AAttrPropdef then
- if nprop.mreadpropdef == self then
- page.append("<h3 class='signature'>{mproperty.name}: ")
- nprop.html_signature(page)
- page.append("</h3>")
+ page.append("<div class='description'>")
+ if not is_intro then
+ var intro_nprop = page.ctx.mbuilder.mpropdef2npropdef[mproperty.intro]
+ page.append("<p>from ")
+ mproperty.html_namespace(page)
+ page.append("</p>")
+ if intro_nprop.full_comment == "" then
+ page.append("<a class=\"newComment\" title=\"32\" tag=\"\">New Comment</a>")
else
- page.append("<h3 class='signature'>{mproperty.name}(value: ")
- nprop.html_signature(page)
- page.append(")</h3>")
+ page.append("<pre class=\"text_label\" title=\"\" name=\"\" tag=\"\" type=\"1\">{intro_nprop.full_comment}</pre>")
end
- else
- var intro_nprop = page.ctx.mbuilder.mpropdef2npropdef[mproperty.intro]
- page.append("<h3 class='signature'>{mproperty.name}")
- intro_nprop.html_signature(page)
- page.append("</h3>")
+ page.append("<p>from ")
+ mclassdef.html_namespace(page)
+ page.append("</p>")
end
- html_info(page)
- page.append("<div class='description'>")
if nprop.full_comment == "" then
page.append("<a class=\"newComment\" title=\"32\" tag=\"\">New Comment</a>")
else
page.append("<textarea id=\"fileContent\" class=\"edit\" cols=\"76\" rows=\"1\" style=\"display: none;\"></textarea><a id=\"cancelBtn\" style=\"display: none;\">Cancel</a><a id=\"commitBtn\" style=\"display: none;\">Commit</a><pre id=\"preSave\" class=\"text_label\" type=\"2\"></pre>")
html_inheritance(page)
page.append("</div>")
+ end
+end
+
+redef class MMethodDef
+ redef fun html_full_desc(page) do
+ var classes = new Array[String]
+ var is_redef = mproperty.intro_mclassdef.mclass != page.mclass
+ if mproperty.is_init then
+ classes.add("init")
+ else
+ classes.add("fun")
+ end
+ if is_redef then classes.add("redef")
+ classes.add(mproperty.visibility.to_s)
+ page.append("<article class='{classes.join(" ")}' id='{anchor}'>")
+ if page.ctx.mbuilder.mpropdef2npropdef.has_key(self) then
+ page.append("<h3 class='signature'>{mproperty.name}")
+ msignature.html_signature(page)
+ page.append("</h3>")
+ else
+ page.append("<h3 class='signature'>init")
+ msignature.html_signature(page)
+ page.append("</h3>")
+ end
+ html_info(page)
+ html_comment(page)
page.append("</article>")
end
page.append("<div class='info'>")
if mproperty.visibility < public_visibility then page.append("{mproperty.visibility.to_s} ")
if mproperty.intro_mclassdef.mclass != page.mclass then page.append("redef ")
- page.append("fun ")
+ if mproperty.is_init then
+ page.append("init ")
+ else
+ page.append("fun ")
+ end
mproperty.html_namespace(page)
page.append("</div>")
page.append("<div style=\"float: right;\"><a id=\"lblDiffCommit\"></a></div>")
bound.html_link(page)
page.append("</h3>")
html_info(page)
- page.append("<div class='description'>")
-
- if page.ctx.mbuilder.mpropdef2npropdef.has_key(self) and page.ctx.mbuilder.mpropdef2npropdef[self].full_comment != "" then
- var nprop = page.ctx.mbuilder.mpropdef2npropdef[self]
- page.append("<pre class=\"text_label\" title=\"\" name=\"\" tag=\"\" type=\"1\">{nprop.full_comment}</pre>")
- else
- page.append("<a class=\"newComment\" title=\"32\" tag=\"\">New Comment</a>")
- end
- page.append("<textarea id=\"fileContent\" class=\"edit\" cols=\"76\" rows=\"1\" style=\"display: none;\"></textarea><a id=\"cancelBtn\" style=\"display: none;\">Cancel</a><a id=\"commitBtn\" style=\"display: none;\">Commit</a><pre id=\"preSave\" class=\"text_label\" type=\"2\"></pre>")
- html_inheritance(page)
- page.append("</div>")
+ html_comment(page)
page.append("</article>")
end
end
end
+redef class MSignature
+ private fun html_signature(page: NitdocPage) do
+ if not mparameters.is_empty then
+ page.append("(")
+ for i in [0..mparameters.length[ do
+ mparameters[i].html_link(page)
+ if i < mparameters.length - 1 then page.append(", ")
+ end
+ page.append(")")
+ end
+ if return_mtype != null then
+ page.append(": ")
+ return_mtype.html_link(page)
+ end
+ end
+end
+
+redef class MParameter
+ private fun html_link(page: NitdocPage) do
+ page.append("{name}: ")
+ mtype.html_link(page)
+ if is_vararg then page.append("...")
+ end
+end
+
#
# Nodes redefs
#
end
redef class APropdef
- private fun short_comment: String is abstract
- private fun full_comment: String is abstract
- private fun html_signature(page: NitdocPage) is abstract
-end
-
-redef class AAttrPropdef
- redef fun short_comment do
- if n_doc != null then return n_doc.n_comment.first.text.substring_from(2).replace("\n", "").html_escape
- return ""
- end
-
- redef fun full_comment: String do
- var res = new Buffer
- if n_doc != null then
- for t in n_doc.n_comment do res.append(t.text.substring_from(1).html_escape)
- end
- return res.to_s
- end
-
- redef fun html_signature(page) do
- if n_type != null then n_type.mtype.html_link(page)
- end
-end
-
-redef class AMethPropdef
- redef fun short_comment do
- if n_doc != null then return n_doc.n_comment.first.text.substring_from(2).replace("\n", "").html_escape
- return ""
- end
-
- redef fun full_comment do
- var res = new Buffer
- if n_doc != null then
- for t in n_doc.n_comment do res.append(t.text.substring_from(1).html_escape)
- end
- return res.to_s
- end
-
- redef fun html_signature(page) do
- if n_signature != null then n_signature.html_link(page)
- end
-end
-
-redef class ATypePropdef
- redef fun short_comment do
+ private fun short_comment: String do
if n_doc != null then return n_doc.n_comment.first.text.substring_from(2).replace("\n", "").html_escape
return ""
end
- redef fun full_comment do
+ private fun full_comment: String do
var res = new Buffer
if n_doc != null then
for t in n_doc.n_comment do res.append(t.text.substring_from(1).html_escape)
end
return res.to_s
end
-
- redef fun html_signature(page) do
- mpropdef.bound.html_link(page)
- end
-end
-
-redef class ASignature
- fun html_link(page: NitdocPage) do
- #TODO closures
- if not n_params.is_empty then
- page.append("(")
- for i in [0..n_params.length[ do
- n_params[i].html_link(page)
- if i < n_params.length - 1 then page.append(", ")
- end
- page.append(")")
- end
- if n_type != null then
- page.append(":")
- n_type.mtype.html_link(page)
- end
- end
-end
-
-redef class AParam
- fun html_link(page: NitdocPage) do
- page.append(n_id.text)
- if n_type != null then
- page.append(": ")
- n_type.mtype.html_link(page)
- if n_dotdotdot != null then page.append("...")
- end
- end
end
var nitdoc = new NitdocContext