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
, 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 mbuilder
: ModelBuilder
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
(mbuilder
: ModelBuilder, opt_nodot
: Bool, destination
: String) do
182 self.mbuilder
= mbuilder
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 mmodules
= list_mmodules
266 var sorted
= new Array[MModule].from
(mmodules
)
267 var sorter
= new ComparableSorter[MModule]
269 for mmodule
in sorted
do
270 var amodule
= mbuilder
.mmodule2nmodule
[mmodule
]
272 add
("a").attr
("href", "{mmodule.name}.html").text
("{mmodule.to_s} ")
273 add_html
(amodule
.short_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 mmodule
in list_mmodules
do
282 op
.append
("\"{mmodule.name}\
"[URL=\"{mmodule.name}.html\
"];\n")
283 for imported
in mmodule
.in_importation
.direct_greaters
do
284 if imported
.direct_owner
== null then
285 op
.append
("\"{mmodule.name}\
"->\"{imported.name}\
";\n")
290 generate_dot
(op
.to_s
, "dep", "Modules hierarchy")
293 private fun list_mmodules
: Set[MModule] do
294 var mmodules
= new HashSet[MModule]
295 for mmodule
in mbuilder
.model
.mmodules
do
296 var owner
= mmodule
.public_owner
297 if owner
!= null then
300 mmodules
.add
(mmodule
)
308 class NitdocFullindex
311 var mmodules
: Array[MModule]
313 init with
(mmodules
: Array[MModule]) do
314 self.mmodules
= mmodules
321 add
("title").text
("Full Index | Nit Standard Library")
326 open
("nav").add_class
("main")
329 add_html
("<a href=\"index
.html\
">Overview</a>")
331 add
("li").add_class
("current").text
("Full Index")
332 open
("li").attr
("id", "liGitHub")
333 open
("a").add_class
("btn").attr
("id", "logGitHub")
334 add
("img").attr
("id", "imgGitHub").attr
("src", "resources/icons/github-icon.png")
336 open
("div").add_class
("popover bottom")
337 add
("div").add_class
("arrow").text
(" ")
338 open
("div").add_class
("githubTitle")
339 add
("h3").text
("Github Sign In")
342 add
("label").attr
("id", "lbloginGit").text
("Username")
343 add
("input").attr
("id", "loginGit").attr
("name", "login").attr
("type", "text")
344 open
("label").attr
("id", "logginMessage").text
("Hello ")
345 open
("a").attr
("id", "githubAccount")
346 add
("strong").attr
("id", "nickName").text
(" ")
351 add
("label").attr
("id", "lbpasswordGit").text
("Password")
352 add
("input").attr
("id", "passwordGit").attr
("name", "password").attr
("type", "password")
353 open
("div").attr
("id", "listBranches")
354 add
("label").attr
("id", "lbBranches").text
("Branch")
355 add
("select").add_class
("dropdown").attr
("id", "dropBranches").attr
("name", "dropBranches").attr
("tabindex", "1").text
(" ")
359 add
("label").attr
("id", "lbrepositoryGit").text
("Repository")
360 add
("input").attr
("id", "repositoryGit").attr
("name", "repository").attr
("type", "text")
363 add
("label").attr
("id", "lbbranchGit").text
("Branch")
364 add
("input").attr
("id", "branchGit").attr
("name", "branch").attr
("type", "text")
367 add
("a").attr
("id", "signIn").text
("Sign In")
378 open
("div").add_class
("page")
379 open
("div").add_class
("content fullpage")
380 add
("h1").text
("Full Index")
384 add
("footer").text
("Nit standard library. Version jenkins-component=stdlib-19.")
393 # Add to content modules column
395 var ls
= new List[nullable MModule]
396 var sorted
= mmodules
397 var sorterp
= new ComparableSorter[MModule]
399 open
("article").add_class
("modules filterable")
400 add
("h2").text
("Modules")
402 for mmodule
in sorted
do
403 if mmodule
.public_owner
!= null and not ls
.has
(mmodule
.public_owner
) then
404 ls
.add
(mmodule
.public_owner
)
406 add
("a").attr
("href", "{mmodule.public_owner.name}.html").text
(mmodule
.public_owner
.name
)
414 # Add to content classes modules
415 fun classes_column
do
416 var sorted
= mmodules
.first
.imported_mclasses
.to_a
417 var sorterp
= new ComparableSorter[MClass]
419 open
("article").add_class
("classes filterable")
420 add
("h2").text
("Classes")
423 for mclass
in sorted
do
425 add
("a").attr
("href", "{mclass.name}.html").text
(mclass
.name
)
433 # Insert the properties column of fullindex page
434 fun properties_column
do
435 open
("article").add_class
("properties filterable")
436 add
("h2").text
("Properties")
438 var sorted_imported
= mmodules
.first
.imported_methods
.to_a
439 var sorted_redef
= mmodules
.first
.redef_methods
.to_a
440 var sorterp
= new ComparableSorter[MProperty]
441 sorterp
.sort
(sorted_imported
)
442 sorterp
.sort
(sorted_redef
)
444 for method
in sorted_imported
do
445 if method
.visibility
is none_visibility
or method
.visibility
is intrude_visibility
then continue
446 open
("li").add_class
("intro")
447 add
("span").attr
("title", "introduction").text
("I")
449 add
("a").attr
("href", "{method.local_class.name}.html").attr
("title", "").text
("{method.name} ({method.local_class.name})")
453 for method
in sorted_redef
do
454 if method
.visibility
is none_visibility
or method
.visibility
is intrude_visibility
then continue
455 open
("li").add_class
("redef")
456 add
("span").attr
("title", "redefinition").text
("R")
458 add
("a").attr
("href", "{method.local_class.name}.html").attr
("title", "").text
("{method.name} ({method.local_class.name})")
472 var modulename
: String
473 init with
(amodule
: AModule) do
474 self.amodule
= amodule
475 self.modulename
= self.amodule
.mmodule
.name
482 add
("title").text
("{modulename} module | {amodule.short_comment}")
487 open
("nav").add_class
("main")
490 add_html
("<a href=\"index
.html\
">Overview</a>")
492 add
("li").add_class
("current").text
(modulename
)
494 add_html
("<a href=\"full-index
.html\
" >Full Index</a>")
496 open
("li").attr
("id", "liGitHub")
497 open
("a").add_class
("btn").attr
("id", "logGitHub")
498 add
("img").attr
("id", "imgGitHub").attr
("src", "resources/icons/github-icon.png")
500 open
("div").add_class
("popover bottom")
501 add
("div").add_class
("arrow").text
(" ")
502 open
("div").add_class
("githubTitle")
503 add
("h3").text
("Github Sign In")
506 add
("label").attr
("id", "lbloginGit").text
("Username")
507 add
("input").attr
("id", "loginGit").attr
("name", "login").attr
("type", "text")
508 open
("label").attr
("id", "logginMessage").text
("Hello ")
509 open
("a").attr
("id", "githubAccount")
510 add
("strong").attr
("id", "nickName").text
(" ")
515 add
("label").attr
("id", "lbpasswordGit").text
("Password")
516 add
("input").attr
("id", "passwordGit").attr
("name", "password").attr
("type", "password")
517 open
("div").attr
("id", "listBranches")
518 add
("label").attr
("id", "lbBranches").text
("Branch")
519 add
("select").add_class
("dropdown").attr
("id", "dropBranches").attr
("name", "dropBranches").attr
("tabindex", "1").text
(" ")
523 add
("label").attr
("id", "lbrepositoryGit").text
("Repository")
524 add
("input").attr
("id", "repositoryGit").attr
("name", "repository").attr
("type", "text")
527 add
("label").attr
("id", "lbbranchGit").text
("Branch")
528 add
("input").attr
("id", "branchGit").attr
("name", "branch").attr
("type", "text")
531 add
("a").attr
("id", "signIn").text
("Sign In")
542 open
("div").add_class
("page")
546 add
("footer").text
("Nit standard library. Version jenkins-component=stdlib-19.")
549 # Insert all tags in content part
551 open
("div").add_class
("content")
552 add
("h1").text
(modulename
)
553 add
("div").add_class
("subtitle").text
("module {modulename}")
560 # Insert module comment in the content
561 fun module_comment
do
562 var doc
= amodule
.comment
563 open
("div").attr
("id", "description")
564 add
("pre").add_class
("text_label").text
(doc
)
565 add
("textarea").add_class
("edit").attr
("rows", "1").attr
("cols", "76").attr
("id", "fileContent").text
(" ")
566 add
("a").attr
("id", "cancelBtn").text
("Cancel")
567 add
("a").attr
("id", "commitBtn").text
("Commit")
568 add
("pre").add_class
("text_label").attr
("id", "preSave").attr
("type", "2")
573 var mmodule
= amodule
.mmodule
574 open
("div").add_class
("menu")
576 add
("h3").text
("Module Hierarchy").attr
("style","cursor: pointer;")
577 if mmodule
.in_importation
.direct_greaters
.length
> 0 then
578 add_html
("<h4>All dependencies</h4><ul>")
579 var sorted
= mmodule
.in_importation
.direct_greaters
.to_a
580 var sorterp
= new ComparableSorter[MModule]
583 if m
== mmodule
or mmodule
== m
.public_owner
then continue
585 add
("a").attr
("href", "{m.name}.html").text
(m
.name
)
590 if mmodule
.in_importation
.greaters
.length
> 0 then
591 add_html
("<h4>All clients</h4><ul>")
592 var sorted
= mmodule
.in_importation
.greaters
.to_a
593 var sorterp
= new ComparableSorter[MModule]
596 if m
== mmodule
then continue
598 add
("a").attr
("href", "{m.name}.html").text
(m
.name
)
604 if mmodule
.in_nesting
.direct_greaters
.length
> 0 then
605 var sorted
= mmodule
.in_nesting
.direct_greaters
.to_a
606 var sorterp
= new ComparableSorter[MModule]
609 add
("h3").text
("Nested Modules").attr
("style","cursor: pointer;")
613 add
("a").attr
("href", "{m.name}.html").text
(m
.name
)
624 var sorted
= new Array[MClass]
625 sorted
.add_all
(amodule
.mmodule
.mclasses
.keys
)
626 var sorterp
= new ComparableSorter[MClass]
628 open
("div").add_class
("module")
629 open
("article").add_class
("classes filterable")
630 add
("h2").text
("Classes")
633 var state
= amodule
.mmodule
.mclasses
[c
]
635 if state
== c_is_intro
or state
== c_is_imported
then
636 open
("li").add_class
("intro")
637 add
("span").attr
("title", "introduced in this module").text
("I ")
639 open
("li").add_class
("redef")
640 add
("span").attr
("title", "refined in this module").text
("R ")
642 add
("a").attr
("href", "{name}.html").text
(name
)
651 var sorted_imported
= amodule
.mmodule
.imported_methods
.to_a
652 var sorted_redef
= amodule
.mmodule
.redef_methods
.to_a
653 var sorterp
= new ComparableSorter[MProperty]
654 sorterp
.sort
(sorted_imported
)
655 sorterp
.sort
(sorted_redef
)
656 open
("article").add_class
("properties filterable")
657 add_html
("<h2>Properties</h2>")
659 for method
in sorted_imported
do
660 if method
.visibility
is none_visibility
or method
.visibility
is intrude_visibility
then continue
661 open
("li").add_class
("intro")
662 add
("span").attr
("title", "introduction").text
("I")
664 add
("a").attr
("href", "{method.local_class.name}.html").attr
("title", "").text
("{method.name} ({method.local_class.name})")
668 for method
in sorted_redef
do
669 if method
.visibility
is none_visibility
or method
.visibility
is intrude_visibility
then continue
670 open
("li").add_class
("redef")
671 add
("span").attr
("title", "redefinition").text
("R")
673 add
("a").attr
("href", "{method.local_class.name}.html").attr
("title", "").text
("{method.name} ({method.local_class.name})")
683 # Nit Standard Library
688 var aclassdef
: AClassdef
689 var stdclassdef
: nullable AStdClassdef
690 var public_owner
: nullable MModule
692 init with
(mclass
: MClass, aclassdef
: AClassdef, source
: nullable String) do
694 self.aclassdef
= aclassdef
695 if aclassdef
isa AStdClassdef then self.stdclassdef
= aclassdef
696 self.public_owner
= mclass
.intro_mmodule
.public_owner
704 add
("title").text
("{self.mclass.name} class | Nit Standard Library")
709 open
("nav").add_class
("main")
712 add_html
("<a href=\"index
.html\
">Overview</a>")
715 if public_owner
is null then
716 add_html
("<a href=\"{mclass.intro_mmodule.name}.html\
">{mclass.intro_mmodule.name}</a>")
718 add_html
("<a href=\"{public_owner.name}.html\
">{public_owner.name}</a>")
721 add
("li").add_class
("current").text
(mclass
.name
)
723 add_html
("<a href=\"full-index
.html\
" >Full Index</a>")
725 open
("li").attr
("id", "liGitHub")
726 open
("a").add_class
("btn").attr
("id", "logGitHub")
727 add
("img").attr
("id", "imgGitHub").attr
("src", "resources/icons/github-icon.png")
729 open
("div").add_class
("popover bottom")
730 add
("div").add_class
("arrow").text
(" ")
731 open
("div").add_class
("githubTitle")
732 add
("h3").text
("Github Sign In")
735 add
("label").attr
("id", "lbloginGit").text
("Username")
736 add
("input").attr
("id", "loginGit").attr
("name", "login").attr
("type", "text")
737 open
("label").attr
("id", "logginMessage").text
("Hello ")
738 open
("a").attr
("id", "githubAccount")
739 add
("strong").attr
("id", "nickName").text
(" ")
744 add
("label").attr
("id", "lbpasswordGit").text
("Password")
745 add
("input").attr
("id", "passwordGit").attr
("name", "password").attr
("type", "password")
746 open
("div").attr
("id", "listBranches")
747 add
("label").attr
("id", "lbBranches").text
("Branch")
748 add
("select").add_class
("dropdown").attr
("id", "dropBranches").attr
("name", "dropBranches").attr
("tabindex", "1").text
(" ")
752 add
("label").attr
("id", "lbrepositoryGit").text
("Repository")
753 add
("input").attr
("id", "repositoryGit").attr
("name", "repository").attr
("type", "text")
756 add
("label").attr
("id", "lbbranchGit").text
("Branch")
757 add
("input").attr
("id", "branchGit").attr
("name", "branch").attr
("type", "text")
760 add
("a").attr
("id", "signIn").text
("Sign In")
771 open
("div").add_class
("page")
774 add
("footer").text
("Nit standard library. Version jenkins-component=stdlib-19.")
777 # Insert all tags in content part
779 open
("div").add_class
("menu")
783 open
("div").add_class
("content")
788 fun properties_column
do
789 var sorted
= new Array[MProperty]
790 var sorterp
= new ComparableSorter[MProperty]
791 open
("nav").add_class
("properties filterable")
792 add
("h3").text
("Properties")
794 if mclass
.virtual_types
.length
> 0 then
795 add
("h4").text
("Virtual Types")
797 sorted
= mclass
.virtual_types
.to_a
799 for prop
in sorted
do
800 add_html
("<li class=\"redef\
"><span title=\"Redefined\
">R</span><a href=\"{prop.link_anchor}\
">{prop.name}</a></li>")
804 if mclass
.constructors
.length
> 0 then
805 sorted
= mclass
.constructors
.to_a
807 add
("h4").text
("Constructors")
809 for prop
in sorted
do
810 add_html
("<li class=\"intro\
"><span title=\"Introduced\
">I</span><a href=\"{prop.link_anchor}\
">{prop.name}</a></li>")
814 add
("h4").text
("Methods")
816 if mclass
.intro_methods
.length
> 0 then
817 sorted
= mclass
.intro_methods
.to_a
819 for prop
in sorted
do
820 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>")
823 if mclass
.inherited_methods
.length
> 0 then
824 sorted
= mclass
.inherited_methods
.to_a
826 for prop
in sorted
do
827 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>")
830 if mclass
.redef_methods
.length
> 0 then
831 sorted
= mclass
.redef_methods
.to_a
833 for prop
in sorted
do
834 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>")
841 fun inheritance_column
do
842 var sorted
= new Array[MClass]
843 var sorterp
= new ComparableSorter[MClass]
845 add
("h3").text
("Inheritance")
846 if mclass
.parents
.length
> 0 then
847 sorted
= mclass
.parents
.to_a
849 add
("h4").text
("Superclasses")
851 for sup
in sorted
do add_html
("<li><a href=\"{sup.name}.html\
">{sup.name}</a></li>")
855 if mclass
.descendants
.length
is 0 then
856 add
("h4").text
("No Known Subclasses")
857 else if mclass
.descendants
.length
<= 100 then
858 sorted
= mclass
.descendants
.to_a
860 add
("h4").text
("Subclasses")
862 for sub
in sorted
do add_html
("<li><a href=\"{sub.name}\
">{sub.name}</a></li>")
864 else if mclass
.children
.length
<= 100 then
865 sorted
= mclass
.children
.to_a
867 add
("h4").text
("Direct Subclasses Only")
869 for sub
in sorted
do add_html
("<li><a href=\"{sub.name}\
">{sub.name}</a></li>")
872 add
("h4").text
("Too much Subclasses to list")
878 var sorted
= new Array[MModule]
879 sorted
.add_all
(mclass
.concerns
.keys
)
880 var sorterp
= new ComparableSorter[MModule]
881 var sorterprop
= new ComparableSorter[MProperty]
882 var sorterc
= new ComparableSorter[MClass]
885 var lmmodule
= new List[MModule]
886 # Insert the subtitle part
887 add
("h1").text
(mclass
.name
)
888 open
("div").add_class
("subtitle")
889 if mclass
.visibility
is none_visibility
then subtitle
+= "private "
890 subtitle
+= "{mclass.kind} <a href=\"{mclass.public_owner.name}.html\
">{mclass.public_owner.name}</a>::{mclass.name}"
893 add_html
("<div style=\"float
: right
;\
"><a id=\"lblDiffCommit\
"></a></div>")
894 # We add the class description
895 open
("section").add_class
("description")
896 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>")
898 open
("section").add_class
("concerns")
899 add
("h2").add_class
("section-header").text
("Concerns")
901 for owner
in sorted
do
902 var childs
= mclass
.concerns
[owner
]
904 add_html
("<a href=\"#MOD_{owner.name}\">{owner.name}</a>: {owner.amodule.short_comment}")
905 if not childs
is null then
907 var sortedc
= childs
.to_a
908 var sorterpc
= new ComparableSorter[MModule]
909 sorterpc
.sort
(sortedc
)
910 for child
in sortedc
do
911 add_html
("<li><a href=\"#MOD_{child.name}\">{child.name}</a>: {child.amodule.short_comment} </li>")
919 # Insert virtual types if there is almost one
920 if mclass
.virtual_types
.length
> 0 or (stdclassdef
!= null and stdclassdef
.n_formaldefs
.length
> 0) then
921 open
("section").add_class
("types")
922 add
("h2").text
("Formal and Virtual Types")
923 if mclass
.virtual_types
.length
> 0 then for prop
in mclass
.virtual_types
do description
(prop
)
924 if stdclassdef
.n_formaldefs
.length
> 0 then
925 for prop
in stdclassdef
.n_formaldefs
do
926 open
("article").attr
("id", "FT_Object_{prop.collect_text}")
927 open
("h3").add_class
("signature").text
("{prop.collect_text}: nullable ")
928 add_html
("<a title=\"The root of the
class hierarchy
.\
" href=\"Object.html\
">Object</a>")
930 add_html
("<div class=\"info\
">formal generic type</div>")
936 # Insert constructors if there is almost one
937 if mclass
.constructors
.length
> 0 then
938 var sortedc
= mclass
.constructors
.to_a
939 sorterprop
.sort
(sortedc
)
940 open
("section").add_class
("constructors")
941 add
("h2").add_class
("section-header").text
("Constructors")
942 for prop
in sortedc
do description
(prop
)
945 open
("section").add_class
("methods")
946 add
("h2").add_class
("section-header").text
("Methods")
947 for mmodule
, mmethods
in mclass
.all_methods
do
948 add_html
("<a id=\"MOD_{mmodule.name}\
"></a>")
949 if mmodule
!= mclass
.intro_mmodule
and mmodule
!= mclass
.public_owner
then
950 if mclass
.has_mmodule
(mmodule
) then
951 add_html
("<p class=\"concern-doc\
">{mmodule.name}: {mmodule.amodule.short_comment}</p>")
953 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>")
956 var sortedc
= mmethods
.to_a
957 sorterprop
.sort
(sortedc
)
958 for prop
in sortedc
do description
(prop
)
960 # Insert inherited methods
961 if mclass
.inherited_methods
.length
> 0 then
962 var sortedc
= new Array[MClass]
963 sortedc
.add_all
(mclass
.inherited
.keys
)
964 sorterc
.sort
(sortedc
)
965 add
("h3").text
("Inherited Methods")
966 for i_mclass
in sortedc
do
967 var sortedp
= mclass
.inherited
[i_mclass
].to_a
968 sorterprop
.sort
(sortedp
)
970 add_html
("Defined in <a href=\"{i_mclass.name}.html\
">{i_mclass.name}</a>: ")
971 for method
in sortedp
do
972 add_html
("<a href=\"{method.link_anchor}\
">{method.name}</a>")
973 if method
!= sortedp
.last
then add_html
(", ")
981 # Insert description tags for 'prop'
982 fun description
(prop
: MProperty) do
983 open
("article").add_class
("fun public {if prop.is_redef then "redef" else ""}").attr
("id", "{prop.anchor}")
985 if prop
.apropdef
!= null then sign
+= prop
.apropdef
.signature
986 add_html
("<h3 class=\"signature\
">{sign}</h3>")
987 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>")
989 open
("div").add_class
("description")
990 if prop
.apropdef
is null or prop
.apropdef
.comment
== "" then
991 add_html
("<a class=\"newComment\
" title=\"32\
" tag=\"\
">New Comment</a>")
993 add_html
("<pre class=\"text_label\
" title=\"\
" name=\"\
" tag=\"\
" type=\"1\
">{prop.apropdef.comment}</pre>")
995 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>")
997 if prop
.local_class
!= mclass
then add_html
("inherited from {prop.local_class.intro_mmodule.name} ")
998 #TODO display show code if doc github
999 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)}.")
1001 for parent
in mclass
.parents
do
1002 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>.")
1016 var destinationdir
: String
1017 var source
: nullable String
1020 add
("meta").attr
("charset", "utf-8")
1021 add
("script").attr
("type", "text/javascript").attr
("src", "scripts/jquery-1.7.1.min.js")
1022 add
("script").attr
("type", "text/javascript").attr
("src", "quicksearch-list.js")
1023 add
("script").attr
("type", "text/javascript").attr
("src", "scripts/js-facilities.js")
1024 add
("link").attr
("rel", "stylesheet").attr
("href", "styles/main.css").attr
("type", "text/css").attr
("media", "screen")
1027 redef fun body
do header
1030 # Generate a clickable graphviz image using a dot content
1031 fun generate_dot
(dot
: String, name
: String, alt
: String) do
1032 if opt_nodot
then return
1033 var file
= new OFStream.open
("{self.destinationdir}/{name}.dot")
1036 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 ; \}")
1037 open
("article").add_class
("graph")
1038 add
("img").attr
("src", "{name}.png").attr
("usemap", "#{name}").attr
("style", "margin:auto").attr
("alt", "{alt}")
1040 var fmap
= new IFStream.open
("{self.destinationdir}/{name}.map")
1041 add_html
(fmap
.read_all
)
1045 # Add a (source) link fo a given location
1046 fun show_source
(l
: Location): String
1048 if source
== null then
1049 return "({l.file.filename.simplify_path})"
1051 # THIS IS JUST UGLY ! (but there is no replace yet)
1052 var x
= source
.split_with
("%f")
1053 source
= x
.join
(l
.file
.filename
.simplify_path
)
1054 x
= source
.split_with
("%l")
1055 source
= x
.join
(l
.line_start
.to_s
)
1056 x
= source
.split_with
("%L")
1057 source
= x
.join
(l
.line_end
.to_s
)
1058 return " (<a href=\"{source.to_s}\
">show code</a>)"
1065 private fun comment
: String do
1067 if n_moduledecl
is null or n_moduledecl
.n_doc
is null then ret
1068 if n_moduledecl
.n_doc
is null then return ""
1069 for t
in n_moduledecl
.n_doc
.n_comment
do
1070 ret
+= "{t.text.replace("# ", "")}"
1075 private fun short_comment
: String do
1077 if n_moduledecl
!= null and n_moduledecl
.n_doc
!= null then
1078 var txt
= n_moduledecl
.n_doc
.n_comment
.first
.text
1079 txt
= txt
.replace
("# ", "")
1080 txt
= txt
.replace
("\n", "")
1090 redef type OTHER: MModule
1091 redef fun <(other
: OTHER): Bool do return self.name
< other
.name
1093 var amodule
: nullable AModule
1095 # Get the list of all methods in a module
1096 fun imported_methods
: Set[MMethod] do
1097 var methods
= new HashSet[MMethod]
1098 for mclass
in imported_mclasses
do
1099 for method
in mclass
.intro_methods
do
1106 # Get the list aof all refined methods in a module
1107 fun redef_methods
: Set[MMethod] do
1108 var methods
= new HashSet[MMethod]
1109 for mclass
in redef_mclasses
do
1110 for method
in mclass
.intro_methods
do
1118 redef class MProperty
1121 redef type OTHER: MProperty
1122 redef fun <(other
: OTHER): Bool do return self.name
< other
.name
1125 var apropdef
: nullable APropdef
1127 redef init(intro_mclassdef
: MClassDef, name
: String, visibility
: MVisibility)
1133 fun local_class
: MClass do
1134 var classdef
= self.intro_mclassdef
1135 return classdef
.mclass
1138 fun class_text
: String do
1139 return local_class
.name
1142 fun link_anchor
: String do
1143 return "{class_text}.html#{anchor}"
1146 fun anchor
: String do
1147 return "PROP_{c_name}"
1155 redef type OTHER: MClass
1156 redef fun <(other
: OTHER): Bool do return self.name
< other
.name
1158 # Associate all MMethods to each MModule concerns
1159 fun all_methods
: HashMap[MModule, Set[MMethod]] do
1160 var hm
= new HashMap[MModule, Set[MMethod]]
1161 for mmodule
, childs
in concerns
do
1162 if not hm
.has_key
(mmodule
) then hm
[mmodule
] = new HashSet[MMethod]
1163 for prop
in intro_methods
do
1164 if mmodule
== prop
.intro_mclassdef
.mmodule
then
1165 prop
.is_redef
= false
1166 hm
[mmodule
].add
(prop
)
1169 for prop
in redef_methods
do
1170 if mmodule
== prop
.intro_mclassdef
.mmodule
then
1171 prop
.is_redef
= true
1172 hm
[mmodule
].add
(prop
)
1176 if childs
!= null then
1177 for child
in childs
do
1178 if not hm
.has_key
(child
) then hm
[child
] = new HashSet[MMethod]
1179 for prop
in intro_methods
do
1180 if child
== prop
.intro_mclassdef
.mmodule
then
1181 prop
.is_redef
= false
1185 for prop
in redef_methods
do
1186 if child
== prop
.intro_mclassdef
.mmodule
then
1187 prop
.is_redef
= true
1197 fun public_owner
: MModule do
1198 var owner
= intro_mmodule
1199 if owner
.public_owner
is null then
1202 return owner
.public_owner
.as(not null)
1206 # Associate Amodule to all MModule concern by 'self'
1207 fun amodule
(amodules
: HashMap[MModule, AModule]) do
1208 for owner
, childs
in concerns
do
1209 if childs
!= null then for child
in childs
do child
.amodule
= amodules
[child
]
1210 owner
.amodule
= amodules
[owner
]
1214 # Associate MClass to all MMethod include in 'inherited_methods'
1215 fun inherited
: HashMap[MClass, Set[MMethod]] do
1216 var hm
= new HashMap[MClass, Set[MMethod]]
1217 for method
in inherited_methods
do
1218 var mclass
= method
.intro_mclassdef
.mclass
1219 if not hm
.has_key
(mclass
) then hm
[mclass
] = new HashSet[MMethod]
1220 hm
[mclass
].add
(method
)
1225 # Return true if MModule concern contain subMModule
1226 fun has_mmodule
(sub
: MModule): Bool do
1227 for mmodule
, childs
in concerns
do
1228 if childs
is null then continue
1229 if childs
.has
(sub
) then return true
1234 fun mmethod
(mprop2npropdef
: Map[MProperty, APropdef]) do
1235 for const
in constructors
do
1236 if mprop2npropdef
.has_key
(const
)then
1237 const
.apropdef
= mprop2npropdef
[const
].as(AMethPropdef)
1241 for intro
in intro_methods
do
1242 if mprop2npropdef
.has_key
(intro
)then
1243 if mprop2npropdef
[intro
] isa AMethPropdef then intro
.apropdef
= mprop2npropdef
[intro
].as(AMethPropdef)
1247 for rd
in redef_methods
do
1248 if mprop2npropdef
.has_key
(rd
)then
1249 if mprop2npropdef
[rd
] isa AMethPropdef then rd
.apropdef
= mprop2npropdef
[rd
].as(AMethPropdef)
1254 fun link_anchor
: String do
1255 return "{name}.html"
1260 redef class AStdClassdef
1261 private fun comment
: String do
1263 if n_doc
!= null then
1264 for t
in n_doc
.n_comment
do
1265 var txt
= t
.text
.replace
("# ", "")
1266 txt
= txt
.replace
("#", "")
1273 private fun short_comment
: String do
1275 if n_doc
!= null then
1276 var txt
= n_doc
.n_comment
.first
.text
1277 txt
= txt
.replace
("# ", "")
1278 txt
= txt
.replace
("\n", "")
1285 redef class ASignature
1289 if not n_params
.is_empty
then
1290 ret
= "{ret}({n_params.join(", ")})"
1292 if n_type
!= null and n_type
.to_s
!= "" then ret
+= " {n_type.to_s}"
1299 var ret
= "{n_id.text}"
1300 if n_type
!= null then
1301 ret
= "{ret}: {n_type.to_s}"
1302 if n_dotdotdot
!= null then ret
= "{ret}..."
1310 var ret
= "<a href=\"{n_id.text}.html\
">{n_id.text}</a>"
1311 if n_kwnullable
!= null then ret
= "nullable {ret}"
1312 if not n_types
.is_empty
then ret
= "{ret}[{n_types.join(", ")}]"
1317 redef class APropdef
1318 private fun short_comment
: String is abstract
1319 private fun signature
: String is abstract
1320 private fun comment
: String is abstract
1323 redef class AAttrPropdef
1324 redef fun short_comment
do
1326 if n_doc
!= null then
1327 var txt
= n_doc
.n_comment
.first
.text
1328 txt
= txt
.replace
("# ", "")
1329 txt
= txt
.replace
("\n", "")
1336 redef class AMethPropdef
1337 redef fun short_comment
do
1339 if n_doc
!= null then
1340 var txt
= n_doc
.n_comment
.first
.text
1341 txt
= txt
.replace
("# ", "")
1342 txt
= txt
.replace
("\n", "")
1348 redef fun signature
: String do
1350 if n_signature
!= null then sign
= " {n_signature.to_s}"
1354 redef private fun comment
: String do
1356 if n_doc
!= null then
1357 for t
in n_doc
.n_comment
do
1358 var txt
= t
.text
.replace
("# ", "")
1359 txt
= txt
.replace
("#", "")
1367 redef class MClassDef
1368 private fun namespace
(mclass
: MClass): String do
1370 if mmodule
.public_owner
is null then
1371 return "{mmodule.full_name}::{mclass.name}"
1372 else if mclass
is self.mclass
then
1373 return "{mmodule.public_owner.name}::{mclass.name}"
1375 return "{mmodule.public_owner.name}::<a href=\"{mclass.name}.html\
">{mclass.name}</a>"
1382 return to_a
[length-1
]
1386 # Create a tool context to handle options and paths
1387 var toolcontext
= new ToolContext
1389 # Here we launch the nit index
1390 var nitdoc
= new Nitdoc(toolcontext
)