1 # This file is part of NIT ( http://www.nitlanguage.org ).
3 # Copyright 2008 Jean Privat <jean@pryen.org>
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
9 # http://www.apache.org/licenses/LICENSE-2.0
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
20 import abstract_compiler
24 private var toolcontext
: ToolContext
25 private var model
: Model
26 private var modelbuilder
: ModelBuilder
27 private var mainmodule
: MModule
28 private var arguments
: Array[String]
29 private var destinationdir
: nullable String
30 private var sharedir
: nullable String
31 private var source
: nullable String
33 private var opt_dir
= new OptionString("Directory where doc is generated", "-d", "--dir")
34 private var opt_source
= new OptionString("What link for source (%f for filename, %l for first line, %L for last line)", "--source")
35 private var opt_sharedir
= new OptionString("Directory containing the nitdoc files", "--sharedir")
36 private var opt_nodot
= new OptionBool("Do not generate graphes with graphiviz", "--no-dot")
38 init(toolcontext
: ToolContext) do
39 # We need a model to collect stufs
40 self.toolcontext
= toolcontext
41 self.arguments
= toolcontext
.option_context
.rest
42 toolcontext
.option_context
.options
.clear
43 toolcontext
.option_context
.add_option
(opt_dir
)
44 toolcontext
.option_context
.add_option
(opt_source
)
45 toolcontext
.option_context
.add_option
(opt_sharedir
)
46 toolcontext
.option_context
.add_option
(opt_nodot
)
47 toolcontext
.process_options
50 if arguments
.length
< 1 then
51 toolcontext
.option_context
.usage
56 modelbuilder
= new ModelBuilder(model
, toolcontext
)
58 # Here we load an process std modules
59 var mmodules
= modelbuilder
.parse_and_build
([arguments
.first
])
60 if mmodules
.is_empty
then return
61 modelbuilder
.full_propdef_semantic_analysis
62 assert mmodules
.length
== 1
63 self.mainmodule
= mmodules
.first
66 private fun process_options
do
67 if not opt_dir
.value
is null then
68 destinationdir
= opt_dir
.value
70 destinationdir
= "nitdoc_directory"
72 if not opt_sharedir
.value
is null then
73 sharedir
= opt_sharedir
.value
75 var dir
= "NIT_DIR".environ
77 dir
= "{sys.program_name.dirname}/../share/nitdoc"
79 dir
= "{dir}/share/nitdoc"
82 if sharedir
is null then
83 print
"Error: Cannot locate nitdoc share files. Uses --sharedir or envvar NIT_DIR"
86 dir
= "{sharedir.to_s}/scripts/js-facilities.js"
87 if sharedir
is null then
88 print
"Error: Invalid nitdoc share files. Check --sharedir or envvar NIT_DIR"
92 if not opt_source
.value
is null then
95 source
= opt_source
.value
100 if arguments
.length
== 1 then
101 # Create destination dir if it's necessary
102 if not destinationdir
.file_exists
then destinationdir
.mkdir
103 sys
.system
("cp -r {sharedir.to_s}/* {destinationdir.to_s}/")
113 var overviewpage
= new NitdocOverview.with
(modelbuilder
.nmodules
, self.opt_nodot
.value
, destinationdir
.to_s
)
114 overviewpage
.save
("{destinationdir.to_s}/index.html")
118 var fullindex
= new NitdocFullindex.with
(model
.mmodules
)
119 fullindex
.save
("{destinationdir.to_s}/full-index.html")
123 for mod
in modelbuilder
.nmodules
do
124 var modulepage
= new NitdocModules.with
(mod
)
125 modulepage
.save
("{destinationdir.to_s}/{mod.mmodule.name}.html")
130 for amodule
in modelbuilder
.nmodules
do
131 for mclass
, aclassdef
in amodule
.mclass2nclassdef
do
132 mclass
.amodule
(modelbuilder
.mmodule2nmodule
)
133 mclass
.mmethod
(aclassdef
.mprop2npropdef
)
134 var classpage
= new NitdocMClasses.with
(mclass
, aclassdef
, source
)
135 classpage
.save
("{destinationdir.to_s}/{mclass.name}.html")
140 # Generate QuickSearch file
141 fun quicksearch_list
do
142 var file
= new OFStream.open
("{destinationdir.to_s}/quicksearch-list.js")
143 var content
= new Buffer
144 content
.append
("var entries = \{ ")
145 for prop
in model
.mproperties
do
146 if not prop
isa MMethod then continue
147 content
.append
("\"{prop.name}\
": [")
148 for propdef
in prop
.mpropdefs
do
149 content
.append
("\{txt: \"{propdef.mproperty.full_name}\", url
:\
"{propdef.mproperty.link_anchor}\" \
}")
150 if not propdef is prop.mpropdefs.last then content.append(", ")
156 for mclass in model.mclasses do
157 content.append("\
"{mclass.name}\": [")
158 for mclassdef in mclass.mclassdefs do
159 content.append("\
{txt: \"{mclassdef.mclass.full_name}\
", url:\"{mclass.link_anchor}\
" \}")
160 if not mclassdef
is mclass
.mclassdefs
.last
then content
.append
(", ")
163 if not mclass
is model
.mclasses
.last
then content
.append
(", ")
166 content
.append
(" \};")
167 file
.write
(content
.to_s
)
176 var amodules
: Array[AModule]
178 # Init with Array[AModule] to get all ifnormations about each MModule containt in a program
179 # opt_nodot to inform about the graph gen
180 # destination: to know where will be saved dot files
181 init with
(modules
: Array[AModule], opt_nodot
: Bool, destination
: String) do
182 self.amodules
= modules
183 self.opt_nodot
= opt_nodot
184 self.destinationdir
= destination
189 add
("title").text
("Overview | Nit Standard Library")
194 open
("nav").add_class
("main")
196 add
("li").add_class
("current").text
("Overview")
198 add_html
("<a href=\"full-index
.html\
">Full Index</a>")
200 open
("li").attr
("id", "liGitHub")
201 open
("a").add_class
("btn").attr
("id", "logGitHub")
202 add
("img").attr
("id", "imgGitHub").attr
("src", "resources/icons/github-icon.png")
204 open
("div").add_class
("popover bottom")
205 add
("div").add_class
("arrow").text
(" ")
206 open
("div").add_class
("githubTitle")
207 add
("h3").text
("Github Sign In")
210 add
("label").attr
("id", "lbloginGit").text
("Username")
211 add
("input").attr
("id", "loginGit").attr
("name", "login").attr
("type", "text")
212 open
("label").attr
("id", "logginMessage").text
("Hello ")
213 open
("a").attr
("id", "githubAccount")
214 add
("strong").attr
("id", "nickName").text
(" ")
219 add
("label").attr
("id", "lbpasswordGit").text
("Password")
220 add
("input").attr
("id", "passwordGit").attr
("name", "password").attr
("type", "password")
221 open
("div").attr
("id", "listBranches")
222 add
("label").attr
("id", "lbBranches").text
("Branch")
223 add
("select").add_class
("dropdown").attr
("id", "dropBranches").attr
("name", "dropBranches").attr
("tabindex", "1").text
(" ")
227 add
("label").attr
("id", "lbrepositoryGit").text
("Repository")
228 add
("input").attr
("id", "repositoryGit").attr
("name", "repository").attr
("type", "text")
231 add
("label").attr
("id", "lbbranchGit").text
("Branch")
232 add
("input").attr
("id", "branchGit").attr
("name", "branch").attr
("type", "text")
235 add
("a").attr
("id", "signIn").text
("Sign In")
246 open
("div").add_class
("page")
247 open
("div").add_class
("content fullpage")
248 add
("h1").text
("Nit Standard Library")
249 open
("article").add_class
("overview")
250 add_html
("<p>Documentation for the standard library of Nit<br />Version jenkins-component=stdlib-19<br />Date: TODAY</p>")
252 open
("article").add_class
("overview")
253 add
("h2").text
("Modules")
261 add
("footer").text
("Nit standard library. Version jenkins-component=stdlib-19.")
265 var ls
= new List[nullable MModule]
266 for amodule
in amodules
do
267 var mmodule
= amodule
.mmodule
.public_owner
268 if mmodule
!= null and not ls
.has
(mmodule
) then
270 add
("a").attr
("href", "{mmodule.name}.html").text
("{mmodule.to_s} ")
271 add_html
(amodule
.comment
)
278 fun process_generate_dot
do
280 op
.append
("digraph dep \{ rankdir=BT; node[shape=none,margin=0,width=0,height=0,fontsize=10]; edge[dir=none,color=gray]; ranksep=0.2; nodesep=0.1;\n")
281 for amodule
in amodules
do
282 op
.append
("\"{amodule.mmodule.name}\
"[URL=\"{amodule.mmodule.name}.html\
"];\n")
283 for mmodule2
in amodule
.mmodule
.in_importation
.direct_greaters
do
284 op
.append
("\"{amodule.mmodule.name}\
"->\"{mmodule2.name}\
";\n")
288 generate_dot
(op
.to_s
, "dep", "Modules hierarchy")
293 class NitdocFullindex
296 var mmodules
: Array[MModule]
298 init with
(mmodules
: Array[MModule]) do
299 self.mmodules
= mmodules
306 add
("title").text
("Full Index | Nit Standard Library")
311 open
("nav").add_class
("main")
314 add_html
("<a href=\"index
.html\
">Overview</a>")
316 add
("li").add_class
("current").text
("Full Index")
317 open
("li").attr
("id", "liGitHub")
318 open
("a").add_class
("btn").attr
("id", "logGitHub")
319 add
("img").attr
("id", "imgGitHub").attr
("src", "resources/icons/github-icon.png")
321 open
("div").add_class
("popover bottom")
322 add
("div").add_class
("arrow").text
(" ")
323 open
("div").add_class
("githubTitle")
324 add
("h3").text
("Github Sign In")
327 add
("label").attr
("id", "lbloginGit").text
("Username")
328 add
("input").attr
("id", "loginGit").attr
("name", "login").attr
("type", "text")
329 open
("label").attr
("id", "logginMessage").text
("Hello ")
330 open
("a").attr
("id", "githubAccount")
331 add
("strong").attr
("id", "nickName").text
(" ")
336 add
("label").attr
("id", "lbpasswordGit").text
("Password")
337 add
("input").attr
("id", "passwordGit").attr
("name", "password").attr
("type", "password")
338 open
("div").attr
("id", "listBranches")
339 add
("label").attr
("id", "lbBranches").text
("Branch")
340 add
("select").add_class
("dropdown").attr
("id", "dropBranches").attr
("name", "dropBranches").attr
("tabindex", "1").text
(" ")
344 add
("label").attr
("id", "lbrepositoryGit").text
("Repository")
345 add
("input").attr
("id", "repositoryGit").attr
("name", "repository").attr
("type", "text")
348 add
("label").attr
("id", "lbbranchGit").text
("Branch")
349 add
("input").attr
("id", "branchGit").attr
("name", "branch").attr
("type", "text")
352 add
("a").attr
("id", "signIn").text
("Sign In")
363 open
("div").add_class
("page")
364 open
("div").add_class
("content fullpage")
365 add
("h1").text
("Full Index")
369 add
("footer").text
("Nit standard library. Version jenkins-component=stdlib-19.")
378 # Add to content modules column
380 var ls
= new List[nullable MModule]
381 open
("article").add_class
("modules filterable")
382 add
("h2").text
("Modules")
384 for mmodule
in mmodules
do
385 if mmodule
.public_owner
!= null and not ls
.has
(mmodule
.public_owner
) then
386 ls
.add
(mmodule
.public_owner
)
388 add
("a").attr
("href", "{mmodule.public_owner.name}.html").text
(mmodule
.public_owner
.name
)
396 # Add to content classes modules
397 fun classes_column
do
398 open
("article").add_class
("classes filterable")
399 add
("h2").text
("Classes")
402 for mclass
in mmodules
.first
.imported_mclasses
do
404 add
("a").attr
("href", "{mclass.name}.html").text
(mclass
.name
)
412 # Insert the properties column of fullindex page
413 fun properties_column
do
414 open
("article").add_class
("properties filterable")
415 add
("h2").text
("Properties")
418 for method
in mmodules
.first
.imported_methods
do
419 if method
.visibility
is none_visibility
or method
.visibility
is intrude_visibility
then continue
420 open
("li").add_class
("intro")
421 add
("span").attr
("title", "introduction").text
("I")
423 add
("a").attr
("href", "{method.local_class.name}.html").attr
("title", "").text
("{method.name} ({method.local_class.name})")
427 for method
in mmodules
.first
.redef_methods
do
428 if method
.visibility
is none_visibility
or method
.visibility
is intrude_visibility
then continue
429 open
("li").add_class
("redef")
430 add
("span").attr
("title", "redefinition").text
("R")
432 add
("a").attr
("href", "{method.local_class.name}.html").attr
("title", "").text
("{method.name} ({method.local_class.name})")
446 var modulename
: String
447 init with
(amodule
: AModule) do
448 self.amodule
= amodule
449 self.modulename
= self.amodule
.mmodule
.name
456 add
("title").text
("{modulename} module | {amodule.short_comment}")
461 open
("nav").add_class
("main")
464 add_html
("<a href=\"index
.html\
">Overview</a>")
466 add
("li").add_class
("current").text
(modulename
)
468 add_html
("<a href=\"full-index
.html\
" >Full Index</a>")
470 open
("li").attr
("id", "liGitHub")
471 open
("a").add_class
("btn").attr
("id", "logGitHub")
472 add
("img").attr
("id", "imgGitHub").attr
("src", "resources/icons/github-icon.png")
474 open
("div").add_class
("popover bottom")
475 add
("div").add_class
("arrow").text
(" ")
476 open
("div").add_class
("githubTitle")
477 add
("h3").text
("Github Sign In")
480 add
("label").attr
("id", "lbloginGit").text
("Username")
481 add
("input").attr
("id", "loginGit").attr
("name", "login").attr
("type", "text")
482 open
("label").attr
("id", "logginMessage").text
("Hello ")
483 open
("a").attr
("id", "githubAccount")
484 add
("strong").attr
("id", "nickName").text
(" ")
489 add
("label").attr
("id", "lbpasswordGit").text
("Password")
490 add
("input").attr
("id", "passwordGit").attr
("name", "password").attr
("type", "password")
491 open
("div").attr
("id", "listBranches")
492 add
("label").attr
("id", "lbBranches").text
("Branch")
493 add
("select").add_class
("dropdown").attr
("id", "dropBranches").attr
("name", "dropBranches").attr
("tabindex", "1").text
(" ")
497 add
("label").attr
("id", "lbrepositoryGit").text
("Repository")
498 add
("input").attr
("id", "repositoryGit").attr
("name", "repository").attr
("type", "text")
501 add
("label").attr
("id", "lbbranchGit").text
("Branch")
502 add
("input").attr
("id", "branchGit").attr
("name", "branch").attr
("type", "text")
505 add
("a").attr
("id", "signIn").text
("Sign In")
516 open
("div").add_class
("page")
520 add
("footer").text
("Nit standard library. Version jenkins-component=stdlib-19.")
523 # Insert all tags in content part
525 open
("div").add_class
("content")
526 add
("h1").text
(modulename
)
527 add
("div").add_class
("subtitle").text
("module {modulename}")
534 # Insert module comment in the content
535 fun module_comment
do
536 var doc
= amodule
.comment
537 open
("div").attr
("id", "description")
538 add
("pre").add_class
("text_label").text
(doc
)
539 add
("textarea").add_class
("edit").attr
("rows", "1").attr
("cols", "76").attr
("id", "fileContent").text
(" ")
540 add
("a").attr
("id", "cancelBtn").text
("Cancel")
541 add
("a").attr
("id", "commitBtn").text
("Commit")
542 add
("pre").add_class
("text_label").attr
("id", "preSave").attr
("type", "2")
547 var mmodule
= amodule
.mmodule
548 open
("div").add_class
("menu")
550 add
("h3").text
("Module Hierarchy").attr
("style","cursor: pointer;")
551 if mmodule
.in_importation
.direct_greaters
.length
> 0 then
552 add_html
("<h4>All dependencies</h4><ul>")
553 for m
in mmodule
.in_importation
.direct_greaters
do
554 if m
== mmodule
or mmodule
== m
.public_owner
then continue
556 add
("a").attr
("href", "{m.name}.html").text
(m
.name
)
561 if mmodule
.in_importation
.greaters
.length
> 0 then
562 add_html
("<h4>All clients</h4><ul>")
563 for m
in mmodule
.in_importation
.greaters
do
564 if m
== mmodule
then continue
566 add
("a").attr
("href", "{m.name}.html").text
(m
.name
)
572 if mmodule
.in_nesting
.direct_greaters
.length
> 0 then
574 add
("h3").text
("Nested Modules").attr
("style","cursor: pointer;")
576 for m
in mmodule
.in_nesting
.direct_greaters
do
578 add
("a").attr
("href", "{m.name}.html").text
(m
.name
)
589 open
("div").add_class
("module")
590 open
("article").add_class
("classes filterable")
591 add
("h2").text
("Classes")
593 for c
, state
in amodule
.mmodule
.mclasses
do
595 if state
== c_is_intro
or state
== c_is_imported
then
596 open
("li").add_class
("intro")
597 add
("span").attr
("title", "introduced in this module").text
("I ")
599 open
("li").add_class
("redef")
600 add
("span").attr
("title", "refined in this module").text
("R ")
602 add
("a").attr
("href", "{name}.html").text
(name
)
611 open
("article").add_class
("properties filterable")
612 add_html
("<h2>Properties</h2>")
614 for method
in amodule
.mmodule
.imported_methods
do
615 if method
.visibility
is none_visibility
or method
.visibility
is intrude_visibility
then continue
616 open
("li").add_class
("intro")
617 add
("span").attr
("title", "introduction").text
("I")
619 add
("a").attr
("href", "{method.local_class.name}.html").attr
("title", "").text
("{method.name} ({method.local_class.name})")
623 for method
in amodule
.mmodule
.redef_methods
do
624 if method
.visibility
is none_visibility
or method
.visibility
is intrude_visibility
then continue
625 open
("li").add_class
("redef")
626 add
("span").attr
("title", "redefinition").text
("R")
628 add
("a").attr
("href", "{method.local_class.name}.html").attr
("title", "").text
("{method.name} ({method.local_class.name})")
638 # Nit Standard Library
643 var aclassdef
: AClassdef
644 var stdclassdef
: nullable AStdClassdef
645 var public_owner
: nullable MModule
647 init with
(mclass
: MClass, aclassdef
: AClassdef, source
: nullable String) do
649 self.aclassdef
= aclassdef
650 if aclassdef
isa AStdClassdef then self.stdclassdef
= aclassdef
651 self.public_owner
= mclass
.intro_mmodule
.public_owner
659 add
("title").text
("{self.mclass.name} class | Nit Standard Library")
664 open
("nav").add_class
("main")
667 add_html
("<a href=\"index
.html\
">Overview</a>")
670 if public_owner
is null then
671 add_html
("<a href=\"{mclass.intro_mmodule.name}.html\
">{mclass.intro_mmodule.name}</a>")
673 add_html
("<a href=\"{public_owner.name}.html\
">{public_owner.name}</a>")
676 add
("li").add_class
("current").text
(mclass
.name
)
678 add_html
("<a href=\"full-index
.html\
" >Full Index</a>")
680 open
("li").attr
("id", "liGitHub")
681 open
("a").add_class
("btn").attr
("id", "logGitHub")
682 add
("img").attr
("id", "imgGitHub").attr
("src", "resources/icons/github-icon.png")
684 open
("div").add_class
("popover bottom")
685 add
("div").add_class
("arrow").text
(" ")
686 open
("div").add_class
("githubTitle")
687 add
("h3").text
("Github Sign In")
690 add
("label").attr
("id", "lbloginGit").text
("Username")
691 add
("input").attr
("id", "loginGit").attr
("name", "login").attr
("type", "text")
692 open
("label").attr
("id", "logginMessage").text
("Hello ")
693 open
("a").attr
("id", "githubAccount")
694 add
("strong").attr
("id", "nickName").text
(" ")
699 add
("label").attr
("id", "lbpasswordGit").text
("Password")
700 add
("input").attr
("id", "passwordGit").attr
("name", "password").attr
("type", "password")
701 open
("div").attr
("id", "listBranches")
702 add
("label").attr
("id", "lbBranches").text
("Branch")
703 add
("select").add_class
("dropdown").attr
("id", "dropBranches").attr
("name", "dropBranches").attr
("tabindex", "1").text
(" ")
707 add
("label").attr
("id", "lbrepositoryGit").text
("Repository")
708 add
("input").attr
("id", "repositoryGit").attr
("name", "repository").attr
("type", "text")
711 add
("label").attr
("id", "lbbranchGit").text
("Branch")
712 add
("input").attr
("id", "branchGit").attr
("name", "branch").attr
("type", "text")
715 add
("a").attr
("id", "signIn").text
("Sign In")
726 open
("div").add_class
("page")
729 add
("footer").text
("Nit standard library. Version jenkins-component=stdlib-19.")
732 # Insert all tags in content part
734 open
("div").add_class
("menu")
738 open
("div").add_class
("content")
743 fun properties_column
do
744 open
("nav").add_class
("properties filterable")
745 add
("h3").text
("Properties")
747 if mclass
.virtual_types
.length
> 0 then
748 add
("h4").text
("Virtual Types")
750 for prop
in mclass
.virtual_types
do
751 add_html
("<li class=\"redef\
"><span title=\"Redefined\
">R</span><a href=\"{prop.link_anchor}\
">{prop.name}</a></li>")
755 if mclass
.constructors
.length
> 0 then
756 add
("h4").text
("Constructors")
758 for prop
in mclass
.constructors
do
759 add_html
("<li class=\"intro\
"><span title=\"Introduced\
">I</span><a href=\"{prop.link_anchor}\
">{prop.name}</a></li>")
763 add
("h4").text
("Methods")
765 if mclass
.intro_methods
.length
> 0 then
766 for prop
in mclass
.intro_methods
do
767 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>")
770 if mclass
.inherited_methods
.length
> 0 then
771 for prop
in mclass
.inherited_methods
do
772 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>")
775 if mclass
.redef_methods
.length
> 0 then
776 for prop
in mclass
.redef_methods
do
777 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>")
784 fun inheritance_column
do
786 add
("h3").text
("Inheritance")
787 if mclass
.parents
.length
> 0 then
788 add
("h4").text
("Superclasses")
790 for sup
in mclass
.parents
do add_html
("<li><a href=\"{sup.name}.html\
">{sup.name}</a></li>")
794 if mclass
.descendants
.length
is 0 then
795 add
("h4").text
("No Known Subclasses")
796 else if mclass
.descendants
.length
<= 100 then
797 add
("h4").text
("Subclasses")
799 for sub
in mclass
.descendants
do add_html
("<li><a href=\"{sub.name}\
">{sub.name}</a></li>")
801 else if mclass
.children
.length
<= 100 then
802 add
("h4").text
("Direct Subclasses Only")
804 for sub
in mclass
.children
do add_html
("<li><a href=\"{sub.name}\
">{sub.name}</a></li>")
807 add
("h4").text
("Too much Subclasses to list")
814 var lmmodule
= new List[MModule]
815 # Insert the subtitle part
816 add
("h1").text
(mclass
.name
)
817 open
("div").add_class
("subtitle")
818 if mclass
.visibility
is none_visibility
then subtitle
+= "private "
819 subtitle
+= "{mclass.kind} <a href=\"{mclass.public_owner.name}.html\
">{mclass.public_owner.name}</a>::{mclass.name}"
822 add_html
("<div style=\"float
: right
;\
"><a id=\"lblDiffCommit\
"></a></div>")
823 # We add the class description
824 open
("section").add_class
("description")
825 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>")
827 open
("section").add_class
("concerns")
828 add
("h2").add_class
("section-header").text
("Concerns")
830 for owner
, childs
in mclass
.concerns
do
832 add_html
("<a href=\"#MOD_{owner.name}\">{owner.name}</a>: {owner.amodule.short_comment}")
833 if not childs
is null then
835 for child
in childs
.as(not null) do add_html
("<li><a href=\"#MOD_{child.name}\">{child.name}</a>: {child.amodule.short_comment} </li>")
842 # Insert virtual types if there is almost one
843 if mclass
.virtual_types
.length
> 0 or (stdclassdef
!= null and stdclassdef
.n_formaldefs
.length
> 0) then
844 open
("section").add_class
("types")
845 add
("h2").text
("Formal and Virtual Types")
846 if mclass
.virtual_types
.length
> 0 then for prop
in mclass
.virtual_types
do description
(prop
)
847 if stdclassdef
.n_formaldefs
.length
> 0 then
848 for prop
in stdclassdef
.n_formaldefs
do
849 open
("article").attr
("id", "FT_Object_{prop.collect_text}")
850 open
("h3").add_class
("signature").text
("{prop.collect_text}: nullable ")
851 add_html
("<a title=\"The root of the
class hierarchy
.\
" href=\"Object.html\
">Object</a>")
853 add_html
("<div class=\"info\
">formal generic type</div>")
859 # Insert constructors if there is almost one
860 if mclass
.constructors
.length
> 0 then
861 open
("section").add_class
("constructors")
862 add
("h2").add_class
("section-header").text
("Constructors")
863 for prop
in mclass
.constructors
do description
(prop
)
866 open
("section").add_class
("methods")
867 add
("h2").add_class
("section-header").text
("Methods")
868 for mmodule
, mmethods
in mclass
.all_methods
do
869 add_html
("<a id=\"MOD_{mmodule.name}\
"></a>")
870 if mmodule
!= mclass
.intro_mmodule
and mmodule
!= mclass
.public_owner
then
871 if mclass
.has_mmodule
(mmodule
) then
872 add_html
("<p class=\"concern-doc\
">{mmodule.name}: {mmodule.amodule.short_comment}</p>")
874 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>")
877 for prop
in mmethods
do description
(prop
)
879 # Insert inherited methods
880 if mclass
.inherited_methods
.length
> 0 then
881 add
("h3").text
("Inherited Methods")
882 for i_mclass
, methods
in mclass
.inherited
do
884 add_html
("Defined in <a href=\"{i_mclass.name}.html\
">{i_mclass.name}</a>: ")
885 for method
in methods
do
886 add_html
("<a href=\"{method.link_anchor}\
">{method.name}</a>")
887 if method
!= methods
.last
then add_html
(", ")
895 # Insert description tags for 'prop'
896 fun description
(prop
: MProperty) do
897 open
("article").add_class
("fun public {if prop.is_redef then "redef" else ""}").attr
("id", "{prop.anchor}")
899 if prop
.apropdef
!= null then sign
+= prop
.apropdef
.signature
900 add_html
("<h3 class=\"signature\
">{sign}</h3>")
901 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>")
903 open
("div").add_class
("description")
904 if prop
.apropdef
is null or prop
.apropdef
.comment
== "" then
905 add_html
("<a class=\"newComment\
" title=\"32\
" tag=\"\
">New Comment</a>")
907 add_html
("<pre class=\"text_label\
" title=\"\
" name=\"\
" tag=\"\
" type=\"1\
">{prop.apropdef.comment}</pre>")
909 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>")
911 if prop
.local_class
!= mclass
then add_html
("inherited from {prop.local_class.intro_mmodule.name} ")
912 #TODO display show code if doc github
913 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)}.")
915 for parent
in mclass
.parents
do
916 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>.")
930 var destinationdir
: String
931 var source
: nullable String
934 add
("meta").attr
("charset", "utf-8")
935 add
("script").attr
("type", "text/javascript").attr
("src", "scripts/jquery-1.7.1.min.js")
936 add
("script").attr
("type", "text/javascript").attr
("src", "quicksearch-list.js")
937 add
("script").attr
("type", "text/javascript").attr
("src", "scripts/js-facilities.js")
938 add
("link").attr
("rel", "stylesheet").attr
("href", "styles/main.css").attr
("type", "text/css").attr
("media", "screen")
941 redef fun body
do header
944 # Generate a clickable graphviz image using a dot content
945 fun generate_dot
(dot
: String, name
: String, alt
: String) do
946 if opt_nodot
then return
947 var file
= new OFStream.open
("{self.destinationdir}/{name}.dot")
950 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 ; \}")
951 open
("article").add_class
("graph")
952 add
("img").attr
("src", "{name}.png").attr
("usemap", "#{name}").attr
("style", "margin:auto").attr
("alt", "{alt}")
954 var fmap
= new IFStream.open
("{self.destinationdir}/{name}.map")
955 add_html
(fmap
.read_all
)
959 # Add a (source) link fo a given location
960 fun show_source
(l
: Location): String
962 if source
== null then
963 return "({l.file.filename.simplify_path})"
965 # THIS IS JUST UGLY ! (but there is no replace yet)
966 var x
= source
.split_with
("%f")
967 source
= x
.join
(l
.file
.filename
.simplify_path
)
968 x
= source
.split_with
("%l")
969 source
= x
.join
(l
.line_start
.to_s
)
970 x
= source
.split_with
("%L")
971 source
= x
.join
(l
.line_end
.to_s
)
972 return " (<a href=\"{source.to_s}\
">show code</a>)"
979 private fun comment
: String do
981 if n_moduledecl
is null or n_moduledecl
.n_doc
is null then ret
982 if n_moduledecl
.n_doc
is null then return ""
983 for t
in n_moduledecl
.n_doc
.n_comment
do
984 ret
+= "{t.text.replace("# ", "")}"
989 private fun short_comment
: String do
991 if n_moduledecl
!= null and n_moduledecl
.n_doc
!= null then
992 var txt
= n_moduledecl
.n_doc
.n_comment
.first
.text
993 txt
= txt
.replace
("# ", "")
994 txt
= txt
.replace
("\n", "")
1003 var amodule
: nullable AModule
1005 # Get the list of all methods in a module
1006 fun imported_methods
: Set[MMethod] do
1007 var methods
= new HashSet[MMethod]
1008 for mclass
in imported_mclasses
do
1009 for method
in mclass
.intro_methods
do
1016 # Get the list aof all refined methods in a module
1017 fun redef_methods
: Set[MMethod] do
1018 var methods
= new HashSet[MMethod]
1019 for mclass
in redef_mclasses
do
1020 for method
in mclass
.intro_methods
do
1028 redef class MProperty
1031 var apropdef
: nullable APropdef
1033 redef init(intro_mclassdef
: MClassDef, name
: String, visibility
: MVisibility)
1039 fun local_class
: MClass do
1040 var classdef
= self.intro_mclassdef
1041 return classdef
.mclass
1044 fun class_text
: String do
1045 return local_class
.name
1048 fun link_anchor
: String do
1049 return "{class_text}.html#{anchor}"
1052 fun anchor
: String do
1053 return "PROP_{c_name}"
1060 # Associate all MMethods to each MModule concerns
1061 fun all_methods
: HashMap[MModule, Set[MMethod]] do
1062 var hm
= new HashMap[MModule, Set[MMethod]]
1063 for mmodule
, childs
in concerns
do
1064 if not hm
.has_key
(mmodule
) then hm
[mmodule
] = new HashSet[MMethod]
1065 for prop
in intro_methods
do
1066 if mmodule
== prop
.intro_mclassdef
.mmodule
then
1067 prop
.is_redef
= false
1068 hm
[mmodule
].add
(prop
)
1071 for prop
in redef_methods
do
1072 if mmodule
== prop
.intro_mclassdef
.mmodule
then
1073 prop
.is_redef
= true
1074 hm
[mmodule
].add
(prop
)
1078 if childs
!= null then
1079 for child
in childs
do
1080 if not hm
.has_key
(child
) then hm
[child
] = new HashSet[MMethod]
1081 for prop
in intro_methods
do
1082 if child
== prop
.intro_mclassdef
.mmodule
then
1083 prop
.is_redef
= false
1087 for prop
in redef_methods
do
1088 if child
== prop
.intro_mclassdef
.mmodule
then
1089 prop
.is_redef
= true
1099 fun public_owner
: MModule do
1100 var owner
= intro_mmodule
1101 if owner
.public_owner
is null then
1104 return owner
.public_owner
.as(not null)
1108 # Associate Amodule to all MModule concern by 'self'
1109 fun amodule
(amodules
: HashMap[MModule, AModule]) do
1110 for owner
, childs
in concerns
do
1111 if childs
!= null then for child
in childs
do child
.amodule
= amodules
[child
]
1112 owner
.amodule
= amodules
[owner
]
1116 # Associate MClass to all MMethod include in 'inherited_methods'
1117 fun inherited
: HashMap[MClass, Set[MMethod]] do
1118 var hm
= new HashMap[MClass, Set[MMethod]]
1119 for method
in inherited_methods
do
1120 var mclass
= method
.intro_mclassdef
.mclass
1121 if not hm
.has_key
(mclass
) then hm
[mclass
] = new HashSet[MMethod]
1122 hm
[mclass
].add
(method
)
1127 # Return true if MModule concern contain subMModule
1128 fun has_mmodule
(sub
: MModule): Bool do
1129 for mmodule
, childs
in concerns
do
1130 if childs
is null then continue
1131 if childs
.has
(sub
) then return true
1136 fun mmethod
(mprop2npropdef
: Map[MProperty, APropdef]) do
1137 for const
in constructors
do
1138 if mprop2npropdef
.has_key
(const
)then
1139 const
.apropdef
= mprop2npropdef
[const
].as(AMethPropdef)
1143 for intro
in intro_methods
do
1144 if mprop2npropdef
.has_key
(intro
)then
1145 if mprop2npropdef
[intro
] isa AMethPropdef then intro
.apropdef
= mprop2npropdef
[intro
].as(AMethPropdef)
1149 for rd
in redef_methods
do
1150 if mprop2npropdef
.has_key
(rd
)then
1151 if mprop2npropdef
[rd
] isa AMethPropdef then rd
.apropdef
= mprop2npropdef
[rd
].as(AMethPropdef)
1156 fun link_anchor
: String do
1157 return "{name}.html"
1162 redef class AStdClassdef
1163 private fun comment
: String do
1165 if n_doc
!= null then
1166 for t
in n_doc
.n_comment
do
1167 var txt
= t
.text
.replace
("# ", "")
1168 txt
= txt
.replace
("#", "")
1175 private fun short_comment
: String do
1177 if n_doc
!= null then
1178 var txt
= n_doc
.n_comment
.first
.text
1179 txt
= txt
.replace
("# ", "")
1180 txt
= txt
.replace
("\n", "")
1187 redef class ASignature
1191 if not n_params
.is_empty
then
1192 ret
= "{ret}({n_params.join(", ")})"
1194 if n_type
!= null and n_type
.to_s
!= "" then ret
+= " {n_type.to_s}"
1201 var ret
= "{n_id.text}"
1202 if n_type
!= null then
1203 ret
= "{ret}: {n_type.to_s}"
1204 if n_dotdotdot
!= null then ret
= "{ret}..."
1212 var ret
= "<a href=\"{n_id.text}.html\
">{n_id.text}</a>"
1213 if n_kwnullable
!= null then ret
= "nullable {ret}"
1214 if not n_types
.is_empty
then ret
= "{ret}[{n_types.join(", ")}]"
1219 redef class APropdef
1220 private fun short_comment
: String is abstract
1221 private fun signature
: String is abstract
1222 private fun comment
: String is abstract
1225 redef class AAttrPropdef
1226 redef fun short_comment
do
1228 if n_doc
!= null then
1229 var txt
= n_doc
.n_comment
.first
.text
1230 txt
= txt
.replace
("# ", "")
1231 txt
= txt
.replace
("\n", "")
1238 redef class AMethPropdef
1239 redef fun short_comment
do
1241 if n_doc
!= null then
1242 var txt
= n_doc
.n_comment
.first
.text
1243 txt
= txt
.replace
("# ", "")
1244 txt
= txt
.replace
("\n", "")
1250 redef fun signature
: String do
1252 if n_signature
!= null then sign
= " {n_signature.to_s}"
1256 redef private fun comment
: String do
1258 if n_doc
!= null then
1259 for t
in n_doc
.n_comment
do
1260 var txt
= t
.text
.replace
("# ", "")
1261 txt
= txt
.replace
("#", "")
1269 redef class MClassDef
1270 private fun namespace
(mclass
: MClass): String do
1272 if mmodule
.public_owner
is null then
1273 return "{mmodule.full_name}::{mclass.name}"
1274 else if mclass
is self.mclass
then
1275 return "{mmodule.public_owner.name}::{mclass.name}"
1277 return "{mmodule.public_owner.name}::<a href=\"{mclass.name}.html\
">{mclass.name}</a>"
1284 return to_a
[length-1
]
1288 # Create a tool context to handle options and paths
1289 var toolcontext
= new ToolContext
1291 # Here we launch the nit index
1292 var nitdoc
= new Nitdoc(toolcontext
)