1 # This file is part of NIT ( http://www.nitlanguage.org ).
3 # Copyright 2008 Jean Privat <jean@pryen.org>
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
9 # http://www.apache.org/licenses/LICENSE-2.0
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
20 import abstract_compiler
24 private var toolcontext
: ToolContext
25 private var model
: Model
26 private var modelbuilder
: ModelBuilder
27 private var mainmodule
: MModule
28 private var arguments
: Array[String]
29 private var destinationdir
: nullable String
30 private var sharedir
: nullable String
31 private var source
: nullable String
33 private var opt_dir
= new OptionString("Directory where doc is generated", "-d", "--dir")
34 private var opt_source
= new OptionString("What link for source (%f for filename, %l for first line, %L for last line)", "--source")
35 private var opt_sharedir
= new OptionString("Directory containing the nitdoc files", "--sharedir")
36 private var opt_nodot
= new OptionBool("Do not generate graphes with graphiviz", "--no-dot")
38 init(toolcontext
: ToolContext) do
39 # We need a model to collect stufs
40 self.toolcontext
= toolcontext
41 self.arguments
= toolcontext
.option_context
.rest
42 toolcontext
.option_context
.options
.clear
43 toolcontext
.option_context
.add_option
(opt_dir
)
44 toolcontext
.option_context
.add_option
(opt_source
)
45 toolcontext
.option_context
.add_option
(opt_sharedir
)
46 toolcontext
.option_context
.add_option
(opt_nodot
)
47 toolcontext
.process_options
50 if arguments
.length
< 1 then
51 toolcontext
.option_context
.usage
56 modelbuilder
= new ModelBuilder(model
, toolcontext
)
58 # Here we load an process std modules
59 var mmodules
= modelbuilder
.parse_and_build
([arguments
.first
])
60 if mmodules
.is_empty
then return
61 modelbuilder
.full_propdef_semantic_analysis
62 assert mmodules
.length
== 1
63 self.mainmodule
= mmodules
.first
66 private fun process_options
do
67 if not opt_dir
.value
is null then
68 destinationdir
= opt_dir
.value
70 destinationdir
= "nitdoc_directory"
72 if not opt_sharedir
.value
is null then
73 sharedir
= opt_sharedir
.value
75 var dir
= "NIT_DIR".environ
77 dir
= "{sys.program_name.dirname}/../share/nitdoc"
79 dir
= "{dir}/share/nitdoc"
82 if sharedir
is null then
83 print
"Error: Cannot locate nitdoc share files. Uses --sharedir or envvar NIT_DIR"
86 dir
= "{sharedir.to_s}/scripts/js-facilities.js"
87 if sharedir
is null then
88 print
"Error: Invalid nitdoc share files. Check --sharedir or envvar NIT_DIR"
92 if not opt_source
.value
is null then
95 source
= opt_source
.value
100 if arguments
.length
== 1 then
101 # Create destination dir if it's necessary
102 if not destinationdir
.file_exists
then destinationdir
.mkdir
103 sys
.system
("cp -r {sharedir.to_s}/* {destinationdir.to_s}/")
113 var overviewpage
= new NitdocOverview.with
(modelbuilder
.nmodules
, self.opt_nodot
.value
, destinationdir
.to_s
)
114 overviewpage
.save
("{destinationdir.to_s}/index.html")
118 var fullindex
= new NitdocFullindex.with
(model
.mmodules
)
119 fullindex
.save
("{destinationdir.to_s}/full-index.html")
123 for mod
in modelbuilder
.nmodules
do
124 var modulepage
= new NitdocModules.with
(mod
)
125 modulepage
.save
("{destinationdir.to_s}/{mod.mmodule.name}.html")
130 for amodule
in modelbuilder
.nmodules
do
131 for mclass
, aclassdef
in amodule
.mclass2nclassdef
do
132 mclass
.amodule
(modelbuilder
.mmodule2nmodule
)
133 mclass
.mmethod
(aclassdef
.mprop2npropdef
)
134 var classpage
= new NitdocMClasses.with
(mclass
, aclassdef
, source
)
135 classpage
.save
("{destinationdir.to_s}/{mclass.name}.html")
140 # Generate QuickSearch file
141 fun quicksearch_list
do
142 var file
= new OFStream.open
("{destinationdir.to_s}/quicksearch-list.js")
143 var content
= new Buffer
144 content
.append
("var entries = \{ ")
145 for prop
in model
.mproperties
do
146 if not prop
isa MMethod then continue
147 content
.append
("\"{prop.name}\
": [")
148 for propdef
in prop
.mpropdefs
do
149 content
.append
("\{txt: \"{propdef.mproperty.full_name}\", url
:\
"{propdef.mproperty.link_anchor}\" \
}")
150 if not propdef is prop.mpropdefs.last then content.append(", ")
156 for mclass in model.mclasses do
157 content.append("\
"{mclass.name}\": [")
158 for mclassdef in mclass.mclassdefs do
159 content.append("\
{txt: \"{mclassdef.mclass.full_name}\
", url:\"{mclass.link_anchor}\
" \}")
160 if not mclassdef
is mclass
.mclassdefs
.last
then content
.append
(", ")
163 if not mclass
is model
.mclasses
.last
then content
.append
(", ")
166 content
.append
(" \};")
167 file
.write
(content
.to_s
)
176 var amodules
: Array[AModule]
178 # Init with Array[AModule] to get all ifnormations about each MModule containt in a program
179 # opt_nodot to inform about the graph gen
180 # destination: to know where will be saved dot files
181 init with
(modules
: Array[AModule], opt_nodot
: Bool, destination
: String) do
182 self.amodules
= modules
183 self.opt_nodot
= opt_nodot
184 self.destinationdir
= destination
189 add
("title").text
("Overview | Nit Standard Library")
194 open
("nav").add_class
("main")
196 add
("li").add_class
("current").text
("Overview")
198 add_html
("<a href=\"full-index
.html\
">Full Index</a>")
200 open
("li").attr
("id", "liGitHub")
201 open
("a").add_class
("btn").attr
("id", "logGitHub")
202 add
("img").attr
("id", "imgGitHub").attr
("src", "resources/icons/github-icon.png")
204 open
("div").add_class
("popover bottom")
205 add
("div").add_class
("arrow").text
(" ")
206 open
("div").add_class
("githubTitle")
207 add
("h3").text
("Github Sign In")
210 add
("label").attr
("id", "lbloginGit").text
("Username")
211 add
("input").attr
("id", "loginGit").attr
("name", "login").attr
("type", "text")
212 open
("label").attr
("id", "logginMessage").text
("Hello ")
213 open
("a").attr
("id", "githubAccount")
214 add
("strong").attr
("id", "nickName").text
(" ")
219 add
("label").attr
("id", "lbpasswordGit").text
("Password")
220 add
("input").attr
("id", "passwordGit").attr
("name", "password").attr
("type", "password")
221 open
("div").attr
("id", "listBranches")
222 add
("label").attr
("id", "lbBranches").text
("Branch")
223 add
("select").add_class
("dropdown").attr
("id", "dropBranches").attr
("name", "dropBranches").attr
("tabindex", "1").text
(" ")
227 add
("label").attr
("id", "lbrepositoryGit").text
("Repository")
228 add
("input").attr
("id", "repositoryGit").attr
("name", "repository").attr
("type", "text")
231 add
("label").attr
("id", "lbbranchGit").text
("Branch")
232 add
("input").attr
("id", "branchGit").attr
("name", "branch").attr
("type", "text")
235 add
("a").attr
("id", "signIn").text
("Sign In")
246 open
("div").add_class
("page")
247 open
("div").add_class
("content fullpage")
248 add
("h1").text
("Nit Standard Library")
249 open
("article").add_class
("overview")
250 add_html
("<p>Documentation for the standard library of Nit<br />Version jenkins-component=stdlib-19<br />Date: TODAY</p>")
252 open
("article").add_class
("overview")
253 add
("h2").text
("Modules")
261 add
("footer").text
("Nit standard library. Version jenkins-component=stdlib-19.")
265 var ls
= new List[nullable MModule]
266 for amodule
in amodules
do
267 var mmodule
= amodule
.mmodule
.public_owner
268 if mmodule
!= null and not ls
.has
(mmodule
) then
270 add
("a").attr
("href", "{mmodule.name}.html").text
("{mmodule.to_s} ")
271 add_html
(amodule
.comment
)
278 fun process_generate_dot
do
280 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")
281 for amodule
in amodules
do
282 op
.append
("\"{amodule.mmodule.name}\
"[URL=\"{amodule.mmodule.name}.html\
"];\n")
283 for mmodule2
in amodule
.mmodule
.in_importation
.direct_greaters
do
284 op
.append
("\"{amodule.mmodule.name}\
"->\"{mmodule2.name}\
";\n")
288 generate_dot
(op
.to_s
, "dep", "Modules hierarchy")
293 class NitdocFullindex
296 var mmodules
: Array[MModule]
298 init with
(mmodules
: Array[MModule]) do
299 self.mmodules
= mmodules
306 add
("title").text
("Full Index | Nit Standard Library")
311 open
("nav").add_class
("main")
314 add_html
("<a href=\"index
.html\
">Overview</a>")
316 add
("li").add_class
("current").text
("Full Index")
317 open
("li").attr
("id", "liGitHub")
318 open
("a").add_class
("btn").attr
("id", "logGitHub")
319 add
("img").attr
("id", "imgGitHub").attr
("src", "resources/icons/github-icon.png")
321 open
("div").add_class
("popover bottom")
322 add
("div").add_class
("arrow").text
(" ")
323 open
("div").add_class
("githubTitle")
324 add
("h3").text
("Github Sign In")
327 add
("label").attr
("id", "lbloginGit").text
("Username")
328 add
("input").attr
("id", "loginGit").attr
("name", "login").attr
("type", "text")
329 open
("label").attr
("id", "logginMessage").text
("Hello ")
330 open
("a").attr
("id", "githubAccount")
331 add
("strong").attr
("id", "nickName").text
(" ")
336 add
("label").attr
("id", "lbpasswordGit").text
("Password")
337 add
("input").attr
("id", "passwordGit").attr
("name", "password").attr
("type", "password")
338 open
("div").attr
("id", "listBranches")
339 add
("label").attr
("id", "lbBranches").text
("Branch")
340 add
("select").add_class
("dropdown").attr
("id", "dropBranches").attr
("name", "dropBranches").attr
("tabindex", "1").text
(" ")
344 add
("label").attr
("id", "lbrepositoryGit").text
("Repository")
345 add
("input").attr
("id", "repositoryGit").attr
("name", "repository").attr
("type", "text")
348 add
("label").attr
("id", "lbbranchGit").text
("Branch")
349 add
("input").attr
("id", "branchGit").attr
("name", "branch").attr
("type", "text")
352 add
("a").attr
("id", "signIn").text
("Sign In")
363 open
("div").add_class
("page")
364 open
("div").add_class
("content fullpage")
365 add
("h1").text
("Full Index")
369 add
("footer").text
("Nit standard library. Version jenkins-component=stdlib-19.")
378 # Add to content modules column
380 var ls
= new List[nullable MModule]
381 var sorted
= mmodules
382 var sorterp
= new ComparableSorter[MModule]
384 open
("article").add_class
("modules filterable")
385 add
("h2").text
("Modules")
387 for mmodule
in sorted
do
388 if mmodule
.public_owner
!= null and not ls
.has
(mmodule
.public_owner
) then
389 ls
.add
(mmodule
.public_owner
)
391 add
("a").attr
("href", "{mmodule.public_owner.name}.html").text
(mmodule
.public_owner
.name
)
399 # Add to content classes modules
400 fun classes_column
do
401 var sorted
= mmodules
.first
.imported_mclasses
.to_a
402 var sorterp
= new ComparableSorter[MClass]
404 open
("article").add_class
("classes filterable")
405 add
("h2").text
("Classes")
408 for mclass
in sorted
do
410 add
("a").attr
("href", "{mclass.name}.html").text
(mclass
.name
)
418 # Insert the properties column of fullindex page
419 fun properties_column
do
420 open
("article").add_class
("properties filterable")
421 add
("h2").text
("Properties")
423 var sorted_imported
= mmodules
.first
.imported_methods
.to_a
424 var sorted_redef
= mmodules
.first
.redef_methods
.to_a
425 var sorterp
= new ComparableSorter[MProperty]
426 sorterp
.sort
(sorted_imported
)
427 sorterp
.sort
(sorted_redef
)
429 for method
in sorted_imported
do
430 if method
.visibility
is none_visibility
or method
.visibility
is intrude_visibility
then continue
431 open
("li").add_class
("intro")
432 add
("span").attr
("title", "introduction").text
("I")
434 add
("a").attr
("href", "{method.local_class.name}.html").attr
("title", "").text
("{method.name} ({method.local_class.name})")
438 for method
in sorted_redef
do
439 if method
.visibility
is none_visibility
or method
.visibility
is intrude_visibility
then continue
440 open
("li").add_class
("redef")
441 add
("span").attr
("title", "redefinition").text
("R")
443 add
("a").attr
("href", "{method.local_class.name}.html").attr
("title", "").text
("{method.name} ({method.local_class.name})")
457 var modulename
: String
458 init with
(amodule
: AModule) do
459 self.amodule
= amodule
460 self.modulename
= self.amodule
.mmodule
.name
467 add
("title").text
("{modulename} module | {amodule.short_comment}")
472 open
("nav").add_class
("main")
475 add_html
("<a href=\"index
.html\
">Overview</a>")
477 add
("li").add_class
("current").text
(modulename
)
479 add_html
("<a href=\"full-index
.html\
" >Full Index</a>")
481 open
("li").attr
("id", "liGitHub")
482 open
("a").add_class
("btn").attr
("id", "logGitHub")
483 add
("img").attr
("id", "imgGitHub").attr
("src", "resources/icons/github-icon.png")
485 open
("div").add_class
("popover bottom")
486 add
("div").add_class
("arrow").text
(" ")
487 open
("div").add_class
("githubTitle")
488 add
("h3").text
("Github Sign In")
491 add
("label").attr
("id", "lbloginGit").text
("Username")
492 add
("input").attr
("id", "loginGit").attr
("name", "login").attr
("type", "text")
493 open
("label").attr
("id", "logginMessage").text
("Hello ")
494 open
("a").attr
("id", "githubAccount")
495 add
("strong").attr
("id", "nickName").text
(" ")
500 add
("label").attr
("id", "lbpasswordGit").text
("Password")
501 add
("input").attr
("id", "passwordGit").attr
("name", "password").attr
("type", "password")
502 open
("div").attr
("id", "listBranches")
503 add
("label").attr
("id", "lbBranches").text
("Branch")
504 add
("select").add_class
("dropdown").attr
("id", "dropBranches").attr
("name", "dropBranches").attr
("tabindex", "1").text
(" ")
508 add
("label").attr
("id", "lbrepositoryGit").text
("Repository")
509 add
("input").attr
("id", "repositoryGit").attr
("name", "repository").attr
("type", "text")
512 add
("label").attr
("id", "lbbranchGit").text
("Branch")
513 add
("input").attr
("id", "branchGit").attr
("name", "branch").attr
("type", "text")
516 add
("a").attr
("id", "signIn").text
("Sign In")
527 open
("div").add_class
("page")
531 add
("footer").text
("Nit standard library. Version jenkins-component=stdlib-19.")
534 # Insert all tags in content part
536 open
("div").add_class
("content")
537 add
("h1").text
(modulename
)
538 add
("div").add_class
("subtitle").text
("module {modulename}")
545 # Insert module comment in the content
546 fun module_comment
do
547 var doc
= amodule
.comment
548 open
("div").attr
("id", "description")
549 add
("pre").add_class
("text_label").text
(doc
)
550 add
("textarea").add_class
("edit").attr
("rows", "1").attr
("cols", "76").attr
("id", "fileContent").text
(" ")
551 add
("a").attr
("id", "cancelBtn").text
("Cancel")
552 add
("a").attr
("id", "commitBtn").text
("Commit")
553 add
("pre").add_class
("text_label").attr
("id", "preSave").attr
("type", "2")
558 var mmodule
= amodule
.mmodule
559 open
("div").add_class
("menu")
561 add
("h3").text
("Module Hierarchy").attr
("style","cursor: pointer;")
562 if mmodule
.in_importation
.direct_greaters
.length
> 0 then
563 add_html
("<h4>All dependencies</h4><ul>")
564 var sorted
= mmodule
.in_importation
.direct_greaters
.to_a
565 var sorterp
= new ComparableSorter[MModule]
568 if m
== mmodule
or mmodule
== m
.public_owner
then continue
570 add
("a").attr
("href", "{m.name}.html").text
(m
.name
)
575 if mmodule
.in_importation
.greaters
.length
> 0 then
576 add_html
("<h4>All clients</h4><ul>")
577 var sorted
= mmodule
.in_importation
.greaters
.to_a
578 var sorterp
= new ComparableSorter[MModule]
581 if m
== mmodule
then continue
583 add
("a").attr
("href", "{m.name}.html").text
(m
.name
)
589 if mmodule
.in_nesting
.direct_greaters
.length
> 0 then
590 var sorted
= mmodule
.in_nesting
.direct_greaters
.to_a
591 var sorterp
= new ComparableSorter[MModule]
594 add
("h3").text
("Nested Modules").attr
("style","cursor: pointer;")
598 add
("a").attr
("href", "{m.name}.html").text
(m
.name
)
609 var sorted
= new Array[MClass]
610 sorted
.add_all
(amodule
.mmodule
.mclasses
.keys
)
611 var sorterp
= new ComparableSorter[MClass]
613 open
("div").add_class
("module")
614 open
("article").add_class
("classes filterable")
615 add
("h2").text
("Classes")
618 var state
= amodule
.mmodule
.mclasses
[c
]
620 if state
== c_is_intro
or state
== c_is_imported
then
621 open
("li").add_class
("intro")
622 add
("span").attr
("title", "introduced in this module").text
("I ")
624 open
("li").add_class
("redef")
625 add
("span").attr
("title", "refined in this module").text
("R ")
627 add
("a").attr
("href", "{name}.html").text
(name
)
636 var sorted_imported
= amodule
.mmodule
.imported_methods
.to_a
637 var sorted_redef
= amodule
.mmodule
.redef_methods
.to_a
638 var sorterp
= new ComparableSorter[MProperty]
639 sorterp
.sort
(sorted_imported
)
640 sorterp
.sort
(sorted_redef
)
641 open
("article").add_class
("properties filterable")
642 add_html
("<h2>Properties</h2>")
644 for method
in sorted_imported
do
645 if method
.visibility
is none_visibility
or method
.visibility
is intrude_visibility
then continue
646 open
("li").add_class
("intro")
647 add
("span").attr
("title", "introduction").text
("I")
649 add
("a").attr
("href", "{method.local_class.name}.html").attr
("title", "").text
("{method.name} ({method.local_class.name})")
653 for method
in sorted_redef
do
654 if method
.visibility
is none_visibility
or method
.visibility
is intrude_visibility
then continue
655 open
("li").add_class
("redef")
656 add
("span").attr
("title", "redefinition").text
("R")
658 add
("a").attr
("href", "{method.local_class.name}.html").attr
("title", "").text
("{method.name} ({method.local_class.name})")
668 # Nit Standard Library
673 var aclassdef
: AClassdef
674 var stdclassdef
: nullable AStdClassdef
675 var public_owner
: nullable MModule
677 init with
(mclass
: MClass, aclassdef
: AClassdef, source
: nullable String) do
679 self.aclassdef
= aclassdef
680 if aclassdef
isa AStdClassdef then self.stdclassdef
= aclassdef
681 self.public_owner
= mclass
.intro_mmodule
.public_owner
689 add
("title").text
("{self.mclass.name} class | Nit Standard Library")
694 open
("nav").add_class
("main")
697 add_html
("<a href=\"index
.html\
">Overview</a>")
700 if public_owner
is null then
701 add_html
("<a href=\"{mclass.intro_mmodule.name}.html\
">{mclass.intro_mmodule.name}</a>")
703 add_html
("<a href=\"{public_owner.name}.html\
">{public_owner.name}</a>")
706 add
("li").add_class
("current").text
(mclass
.name
)
708 add_html
("<a href=\"full-index
.html\
" >Full Index</a>")
710 open
("li").attr
("id", "liGitHub")
711 open
("a").add_class
("btn").attr
("id", "logGitHub")
712 add
("img").attr
("id", "imgGitHub").attr
("src", "resources/icons/github-icon.png")
714 open
("div").add_class
("popover bottom")
715 add
("div").add_class
("arrow").text
(" ")
716 open
("div").add_class
("githubTitle")
717 add
("h3").text
("Github Sign In")
720 add
("label").attr
("id", "lbloginGit").text
("Username")
721 add
("input").attr
("id", "loginGit").attr
("name", "login").attr
("type", "text")
722 open
("label").attr
("id", "logginMessage").text
("Hello ")
723 open
("a").attr
("id", "githubAccount")
724 add
("strong").attr
("id", "nickName").text
(" ")
729 add
("label").attr
("id", "lbpasswordGit").text
("Password")
730 add
("input").attr
("id", "passwordGit").attr
("name", "password").attr
("type", "password")
731 open
("div").attr
("id", "listBranches")
732 add
("label").attr
("id", "lbBranches").text
("Branch")
733 add
("select").add_class
("dropdown").attr
("id", "dropBranches").attr
("name", "dropBranches").attr
("tabindex", "1").text
(" ")
737 add
("label").attr
("id", "lbrepositoryGit").text
("Repository")
738 add
("input").attr
("id", "repositoryGit").attr
("name", "repository").attr
("type", "text")
741 add
("label").attr
("id", "lbbranchGit").text
("Branch")
742 add
("input").attr
("id", "branchGit").attr
("name", "branch").attr
("type", "text")
745 add
("a").attr
("id", "signIn").text
("Sign In")
756 open
("div").add_class
("page")
759 add
("footer").text
("Nit standard library. Version jenkins-component=stdlib-19.")
762 # Insert all tags in content part
764 open
("div").add_class
("menu")
768 open
("div").add_class
("content")
773 fun properties_column
do
774 var sorted
= new Array[MProperty]
775 var sorterp
= new ComparableSorter[MProperty]
776 open
("nav").add_class
("properties filterable")
777 add
("h3").text
("Properties")
779 if mclass
.virtual_types
.length
> 0 then
780 add
("h4").text
("Virtual Types")
782 sorted
= mclass
.virtual_types
.to_a
784 for prop
in sorted
do
785 add_html
("<li class=\"redef\
"><span title=\"Redefined\
">R</span><a href=\"{prop.link_anchor}\
">{prop.name}</a></li>")
789 if mclass
.constructors
.length
> 0 then
790 sorted
= mclass
.constructors
.to_a
792 add
("h4").text
("Constructors")
794 for prop
in sorted
do
795 add_html
("<li class=\"intro\
"><span title=\"Introduced\
">I</span><a href=\"{prop.link_anchor}\
">{prop.name}</a></li>")
799 add
("h4").text
("Methods")
801 if mclass
.intro_methods
.length
> 0 then
802 sorted
= mclass
.intro_methods
.to_a
804 for prop
in sorted
do
805 if prop
.visibility
is public_visibility
or prop
.visibility
is protected_visibility
then add_html
("<li class=\"intro\
"><span title=\"Introduced\
">I</span><a href=\"{prop.link_anchor}\
">{prop.name}</a></li>")
808 if mclass
.inherited_methods
.length
> 0 then
809 sorted
= mclass
.inherited_methods
.to_a
811 for prop
in sorted
do
812 if prop
.visibility
is public_visibility
or prop
.visibility
is protected_visibility
then add_html
("<li class=\"inherit\
"><span title=\"Inherited\
">H</span><a href=\"{prop.link_anchor}\
">{prop.name}</a></li>")
815 if mclass
.redef_methods
.length
> 0 then
816 sorted
= mclass
.redef_methods
.to_a
818 for prop
in sorted
do
819 if prop
.visibility
is public_visibility
or prop
.visibility
is protected_visibility
then add_html
("<li class=\"redef\
"><span title=\"Refined\
">R</span><a href=\"{prop.link_anchor}\
">{prop.name}</a></li>")
826 fun inheritance_column
do
827 var sorted
= new Array[MClass]
828 var sorterp
= new ComparableSorter[MClass]
830 add
("h3").text
("Inheritance")
831 if mclass
.parents
.length
> 0 then
832 sorted
= mclass
.parents
.to_a
834 add
("h4").text
("Superclasses")
836 for sup
in sorted
do add_html
("<li><a href=\"{sup.name}.html\
">{sup.name}</a></li>")
840 if mclass
.descendants
.length
is 0 then
841 add
("h4").text
("No Known Subclasses")
842 else if mclass
.descendants
.length
<= 100 then
843 sorted
= mclass
.descendants
.to_a
845 add
("h4").text
("Subclasses")
847 for sub
in sorted
do add_html
("<li><a href=\"{sub.name}\
">{sub.name}</a></li>")
849 else if mclass
.children
.length
<= 100 then
850 sorted
= mclass
.children
.to_a
852 add
("h4").text
("Direct Subclasses Only")
854 for sub
in sorted
do add_html
("<li><a href=\"{sub.name}\
">{sub.name}</a></li>")
857 add
("h4").text
("Too much Subclasses to list")
863 var sorted
= new Array[MModule]
864 sorted
.add_all
(mclass
.concerns
.keys
)
865 var sorterp
= new ComparableSorter[MModule]
866 var sorterprop
= new ComparableSorter[MProperty]
867 var sorterc
= new ComparableSorter[MClass]
870 var lmmodule
= new List[MModule]
871 # Insert the subtitle part
872 add
("h1").text
(mclass
.name
)
873 open
("div").add_class
("subtitle")
874 if mclass
.visibility
is none_visibility
then subtitle
+= "private "
875 subtitle
+= "{mclass.kind} <a href=\"{mclass.public_owner.name}.html\
">{mclass.public_owner.name}</a>::{mclass.name}"
878 add_html
("<div style=\"float
: right
;\
"><a id=\"lblDiffCommit\
"></a></div>")
879 # We add the class description
880 open
("section").add_class
("description")
881 if not stdclassdef
is null and not stdclassdef
.comment
.is_empty
then add_html
("<pre class=\"text_label\
" title=\"122\
" name=\"\
" tag=\"{mclass.mclassdefs.first.location.to_s}\
" type=\"2\
">{stdclassdef.comment} </pre><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>")
883 open
("section").add_class
("concerns")
884 add
("h2").add_class
("section-header").text
("Concerns")
886 for owner
in sorted
do
887 var childs
= mclass
.concerns
[owner
]
889 add_html
("<a href=\"#MOD_{owner.name}\">{owner.name}</a>: {owner.amodule.short_comment}")
890 if not childs
is null then
892 var sortedc
= childs
.to_a
893 var sorterpc
= new ComparableSorter[MModule]
894 sorterpc
.sort
(sortedc
)
895 for child
in sortedc
do
896 add_html
("<li><a href=\"#MOD_{child.name}\">{child.name}</a>: {child.amodule.short_comment} </li>")
904 # Insert virtual types if there is almost one
905 if mclass
.virtual_types
.length
> 0 or (stdclassdef
!= null and stdclassdef
.n_formaldefs
.length
> 0) then
906 open
("section").add_class
("types")
907 add
("h2").text
("Formal and Virtual Types")
908 if mclass
.virtual_types
.length
> 0 then for prop
in mclass
.virtual_types
do description
(prop
)
909 if stdclassdef
.n_formaldefs
.length
> 0 then
910 for prop
in stdclassdef
.n_formaldefs
do
911 open
("article").attr
("id", "FT_Object_{prop.collect_text}")
912 open
("h3").add_class
("signature").text
("{prop.collect_text}: nullable ")
913 add_html
("<a title=\"The root of the
class hierarchy
.\
" href=\"Object.html\
">Object</a>")
915 add_html
("<div class=\"info\
">formal generic type</div>")
921 # Insert constructors if there is almost one
922 if mclass
.constructors
.length
> 0 then
923 var sortedc
= mclass
.constructors
.to_a
924 sorterprop
.sort
(sortedc
)
925 open
("section").add_class
("constructors")
926 add
("h2").add_class
("section-header").text
("Constructors")
927 for prop
in sortedc
do description
(prop
)
930 open
("section").add_class
("methods")
931 add
("h2").add_class
("section-header").text
("Methods")
932 for mmodule
, mmethods
in mclass
.all_methods
do
933 add_html
("<a id=\"MOD_{mmodule.name}\
"></a>")
934 if mmodule
!= mclass
.intro_mmodule
and mmodule
!= mclass
.public_owner
then
935 if mclass
.has_mmodule
(mmodule
) then
936 add_html
("<p class=\"concern-doc\
">{mmodule.name}: {mmodule.amodule.short_comment}</p>")
938 add_html
("<h3 class=\"concern-toplevel\
">Methods refined in <a href=\"{mmodule.name}.html\
">{mmodule.name}</a></h3><p class=\"concern-doc\
">{mmodule.name}: {mmodule.amodule.short_comment}</p>")
941 var sortedc
= mmethods
.to_a
942 sorterprop
.sort
(sortedc
)
943 for prop
in sortedc
do description
(prop
)
945 # Insert inherited methods
946 if mclass
.inherited_methods
.length
> 0 then
947 var sortedc
= new Array[MClass]
948 sortedc
.add_all
(mclass
.inherited
.keys
)
949 sorterc
.sort
(sortedc
)
950 add
("h3").text
("Inherited Methods")
951 for i_mclass
in sortedc
do
952 var sortedp
= mclass
.inherited
[i_mclass
].to_a
953 sorterprop
.sort
(sortedp
)
955 add_html
("Defined in <a href=\"{i_mclass.name}.html\
">{i_mclass.name}</a>: ")
956 for method
in sortedp
do
957 add_html
("<a href=\"{method.link_anchor}\
">{method.name}</a>")
958 if method
!= sortedp
.last
then add_html
(", ")
966 # Insert description tags for 'prop'
967 fun description
(prop
: MProperty) do
968 open
("article").add_class
("fun public {if prop.is_redef then "redef" else ""}").attr
("id", "{prop.anchor}")
970 if prop
.apropdef
!= null then sign
+= prop
.apropdef
.signature
971 add_html
("<h3 class=\"signature\
">{sign}</h3>")
972 add_html
("<div class=\"info\
">{if prop.is_redef then "redef" else ""} fun {prop.intro_mclassdef.namespace(mclass)}::{prop.name}</div><div style=\"float
: right
;\
"><a id=\"lblDiffCommit\
"></a></div>")
974 open
("div").add_class
("description")
975 if prop
.apropdef
is null or prop
.apropdef
.comment
== "" then
976 add_html
("<a class=\"newComment\
" title=\"32\
" tag=\"\
">New Comment</a>")
978 add_html
("<pre class=\"text_label\
" title=\"\
" name=\"\
" tag=\"\
" type=\"1\
">{prop.apropdef.comment}</pre>")
980 add_html
("<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>")
982 if prop
.local_class
!= mclass
then add_html
("inherited from {prop.local_class.intro_mmodule.name} ")
983 #TODO display show code if doc github
984 add_html
("defined by the module <a href=\"{prop.intro_mclassdef.mmodule.name}.html\
">{prop.intro_mclassdef.mmodule.name}</a> {if prop.apropdef is null then "" else show_source(prop.apropdef.location)}.")
986 for parent
in mclass
.parents
do
987 if prop
isa MMethod then if parent
.constructors
.has
(prop
) then add_html
(" Previously defined by: <a href=\"{parent.intro_mmodule.name}.html\
">{parent.intro_mmodule.name}</a> for <a href=\"{parent.name}.html\
">{parent.name}</a>.")
1001 var destinationdir
: String
1002 var source
: nullable String
1005 add
("meta").attr
("charset", "utf-8")
1006 add
("script").attr
("type", "text/javascript").attr
("src", "scripts/jquery-1.7.1.min.js")
1007 add
("script").attr
("type", "text/javascript").attr
("src", "quicksearch-list.js")
1008 add
("script").attr
("type", "text/javascript").attr
("src", "scripts/js-facilities.js")
1009 add
("link").attr
("rel", "stylesheet").attr
("href", "styles/main.css").attr
("type", "text/css").attr
("media", "screen")
1012 redef fun body
do header
1015 # Generate a clickable graphviz image using a dot content
1016 fun generate_dot
(dot
: String, name
: String, alt
: String) do
1017 if opt_nodot
then return
1018 var file
= new OFStream.open
("{self.destinationdir}/{name}.dot")
1021 sys
.system
("\{ test -f {self.destinationdir}/{name}.png && test -f {self.destinationdir}/{name}.s.dot && diff {self.destinationdir}/{name}.dot {self.destinationdir}/{name}.s.dot >/dev/null 2>&1 ; \} || \{ cp {self.destinationdir}/{name}.dot {self.destinationdir}/{name}.s.dot && dot -Tpng -o{self.destinationdir}/{name}.png -Tcmapx -o{self.destinationdir}/{name}.map {self.destinationdir}/{name}.s.dot ; \}")
1022 open
("article").add_class
("graph")
1023 add
("img").attr
("src", "{name}.png").attr
("usemap", "#{name}").attr
("style", "margin:auto").attr
("alt", "{alt}")
1025 var fmap
= new IFStream.open
("{self.destinationdir}/{name}.map")
1026 add_html
(fmap
.read_all
)
1030 # Add a (source) link fo a given location
1031 fun show_source
(l
: Location): String
1033 if source
== null then
1034 return "({l.file.filename.simplify_path})"
1036 # THIS IS JUST UGLY ! (but there is no replace yet)
1037 var x
= source
.split_with
("%f")
1038 source
= x
.join
(l
.file
.filename
.simplify_path
)
1039 x
= source
.split_with
("%l")
1040 source
= x
.join
(l
.line_start
.to_s
)
1041 x
= source
.split_with
("%L")
1042 source
= x
.join
(l
.line_end
.to_s
)
1043 return " (<a href=\"{source.to_s}\
">show code</a>)"
1050 private fun comment
: String do
1052 if n_moduledecl
is null or n_moduledecl
.n_doc
is null then ret
1053 if n_moduledecl
.n_doc
is null then return ""
1054 for t
in n_moduledecl
.n_doc
.n_comment
do
1055 ret
+= "{t.text.replace("# ", "")}"
1060 private fun short_comment
: String do
1062 if n_moduledecl
!= null and n_moduledecl
.n_doc
!= null then
1063 var txt
= n_moduledecl
.n_doc
.n_comment
.first
.text
1064 txt
= txt
.replace
("# ", "")
1065 txt
= txt
.replace
("\n", "")
1075 redef type OTHER: MModule
1076 redef fun <(other
: OTHER): Bool do return self.name
< other
.name
1078 var amodule
: nullable AModule
1080 # Get the list of all methods in a module
1081 fun imported_methods
: Set[MMethod] do
1082 var methods
= new HashSet[MMethod]
1083 for mclass
in imported_mclasses
do
1084 for method
in mclass
.intro_methods
do
1091 # Get the list aof all refined methods in a module
1092 fun redef_methods
: Set[MMethod] do
1093 var methods
= new HashSet[MMethod]
1094 for mclass
in redef_mclasses
do
1095 for method
in mclass
.intro_methods
do
1103 redef class MProperty
1106 redef type OTHER: MProperty
1107 redef fun <(other
: OTHER): Bool do return self.name
< other
.name
1110 var apropdef
: nullable APropdef
1112 redef init(intro_mclassdef
: MClassDef, name
: String, visibility
: MVisibility)
1118 fun local_class
: MClass do
1119 var classdef
= self.intro_mclassdef
1120 return classdef
.mclass
1123 fun class_text
: String do
1124 return local_class
.name
1127 fun link_anchor
: String do
1128 return "{class_text}.html#{anchor}"
1131 fun anchor
: String do
1132 return "PROP_{c_name}"
1140 redef type OTHER: MClass
1141 redef fun <(other
: OTHER): Bool do return self.name
< other
.name
1143 # Associate all MMethods to each MModule concerns
1144 fun all_methods
: HashMap[MModule, Set[MMethod]] do
1145 var hm
= new HashMap[MModule, Set[MMethod]]
1146 for mmodule
, childs
in concerns
do
1147 if not hm
.has_key
(mmodule
) then hm
[mmodule
] = new HashSet[MMethod]
1148 for prop
in intro_methods
do
1149 if mmodule
== prop
.intro_mclassdef
.mmodule
then
1150 prop
.is_redef
= false
1151 hm
[mmodule
].add
(prop
)
1154 for prop
in redef_methods
do
1155 if mmodule
== prop
.intro_mclassdef
.mmodule
then
1156 prop
.is_redef
= true
1157 hm
[mmodule
].add
(prop
)
1161 if childs
!= null then
1162 for child
in childs
do
1163 if not hm
.has_key
(child
) then hm
[child
] = new HashSet[MMethod]
1164 for prop
in intro_methods
do
1165 if child
== prop
.intro_mclassdef
.mmodule
then
1166 prop
.is_redef
= false
1170 for prop
in redef_methods
do
1171 if child
== prop
.intro_mclassdef
.mmodule
then
1172 prop
.is_redef
= true
1182 fun public_owner
: MModule do
1183 var owner
= intro_mmodule
1184 if owner
.public_owner
is null then
1187 return owner
.public_owner
.as(not null)
1191 # Associate Amodule to all MModule concern by 'self'
1192 fun amodule
(amodules
: HashMap[MModule, AModule]) do
1193 for owner
, childs
in concerns
do
1194 if childs
!= null then for child
in childs
do child
.amodule
= amodules
[child
]
1195 owner
.amodule
= amodules
[owner
]
1199 # Associate MClass to all MMethod include in 'inherited_methods'
1200 fun inherited
: HashMap[MClass, Set[MMethod]] do
1201 var hm
= new HashMap[MClass, Set[MMethod]]
1202 for method
in inherited_methods
do
1203 var mclass
= method
.intro_mclassdef
.mclass
1204 if not hm
.has_key
(mclass
) then hm
[mclass
] = new HashSet[MMethod]
1205 hm
[mclass
].add
(method
)
1210 # Return true if MModule concern contain subMModule
1211 fun has_mmodule
(sub
: MModule): Bool do
1212 for mmodule
, childs
in concerns
do
1213 if childs
is null then continue
1214 if childs
.has
(sub
) then return true
1219 fun mmethod
(mprop2npropdef
: Map[MProperty, APropdef]) do
1220 for const
in constructors
do
1221 if mprop2npropdef
.has_key
(const
)then
1222 const
.apropdef
= mprop2npropdef
[const
].as(AMethPropdef)
1226 for intro
in intro_methods
do
1227 if mprop2npropdef
.has_key
(intro
)then
1228 if mprop2npropdef
[intro
] isa AMethPropdef then intro
.apropdef
= mprop2npropdef
[intro
].as(AMethPropdef)
1232 for rd
in redef_methods
do
1233 if mprop2npropdef
.has_key
(rd
)then
1234 if mprop2npropdef
[rd
] isa AMethPropdef then rd
.apropdef
= mprop2npropdef
[rd
].as(AMethPropdef)
1239 fun link_anchor
: String do
1240 return "{name}.html"
1245 redef class AStdClassdef
1246 private fun comment
: String do
1248 if n_doc
!= null then
1249 for t
in n_doc
.n_comment
do
1250 var txt
= t
.text
.replace
("# ", "")
1251 txt
= txt
.replace
("#", "")
1258 private fun short_comment
: String do
1260 if n_doc
!= null then
1261 var txt
= n_doc
.n_comment
.first
.text
1262 txt
= txt
.replace
("# ", "")
1263 txt
= txt
.replace
("\n", "")
1270 redef class ASignature
1274 if not n_params
.is_empty
then
1275 ret
= "{ret}({n_params.join(", ")})"
1277 if n_type
!= null and n_type
.to_s
!= "" then ret
+= " {n_type.to_s}"
1284 var ret
= "{n_id.text}"
1285 if n_type
!= null then
1286 ret
= "{ret}: {n_type.to_s}"
1287 if n_dotdotdot
!= null then ret
= "{ret}..."
1295 var ret
= "<a href=\"{n_id.text}.html\
">{n_id.text}</a>"
1296 if n_kwnullable
!= null then ret
= "nullable {ret}"
1297 if not n_types
.is_empty
then ret
= "{ret}[{n_types.join(", ")}]"
1302 redef class APropdef
1303 private fun short_comment
: String is abstract
1304 private fun signature
: String is abstract
1305 private fun comment
: String is abstract
1308 redef class AAttrPropdef
1309 redef fun short_comment
do
1311 if n_doc
!= null then
1312 var txt
= n_doc
.n_comment
.first
.text
1313 txt
= txt
.replace
("# ", "")
1314 txt
= txt
.replace
("\n", "")
1321 redef class AMethPropdef
1322 redef fun short_comment
do
1324 if n_doc
!= null then
1325 var txt
= n_doc
.n_comment
.first
.text
1326 txt
= txt
.replace
("# ", "")
1327 txt
= txt
.replace
("\n", "")
1333 redef fun signature
: String do
1335 if n_signature
!= null then sign
= " {n_signature.to_s}"
1339 redef private fun comment
: String do
1341 if n_doc
!= null then
1342 for t
in n_doc
.n_comment
do
1343 var txt
= t
.text
.replace
("# ", "")
1344 txt
= txt
.replace
("#", "")
1352 redef class MClassDef
1353 private fun namespace
(mclass
: MClass): String do
1355 if mmodule
.public_owner
is null then
1356 return "{mmodule.full_name}::{mclass.name}"
1357 else if mclass
is self.mclass
then
1358 return "{mmodule.public_owner.name}::{mclass.name}"
1360 return "{mmodule.public_owner.name}::<a href=\"{mclass.name}.html\
">{mclass.name}</a>"
1367 return to_a
[length-1
]
1371 # Create a tool context to handle options and paths
1372 var toolcontext
= new ToolContext
1374 # Here we launch the nit index
1375 var nitdoc
= new Nitdoc(toolcontext
)