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 mmodule
in model
.mmodules
do
124 var modulepage
= new NitdocModules.with
(mmodule
, modelbuilder
)
125 modulepage
.save
("{destinationdir.to_s}/{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 mbuilder
: ModelBuilder
474 init with
(mmodule
: MModule, mbuilder
: ModelBuilder) do
475 self.mmodule
= mmodule
476 self.mbuilder
= mbuilder
483 var amodule
= mbuilder
.mmodule2nmodule
[mmodule
]
484 add
("title").text
("{mmodule.name} module | {amodule.short_comment}")
489 open
("nav").add_class
("main")
492 add_html
("<a href=\"index
.html\
">Overview</a>")
494 add
("li").add_class
("current").text
(mmodule
.name
)
496 add_html
("<a href=\"full-index
.html\
" >Full Index</a>")
498 open
("li").attr
("id", "liGitHub")
499 open
("a").add_class
("btn").attr
("id", "logGitHub")
500 add
("img").attr
("id", "imgGitHub").attr
("src", "resources/icons/github-icon.png")
502 open
("div").add_class
("popover bottom")
503 add
("div").add_class
("arrow").text
(" ")
504 open
("div").add_class
("githubTitle")
505 add
("h3").text
("Github Sign In")
508 add
("label").attr
("id", "lbloginGit").text
("Username")
509 add
("input").attr
("id", "loginGit").attr
("name", "login").attr
("type", "text")
510 open
("label").attr
("id", "logginMessage").text
("Hello ")
511 open
("a").attr
("id", "githubAccount")
512 add
("strong").attr
("id", "nickName").text
(" ")
517 add
("label").attr
("id", "lbpasswordGit").text
("Password")
518 add
("input").attr
("id", "passwordGit").attr
("name", "password").attr
("type", "password")
519 open
("div").attr
("id", "listBranches")
520 add
("label").attr
("id", "lbBranches").text
("Branch")
521 add
("select").add_class
("dropdown").attr
("id", "dropBranches").attr
("name", "dropBranches").attr
("tabindex", "1").text
(" ")
525 add
("label").attr
("id", "lbrepositoryGit").text
("Repository")
526 add
("input").attr
("id", "repositoryGit").attr
("name", "repository").attr
("type", "text")
529 add
("label").attr
("id", "lbbranchGit").text
("Branch")
530 add
("input").attr
("id", "branchGit").attr
("name", "branch").attr
("type", "text")
533 add
("a").attr
("id", "signIn").text
("Sign In")
544 open
("div").add_class
("page")
548 add
("footer").text
("Nit standard library. Version jenkins-component=stdlib-19.")
551 # Insert all tags in content part
553 open
("div").add_class
("content")
554 add
("h1").text
(mmodule
.name
)
555 add
("div").add_class
("subtitle").text
("module {mmodule.name}")
562 # Insert module comment in the content
563 fun module_comment
do
564 var amodule
= mbuilder
.mmodule2nmodule
[mmodule
]
565 var doc
= amodule
.comment
566 open
("div").attr
("id", "description")
567 add
("pre").add_class
("text_label").text
(doc
)
568 add
("textarea").add_class
("edit").attr
("rows", "1").attr
("cols", "76").attr
("id", "fileContent").text
(" ")
569 add
("a").attr
("id", "cancelBtn").text
("Cancel")
570 add
("a").attr
("id", "commitBtn").text
("Commit")
571 add
("pre").add_class
("text_label").attr
("id", "preSave").attr
("type", "2")
576 var amodule
= mbuilder
.mmodule2nmodule
[mmodule
]
577 open
("div").add_class
("menu")
579 add
("h3").text
("Module Hierarchy").attr
("style","cursor: pointer;")
580 if mmodule
.in_importation
.greaters
.length
> 0 then
581 add_html
("<h4>All dependencies</h4><ul>")
582 var sorted
= mmodule
.in_importation
.greaters
.to_a
583 var sorter
= new ComparableSorter[MModule]
586 if m
== mmodule
or m
.public_owner
!= null then continue
588 add
("a").attr
("href", "{m.name}.html").text
(m
.name
)
593 if mmodule
.in_importation
.smallers
.length
> 0 then
594 add_html
("<h4>All clients</h4><ul>")
595 var sorted
= mmodule
.in_importation
.smallers
.to_a
596 var sorter
= new ComparableSorter[MModule]
599 if m
== mmodule
or m
.public_owner
!= null then continue
601 add
("a").attr
("href", "{m.name}.html").text
(m
.name
)
607 if mmodule
.in_nesting
.direct_greaters
.length
> 0 then
608 var sorted
= mmodule
.in_nesting
.direct_greaters
.to_a
609 var sorter
= new ComparableSorter[MModule]
612 add
("h3").text
("Nested Modules").attr
("style","cursor: pointer;")
616 add
("a").attr
("href", "{m.name}.html").text
(m
.name
)
627 var amodule
= mbuilder
.mmodule2nmodule
[mmodule
]
628 var intro_mclasses
= mmodule
.intro_mclasses
629 var redef_mclasses
= mmodule
.redef_mclasses
630 var all_mclasses
= new HashSet[MClass]
631 for m
in mmodule
.in_nesting
.greaters
do
632 all_mclasses
.add_all
(m
.intro_mclasses
)
633 all_mclasses
.add_all
(m
.redef_mclasses
)
635 all_mclasses
.add_all
(intro_mclasses
)
636 all_mclasses
.add_all
(redef_mclasses
)
638 var sorted
= new Array[MClass]
639 sorted
.add_all
(all_mclasses
)
640 var sorter
= new ComparableSorter[MClass]
642 open
("div").add_class
("module")
643 open
("article").add_class
("classes filterable")
644 add
("h2").text
("Classes")
648 if redef_mclasses
.has
(c
) and c
.intro_mmodule
.public_owner
!= mmodule
then
649 open
("li").add_class
("redef")
650 add
("span").attr
("title", "refined in this module").text
("R ")
652 open
("li").add_class
("intro")
653 add
("span").attr
("title", "introduced in this module").text
("I ")
655 add
("a").attr
("href", "{name}.html").text
(name
)
664 var amodule
= mbuilder
.mmodule2nmodule
[mmodule
]
665 var mpropdefs
= new HashSet[MPropDef]
666 for m
in mmodule
.in_nesting
.greaters
do
667 for c
in m
.mclassdefs
do mpropdefs
.add_all
(c
.mpropdefs
)
669 for c
in mmodule
.mclassdefs
do mpropdefs
.add_all
(c
.mpropdefs
)
670 var sorted
= mpropdefs
.to_a
671 var sorter
= new ComparableSorter[MPropDef]
673 open
("article").add_class
("properties filterable")
674 add_html
("<h2>Properties</h2>")
677 if p
.mproperty
.visibility
<= none_visibility
then continue
679 open
("li").add_class
("intro")
680 add
("span").attr
("title", "introduction").text
("I")
682 open
("li").add_class
("redef")
683 add
("span").attr
("title", "redefinition").text
("R")
686 add
("a").attr
("href", "{p.mclassdef.mclass.name}.html").attr
("title", "").text
("{p.mproperty.name} ({p.mclassdef.mclass.name})")
694 # Nit Standard Library
699 var aclassdef
: AClassdef
700 var stdclassdef
: nullable AStdClassdef
701 var public_owner
: nullable MModule
703 init with
(mclass
: MClass, aclassdef
: AClassdef, source
: nullable String) do
705 self.aclassdef
= aclassdef
706 if aclassdef
isa AStdClassdef then self.stdclassdef
= aclassdef
707 self.public_owner
= mclass
.intro_mmodule
.public_owner
715 add
("title").text
("{self.mclass.name} class | Nit Standard Library")
720 open
("nav").add_class
("main")
723 add_html
("<a href=\"index
.html\
">Overview</a>")
726 if public_owner
is null then
727 add_html
("<a href=\"{mclass.intro_mmodule.name}.html\
">{mclass.intro_mmodule.name}</a>")
729 add_html
("<a href=\"{public_owner.name}.html\
">{public_owner.name}</a>")
732 add
("li").add_class
("current").text
(mclass
.name
)
734 add_html
("<a href=\"full-index
.html\
" >Full Index</a>")
736 open
("li").attr
("id", "liGitHub")
737 open
("a").add_class
("btn").attr
("id", "logGitHub")
738 add
("img").attr
("id", "imgGitHub").attr
("src", "resources/icons/github-icon.png")
740 open
("div").add_class
("popover bottom")
741 add
("div").add_class
("arrow").text
(" ")
742 open
("div").add_class
("githubTitle")
743 add
("h3").text
("Github Sign In")
746 add
("label").attr
("id", "lbloginGit").text
("Username")
747 add
("input").attr
("id", "loginGit").attr
("name", "login").attr
("type", "text")
748 open
("label").attr
("id", "logginMessage").text
("Hello ")
749 open
("a").attr
("id", "githubAccount")
750 add
("strong").attr
("id", "nickName").text
(" ")
755 add
("label").attr
("id", "lbpasswordGit").text
("Password")
756 add
("input").attr
("id", "passwordGit").attr
("name", "password").attr
("type", "password")
757 open
("div").attr
("id", "listBranches")
758 add
("label").attr
("id", "lbBranches").text
("Branch")
759 add
("select").add_class
("dropdown").attr
("id", "dropBranches").attr
("name", "dropBranches").attr
("tabindex", "1").text
(" ")
763 add
("label").attr
("id", "lbrepositoryGit").text
("Repository")
764 add
("input").attr
("id", "repositoryGit").attr
("name", "repository").attr
("type", "text")
767 add
("label").attr
("id", "lbbranchGit").text
("Branch")
768 add
("input").attr
("id", "branchGit").attr
("name", "branch").attr
("type", "text")
771 add
("a").attr
("id", "signIn").text
("Sign In")
782 open
("div").add_class
("page")
785 add
("footer").text
("Nit standard library. Version jenkins-component=stdlib-19.")
788 # Insert all tags in content part
790 open
("div").add_class
("menu")
794 open
("div").add_class
("content")
799 fun properties_column
do
800 var sorted
= new Array[MProperty]
801 var sorterp
= new ComparableSorter[MProperty]
802 open
("nav").add_class
("properties filterable")
803 add
("h3").text
("Properties")
805 if mclass
.virtual_types
.length
> 0 then
806 add
("h4").text
("Virtual Types")
808 sorted
= mclass
.virtual_types
.to_a
810 for prop
in sorted
do
811 add_html
("<li class=\"redef\
"><span title=\"Redefined\
">R</span><a href=\"{prop.link_anchor}\
">{prop.name}</a></li>")
815 if mclass
.constructors
.length
> 0 then
816 sorted
= mclass
.constructors
.to_a
818 add
("h4").text
("Constructors")
820 for prop
in sorted
do
821 add_html
("<li class=\"intro\
"><span title=\"Introduced\
">I</span><a href=\"{prop.link_anchor}\
">{prop.name}</a></li>")
825 add
("h4").text
("Methods")
827 if mclass
.intro_methods
.length
> 0 then
828 sorted
= mclass
.intro_methods
.to_a
830 for prop
in sorted
do
831 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>")
834 if mclass
.inherited_methods
.length
> 0 then
835 sorted
= mclass
.inherited_methods
.to_a
837 for prop
in sorted
do
838 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>")
841 if mclass
.redef_methods
.length
> 0 then
842 sorted
= mclass
.redef_methods
.to_a
844 for prop
in sorted
do
845 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>")
852 fun inheritance_column
do
853 var sorted
= new Array[MClass]
854 var sorterp
= new ComparableSorter[MClass]
856 add
("h3").text
("Inheritance")
857 if mclass
.parents
.length
> 0 then
858 sorted
= mclass
.parents
.to_a
860 add
("h4").text
("Superclasses")
862 for sup
in sorted
do add_html
("<li><a href=\"{sup.name}.html\
">{sup.name}</a></li>")
866 if mclass
.descendants
.length
is 0 then
867 add
("h4").text
("No Known Subclasses")
868 else if mclass
.descendants
.length
<= 100 then
869 sorted
= mclass
.descendants
.to_a
871 add
("h4").text
("Subclasses")
873 for sub
in sorted
do add_html
("<li><a href=\"{sub.name}\
">{sub.name}</a></li>")
875 else if mclass
.children
.length
<= 100 then
876 sorted
= mclass
.children
.to_a
878 add
("h4").text
("Direct Subclasses Only")
880 for sub
in sorted
do add_html
("<li><a href=\"{sub.name}\
">{sub.name}</a></li>")
883 add
("h4").text
("Too much Subclasses to list")
889 var sorted
= new Array[MModule]
890 sorted
.add_all
(mclass
.concerns
.keys
)
891 var sorterp
= new ComparableSorter[MModule]
892 var sorterprop
= new ComparableSorter[MProperty]
893 var sorterc
= new ComparableSorter[MClass]
896 var lmmodule
= new List[MModule]
897 # Insert the subtitle part
898 add
("h1").text
(mclass
.name
)
899 open
("div").add_class
("subtitle")
900 if mclass
.visibility
is none_visibility
then subtitle
+= "private "
901 subtitle
+= "{mclass.kind} <a href=\"{mclass.public_owner.name}.html\
">{mclass.public_owner.name}</a>::{mclass.name}"
904 add_html
("<div style=\"float
: right
;\
"><a id=\"lblDiffCommit\
"></a></div>")
905 # We add the class description
906 open
("section").add_class
("description")
907 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>")
909 open
("section").add_class
("concerns")
910 add
("h2").add_class
("section-header").text
("Concerns")
912 for owner
in sorted
do
913 var childs
= mclass
.concerns
[owner
]
915 add_html
("<a href=\"#MOD_{owner.name}\">{owner.name}</a>: {owner.amodule.short_comment}")
916 if not childs
is null then
918 var sortedc
= childs
.to_a
919 var sorterpc
= new ComparableSorter[MModule]
920 sorterpc
.sort
(sortedc
)
921 for child
in sortedc
do
922 add_html
("<li><a href=\"#MOD_{child.name}\">{child.name}</a>: {child.amodule.short_comment} </li>")
930 # Insert virtual types if there is almost one
931 if mclass
.virtual_types
.length
> 0 or (stdclassdef
!= null and stdclassdef
.n_formaldefs
.length
> 0) then
932 open
("section").add_class
("types")
933 add
("h2").text
("Formal and Virtual Types")
934 if mclass
.virtual_types
.length
> 0 then for prop
in mclass
.virtual_types
do description
(prop
)
935 if stdclassdef
.n_formaldefs
.length
> 0 then
936 for prop
in stdclassdef
.n_formaldefs
do
937 open
("article").attr
("id", "FT_Object_{prop.collect_text}")
938 open
("h3").add_class
("signature").text
("{prop.collect_text}: nullable ")
939 add_html
("<a title=\"The root of the
class hierarchy
.\
" href=\"Object.html\
">Object</a>")
941 add_html
("<div class=\"info\
">formal generic type</div>")
947 # Insert constructors if there is almost one
948 if mclass
.constructors
.length
> 0 then
949 var sortedc
= mclass
.constructors
.to_a
950 sorterprop
.sort
(sortedc
)
951 open
("section").add_class
("constructors")
952 add
("h2").add_class
("section-header").text
("Constructors")
953 for prop
in sortedc
do description
(prop
)
956 open
("section").add_class
("methods")
957 add
("h2").add_class
("section-header").text
("Methods")
958 for mmodule
, mmethods
in mclass
.all_methods
do
959 add_html
("<a id=\"MOD_{mmodule.name}\
"></a>")
960 if mmodule
!= mclass
.intro_mmodule
and mmodule
!= mclass
.public_owner
then
961 if mclass
.has_mmodule
(mmodule
) then
962 add_html
("<p class=\"concern-doc\
">{mmodule.name}: {mmodule.amodule.short_comment}</p>")
964 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>")
967 var sortedc
= mmethods
.to_a
968 sorterprop
.sort
(sortedc
)
969 for prop
in sortedc
do description
(prop
)
971 # Insert inherited methods
972 if mclass
.inherited_methods
.length
> 0 then
973 var sortedc
= new Array[MClass]
974 sortedc
.add_all
(mclass
.inherited
.keys
)
975 sorterc
.sort
(sortedc
)
976 add
("h3").text
("Inherited Methods")
977 for i_mclass
in sortedc
do
978 var sortedp
= mclass
.inherited
[i_mclass
].to_a
979 sorterprop
.sort
(sortedp
)
981 add_html
("Defined in <a href=\"{i_mclass.name}.html\
">{i_mclass.name}</a>: ")
982 for method
in sortedp
do
983 add_html
("<a href=\"{method.link_anchor}\
">{method.name}</a>")
984 if method
!= sortedp
.last
then add_html
(", ")
992 # Insert description tags for 'prop'
993 fun description
(prop
: MProperty) do
994 open
("article").add_class
("fun public {if prop.is_redef then "redef" else ""}").attr
("id", "{prop.anchor}")
996 if prop
.apropdef
!= null then sign
+= prop
.apropdef
.signature
997 add_html
("<h3 class=\"signature\
">{sign}</h3>")
998 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>")
1000 open
("div").add_class
("description")
1001 if prop
.apropdef
is null or prop
.apropdef
.comment
== "" then
1002 add_html
("<a class=\"newComment\
" title=\"32\
" tag=\"\
">New Comment</a>")
1004 add_html
("<pre class=\"text_label\
" title=\"\
" name=\"\
" tag=\"\
" type=\"1\
">{prop.apropdef.comment}</pre>")
1006 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>")
1008 if prop
.local_class
!= mclass
then add_html
("inherited from {prop.local_class.intro_mmodule.name} ")
1009 #TODO display show code if doc github
1010 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)}.")
1012 for parent
in mclass
.parents
do
1013 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>.")
1027 var destinationdir
: String
1028 var source
: nullable String
1031 add
("meta").attr
("charset", "utf-8")
1032 add
("script").attr
("type", "text/javascript").attr
("src", "scripts/jquery-1.7.1.min.js")
1033 add
("script").attr
("type", "text/javascript").attr
("src", "quicksearch-list.js")
1034 add
("script").attr
("type", "text/javascript").attr
("src", "scripts/js-facilities.js")
1035 add
("link").attr
("rel", "stylesheet").attr
("href", "styles/main.css").attr
("type", "text/css").attr
("media", "screen")
1038 redef fun body
do header
1041 # Generate a clickable graphviz image using a dot content
1042 fun generate_dot
(dot
: String, name
: String, alt
: String) do
1043 if opt_nodot
then return
1044 var file
= new OFStream.open
("{self.destinationdir}/{name}.dot")
1047 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 ; \}")
1048 open
("article").add_class
("graph")
1049 add
("img").attr
("src", "{name}.png").attr
("usemap", "#{name}").attr
("style", "margin:auto").attr
("alt", "{alt}")
1051 var fmap
= new IFStream.open
("{self.destinationdir}/{name}.map")
1052 add_html
(fmap
.read_all
)
1056 # Add a (source) link fo a given location
1057 fun show_source
(l
: Location): String
1059 if source
== null then
1060 return "({l.file.filename.simplify_path})"
1062 # THIS IS JUST UGLY ! (but there is no replace yet)
1063 var x
= source
.split_with
("%f")
1064 source
= x
.join
(l
.file
.filename
.simplify_path
)
1065 x
= source
.split_with
("%l")
1066 source
= x
.join
(l
.line_start
.to_s
)
1067 x
= source
.split_with
("%L")
1068 source
= x
.join
(l
.line_end
.to_s
)
1069 return " (<a href=\"{source.to_s}\
">show code</a>)"
1076 private fun comment
: String do
1078 if n_moduledecl
is null or n_moduledecl
.n_doc
is null then ret
1079 if n_moduledecl
.n_doc
is null then return ""
1080 for t
in n_moduledecl
.n_doc
.n_comment
do
1082 txt
= txt
.replace
("# ", "")
1083 txt
= txt
.replace
("#", "")
1089 private fun short_comment
: String do
1091 if n_moduledecl
!= null and n_moduledecl
.n_doc
!= null then
1092 var txt
= n_moduledecl
.n_doc
.n_comment
.first
.text
1093 txt
= txt
.replace
("# ", "")
1094 txt
= txt
.replace
("\n", "")
1104 redef type OTHER: MModule
1105 redef fun <(other
: OTHER): Bool do return self.name
< other
.name
1107 var amodule
: nullable AModule
1109 # Get the list of all methods in a module
1110 fun imported_methods
: Set[MMethod] do
1111 var methods
= new HashSet[MMethod]
1112 for mclass
in imported_mclasses
do
1113 for method
in mclass
.intro_methods
do
1120 # Get the list aof all refined methods in a module
1121 fun redef_methods
: Set[MMethod] do
1122 var methods
= new HashSet[MMethod]
1123 for mclass
in redef_mclasses
do
1124 for method
in mclass
.intro_methods
do
1131 redef class MPropDef
1133 redef type OTHER: MPropDef
1134 redef fun <(other
: OTHER): Bool do return self.mproperty
.name
< other
.mproperty
.name
1137 redef class MProperty
1140 redef type OTHER: MProperty
1141 redef fun <(other
: OTHER): Bool do return self.name
< other
.name
1144 var apropdef
: nullable APropdef
1146 redef init(intro_mclassdef
: MClassDef, name
: String, visibility
: MVisibility)
1152 fun local_class
: MClass do
1153 var classdef
= self.intro_mclassdef
1154 return classdef
.mclass
1157 fun class_text
: String do
1158 return local_class
.name
1161 fun link_anchor
: String do
1162 return "{class_text}.html#{anchor}"
1165 fun anchor
: String do
1166 return "PROP_{c_name}"
1174 redef type OTHER: MClass
1175 redef fun <(other
: OTHER): Bool do return self.name
< other
.name
1177 # Associate all MMethods to each MModule concerns
1178 fun all_methods
: HashMap[MModule, Set[MMethod]] do
1179 var hm
= new HashMap[MModule, Set[MMethod]]
1180 for mmodule
, childs
in concerns
do
1181 if not hm
.has_key
(mmodule
) then hm
[mmodule
] = new HashSet[MMethod]
1182 for prop
in intro_methods
do
1183 if mmodule
== prop
.intro_mclassdef
.mmodule
then
1184 prop
.is_redef
= false
1185 hm
[mmodule
].add
(prop
)
1188 for prop
in redef_methods
do
1189 if mmodule
== prop
.intro_mclassdef
.mmodule
then
1190 prop
.is_redef
= true
1191 hm
[mmodule
].add
(prop
)
1195 if childs
!= null then
1196 for child
in childs
do
1197 if not hm
.has_key
(child
) then hm
[child
] = new HashSet[MMethod]
1198 for prop
in intro_methods
do
1199 if child
== prop
.intro_mclassdef
.mmodule
then
1200 prop
.is_redef
= false
1204 for prop
in redef_methods
do
1205 if child
== prop
.intro_mclassdef
.mmodule
then
1206 prop
.is_redef
= true
1216 fun public_owner
: MModule do
1217 var owner
= intro_mmodule
1218 if owner
.public_owner
is null then
1221 return owner
.public_owner
.as(not null)
1225 # Associate Amodule to all MModule concern by 'self'
1226 fun amodule
(amodules
: HashMap[MModule, AModule]) do
1227 for owner
, childs
in concerns
do
1228 if childs
!= null then for child
in childs
do child
.amodule
= amodules
[child
]
1229 owner
.amodule
= amodules
[owner
]
1233 # Associate MClass to all MMethod include in 'inherited_methods'
1234 fun inherited
: HashMap[MClass, Set[MMethod]] do
1235 var hm
= new HashMap[MClass, Set[MMethod]]
1236 for method
in inherited_methods
do
1237 var mclass
= method
.intro_mclassdef
.mclass
1238 if not hm
.has_key
(mclass
) then hm
[mclass
] = new HashSet[MMethod]
1239 hm
[mclass
].add
(method
)
1244 # Return true if MModule concern contain subMModule
1245 fun has_mmodule
(sub
: MModule): Bool do
1246 for mmodule
, childs
in concerns
do
1247 if childs
is null then continue
1248 if childs
.has
(sub
) then return true
1253 fun mmethod
(mprop2npropdef
: Map[MProperty, APropdef]) do
1254 for const
in constructors
do
1255 if mprop2npropdef
.has_key
(const
)then
1256 const
.apropdef
= mprop2npropdef
[const
].as(AMethPropdef)
1260 for intro
in intro_methods
do
1261 if mprop2npropdef
.has_key
(intro
)then
1262 if mprop2npropdef
[intro
] isa AMethPropdef then intro
.apropdef
= mprop2npropdef
[intro
].as(AMethPropdef)
1266 for rd
in redef_methods
do
1267 if mprop2npropdef
.has_key
(rd
)then
1268 if mprop2npropdef
[rd
] isa AMethPropdef then rd
.apropdef
= mprop2npropdef
[rd
].as(AMethPropdef)
1273 fun link_anchor
: String do
1274 return "{name}.html"
1279 redef class AStdClassdef
1280 private fun comment
: String do
1282 if n_doc
!= null then
1283 for t
in n_doc
.n_comment
do
1284 var txt
= t
.text
.replace
("# ", "")
1285 txt
= txt
.replace
("#", "")
1292 private fun short_comment
: String do
1294 if n_doc
!= null then
1295 var txt
= n_doc
.n_comment
.first
.text
1296 txt
= txt
.replace
("# ", "")
1297 txt
= txt
.replace
("\n", "")
1304 redef class ASignature
1308 if not n_params
.is_empty
then
1309 ret
= "{ret}({n_params.join(", ")})"
1311 if n_type
!= null and n_type
.to_s
!= "" then ret
+= " {n_type.to_s}"
1318 var ret
= "{n_id.text}"
1319 if n_type
!= null then
1320 ret
= "{ret}: {n_type.to_s}"
1321 if n_dotdotdot
!= null then ret
= "{ret}..."
1329 var ret
= "<a href=\"{n_id.text}.html\
">{n_id.text}</a>"
1330 if n_kwnullable
!= null then ret
= "nullable {ret}"
1331 if not n_types
.is_empty
then ret
= "{ret}[{n_types.join(", ")}]"
1336 redef class APropdef
1337 private fun short_comment
: String is abstract
1338 private fun signature
: String is abstract
1339 private fun comment
: String is abstract
1342 redef class AAttrPropdef
1343 redef fun short_comment
do
1345 if n_doc
!= null then
1346 var txt
= n_doc
.n_comment
.first
.text
1347 txt
= txt
.replace
("# ", "")
1348 txt
= txt
.replace
("\n", "")
1355 redef class AMethPropdef
1356 redef fun short_comment
do
1358 if n_doc
!= null then
1359 var txt
= n_doc
.n_comment
.first
.text
1360 txt
= txt
.replace
("# ", "")
1361 txt
= txt
.replace
("\n", "")
1367 redef fun signature
: String do
1369 if n_signature
!= null then sign
= " {n_signature.to_s}"
1373 redef private fun comment
: String do
1375 if n_doc
!= null then
1376 for t
in n_doc
.n_comment
do
1377 var txt
= t
.text
.replace
("# ", "")
1378 txt
= txt
.replace
("#", "")
1386 redef class MClassDef
1387 private fun namespace
(mclass
: MClass): String do
1389 if mmodule
.public_owner
is null then
1390 return "{mmodule.full_name}::{mclass.name}"
1391 else if mclass
is self.mclass
then
1392 return "{mmodule.public_owner.name}::{mclass.name}"
1394 return "{mmodule.public_owner.name}::<a href=\"{mclass.name}.html\
">{mclass.name}</a>"
1401 return to_a
[length-1
]
1405 # Create a tool context to handle options and paths
1406 var toolcontext
= new ToolContext
1408 # Here we launch the nit index
1409 var nitdoc
= new Nitdoc(toolcontext
)