X-Git-Url: http://nitlanguage.org diff --git a/src/ni_nitdoc.nit b/src/ni_nitdoc.nit index b61d547..535614b 100644 --- a/src/ni_nitdoc.nit +++ b/src/ni_nitdoc.nit @@ -1,7 +1,5 @@ # This file is part of NIT ( http://www.nitlanguage.org ). # -# Copyright 2008 Jean Privat -# # 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 @@ -14,15 +12,19 @@ # 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 +import modelize_property + +# The NitdocContext contains all the knowledge used for doc generation +class NitdocContext -class Nitdoc - private var toolcontext: ToolContext + private var toolcontext = new ToolContext private var model: Model - private var modelbuilder: ModelBuilder + private var mbuilder: ModelBuilder private var mainmodule: MModule private var class_hierarchy: POSet[MClass] private var arguments: Array[String] @@ -30,23 +32,32 @@ class Nitdoc private var dot_dir: nullable String private var share_dir: nullable String private var source: nullable String + private var min_visibility: MVisibility private var opt_dir = new OptionString("Directory where doc is generated", "-d", "--dir") private var opt_source = new OptionString("What link for source (%f for filename, %l for first line, %L for last line)", "--source") private var opt_sharedir = new OptionString("Directory containing the nitdoc files", "--sharedir") private var opt_nodot = new OptionBool("Do not generate graphes with graphiviz", "--no-dot") + private var opt_private: OptionBool = new OptionBool("Generate the private API", "--private") - init(toolcontext: ToolContext) do - # We need a model to collect stufs - self.toolcontext = toolcontext + private var opt_custom_title: OptionString = new OptionString("Title displayed in the top of the Overview page and as suffix of all page names", "--custom-title") + private var opt_custom_menu_items: OptionString = new OptionString("Items displayed in menu before the 'Overview' item (Each item must be enclosed in 'li' tags)", "--custom-menu-items") + private var opt_custom_overview_text: OptionString = new OptionString("Text displayed as introduction of Overview page before the modules list", "--custom-overview-text") + private var opt_custom_footer_text: OptionString = new OptionString("Text displayed as footer of all pages", "--custom-footer-text") + + init do self.arguments = toolcontext.option_context.rest toolcontext.option_context.options.clear toolcontext.option_context.add_option(opt_dir) toolcontext.option_context.add_option(opt_source) toolcontext.option_context.add_option(opt_sharedir) toolcontext.option_context.add_option(opt_nodot) + toolcontext.option_context.add_option(opt_private) + toolcontext.option_context.add_option(opt_custom_title) + toolcontext.option_context.add_option(opt_custom_footer_text) + toolcontext.option_context.add_option(opt_custom_overview_text) + toolcontext.option_context.add_option(opt_custom_menu_items) toolcontext.process_options - process_options if arguments.length < 1 then toolcontext.option_context.usage @@ -54,15 +65,21 @@ class Nitdoc end model = new Model - modelbuilder = new ModelBuilder(model, toolcontext) - - # Here we load an process std modules - var mmodules = modelbuilder.parse_and_build([arguments.first]) + mbuilder = new ModelBuilder(model, toolcontext) + # Here we load an process all modules passed on the command line + var mmodules = mbuilder.parse(arguments) if mmodules.is_empty then return - modelbuilder.full_propdef_semantic_analysis - assert mmodules.length == 1 - self.mainmodule = mmodules.first + mbuilder.run_phases + + if mmodules.length == 1 then + mainmodule = mmodules.first + else + # We need a main module, so we build it by importing all modules + mainmodule = new MModule(model, null, "
", new Location(null, 0, 0, 0, 0)) + mainmodule.set_imported_mmodules(mmodules) + end self.class_hierarchy = mainmodule.flatten_mclass_hierarchy + self.process_options end private fun process_options do @@ -90,82 +107,83 @@ class Nitdoc print "Error: Invalid nitdoc share files. Check --sharedir or envvar NIT_DIR" abort end + + if opt_private.value then + min_visibility = none_visibility + else + min_visibility = protected_visibility + end end - if not opt_source.value is null then - source = "" - else - source = opt_source.value - end + source = opt_source.value end - fun start do - if arguments.length == 1 then - # Create destination dir if it's necessary - if not output_dir.file_exists then output_dir.mkdir - sys.system("cp -r {share_dir.to_s}/* {output_dir.to_s}/") - self.dot_dir = null - if not opt_nodot.value then self.dot_dir = output_dir.to_s - overview - fullindex - modules - classes - quicksearch_list - end + fun generate_nitdoc do + # Create destination dir if it's necessary + if not output_dir.file_exists then output_dir.mkdir + sys.system("cp -r {share_dir.to_s}/* {output_dir.to_s}/") + self.dot_dir = null + if not opt_nodot.value then self.dot_dir = output_dir.to_s + overview + fullindex + modules + classes + quicksearch_list end - fun overview do - var overviewpage = new NitdocOverview(modelbuilder, dot_dir) + private fun overview do + var overviewpage = new NitdocOverview(self, dot_dir) overviewpage.save("{output_dir.to_s}/index.html") end - fun fullindex do + private fun fullindex do var fullindex = new NitdocFullindex(self) fullindex.save("{output_dir.to_s}/full-index.html") end - fun modules do + private fun modules do for mmodule in model.mmodules do - var modulepage = new NitdocModule(mmodule, modelbuilder, dot_dir) + if mmodule.name == "
" then continue + var modulepage = new NitdocModule(mmodule, self, dot_dir) modulepage.save("{output_dir.to_s}/{mmodule.url}") end end - fun classes do - for mclass in modelbuilder.model.mclasses do + private fun classes do + for mclass in mbuilder.model.mclasses do var classpage = new NitdocClass(mclass, self, dot_dir, source) classpage.save("{output_dir.to_s}/{mclass.url}") end end - # Generate QuickSearch file - fun quicksearch_list do + private fun quicksearch_list do var file = new OFStream.open("{output_dir.to_s}/quicksearch-list.js") - var content = new Buffer - content.append("var entries = \{ ") - + file.write("var entries = \{ ") for mmodule in model.mmodules do - content.append("\"{mmodule.name}\": [") - content.append("\{txt: \"{mmodule.name}\", url:\"{mmodule.url}\" \},") - content.append("],") + file.write("\"{mmodule.name}\": [") + file.write("\{txt: \"{mmodule.name}\", url:\"{mmodule.url}\" \},") + file.write("],") end for mclass in model.mclasses do - if mclass.visibility <= none_visibility then continue - content.append("\"{mclass.name}\": [") - content.append("\{txt: \"{mclass.name}\", url:\"{mclass.url}\" \},") - content.append("],") + if mclass.visibility < min_visibility then continue + file.write("\"{mclass.name}\": [") + file.write("\{txt: \"{mclass.name}\", url:\"{mclass.url}\" \},") + file.write("],") end + var name2mprops = new HashMap[String, Set[MPropDef]] for mproperty in model.mproperties do - if mproperty.visibility <= none_visibility then continue + if mproperty.visibility < min_visibility then continue if mproperty isa MAttribute then continue - content.append("\"{mproperty.name}\": [") - for mpropdef in mproperty.mpropdefs do - content.append("\{txt: \"{mpropdef.full_name}\", url:\"{mpropdef.url}\" \},") + if not name2mprops.has_key(mproperty.name) then name2mprops[mproperty.name] = new HashSet[MPropDef] + name2mprops[mproperty.name].add_all(mproperty.mpropdefs) + end + for mproperty, mpropdefs in name2mprops do + file.write("\"{mproperty}\": [") + for mpropdef in mpropdefs do + file.write("\{txt: \"{mpropdef.full_name}\", url:\"{mpropdef.url}\" \},") end - content.append("],") + file.write("],") end - - content.append(" \};") - file.write(content.to_s) + file.write(" \};") file.close end @@ -176,77 +194,56 @@ abstract class NitdocPage var dot_dir: nullable String var source: nullable String + var ctx: NitdocContext - init do end - - fun append(str: String) do html.append(str) - var html = new Buffer + init(ctx: NitdocContext) do + self.ctx = ctx + end - fun head do + protected fun head do append("") append("") + append("") append("") + append("") + append("") append("") append("") + var title = "" + if ctx.opt_custom_title.value != null then + title = " | {ctx.opt_custom_title.value.to_s}" + end + append("{self.title}{title}") end - fun menu is abstract + protected fun menu do + if ctx.opt_custom_menu_items.value != null then + append(ctx.opt_custom_menu_items.value.to_s) + end + end + + protected fun title: String is abstract - fun header do + protected fun header do append("
") append("") append("
") end - fun content is abstract + protected fun content is abstract - fun footer do - append("
Nit standard library. Version jenkins-component=stdlib-19.
") + protected fun footer do + if ctx.opt_custom_footer_text.value != null then + append("
{ctx.opt_custom_footer_text.value.to_s}
") + end end # Generate a clickable graphviz image using a dot content - fun generate_dot(dot: String, name: String, alt: String) do + protected fun generate_dot(dot: String, name: String, alt: String) do var output_dir = dot_dir if output_dir == null then return var file = new OFStream.open("{output_dir}/{name}.dot") @@ -262,7 +259,7 @@ abstract class NitdocPage end # Add a (source) link for a given location - fun show_source(l: Location): String + protected fun show_source(l: Location): String do if source == null then return "({l.file.filename.simplify_path})" @@ -274,12 +271,12 @@ abstract class NitdocPage source = x.join(l.line_start.to_s) x = source.split_with("%L") source = x.join(l.line_end.to_s) - return " (show code)" + return " (source)" end end # Render the page as a html string - fun render: String do + protected fun render do append("") append("") head @@ -291,15 +288,18 @@ abstract class NitdocPage append("") footer append("") - return html.to_s end + # Append a string to the page + fun append(s: String) do out.write(s) + # Save html page in the specified file fun save(file: String) do - var out = new OFStream.open(file) - out.write(render) - out.close + self.out = new OFStream.open(file) + render + self.out.close end + private var out: nullable OFStream end # The overview page @@ -308,12 +308,14 @@ class NitdocOverview private var mbuilder: ModelBuilder private var mmodules = new Array[MModule] - init(mbuilder: ModelBuilder, dot_dir: nullable String) do - self.mbuilder = mbuilder + init(ctx: NitdocContext, dot_dir: nullable String) do + super(ctx) + self.mbuilder = ctx.mbuilder self.dot_dir = dot_dir # get modules var mmodules = new HashSet[MModule] for mmodule in mbuilder.model.mmodules do + if mmodule.name == "
" then continue var owner = mmodule.public_owner if owner != null then mmodules.add(owner) @@ -322,32 +324,44 @@ class NitdocOverview end end # sort modules - var sorter = new ComparableSorter[MModule] + var sorter = new MModuleNameSorter self.mmodules.add_all(mmodules) sorter.sort(self.mmodules) end - redef fun head do - super - append("Overview | Nit Standard Library") - end + redef fun title do return "Overview" redef fun menu do + super append("
  • Overview
  • ") append("
  • Full Index
  • ") end redef fun content do - append("
    ") - append("

    Nit Standard Library

    ") - append("

    Documentation for the standard library of Nit
    Version jenkins-component=stdlib-19
    Date: TODAY

    ") + var footed = "" + if ctx.opt_custom_footer_text.value != null then footed = "footed" + append("
    ") + var title = "Overview" + if ctx.opt_custom_title.value != null then + title = ctx.opt_custom_title.value.to_s + end + append("

    {title}

    ") + var text = "" + if ctx.opt_custom_overview_text.value != null then + text = ctx.opt_custom_overview_text.value.to_s + end + append("
    {text}
    ") append("
    ") # module list append("

    Modules

    ") append("
      ") for mmodule in mmodules do - var amodule = mbuilder.mmodule2nmodule[mmodule] - append("
    • {mmodule.link(mbuilder)} {amodule.short_comment}
    • ") + if mbuilder.mmodule2nmodule.has_key(mmodule) then + var amodule = mbuilder.mmodule2nmodule[mmodule] + append("
    • ") + mmodule.html_link(self) + append(" {amodule.short_comment}
    • ") + end end append("
    ") # module graph @@ -356,15 +370,26 @@ class NitdocOverview append("
    ") end - fun process_generate_dot do + private fun process_generate_dot do + # build poset with public owners + var poset = new POSet[MModule] + for mmodule in mmodules do + poset.add_node(mmodule) + for omodule in mmodules do + if mmodule == omodule then continue + if mmodule.in_importation < omodule then + poset.add_node(omodule) + poset.add_edge(mmodule, omodule) + end + end + end + # build graph var op = new Buffer op.append("digraph dep \{ 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 mmodule in mmodules do + for mmodule in poset do op.append("\"{mmodule.name}\"[URL=\"{mmodule.url}\"];\n") - for imported in mmodule.in_importation.direct_greaters do - if imported.direct_owner == null then - op.append("\"{mmodule.name}\"->\"{imported.name}\";\n") - end + for omodule in poset[mmodule].direct_greaters do + op.append("\"{mmodule.name}\"->\"{omodule.name}\";\n") end end op.append("\}\n") @@ -376,25 +401,23 @@ end class NitdocFullindex super NitdocPage - private var nitdoc: Nitdoc - - init(nitdoc: Nitdoc) do - self.nitdoc = nitdoc + init(ctx: NitdocContext) do + super(ctx) self.dot_dir = null end - redef fun head do - super - append("Full Index | Nit Standard Library") - end + redef fun title do return "Full Index" redef fun menu do + super append("
  • Overview
  • ") append("
  • Full Index
  • ") end redef fun content do - append("
    ") + var footed = "" + if ctx.opt_custom_footer_text.value != null then footed = "footed" + append("
    ") append("

    Full Index

    ") module_column classes_column @@ -403,49 +426,56 @@ class NitdocFullindex end # Add to content modules column - fun module_column do - var sorter = new ComparableSorter[MModule] - var sorted = new Array[MModule] - for mmodule in nitdoc.modelbuilder.model.mmodule_importation_hierarchy do - sorted.add(mmodule) - end + private fun module_column do + var sorted = ctx.mbuilder.model.mmodule_importation_hierarchy.to_a + var sorter = new MModuleNameSorter sorter.sort(sorted) append("
    ") append("

    Modules

    ") append("
      ") for mmodule in sorted do - append("
    • {mmodule.link(nitdoc.modelbuilder)}
    • ") + append("
    • ") + mmodule.html_link(self) + append("
    • ") end append("
    ") append("
    ") end # Add to content classes modules - fun classes_column do - var sorted = nitdoc.modelbuilder.model.mclasses - var sorter = new ComparableSorter[MClass] + private fun classes_column do + var sorted = ctx.mbuilder.model.mclasses + var sorter = new MClassNameSorter sorter.sort(sorted) append("
    ") append("

    Classes

    ") append("
      ") for mclass in sorted do - append("
    • {mclass.link(nitdoc.modelbuilder)}
    • ") + if mclass.visibility < ctx.min_visibility then continue + append("
    • ") + mclass.html_link(self) + append("
    • ") end append("
    ") append("
    ") end # Insert the properties column of fullindex page - fun properties_column do - var sorted = nitdoc.modelbuilder.model.mproperties - var sorter = new ComparableSorter[MProperty] + private fun properties_column do + var sorted = ctx.mbuilder.model.mproperties + var sorter = new MPropertyNameSorter sorter.sort(sorted) append("
    ") append("

    Properties

    ") append("
      ") for mproperty in sorted do + if mproperty.visibility < ctx.min_visibility then continue if mproperty isa MAttribute then continue - append("
    • {mproperty.intro.link(nitdoc.modelbuilder)} ({mproperty.intro.mclassdef.mclass.link(nitdoc.modelbuilder)})
    • ") + append("
    • ") + mproperty.intro.html_link(self) + append(" (") + mproperty.intro.mclassdef.mclass.html_link(self) + append(")
    • ") end append("
    ") append("
    ") @@ -460,19 +490,24 @@ class NitdocModule private var mmodule: MModule private var mbuilder: ModelBuilder - init(mmodule: MModule, mbuilder: ModelBuilder, dot_dir: nullable String) do + init(mmodule: MModule, ctx: NitdocContext, dot_dir: nullable String) do + super(ctx) self.mmodule = mmodule - self.mbuilder = mbuilder + self.mbuilder = ctx.mbuilder self.dot_dir = dot_dir end - redef fun head do - super - var amodule = mbuilder.mmodule2nmodule[mmodule] - append("{mmodule.name} module | {amodule.short_comment}") + redef fun title do + if mbuilder.mmodule2nmodule.has_key(mmodule) then + var nmodule = mbuilder.mmodule2nmodule[mmodule] + return "{mmodule.name} module | {nmodule.short_comment}" + else + return "{mmodule.name} module" + end end redef fun menu do + super append("
  • Overview
  • ") append("
  • {mmodule.name}
  • ") append("
  • Full Index
  • ") @@ -480,42 +515,57 @@ class NitdocModule redef fun content do sidebar - append("
    ") + var footed = "" + if ctx.opt_custom_footer_text.value != null then footed = "footed" + append("
    ") append("

    {mmodule.name}

    ") - append("
    {mmodule.html_signature(mbuilder)}
    ") - append(mmodule.html_full_comment(mbuilder)) + append("
    ") + mmodule.html_signature(self) + append("
    ") + mmodule.html_full_comment(self) process_generate_dot classes properties append("
    ") end - fun process_generate_dot do - var name = "dep_{mmodule.name}" + private fun process_generate_dot do + # build poset with public owners + var poset = new POSet[MModule] + for mmodule in self.mmodule.in_importation.poset do + if mmodule.name == "
    " then continue + if mmodule.public_owner != null then continue + if not mmodule.in_importation < self.mmodule and not self.mmodule.in_importation < mmodule and mmodule != self.mmodule then continue + poset.add_node(mmodule) + for omodule in mmodule.in_importation.poset do + if mmodule == omodule then continue + if omodule.name == "
    " then continue + if omodule.public_owner != null then continue + if mmodule.in_importation < omodule then + poset.add_node(omodule) + poset.add_edge(mmodule, omodule) + end + end + end + # build graph var op = new Buffer + var name = "dep_{mmodule.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 m in mmodule.in_importation.poset do - var public_owner = m.public_owner - if public_owner == null then - public_owner = m - if m == mmodule then - op.append("\"{m.name}\"[shape=box,margin=0.03];\n") - else - op.append("\"{m.name}\"[URL=\"{m.url}\"];\n") - end + for mmodule in poset do + if mmodule == self.mmodule then + op.append("\"{mmodule.name}\"[shape=box,margin=0.03];\n") + else + op.append("\"{mmodule.name}\"[URL=\"{mmodule.url}\"];\n") end - for imported in m.in_importation.direct_greaters do - if imported.public_owner == null then - op.append("\"{public_owner.name}\"->\"{imported.name}\";\n") - end + for omodule in poset[mmodule].direct_greaters do + op.append("\"{mmodule.name}\"->\"{omodule.name}\";\n") end end op.append("\}\n") generate_dot(op.to_s, name, "Dependency graph for module {mmodule.name}") end - fun sidebar do - var amodule = mbuilder.mmodule2nmodule[mmodule] + private fun sidebar do append("") end private fun display_module_list(list: Array[MModule]) do append("
      ") - var sorter = new ComparableSorter[MModule] + var sorter = new MModuleNameSorter sorter.sort(list) - for m in list do append("
    • {m.link(mbuilder)}
    • ") + for m in list do + append("
    • ") + m.html_link(self) + append("
    • ") + end append("
    ") end # display the class column - fun classes do - var amodule = mbuilder.mmodule2nmodule[mmodule] + private fun classes do var intro_mclasses = mmodule.intro_mclasses var redef_mclasses = mmodule.redef_mclasses var all_mclasses = new HashSet[MClass] @@ -570,13 +626,14 @@ class NitdocModule var sorted = new Array[MClass] sorted.add_all(all_mclasses) - var sorter = new ComparableSorter[MClass] + var sorter = new MClassNameSorter sorter.sort(sorted) append("
    ") append("
    ") append("

    Classes

    ") append("
      ") for c in sorted do + if c.visibility < ctx.min_visibility then continue if redef_mclasses.has(c) and c.intro_mmodule.public_owner != mmodule then append("
    • ") append("R ") @@ -584,7 +641,7 @@ class NitdocModule append("
    • ") append("I ") end - append(c.link(mbuilder)) + c.html_link(self) append("
    • ") end append("
    ") @@ -593,16 +650,15 @@ class NitdocModule end # display the property column - fun properties do + private fun properties do # get properties - var amodule = mbuilder.mmodule2nmodule[mmodule] var mpropdefs = new HashSet[MPropDef] for m in mmodule.in_nesting.greaters do for c in m.mclassdefs do mpropdefs.add_all(c.mpropdefs) 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("
    ") @@ -610,8 +666,8 @@ class NitdocModule append("
      ") for mprop in sorted do if mprop isa MAttributeDef then continue - if mprop.mproperty.visibility <= none_visibility then continue - append(mprop.html_list_item(mbuilder)) + if mprop.mproperty.visibility < ctx.min_visibility then continue + mprop.html_list_item(self) end append("
    ") append("
    ") @@ -623,23 +679,20 @@ class NitdocClass super NitdocPage private var mclass: MClass - private var mbuilder: ModelBuilder - private var nitdoc: Nitdoc private var vtypes = new HashSet[MVirtualTypeDef] private var consts = new HashSet[MMethodDef] private var meths = new HashSet[MMethodDef] private var inherited = new HashSet[MPropDef] - init(mclass: MClass, nitdoc: Nitdoc, dot_dir: nullable String, source: nullable String) do + init(mclass: MClass, ctx: NitdocContext, dot_dir: nullable String, source: nullable String) do + super(ctx) self.mclass = mclass - self.mbuilder = nitdoc.modelbuilder - self.nitdoc = nitdoc self.dot_dir = dot_dir self.source = source # load properties for mclassdef in mclass.mclassdefs do for mpropdef in mclassdef.mpropdefs do - if mpropdef.mproperty.visibility <= none_visibility then continue + if mpropdef.mproperty.visibility < ctx.min_visibility then continue if mpropdef isa MVirtualTypeDef then vtypes.add(mpropdef) if mpropdef isa MMethodDef then if mpropdef.mproperty.is_init then @@ -651,38 +704,47 @@ class NitdocClass end end # get inherited properties - for mprop in mclass.inherited_mproperties do - var mpropdef = mprop.intro - if mprop.visibility <= none_visibility then continue - if mpropdef isa MVirtualTypeDef then vtypes.add(mpropdef) - if mpropdef isa MMethodDef then - if mpropdef.mproperty.is_init then - consts.add(mpropdef) - else - meths.add(mpropdef) + for pclass in mclass.in_hierarchy(ctx.mainmodule).greaters do + if pclass == mclass then continue + for pclassdef in pclass.mclassdefs do + for mprop in pclassdef.intro_mproperties do + var mpropdef = mprop.intro + if mprop.visibility < ctx.min_visibility then continue + if mpropdef isa MVirtualTypeDef then vtypes.add(mpropdef) + if mpropdef isa MMethodDef then + if mpropdef.mproperty.is_init then + consts.add(mpropdef) + else + meths.add(mpropdef) + end + end + inherited.add(mpropdef) end end - inherited.add(mpropdef) end end - redef fun head do - super - var nclass = mbuilder.mclassdef2nclassdef[mclass.intro] + redef fun title do + var nclass = ctx.mbuilder.mclassdef2nclassdef[mclass.intro] if nclass isa AStdClassdef then - append("{mclass.name} class | {nclass.short_comment}") + return "{mclass.name} class | {nclass.short_comment}" else - append("{mclass.name} class") + return "{mclass.name} class" end end redef fun menu do + super append("
  • Overview
  • ") var public_owner = mclass.public_owner if public_owner is null then - append("
  • {mclass.intro_mmodule.link(mbuilder)}
  • ") + append("
  • ") + mclass.intro_mmodule.html_link(self) + append("
  • ") else - append("
  • {public_owner.link(mbuilder)}
  • ") + append("
  • ") + public_owner.html_link(self) + append("
  • ") end append("
  • {mclass.name}
  • ") append("
  • Full Index
  • ") @@ -693,13 +755,15 @@ class NitdocClass properties_column inheritance_column append("
    ") - append("
    ") + var footed = "" + if ctx.opt_custom_footer_text.value != null then footed = "footed" + append("
    ") class_doc append("
    ") end - fun properties_column do - var sorter = new ComparableSorter[MPropDef] + private fun properties_column do + var sorter = new MPropDefNameSorter append("") end - fun inheritance_column do + private fun inheritance_column do var sorted = new Array[MClass] - var sorterp = new ComparableSorter[MClass] + var sorterp = new MClassNameSorter append("") end - fun class_doc do + private fun class_doc do # title - append("

    {mclass.html_signature}

    ") - append("
    {mclass.html_full_signature(mbuilder)}") - + append("

    {mclass.signature}

    ") + append("
    ") + mclass.html_full_signature(self) append("
    ") # comment - var nclass = mbuilder.mclassdef2nclassdef[mclass.intro] - append("
    ") + var nclass = ctx.mbuilder.mclassdef2nclassdef[mclass.intro] append("
    ") - if nclass isa AStdClassdef and not nclass.comment.is_empty then append("
    {nclass.comment}
    CancelCommit
    ")
     		process_generate_dot
     		append("
    ") # concerns @@ -805,7 +873,7 @@ class NitdocClass var sorted_meths = new Array[MMethodDef] var sorted = new Array[MModule] sorted_meths.add_all(meths) - nitdoc.mainmodule.linearize_mpropdefs(sorted_meths) + ctx.mainmodule.linearize_mpropdefs(sorted_meths) for meth in meths do if inherited.has(meth) then continue var mmodule = meth.mclassdef.mmodule @@ -826,7 +894,7 @@ class NitdocClass append("

    Concerns

    ") append("
      ") for owner, mmodules in sections do - var nowner = mbuilder.mmodule2nmodule[owner] + var nowner = ctx.mbuilder.mmodule2nmodule[owner] append("
    • ") if nowner.short_comment.is_empty then append("{owner.name}") @@ -836,7 +904,7 @@ class NitdocClass if not mmodules.is_empty then append("
        ") for mmodule in mmodules do - var nmodule = mbuilder.mmodule2nmodule[mmodule] + var nmodule = ctx.mbuilder.mmodule2nmodule[mmodule] if nmodule.short_comment.is_empty then append("
      • {mmodule.name}
      • ") else @@ -850,9 +918,7 @@ class NitdocClass append("
      ") append("") # 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] @@ -863,15 +929,17 @@ class NitdocClass # formal types if mclass.arity > 0 and nclass isa AStdClassdef then for ft, bound in mclass.parameter_types do - append("
      ") - append("

      {ft}: {bound.link(mbuilder)}

      ") + append("
      ") + append("

      {ft}: ") + bound.html_link(self) + append("

      ") append("
      formal generic type
      ") append("
      ") end end # virtual types prop_sorter.sort(local_vtypes) - for prop in local_vtypes do append(prop.html_full_desc(self)) + for prop in local_vtypes do prop.html_full_desc(self) append("") end # constructors @@ -881,7 +949,7 @@ class NitdocClass if local_consts.length > 0 then append("
      ") append("

      Constructors

      ") - for prop in local_consts do append(prop.html_full_desc(self)) + for prop in local_consts do prop.html_full_desc(self) append("
      ") end # methods @@ -891,32 +959,36 @@ class NitdocClass for owner, mmodules in sections do append("") if owner != mclass.intro_mmodule and owner != mclass.public_owner then - var nowner = mbuilder.mmodule2nmodule[owner] - append("

      Methods refined in {owner.link(mbuilder)}

      ") - if nowner.short_comment.is_empty then - append("

      {owner.name}

      ") - else - append("

      {owner.name}: {nowner.short_comment}

      ") + var nowner = ctx.mbuilder.mmodule2nmodule[owner] + append("

      Methods refined in ") + owner.html_link(self) + append("

      ") + append("

      ") + owner.html_link(self) + if not nowner.short_comment.is_empty then + append(": {nowner.short_comment}") end + append("

      ") end if concern2meths.has_key(owner) then var mmethods = concern2meths[owner] prop_sorter.sort(mmethods) - for prop in mmethods do append(prop.html_full_desc(self)) + for prop in mmethods do prop.html_full_desc(self) end for mmodule in mmodules do append("") - var nmodule = mbuilder.mmodule2nmodule[mmodule] + var nmodule = ctx.mbuilder.mmodule2nmodule[mmodule] if mmodule != mclass.intro_mmodule and mmodule != mclass.public_owner then - if nmodule.short_comment.is_empty then - append("

      {mmodule.name}

      ") - else - append("

      {mmodule.name}: {nmodule.short_comment}

      ") + append("

      ") + mmodule.html_link(self) + if not nmodule.short_comment.is_empty then + append(": {nmodule.short_comment}") end + append("

      ") end var mmethods = concern2meths[mmodule] prop_sorter.sort(mmethods) - for prop in mmethods do append(prop.html_full_desc(self)) + for prop in mmethods do prop.html_full_desc(self) end end end @@ -924,7 +996,7 @@ class NitdocClass if inherited.length > 0 then var sorted_inherited = new Array[MPropDef] sorted_inherited.add_all(inherited) - nitdoc.mainmodule.linearize_mpropdefs(sorted_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 @@ -934,10 +1006,12 @@ class NitdocClass append("

      Inherited Properties

      ") for c, mmethods in classes do prop_sorter.sort(mmethods) - append("

      Defined in {c.link(mbuilder)}: ") + append("

      Defined in ") + c.html_link(self) + append(": ") for i in [0..mmethods.length[ do var mmethod = mmethods[i] - append(mmethod.link(mbuilder)) + mmethod.html_link(self) if i <= mmethods.length - 1 then append(", ") end append("

      ") @@ -946,8 +1020,8 @@ class NitdocClass append("") end - fun process_generate_dot do - var pe = nitdoc.class_hierarchy[mclass] + 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] @@ -998,127 +1072,105 @@ end # 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 - res.append("module_") - var mowner = public_owner - if mowner != null then - res.append("{public_owner.name}_") + if url_cache == null then + var res = new Buffer + res.append("module_") + var mowner = public_owner + if mowner != null then + res.append("{public_owner.name}_") + end + res.append("{self.name}.html") + url_cache = res.to_s end - res.append("{self.name}.html") - return res.to_s + return url_cache.as(not null) end + private var url_cache: nullable String # html anchor id to the module in a nitdoc page fun anchor: String do - var res = new Buffer - res.append("MOD_") - var mowner = public_owner - if mowner != null then - res.append("{public_owner.name}_") + if anchor_cache == null then + var res = new Buffer + res.append("MOD_") + var mowner = public_owner + if mowner != null then + res.append("{public_owner.name}_") + end + res.append(self.name) + anchor_cache = res.to_s end - res.append(self.name) - return res.to_s + return anchor_cache.as(not null) end + private var anchor_cache: nullable String # Return a link (html a tag) to the nitdoc module page - fun link(mbuilder: ModelBuilder): String do - return "{name}" + fun html_link(page: NitdocPage) do + if html_link_cache == null then + var res = new Buffer + if page.ctx.mbuilder.mmodule2nmodule.has_key(self) then + res.append("{name}") + else + res.append("{name}") + end + html_link_cache = res.to_s + end + page.append(html_link_cache.as(not null)) end + private var html_link_cache: nullable String # Return the module signature decorated with html - fun html_signature(mbuilder: ModelBuilder): String do - return "module {html_full_namespace(mbuilder)}" + fun html_signature(page: NitdocPage) do + page.append("module ") + html_full_namespace(page) + page.append("") end # Return the module full namespace decorated with html - fun html_full_namespace(mbuilder: ModelBuilder): String do - var res = new Buffer - res.append("") + fun html_full_namespace(page: NitdocPage) do + page.append("") var mowner = public_owner if mowner != null then - res.append(public_owner.html_namespace(mbuilder)) - res.append("::") + public_owner.html_namespace(page) + page.append("::") end - res.append(self.link(mbuilder)) - res.append("") - return res.to_s + html_link(page) + page.append("") end # Return the module full namespace decorated with html - fun html_namespace(mbuilder: ModelBuilder): String do - var res = new Buffer - res.append("") + fun html_namespace(page: NitdocPage) do + page.append("") var mowner = public_owner if mowner != null then - res.append(public_owner.html_namespace(mbuilder)) + public_owner.html_namespace(page) else - res.append(self.link(mbuilder)) + html_link(page) end - res.append("") - return res.to_s + page.append("") end # Return the full comment of the module decorated with html - fun html_full_comment(mbuilder: ModelBuilder): String do - var res = new Buffer - res.append("
      ") - res.append("
      {mbuilder.mmodule2nmodule[self].comment}
      ") - res.append("") - res.append("Cancel") - res.append("Commit") - res.append("
      ")
      -		res.append("
      ") - return res.to_s + fun html_full_comment(page: NitdocPage) do + if page.ctx.mbuilder.mmodule2nmodule.has_key(self) then + page.append("
      ") + page.append("
      {page.ctx.mbuilder.mmodule2nmodule[self].full_comment}
      ") + page.append("
      ") + end end 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(mbuilder: ModelBuilder): String do - var res = new Buffer - if visibility <= none_visibility then - res.append("private ") - else if visibility == protected_visibility then - res.append("protected ") - end - res.append("{kind} {html_namespace(mbuilder)}") - return res.to_s + fun html_full_signature(page: NitdocPage) do + if visibility < public_visibility then page.append("{visibility.to_s} ") + page.append("{kind} ") + html_namespace(page) end - # Add type parameters - fun html_signature: String do + # name with formal parameter + # Foo[A, B] + private fun signature: String do if arity > 0 then return "{name}[{intro.parameter_names.join(", ")}]" else @@ -1127,29 +1179,33 @@ redef class MClass end # Return a link (html a tag) to the nitdoc class page - fun link(mbuilder: ModelBuilder): String do - if mbuilder.mclassdef2nclassdef.has_key(intro) then - var nclass = mbuilder.mclassdef2nclassdef[intro] - if nclass isa AStdClassdef then - return "{html_signature}" - else - return "{html_signature}" + fun html_link(page: NitdocPage) do + if html_link_cache == null then + var res = new Buffer + res.append("{html_signature}" + res.append(">{signature}") + html_link_cache = res.to_s end + page.append(html_link_cache.as(not null)) end + private var html_link_cache: nullable String # Return the class namespace decorated with html - fun html_namespace(mbuilder: ModelBuilder): String do - var res = new Buffer - res.append(intro_mmodule.html_namespace(mbuilder)) - res.append("::{self.link(mbuilder)}") - return res.to_s + fun html_namespace(page: NitdocPage) do + intro_mmodule.html_namespace(page) + page.append("::") + html_link(page) + page.append("") end fun url: String do - return "class_{public_owner}_{c_name}.html" + return "class_{public_owner}_{name}.html" end # Escape name for html output @@ -1157,19 +1213,12 @@ redef class MClass 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(mbuilder: ModelBuilder): String do - return "{intro_mclassdef.mclass.html_namespace(mbuilder)}::{intro.link(mbuilder)}" - end - - # Return the property signature decorated with html - fun html_signature(mbuilder: ModelBuilder): String do - var nprop = mbuilder.mpropdef2npropdef[intro] - return "{name}{nprop.html_signature(mbuilder)}" + fun html_namespace(page: NitdocPage) do + intro_mclassdef.mclass.html_namespace(page) + page.append("::") + intro.html_link(page) + page.append("") end # Escape name for html output @@ -1177,255 +1226,313 @@ redef class MProperty end redef class MType - fun link(mbuilder: ModelBuilder): String is abstract + fun html_link(page: NitdocPage) is abstract end redef class MClassType - redef fun link(mbuilder) do return mclass.link(mbuilder) + redef fun html_link(page) do mclass.html_link(page) end redef class MNullableType - redef fun link(mbuilder) do return "nullable {mtype.link(mbuilder)}" + redef fun html_link(page) do + page.append("nullable ") + mtype.html_link(page) + end +end + +redef class MGenericType + redef fun html_link(page) do + page.append("{mclass.name}[") + for i in [0..arguments.length[ do + arguments[i].html_link(page) + if i < arguments.length - 1 then page.append(", ") + end + page.append("]") + end +end + +redef class MParameterType + redef fun html_link(page) do + var name = mclass.intro.parameter_names[rank] + page.append("{name}") + end +end + +redef class MVirtualType + redef fun html_link(page) do mproperty.intro.html_link(page) end redef class MClassDef # Return the classdef namespace decorated with html - fun html_namespace(mbuilder: ModelBuilder): String do - var res = new Buffer - res.append(mmodule.html_full_namespace(mbuilder)) - res.append("::{self.mclass.link(mbuilder)}") - return res.to_s + fun html_namespace(page: NitdocPage) do + mmodule.html_full_namespace(page) + page.append("::") + mclass.html_link(page) + page.append("") end 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 + if url_cache == null then + url_cache = "{mclassdef.mclass.url}#{anchor}" + end + return url_cache.as(not null) + end + private var url_cache: nullable String - 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 + if anchor_cache == null then + anchor_cache = "PROP_{mclassdef.mclass.public_owner.name}_{mproperty.name}" + end + return anchor_cache.as(not null) + end + private var anchor_cache: nullable String # Return a link (html a tag) to the nitdoc class page - fun link(mbuilder: ModelBuilder): String do - if mbuilder.mpropdef2npropdef.has_key(self) then - var nprop = mbuilder.mpropdef2npropdef[self] - return "{mproperty.name}" - else - return "{mproperty.name}" + fun html_link(page: NitdocPage) do + if html_link_cache == null then + var res = new Buffer + if page.ctx.mbuilder.mpropdef2npropdef.has_key(self) then + var nprop = page.ctx.mbuilder.mpropdef2npropdef[self] + res.append("{mproperty.name}") + else + res.append("{mproperty.name}") + end + html_link_cache = res.to_s end + page.append(html_link_cache.as(not null)) end + private var html_link_cache: nullable String # Return a list item for the mpropdef - fun html_list_item(mbuilder: ModelBuilder): String do - var res = new Buffer + private fun html_list_item(page: NitdocPage) do if is_intro then - res.append("
    • ") - res.append("I {link(mbuilder)} ({mclassdef.mclass.link(mbuilder)})") - res.append("
    • ") + page.append("
    • ") + page.append("I ") else - res.append("
    • ") - res.append("R {link(mbuilder)} ({mclassdef.mclass.link(mbuilder)})") - res.append("
    • ") + page.append("
    • ") + page.append("R ") end - return res.to_s + html_link(page) + page.append("(") + mclassdef.mclass.html_link(page) + page.append(")") + page.append("
    • ") end # Return a list item for the mpropdef - fun html_sidebar_item(page: NitdocClass): String do - var res = new Buffer + private fun html_sidebar_item(page: NitdocClass) do if is_intro and mclassdef.mclass == page.mclass then - res.append("
    • ") - res.append("I") + page.append("
    • ") + page.append("I") else if is_intro and mclassdef.mclass != page.mclass then - res.append("
    • ") - res.append("H") + page.append("
    • ") + page.append("H") else - res.append("
    • ") - res.append("R") + page.append("
    • ") + page.append("R") end - res.append(link(page.mbuilder)) - res.append("
    • ") - return res.to_s + html_link(page) + page.append("
    • ") end - fun html_full_desc(page: NitdocClass): String is abstract - fun html_info(page: NitdocClass): String 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 -end -redef class MMethodDef - redef fun html_full_desc(page) do - if not page.mbuilder.mpropdef2npropdef.has_key(self) then - return "" - end - var res = new Buffer - var mprop = mproperty - var nprop = page.mbuilder.mpropdef2npropdef[self] - var classes = new Array[String] - var is_redef = mprop.intro_mclassdef.mclass != page.mclass - classes.add("fun") - if mprop.is_init then classes.add("init") - if is_redef then classes.add("redef") - if mprop.visibility == none_visibility then - classes.add("private") - else if mprop.visibility == protected_visibility then - classes.add("protected") - else - classes.add("public") - end - res.append("
      ") - res.append("

      {mprop.html_signature(page.mbuilder)}

      ") - res.append(html_info(page)) - res.append("
      ") - if nprop.comment == "" then - res.append("New Comment") - else - res.append("
      {nprop.comment}
      ") - end - res.append("CancelCommit
      ")
      +	private fun html_inheritance(page: NitdocClass) do
       		# definitions block
      -		res.append("

      ") - page.nitdoc.mainmodule.linearize_mpropdefs(mprop.mpropdefs) - var previous_defs = new Array[MMethodDef] - var next_defs = new Array[MMethodDef] + page.append("

      ") + page.ctx.mainmodule.linearize_mpropdefs(mproperty.mpropdefs) + var previous_defs = new Array[MPropDef] + var next_defs = new Array[MPropDef] var self_passed = false - for def in mprop.mpropdefs do + for def in mproperty.mpropdefs do if def == self then self_passed = true continue end if not self_passed then - if not page.mclass.ancestors.has(def.mclassdef.mclass) then continue + if def.mclassdef.mclass.in_hierarchy(page.ctx.mainmodule) < page.mclass then continue if def.is_intro then continue previous_defs.add(def) else - if not page.mclass.descendants.has(def.mclassdef.mclass) then continue + if page.mclass.in_hierarchy(page.ctx.mainmodule) < def.mclassdef.mclass then continue next_defs.add(def) end end - res.append("defined by {mclassdef.mmodule.html_full_namespace(page.mbuilder)}") + page.append("defined by ") + mclassdef.mmodule.html_full_namespace(page) + if page.ctx.mbuilder.mpropdef2npropdef.has_key(self) then + page.append(" {page.show_source(page.ctx.mbuilder.mpropdef2npropdef[self].location)}") + end if not is_intro then - res.append(", introduced by {mprop.intro.mclassdef.mclass.link(page.mbuilder)}") + page.append(", introduced by ") + mproperty.intro.mclassdef.mclass.html_link(page) + if page.ctx.mbuilder.mpropdef2npropdef.has_key(self) then + page.append(" {page.show_source(page.ctx.mbuilder.mpropdef2npropdef[self].location)}") + end end if not previous_defs.is_empty then - res.append(", inherited from ") + page.append(", inherited from ") for i in [0..previous_defs.length[ do - res.append(previous_defs[i].mclassdef.mclass.link(page.mbuilder)) - if i < previous_defs.length - 1 then res.append(", ") + var def = previous_defs[i] + def.mclassdef.mclass.html_link(page) + if page.ctx.mbuilder.mpropdef2npropdef.has_key(def) then + page.append(" {page.show_source(page.ctx.mbuilder.mpropdef2npropdef[def].location)}") + end + + if i < previous_defs.length - 1 then page.append(", ") end end if not next_defs.is_empty then - res.append(", redefined by ") + page.append(", redefined by ") for i in [0..next_defs.length[ do - res.append(next_defs[i].mclassdef.mclass.link(page.mbuilder)) - if i < next_defs.length - 1 then res.append(", ") + var def = next_defs[i] + def.mclassdef.mclass.html_link(page) + if page.ctx.mbuilder.mpropdef2npropdef.has_key(def) then + page.append(" {page.show_source(page.ctx.mbuilder.mpropdef2npropdef[def].location)}") + end + if i < next_defs.length - 1 then page.append(", ") end end - res.append(".

      ") - res.append("
      ") - res.append("
      ") - return res.to_s + page.append(".

      ") end - redef fun html_info(page) do - var res = new Buffer - res.append("
      ") - if mproperty.visibility <= none_visibility then - res.append("private ") - else if mproperty.visibility <= protected_visibility then - res.append("protected ") - end - if mproperty.intro_mclassdef.mclass != page.mclass then res.append("redef ") - res.append("fun {mproperty.html_namespace(page.mbuilder)}") - res.append("
      ") - res.append("
      ") - return res.to_s + 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] + page.append("
      ") + if not is_intro and page.ctx.mbuilder.mpropdef2npropdef.has_key(mproperty.intro) then + var intro_nprop = page.ctx.mbuilder.mpropdef2npropdef[mproperty.intro] + page.append("

      from ") + mproperty.html_namespace(page) + page.append("

      ") + if intro_nprop.full_comment == "" then + page.append("No comment") + else + page.append("
      {intro_nprop.full_comment}
      ") + end + page.append("

      from ") + mclassdef.html_namespace(page) + page.append("

      ") + end + if nprop.full_comment == "" then + page.append("No comment") + else + page.append("
      {nprop.full_comment}
      ") + end + html_inheritance(page) + page.append("
      ") end end -redef class MVirtualTypeDef +redef class MMethodDef redef fun html_full_desc(page) do - var res = new Buffer - var mprop = mproperty - var is_redef = mprop.intro_mclassdef.mclass != page.mclass var classes = new Array[String] - classes.add("type") + 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") - if mprop.visibility == none_visibility then - classes.add("private") - else if mprop.visibility == protected_visibility then - classes.add("protected") + classes.add(mproperty.visibility.to_s) + page.append("
      ") + if page.ctx.mbuilder.mpropdef2npropdef.has_key(self) then + page.append("

      ") + page.append("{mproperty.name}") + msignature.html_signature(page) + page.append("

      ") else - classes.add("public") + page.append("

      ") + page.append("init") + msignature.html_signature(page) + page.append("

      ") end - res.append("
      ") - res.append("

      {mprop.name}: {bound.link(page.mbuilder)}

      ") - res.append(html_info(page)) - res.append("
      ") + html_info(page) + html_comment(page) + page.append("
      ") + end - if page.mbuilder.mpropdef2npropdef.has_key(self) and page.mbuilder.mpropdef2npropdef[self].comment != "" then - var nprop = page.mbuilder.mpropdef2npropdef[self] - res.append("
      {nprop.comment}
      ") + redef fun html_info(page) do + page.append("
      ") + if mproperty.visibility < public_visibility then page.append("{mproperty.visibility.to_s} ") + if mproperty.intro_mclassdef.mclass != page.mclass then page.append("redef ") + if mproperty.is_init then + page.append("init ") else - res.append("New Comment") + page.append("fun ") end - res.append("CancelCommit
      ")
      -		# definitions block
      -		res.append("

      ") - page.nitdoc.mainmodule.linearize_mpropdefs(mprop.mpropdefs) - var previous_defs = new Array[MVirtualTypeDef] - var next_defs = new Array[MVirtualTypeDef] - var self_passed = false - for def in mprop.mpropdefs do - if def == self then - self_passed = true - continue - end - if not self_passed then - if not page.mclass.ancestors.has(def.mclassdef.mclass) then continue - if def.is_intro then continue - previous_defs.add(def) - else - if not page.mclass.descendants.has(def.mclassdef.mclass) then continue - next_defs.add(def) + mproperty.html_namespace(page) + page.append("

      ") + end +end + +redef class MVirtualTypeDef + redef fun html_full_desc(page) do + var is_redef = mproperty.intro_mclassdef.mclass != page.mclass + var classes = new Array[String] + classes.add("type") + if is_redef then classes.add("redef") + classes.add(mproperty.visibility.to_s) + page.append("
      ") + page.append("

      {mproperty.name}: ") + bound.html_link(page) + page.append("

      ") + html_info(page) + html_comment(page) + page.append("
      ") + end + + redef fun html_info(page) do + page.append("
      ") + if mproperty.intro_mclassdef.mclass != page.mclass then page.append("redef ") + page.append("type ") + mproperty.html_namespace(page) + page.append("
      ") + 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 - res.append("defined by {mclassdef.mmodule.html_full_namespace(page.mbuilder)}") - if not is_intro then - res.append(", introduced by {mprop.intro.mclassdef.mclass.link(page.mbuilder)}") - end - if not previous_defs.is_empty then - res.append(", inherited from ") - for i in [0..previous_defs.length[ do - res.append(previous_defs[i].mclassdef.mclass.link(page.mbuilder)) - if i < previous_defs.length - 1 then res.append(", ") - end + if return_mtype != null then + page.append(": ") + return_mtype.html_link(page) end - if not next_defs.is_empty then - res.append(", redefined by ") - for i in [0..next_defs.length[ do - res.append(next_defs[i].mclassdef.mclass.link(page.mbuilder)) - if i < next_defs.length - 1 then res.append(", ") + end + + private fun untyped_signature(page: NitdocPage): String do + var res = new Buffer + if not mparameters.is_empty then + res.append("(") + for i in [0..mparameters.length[ do + res.append(mparameters[i].name) + if i < mparameters.length - 1 then res.append(", ") end + res.append(")") end - res.append(".

      ") - res.append("
    ") - res.append("") return res.to_s end +end - redef fun html_info(page) do - var res = new Buffer - res.append("
    ") - if mproperty.intro_mclassdef.mclass != page.mclass then res.append("redef ") - res.append("type {mproperty.html_namespace(page.mbuilder)}") - res.append("
    ") - res.append("
    ") - return res.to_s +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 @@ -1434,147 +1541,53 @@ end # redef class AModule - private fun comment: String do - var ret = new Buffer - if n_moduledecl is null or n_moduledecl.n_doc is null then ret - if n_moduledecl.n_doc is null then return "" - for t in n_moduledecl.n_doc.n_comment do - ret.append(t.text.substring_from(1)) + private fun short_comment: String do + if n_moduledecl != null and n_moduledecl.n_doc != null then + return n_moduledecl.n_doc.n_comment.first.text.substring_from(2).replace("\n", "").html_escape end - return ret.to_s.html_escape + return "" end - private fun short_comment: String do - var ret = new Buffer + private fun full_comment: String do + var res = new Buffer if n_moduledecl != null and n_moduledecl.n_doc != null then - ret.append(n_moduledecl.n_doc.n_comment.first.text.substring_from(2).replace("\n", "")) + for t in n_moduledecl.n_doc.n_comment do + res.append(t.text.substring_from(1).html_escape) + end end - return ret.to_s.html_escape + return res.to_s end end redef class AStdClassdef - private fun comment: String do - var ret = new Buffer - if n_doc != null then - for t in n_doc.n_comment do ret.append(t.text.substring_from(1)) - end - return ret.to_s.html_escape - end - private fun short_comment: String do - var ret = new Buffer - if n_doc != null then ret.append(n_doc.n_comment.first.text.substring_from(2).replace("\n", "")) - return ret.to_s.html_escape - end -end - -redef class APropdef - private fun short_comment: String is abstract - private fun html_signature(mbuilder: ModelBuilder): String is abstract - private fun comment: String is abstract -end - -redef class AAttrPropdef - redef fun short_comment do - var ret = new Buffer - if n_doc != null then ret.append(n_doc.n_comment.first.text.substring_from(2).replace("\n", "")) - return ret.to_s.html_escape + if n_doc != null then return n_doc.n_comment.first.text.substring_from(2).replace("\n", "").html_escape + return "" end - redef private fun comment: String do - var ret = new Buffer + private fun full_comment: String do + var res = new Buffer if n_doc != null then - for t in n_doc.n_comment do ret.append(t.text.substring_from(1)) + for t in n_doc.n_comment do res.append(t.text.substring_from(1).html_escape) end - return ret.to_s.html_escape - end - - redef fun html_signature(mbuilder) do - var res = "" - if n_type != null and n_type.to_html != "" then res += ": {n_type.to_html}" - return res + return res.to_s end end -redef class AMethPropdef - redef fun short_comment do - var ret = new Buffer - if n_doc != null then ret.append(n_doc.n_comment.first.text.substring_from(2).replace("\n", "")) - return ret.to_s.html_escape - end - - redef private fun comment: String do - var ret = new Buffer - if n_doc != null then - for t in n_doc.n_comment do ret.append(t.text.substring_from(1)) - end - return ret.to_s.html_escape - end - - redef fun html_signature(mbuilder) do - if n_signature != null then return n_signature.to_html +redef class APropdef + 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 -end - -redef class ATypePropdef - redef fun short_comment do - var ret = new Buffer - if n_doc != null then ret.append(n_doc.n_comment.first.text.substring_from(2).replace("\n", "")) - return ret.to_s.html_escape - end - redef private fun comment: String do - var ret = new Buffer + private fun full_comment: String do + var res = new Buffer if n_doc != null then - for t in n_doc.n_comment do ret.append(t.text.substring_from(1)) + for t in n_doc.n_comment do res.append(t.text.substring_from(1).html_escape) end - return ret.to_s.html_escape - end - - redef fun html_signature(mbuilder) do - return mpropdef.bound.link(mbuilder) - end -end - -redef class ASignature - fun to_html: String do - #TODO closures - var ret = "" - if not n_params.is_empty then - ret = "{ret}({n_params.join(", ")})" - end - if n_type != null and n_type.to_html != "" then ret += ": {n_type.to_html}" - return ret - end -end - -redef class AParam - redef fun to_s do - var ret = "{n_id.text}" - if n_type != null then - ret = "{ret}: {n_type.to_html}" - if n_dotdotdot != null then ret = "{ret}..." - end - return ret - end -end - -redef class AType - fun to_html: String do - var ret = "{n_id.text}" - if n_kwnullable != null then ret = "nullable {ret}" - if not n_types.is_empty then ret = "{ret}[{n_types.join(", ")}]" - return ret + return res.to_s end - - fun name: String do return n_id.text.html_escape end -# Create a tool context to handle options and paths -var toolcontext = new ToolContext - -# Here we launch the nit index -var nitdoc = new Nitdoc(toolcontext) -nitdoc.start +var nitdoc = new NitdocContext +nitdoc.generate_nitdoc