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 mclass
in modelbuilder
.model
.mclasses
do
131 var classpage
= new NitdocMClasses.with
(mclass
, modelbuilder
, source
)
132 classpage
.save
("{destinationdir.to_s}/{mclass.name}.html")
136 # Generate QuickSearch file
137 fun quicksearch_list
do
138 var file
= new OFStream.open
("{destinationdir.to_s}/quicksearch-list.js")
139 var content
= new Buffer
140 content
.append
("var entries = \{ ")
141 for prop
in model
.mproperties
do
142 if not prop
isa MMethod then continue
143 content
.append
("\"{prop.name}\
": [")
144 for propdef
in prop
.mpropdefs
do
145 content
.append
("\{txt: \"{propdef.mproperty.full_name}\", url
:\
"{propdef.mproperty.link_anchor}\" \
}")
146 if not propdef is prop.mpropdefs.last then content.append(", ")
152 for mclass in model.mclasses do
153 content.append("\
"{mclass.name}\": [")
154 for mclassdef in mclass.mclassdefs do
155 content.append("\
{txt: \"{mclassdef.mclass.full_name}\
", url:\"{mclass.link_anchor}\
" \}")
156 if not mclassdef
is mclass
.mclassdefs
.last
then content
.append
(", ")
159 if not mclass
is model
.mclasses
.last
then content
.append
(", ")
162 content
.append
(" \};")
163 file
.write
(content
.to_s
)
172 var mbuilder
: ModelBuilder
174 # Init with Array[AModule] to get all ifnormations about each MModule containt in a program
175 # opt_nodot to inform about the graph gen
176 # destination: to know where will be saved dot files
177 init with
(mbuilder
: ModelBuilder, opt_nodot
: Bool, destination
: String) do
178 self.mbuilder
= mbuilder
179 self.opt_nodot
= opt_nodot
180 self.destinationdir
= destination
185 add
("title").text
("Overview | Nit Standard Library")
190 open
("nav").add_class
("main")
192 add
("li").add_class
("current").text
("Overview")
194 add_html
("<a href=\"full-index
.html\
">Full Index</a>")
196 open
("li").attr
("id", "liGitHub")
197 open
("a").add_class
("btn").attr
("id", "logGitHub")
198 add
("img").attr
("id", "imgGitHub").attr
("src", "resources/icons/github-icon.png")
200 open
("div").add_class
("popover bottom")
201 add
("div").add_class
("arrow").text
(" ")
202 open
("div").add_class
("githubTitle")
203 add
("h3").text
("Github Sign In")
206 add
("label").attr
("id", "lbloginGit").text
("Username")
207 add
("input").attr
("id", "loginGit").attr
("name", "login").attr
("type", "text")
208 open
("label").attr
("id", "logginMessage").text
("Hello ")
209 open
("a").attr
("id", "githubAccount")
210 add
("strong").attr
("id", "nickName").text
(" ")
215 add
("label").attr
("id", "lbpasswordGit").text
("Password")
216 add
("input").attr
("id", "passwordGit").attr
("name", "password").attr
("type", "password")
217 open
("div").attr
("id", "listBranches")
218 add
("label").attr
("id", "lbBranches").text
("Branch")
219 add
("select").add_class
("dropdown").attr
("id", "dropBranches").attr
("name", "dropBranches").attr
("tabindex", "1").text
(" ")
223 add
("label").attr
("id", "lbrepositoryGit").text
("Repository")
224 add
("input").attr
("id", "repositoryGit").attr
("name", "repository").attr
("type", "text")
227 add
("label").attr
("id", "lbbranchGit").text
("Branch")
228 add
("input").attr
("id", "branchGit").attr
("name", "branch").attr
("type", "text")
231 add
("a").attr
("id", "signIn").text
("Sign In")
242 open
("div").add_class
("page")
243 open
("div").add_class
("content fullpage")
244 add
("h1").text
("Nit Standard Library")
245 open
("article").add_class
("overview")
246 add_html
("<p>Documentation for the standard library of Nit<br />Version jenkins-component=stdlib-19<br />Date: TODAY</p>")
248 open
("article").add_class
("overview")
249 add
("h2").text
("Modules")
257 add
("footer").text
("Nit standard library. Version jenkins-component=stdlib-19.")
261 var mmodules
= list_mmodules
262 var sorted
= new Array[MModule].from
(mmodules
)
263 var sorter
= new ComparableSorter[MModule]
265 for mmodule
in sorted
do
266 var amodule
= mbuilder
.mmodule2nmodule
[mmodule
]
268 add
("a").attr
("href", "{mmodule.name}.html").text
("{mmodule.to_s} ")
269 add_html
(amodule
.short_comment
)
274 fun process_generate_dot
do
276 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")
277 for mmodule
in list_mmodules
do
278 op
.append
("\"{mmodule.name}\
"[URL=\"{mmodule.name}.html\
"];\n")
279 for imported
in mmodule
.in_importation
.direct_greaters
do
280 if imported
.direct_owner
== null then
281 op
.append
("\"{mmodule.name}\
"->\"{imported.name}\
";\n")
286 generate_dot
(op
.to_s
, "dep", "Modules hierarchy")
289 private fun list_mmodules
: Set[MModule] do
290 var mmodules
= new HashSet[MModule]
291 for mmodule
in mbuilder
.model
.mmodules
do
292 var owner
= mmodule
.public_owner
293 if owner
!= null then
296 mmodules
.add
(mmodule
)
304 class NitdocFullindex
307 var mmodules
: Array[MModule]
309 init with
(mmodules
: Array[MModule]) do
310 self.mmodules
= mmodules
317 add
("title").text
("Full Index | Nit Standard Library")
322 open
("nav").add_class
("main")
325 add_html
("<a href=\"index
.html\
">Overview</a>")
327 add
("li").add_class
("current").text
("Full Index")
328 open
("li").attr
("id", "liGitHub")
329 open
("a").add_class
("btn").attr
("id", "logGitHub")
330 add
("img").attr
("id", "imgGitHub").attr
("src", "resources/icons/github-icon.png")
332 open
("div").add_class
("popover bottom")
333 add
("div").add_class
("arrow").text
(" ")
334 open
("div").add_class
("githubTitle")
335 add
("h3").text
("Github Sign In")
338 add
("label").attr
("id", "lbloginGit").text
("Username")
339 add
("input").attr
("id", "loginGit").attr
("name", "login").attr
("type", "text")
340 open
("label").attr
("id", "logginMessage").text
("Hello ")
341 open
("a").attr
("id", "githubAccount")
342 add
("strong").attr
("id", "nickName").text
(" ")
347 add
("label").attr
("id", "lbpasswordGit").text
("Password")
348 add
("input").attr
("id", "passwordGit").attr
("name", "password").attr
("type", "password")
349 open
("div").attr
("id", "listBranches")
350 add
("label").attr
("id", "lbBranches").text
("Branch")
351 add
("select").add_class
("dropdown").attr
("id", "dropBranches").attr
("name", "dropBranches").attr
("tabindex", "1").text
(" ")
355 add
("label").attr
("id", "lbrepositoryGit").text
("Repository")
356 add
("input").attr
("id", "repositoryGit").attr
("name", "repository").attr
("type", "text")
359 add
("label").attr
("id", "lbbranchGit").text
("Branch")
360 add
("input").attr
("id", "branchGit").attr
("name", "branch").attr
("type", "text")
363 add
("a").attr
("id", "signIn").text
("Sign In")
374 open
("div").add_class
("page")
375 open
("div").add_class
("content fullpage")
376 add
("h1").text
("Full Index")
380 add
("footer").text
("Nit standard library. Version jenkins-component=stdlib-19.")
389 # Add to content modules column
391 var ls
= new List[nullable MModule]
392 var sorted
= mmodules
393 var sorterp
= new ComparableSorter[MModule]
395 open
("article").add_class
("modules filterable")
396 add
("h2").text
("Modules")
398 for mmodule
in sorted
do
399 if mmodule
.public_owner
!= null and not ls
.has
(mmodule
.public_owner
) then
400 ls
.add
(mmodule
.public_owner
)
402 add
("a").attr
("href", "{mmodule.public_owner.name}.html").text
(mmodule
.public_owner
.name
)
410 # Add to content classes modules
411 fun classes_column
do
412 var sorted
= mmodules
.first
.imported_mclasses
.to_a
413 var sorterp
= new ComparableSorter[MClass]
415 open
("article").add_class
("classes filterable")
416 add
("h2").text
("Classes")
419 for mclass
in sorted
do
421 add
("a").attr
("href", "{mclass.name}.html").text
(mclass
.name
)
429 # Insert the properties column of fullindex page
430 fun properties_column
do
431 open
("article").add_class
("properties filterable")
432 add
("h2").text
("Properties")
434 var sorted_imported
= mmodules
.first
.imported_methods
.to_a
435 var sorted_redef
= mmodules
.first
.redef_methods
.to_a
436 var sorterp
= new ComparableSorter[MProperty]
437 sorterp
.sort
(sorted_imported
)
438 sorterp
.sort
(sorted_redef
)
440 for method
in sorted_imported
do
441 if method
.visibility
is none_visibility
or method
.visibility
is intrude_visibility
then continue
442 open
("li").add_class
("intro")
443 add
("span").attr
("title", "introduction").text
("I")
445 add
("a").attr
("href", "{method.local_class.name}.html").attr
("title", "").text
("{method.name} ({method.local_class.name})")
449 for method
in sorted_redef
do
450 if method
.visibility
is none_visibility
or method
.visibility
is intrude_visibility
then continue
451 open
("li").add_class
("redef")
452 add
("span").attr
("title", "redefinition").text
("R")
454 add
("a").attr
("href", "{method.local_class.name}.html").attr
("title", "").text
("{method.name} ({method.local_class.name})")
468 var mbuilder
: ModelBuilder
470 init with
(mmodule
: MModule, mbuilder
: ModelBuilder) do
471 self.mmodule
= mmodule
472 self.mbuilder
= mbuilder
479 var amodule
= mbuilder
.mmodule2nmodule
[mmodule
]
480 add
("title").text
("{mmodule.name} module | {amodule.short_comment}")
485 open
("nav").add_class
("main")
488 add_html
("<a href=\"index
.html\
">Overview</a>")
490 add
("li").add_class
("current").text
(mmodule
.name
)
492 add_html
("<a href=\"full-index
.html\
" >Full Index</a>")
494 open
("li").attr
("id", "liGitHub")
495 open
("a").add_class
("btn").attr
("id", "logGitHub")
496 add
("img").attr
("id", "imgGitHub").attr
("src", "resources/icons/github-icon.png")
498 open
("div").add_class
("popover bottom")
499 add
("div").add_class
("arrow").text
(" ")
500 open
("div").add_class
("githubTitle")
501 add
("h3").text
("Github Sign In")
504 add
("label").attr
("id", "lbloginGit").text
("Username")
505 add
("input").attr
("id", "loginGit").attr
("name", "login").attr
("type", "text")
506 open
("label").attr
("id", "logginMessage").text
("Hello ")
507 open
("a").attr
("id", "githubAccount")
508 add
("strong").attr
("id", "nickName").text
(" ")
513 add
("label").attr
("id", "lbpasswordGit").text
("Password")
514 add
("input").attr
("id", "passwordGit").attr
("name", "password").attr
("type", "password")
515 open
("div").attr
("id", "listBranches")
516 add
("label").attr
("id", "lbBranches").text
("Branch")
517 add
("select").add_class
("dropdown").attr
("id", "dropBranches").attr
("name", "dropBranches").attr
("tabindex", "1").text
(" ")
521 add
("label").attr
("id", "lbrepositoryGit").text
("Repository")
522 add
("input").attr
("id", "repositoryGit").attr
("name", "repository").attr
("type", "text")
525 add
("label").attr
("id", "lbbranchGit").text
("Branch")
526 add
("input").attr
("id", "branchGit").attr
("name", "branch").attr
("type", "text")
529 add
("a").attr
("id", "signIn").text
("Sign In")
540 open
("div").add_class
("page")
544 add
("footer").text
("Nit standard library. Version jenkins-component=stdlib-19.")
547 # Insert all tags in content part
549 open
("div").add_class
("content")
550 add
("h1").text
(mmodule
.name
)
551 add
("div").add_class
("subtitle").text
("module {mmodule.name}")
558 # Insert module comment in the content
559 fun module_comment
do
560 var amodule
= mbuilder
.mmodule2nmodule
[mmodule
]
561 var doc
= amodule
.comment
562 open
("div").attr
("id", "description")
563 add
("pre").add_class
("text_label").text
(doc
)
564 add
("textarea").add_class
("edit").attr
("rows", "1").attr
("cols", "76").attr
("id", "fileContent").text
(" ")
565 add
("a").attr
("id", "cancelBtn").text
("Cancel")
566 add
("a").attr
("id", "commitBtn").text
("Commit")
567 add
("pre").add_class
("text_label").attr
("id", "preSave").attr
("type", "2")
572 var amodule
= mbuilder
.mmodule2nmodule
[mmodule
]
573 open
("div").add_class
("menu")
575 add
("h3").text
("Module Hierarchy").attr
("style","cursor: pointer;")
576 if mmodule
.in_importation
.greaters
.length
> 0 then
577 add_html
("<h4>All dependencies</h4><ul>")
578 var sorted
= mmodule
.in_importation
.greaters
.to_a
579 var sorter
= new ComparableSorter[MModule]
582 if m
== mmodule
or m
.public_owner
!= null then continue
584 add
("a").attr
("href", "{m.name}.html").text
(m
.name
)
589 if mmodule
.in_importation
.smallers
.length
> 0 then
590 add_html
("<h4>All clients</h4><ul>")
591 var sorted
= mmodule
.in_importation
.smallers
.to_a
592 var sorter
= new ComparableSorter[MModule]
595 if m
== mmodule
or m
.public_owner
!= null then continue
597 add
("a").attr
("href", "{m.name}.html").text
(m
.name
)
603 if mmodule
.in_nesting
.direct_greaters
.length
> 0 then
604 var sorted
= mmodule
.in_nesting
.direct_greaters
.to_a
605 var sorter
= new ComparableSorter[MModule]
608 add
("h3").text
("Nested Modules").attr
("style","cursor: pointer;")
612 add
("a").attr
("href", "{m.name}.html").text
(m
.name
)
623 var amodule
= mbuilder
.mmodule2nmodule
[mmodule
]
624 var intro_mclasses
= mmodule
.intro_mclasses
625 var redef_mclasses
= mmodule
.redef_mclasses
626 var all_mclasses
= new HashSet[MClass]
627 for m
in mmodule
.in_nesting
.greaters
do
628 all_mclasses
.add_all
(m
.intro_mclasses
)
629 all_mclasses
.add_all
(m
.redef_mclasses
)
631 all_mclasses
.add_all
(intro_mclasses
)
632 all_mclasses
.add_all
(redef_mclasses
)
634 var sorted
= new Array[MClass]
635 sorted
.add_all
(all_mclasses
)
636 var sorter
= new ComparableSorter[MClass]
638 open
("div").add_class
("module")
639 open
("article").add_class
("classes filterable")
640 add
("h2").text
("Classes")
644 if redef_mclasses
.has
(c
) and c
.intro_mmodule
.public_owner
!= mmodule
then
645 open
("li").add_class
("redef")
646 add
("span").attr
("title", "refined in this module").text
("R ")
648 open
("li").add_class
("intro")
649 add
("span").attr
("title", "introduced in this module").text
("I ")
651 add
("a").attr
("href", "{name}.html").text
(name
)
660 var amodule
= mbuilder
.mmodule2nmodule
[mmodule
]
661 var mpropdefs
= new HashSet[MPropDef]
662 for m
in mmodule
.in_nesting
.greaters
do
663 for c
in m
.mclassdefs
do mpropdefs
.add_all
(c
.mpropdefs
)
665 for c
in mmodule
.mclassdefs
do mpropdefs
.add_all
(c
.mpropdefs
)
666 var sorted
= mpropdefs
.to_a
667 var sorter
= new ComparableSorter[MPropDef]
669 open
("article").add_class
("properties filterable")
670 add_html
("<h2>Properties</h2>")
673 if p
.mproperty
.visibility
<= none_visibility
then continue
675 open
("li").add_class
("intro")
676 add
("span").attr
("title", "introduction").text
("I")
678 open
("li").add_class
("redef")
679 add
("span").attr
("title", "redefinition").text
("R")
682 add
("a").attr
("href", "{p.mclassdef.mclass.name}.html").attr
("title", "").text
("{p.mproperty.name} ({p.mclassdef.mclass.name})")
690 # Nit Standard Library
695 var mbuilder
: ModelBuilder
697 init with
(mclass
: MClass, mbuilder
: ModelBuilder, source
: nullable String) do
699 self.mbuilder
= mbuilder
700 self.opt_nodot
= false
701 self.destinationdir
= ""
707 var nclass
= mbuilder
.mclassdef2nclassdef
[mclass
.intro
]
708 if nclass
isa AStdClassdef then
709 add
("title").text
("{mclass.name} class | {nclass.short_comment}")
711 add
("title").text
("{mclass.name} class")
717 open
("nav").add_class
("main")
720 add_html
("<a href=\"index
.html\
">Overview</a>")
723 var public_owner
= mclass
.public_owner
724 if public_owner
is null then
725 add_html
("<a href=\"{mclass.intro_mmodule.name}.html\
">{mclass.intro_mmodule.name}</a>")
727 add_html
("<a href=\"{public_owner.name}.html\
">{public_owner.name}</a>")
730 add
("li").add_class
("current").text
(mclass
.name
)
732 add_html
("<a href=\"full-index
.html\
" >Full Index</a>")
734 open
("li").attr
("id", "liGitHub")
735 open
("a").add_class
("btn").attr
("id", "logGitHub")
736 add
("img").attr
("id", "imgGitHub").attr
("src", "resources/icons/github-icon.png")
738 open
("div").add_class
("popover bottom")
739 add
("div").add_class
("arrow").text
(" ")
740 open
("div").add_class
("githubTitle")
741 add
("h3").text
("Github Sign In")
744 add
("label").attr
("id", "lbloginGit").text
("Username")
745 add
("input").attr
("id", "loginGit").attr
("name", "login").attr
("type", "text")
746 open
("label").attr
("id", "logginMessage").text
("Hello ")
747 open
("a").attr
("id", "githubAccount")
748 add
("strong").attr
("id", "nickName").text
(" ")
753 add
("label").attr
("id", "lbpasswordGit").text
("Password")
754 add
("input").attr
("id", "passwordGit").attr
("name", "password").attr
("type", "password")
755 open
("div").attr
("id", "listBranches")
756 add
("label").attr
("id", "lbBranches").text
("Branch")
757 add
("select").add_class
("dropdown").attr
("id", "dropBranches").attr
("name", "dropBranches").attr
("tabindex", "1").text
(" ")
761 add
("label").attr
("id", "lbrepositoryGit").text
("Repository")
762 add
("input").attr
("id", "repositoryGit").attr
("name", "repository").attr
("type", "text")
765 add
("label").attr
("id", "lbbranchGit").text
("Branch")
766 add
("input").attr
("id", "branchGit").attr
("name", "branch").attr
("type", "text")
769 add
("a").attr
("id", "signIn").text
("Sign In")
780 open
("div").add_class
("page")
783 add
("footer").text
("Nit standard library. Version jenkins-component=stdlib-19.")
786 # Insert all tags in content part
788 open
("div").add_class
("menu")
792 open
("div").add_class
("content")
797 fun properties_column
do
798 var sorted
= new Array[MProperty]
799 var sorterp
= new ComparableSorter[MProperty]
800 open
("nav").add_class
("properties filterable")
801 add
("h3").text
("Properties")
803 if mclass
.virtual_types
.length
> 0 then
804 add
("h4").text
("Virtual Types")
806 sorted
= mclass
.virtual_types
.to_a
808 for prop
in sorted
do
809 add_html
("<li class=\"redef\
"><span title=\"Redefined\
">R</span><a href=\"{prop.link_anchor}\
">{prop.name}</a></li>")
813 if mclass
.constructors
.length
> 0 then
814 sorted
= mclass
.constructors
.to_a
816 add
("h4").text
("Constructors")
818 for prop
in sorted
do
819 add_html
("<li class=\"intro\
"><span title=\"Introduced\
">I</span><a href=\"{prop.link_anchor}\
">{prop.name}</a></li>")
823 add
("h4").text
("Methods")
825 if mclass
.intro_methods
.length
> 0 then
826 sorted
= mclass
.intro_methods
.to_a
828 for prop
in sorted
do
829 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>")
832 if mclass
.inherited_methods
.length
> 0 then
833 sorted
= mclass
.inherited_methods
.to_a
835 for prop
in sorted
do
836 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>")
839 if mclass
.redef_methods
.length
> 0 then
840 sorted
= mclass
.redef_methods
.to_a
842 for prop
in sorted
do
843 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>")
850 fun inheritance_column
do
851 var sorted
= new Array[MClass]
852 var sorterp
= new ComparableSorter[MClass]
854 add
("h3").text
("Inheritance")
855 if mclass
.parents
.length
> 0 then
856 sorted
= mclass
.parents
.to_a
858 add
("h4").text
("Superclasses")
860 for sup
in sorted
do add_html
("<li><a href=\"{sup.name}.html\
">{sup.name}</a></li>")
864 if mclass
.descendants
.length
is 0 then
865 add
("h4").text
("No Known Subclasses")
866 else if mclass
.descendants
.length
<= 100 then
867 sorted
= mclass
.descendants
.to_a
869 add
("h4").text
("Subclasses")
871 for sub
in sorted
do add_html
("<li><a href=\"{sub.name}\
">{sub.name}</a></li>")
873 else if mclass
.children
.length
<= 100 then
874 sorted
= mclass
.children
.to_a
876 add
("h4").text
("Direct Subclasses Only")
878 for sub
in sorted
do add_html
("<li><a href=\"{sub.name}\
">{sub.name}</a></li>")
881 add
("h4").text
("Too much Subclasses to list")
887 var nclass
= mbuilder
.mclassdef2nclassdef
[mclass
.intro
]
888 var sorted
= new Array[MModule]
889 sorted
.add_all
(mclass
.concerns
.keys
)
890 var sorterp
= new ComparableSorter[MModule]
891 var sorterprop
= new ComparableSorter[MProperty]
892 var sorterc
= new ComparableSorter[MClass]
895 var lmmodule
= new List[MModule]
896 # Insert the subtitle part
897 add
("h1").text
(mclass
.name
)
898 open
("div").add_class
("subtitle")
899 if mclass
.visibility
is none_visibility
then subtitle
+= "private "
900 subtitle
+= "{mclass.kind} <a href=\"{mclass.public_owner.name}.html\
">{mclass.public_owner.name}</a>::{mclass.name}"
903 add_html
("<div style=\"float
: right
;\
"><a id=\"lblDiffCommit\
"></a></div>")
904 # We add the class description
905 open
("section").add_class
("description")
906 if nclass
isa AStdClassdef and not nclass
.comment
.is_empty
then add_html
("<pre class=\"text_label\
" title=\"122\
" name=\"\
" tag=\"{mclass.mclassdefs.first.location.to_s}\
" type=\"2\
">{nclass.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>")
908 open
("section").add_class
("concerns")
909 add
("h2").add_class
("section-header").text
("Concerns")
911 for owner
in sorted
do
912 var nmodule
= mbuilder
.mmodule2nmodule
[owner
]
913 var childs
= mclass
.concerns
[owner
]
915 add_html
("<a href=\"#MOD_{owner.name}\">{owner.name}</a>: {nmodule.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 var nchild
= mbuilder
.mmodule2nmodule
[child
]
923 add_html
("<li><a href=\"#MOD_{child.name}\">{child.name}</a>: {nchild.short_comment} </li>")
931 # Insert virtual types if there is almost one
932 if mclass
.virtual_types
.length
> 0 or mclass
.arity
> 0 then
933 open
("section").add_class
("types")
934 add
("h2").text
("Formal and Virtual Types")
935 if mclass
.virtual_types
.length
> 0 then for prop
in mclass
.virtual_types
do description
(prop
)
936 if mclass
.arity
> 0 and nclass
isa AStdClassdef then
937 for prop
in nclass
.n_formaldefs
do
938 open
("article").attr
("id", "FT_Object_{prop.collect_text}")
939 open
("h3").add_class
("signature").text
("{prop.collect_text}: nullable ")
940 add_html
("<a title=\"The root of the
class hierarchy
.\
" href=\"Object.html\
">Object</a>")
942 add_html
("<div class=\"info\
">formal generic type</div>")
948 # Insert constructors if there is almost one
949 if mclass
.constructors
.length
> 0 then
950 var sortedc
= mclass
.constructors
.to_a
951 sorterprop
.sort
(sortedc
)
952 open
("section").add_class
("constructors")
953 add
("h2").add_class
("section-header").text
("Constructors")
954 for prop
in sortedc
do description
(prop
)
957 open
("section").add_class
("methods")
958 add
("h2").add_class
("section-header").text
("Methods")
959 for mmodule
, mmethods
in mclass
.all_methods
do
960 var nmodule
= mbuilder
.mmodule2nmodule
[mmodule
]
961 add_html
("<a id=\"MOD_{mmodule.name}\
"></a>")
962 if mmodule
!= mclass
.intro_mmodule
and mmodule
!= mclass
.public_owner
then
963 if mclass
.has_mmodule
(mmodule
) then
964 add_html
("<p class=\"concern-doc\
">{mmodule.name}: {nmodule.short_comment}</p>")
966 add_html
("<h3 class=\"concern-toplevel\
">Methods refined in <a href=\"{mmodule.name}.html\
">{mmodule.name}</a></h3><p class=\"concern-doc\
">{mmodule.name}: {nmodule.short_comment}</p>")
969 var sortedc
= mmethods
.to_a
970 sorterprop
.sort
(sortedc
)
971 for prop
in sortedc
do description
(prop
)
973 # Insert inherited methods
974 if mclass
.inherited_methods
.length
> 0 then
975 var sortedc
= new Array[MClass]
976 sortedc
.add_all
(mclass
.inherited
.keys
)
977 sorterc
.sort
(sortedc
)
978 add
("h3").text
("Inherited Methods")
979 for i_mclass
in sortedc
do
980 var sortedp
= mclass
.inherited
[i_mclass
].to_a
981 sorterprop
.sort
(sortedp
)
983 add_html
("Defined in <a href=\"{i_mclass.name}.html\
">{i_mclass.name}</a>: ")
984 for method
in sortedp
do
985 add_html
("<a href=\"{method.link_anchor}\
">{method.name}</a>")
986 if method
!= sortedp
.last
then add_html
(", ")
994 # Insert description tags for 'prop'
995 fun description
(prop
: MProperty) do
996 open
("article").add_class
("fun public {if prop.is_redef then "redef" else ""}").attr
("id", "{prop.anchor}")
998 if prop
.apropdef
!= null then sign
+= prop
.apropdef
.signature
999 add_html
("<h3 class=\"signature\
">{sign}</h3>")
1000 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>")
1002 open
("div").add_class
("description")
1003 if prop
.apropdef
is null or prop
.apropdef
.comment
== "" then
1004 add_html
("<a class=\"newComment\
" title=\"32\
" tag=\"\
">New Comment</a>")
1006 add_html
("<pre class=\"text_label\
" title=\"\
" name=\"\
" tag=\"\
" type=\"1\
">{prop.apropdef.comment}</pre>")
1008 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>")
1010 if prop
.local_class
!= mclass
then add_html
("inherited from {prop.local_class.intro_mmodule.name} ")
1011 #TODO display show code if doc github
1012 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)}.")
1014 for parent
in mclass
.parents
do
1015 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>.")
1029 var destinationdir
: String
1030 var source
: nullable String
1033 add
("meta").attr
("charset", "utf-8")
1034 add
("script").attr
("type", "text/javascript").attr
("src", "scripts/jquery-1.7.1.min.js")
1035 add
("script").attr
("type", "text/javascript").attr
("src", "quicksearch-list.js")
1036 add
("script").attr
("type", "text/javascript").attr
("src", "scripts/js-facilities.js")
1037 add
("link").attr
("rel", "stylesheet").attr
("href", "styles/main.css").attr
("type", "text/css").attr
("media", "screen")
1040 redef fun body
do header
1043 # Generate a clickable graphviz image using a dot content
1044 fun generate_dot
(dot
: String, name
: String, alt
: String) do
1045 if opt_nodot
then return
1046 var file
= new OFStream.open
("{self.destinationdir}/{name}.dot")
1049 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 ; \}")
1050 open
("article").add_class
("graph")
1051 add
("img").attr
("src", "{name}.png").attr
("usemap", "#{name}").attr
("style", "margin:auto").attr
("alt", "{alt}")
1053 var fmap
= new IFStream.open
("{self.destinationdir}/{name}.map")
1054 add_html
(fmap
.read_all
)
1058 # Add a (source) link fo a given location
1059 fun show_source
(l
: Location): String
1061 if source
== null then
1062 return "({l.file.filename.simplify_path})"
1064 # THIS IS JUST UGLY ! (but there is no replace yet)
1065 var x
= source
.split_with
("%f")
1066 source
= x
.join
(l
.file
.filename
.simplify_path
)
1067 x
= source
.split_with
("%l")
1068 source
= x
.join
(l
.line_start
.to_s
)
1069 x
= source
.split_with
("%L")
1070 source
= x
.join
(l
.line_end
.to_s
)
1071 return " (<a href=\"{source.to_s}\
">show code</a>)"
1078 private fun comment
: String do
1080 if n_moduledecl
is null or n_moduledecl
.n_doc
is null then ret
1081 if n_moduledecl
.n_doc
is null then return ""
1082 for t
in n_moduledecl
.n_doc
.n_comment
do
1084 txt
= txt
.replace
("# ", "")
1085 txt
= txt
.replace
("#", "")
1091 private fun short_comment
: String do
1093 if n_moduledecl
!= null and n_moduledecl
.n_doc
!= null then
1094 var txt
= n_moduledecl
.n_doc
.n_comment
.first
.text
1095 txt
= txt
.replace
("# ", "")
1096 txt
= txt
.replace
("\n", "")
1106 redef type OTHER: MModule
1107 redef fun <(other
: OTHER): Bool do return self.name
< other
.name
1109 var amodule
: nullable AModule
1111 # Get the list of all methods in a module
1112 fun imported_methods
: Set[MMethod] do
1113 var methods
= new HashSet[MMethod]
1114 for mclass
in imported_mclasses
do
1115 for method
in mclass
.intro_methods
do
1122 # Get the list aof all refined methods in a module
1123 fun redef_methods
: Set[MMethod] do
1124 var methods
= new HashSet[MMethod]
1125 for mclass
in redef_mclasses
do
1126 for method
in mclass
.intro_methods
do
1133 redef class MPropDef
1135 redef type OTHER: MPropDef
1136 redef fun <(other
: OTHER): Bool do return self.mproperty
.name
< other
.mproperty
.name
1139 redef class MProperty
1142 redef type OTHER: MProperty
1143 redef fun <(other
: OTHER): Bool do return self.name
< other
.name
1146 var apropdef
: nullable APropdef
1148 redef init(intro_mclassdef
: MClassDef, name
: String, visibility
: MVisibility)
1154 fun local_class
: MClass do
1155 var classdef
= self.intro_mclassdef
1156 return classdef
.mclass
1159 fun class_text
: String do
1160 return local_class
.name
1163 fun link_anchor
: String do
1164 return "{class_text}.html#{anchor}"
1167 fun anchor
: String do
1168 return "PROP_{c_name}"
1176 redef type OTHER: MClass
1177 redef fun <(other
: OTHER): Bool do return self.name
< other
.name
1179 # Associate all MMethods to each MModule concerns
1180 fun all_methods
: HashMap[MModule, Set[MMethod]] do
1181 var hm
= new HashMap[MModule, Set[MMethod]]
1182 for mmodule
, childs
in concerns
do
1183 if not hm
.has_key
(mmodule
) then hm
[mmodule
] = new HashSet[MMethod]
1184 for prop
in intro_methods
do
1185 if mmodule
== prop
.intro_mclassdef
.mmodule
then
1186 prop
.is_redef
= false
1187 hm
[mmodule
].add
(prop
)
1190 for prop
in redef_methods
do
1191 if mmodule
== prop
.intro_mclassdef
.mmodule
then
1192 prop
.is_redef
= true
1193 hm
[mmodule
].add
(prop
)
1197 if childs
!= null then
1198 for child
in childs
do
1199 if not hm
.has_key
(child
) then hm
[child
] = new HashSet[MMethod]
1200 for prop
in intro_methods
do
1201 if child
== prop
.intro_mclassdef
.mmodule
then
1202 prop
.is_redef
= false
1206 for prop
in redef_methods
do
1207 if child
== prop
.intro_mclassdef
.mmodule
then
1208 prop
.is_redef
= true
1218 fun public_owner
: MModule do
1219 var owner
= intro_mmodule
1220 if owner
.public_owner
is null then
1223 return owner
.public_owner
.as(not null)
1227 # Associate Amodule to all MModule concern by 'self'
1228 fun amodule
(amodules
: HashMap[MModule, AModule]) do
1229 for owner
, childs
in concerns
do
1230 if childs
!= null then for child
in childs
do child
.amodule
= amodules
[child
]
1231 owner
.amodule
= amodules
[owner
]
1235 # Associate MClass to all MMethod include in 'inherited_methods'
1236 fun inherited
: HashMap[MClass, Set[MMethod]] do
1237 var hm
= new HashMap[MClass, Set[MMethod]]
1238 for method
in inherited_methods
do
1239 var mclass
= method
.intro_mclassdef
.mclass
1240 if not hm
.has_key
(mclass
) then hm
[mclass
] = new HashSet[MMethod]
1241 hm
[mclass
].add
(method
)
1246 # Return true if MModule concern contain subMModule
1247 fun has_mmodule
(sub
: MModule): Bool do
1248 for mmodule
, childs
in concerns
do
1249 if childs
is null then continue
1250 if childs
.has
(sub
) then return true
1255 fun mmethod
(mprop2npropdef
: Map[MProperty, APropdef]) do
1256 for const
in constructors
do
1257 if mprop2npropdef
.has_key
(const
)then
1258 const
.apropdef
= mprop2npropdef
[const
].as(AMethPropdef)
1262 for intro
in intro_methods
do
1263 if mprop2npropdef
.has_key
(intro
)then
1264 if mprop2npropdef
[intro
] isa AMethPropdef then intro
.apropdef
= mprop2npropdef
[intro
].as(AMethPropdef)
1268 for rd
in redef_methods
do
1269 if mprop2npropdef
.has_key
(rd
)then
1270 if mprop2npropdef
[rd
] isa AMethPropdef then rd
.apropdef
= mprop2npropdef
[rd
].as(AMethPropdef)
1275 fun link_anchor
: String do
1276 return "{name}.html"
1281 redef class AStdClassdef
1282 private fun comment
: String do
1284 if n_doc
!= null then
1285 for t
in n_doc
.n_comment
do
1286 var txt
= t
.text
.replace
("# ", "")
1287 txt
= txt
.replace
("#", "")
1294 private fun short_comment
: String do
1296 if n_doc
!= null then
1297 var txt
= n_doc
.n_comment
.first
.text
1298 txt
= txt
.replace
("# ", "")
1299 txt
= txt
.replace
("\n", "")
1306 redef class ASignature
1310 if not n_params
.is_empty
then
1311 ret
= "{ret}({n_params.join(", ")})"
1313 if n_type
!= null and n_type
.to_s
!= "" then ret
+= " {n_type.to_s}"
1320 var ret
= "{n_id.text}"
1321 if n_type
!= null then
1322 ret
= "{ret}: {n_type.to_s}"
1323 if n_dotdotdot
!= null then ret
= "{ret}..."
1331 var ret
= "<a href=\"{n_id.text}.html\
">{n_id.text}</a>"
1332 if n_kwnullable
!= null then ret
= "nullable {ret}"
1333 if not n_types
.is_empty
then ret
= "{ret}[{n_types.join(", ")}]"
1338 redef class APropdef
1339 private fun short_comment
: String is abstract
1340 private fun signature
: String is abstract
1341 private fun comment
: String is abstract
1344 redef class AAttrPropdef
1345 redef fun short_comment
do
1347 if n_doc
!= null then
1348 var txt
= n_doc
.n_comment
.first
.text
1349 txt
= txt
.replace
("# ", "")
1350 txt
= txt
.replace
("\n", "")
1357 redef class AMethPropdef
1358 redef fun short_comment
do
1360 if n_doc
!= null then
1361 var txt
= n_doc
.n_comment
.first
.text
1362 txt
= txt
.replace
("# ", "")
1363 txt
= txt
.replace
("\n", "")
1369 redef fun signature
: String do
1371 if n_signature
!= null then sign
= " {n_signature.to_s}"
1375 redef private fun comment
: String do
1377 if n_doc
!= null then
1378 for t
in n_doc
.n_comment
do
1379 var txt
= t
.text
.replace
("# ", "")
1380 txt
= txt
.replace
("#", "")
1388 redef class MClassDef
1389 private fun namespace
(mclass
: MClass): String do
1391 if mmodule
.public_owner
is null then
1392 return "{mmodule.full_name}::{mclass.name}"
1393 else if mclass
is self.mclass
then
1394 return "{mmodule.public_owner.name}::{mclass.name}"
1396 return "{mmodule.public_owner.name}::<a href=\"{mclass.name}.html\
">{mclass.name}</a>"
1403 return to_a
[length-1
]
1407 # Create a tool context to handle options and paths
1408 var toolcontext
= new ToolContext
1410 # Here we launch the nit index
1411 var nitdoc
= new Nitdoc(toolcontext
)