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
32 private var opt_dir
= new OptionString("Directory where doc is generated", "-d", "--dir")
33 private var opt_source
= new OptionString("What link for source (%f for filename, %l for first line, %L for last line)", "--source")
34 private var opt_sharedir
= new OptionString("Directory containing the nitdoc files", "--sharedir")
35 private var opt_nodot
= new OptionBool("Do not generate graphes with graphiviz", "--no-dot")
37 init(toolcontext
: ToolContext) do
38 # We need a model to collect stufs
39 self.toolcontext
= toolcontext
40 self.arguments
= toolcontext
.option_context
.rest
41 toolcontext
.option_context
.add_option
(opt_dir
)
42 toolcontext
.option_context
.add_option
(opt_source
)
43 toolcontext
.option_context
.add_option
(opt_sharedir
)
44 toolcontext
.option_context
.add_option
(opt_nodot
)
47 if arguments
.length
< 1 then
48 toolcontext
.option_context
.usage
53 modelbuilder
= new ModelBuilder(model
, toolcontext
)
55 # Here we load an process std modules
56 var mmodules
= modelbuilder
.parse_and_build
([arguments
.first
])
57 if mmodules
.is_empty
then return
58 modelbuilder
.full_propdef_semantic_analysis
59 assert mmodules
.length
== 1
60 self.mainmodule
= mmodules
.first
63 private fun process_options
do
64 if not opt_dir
.value
is null then
65 destinationdir
= opt_dir
.value
67 destinationdir
= "nitdoc_directory"
69 if not opt_sharedir
.value
is null then
70 sharedir
= opt_sharedir
.value
72 var dir
= "NIT_DIR".environ
74 dir
= "{sys.program_name.dirname}/../share/nitdoc"
76 dir
= "{dir}/share/nitdoc"
79 if sharedir
is null then
80 print
"Error: Cannot locate nitdoc share files. Uses --sharedir or envvar NIT_DIR"
83 dir
= "{sharedir.to_s}/scripts/js-facilities.js"
84 if sharedir
is null then
85 print
"Error: Invalid nitdoc share files. Check --sharedir or envvar NIT_DIR"
92 if arguments
.length
== 1 then
93 # Create destination dir if it's necessary
94 if not destinationdir
.file_exists
then destinationdir
.mkdir
95 sys
.system
("cp -r {sharedir.to_s}/* {destinationdir.to_s}/")
104 var overviewpage
= new NitdocOverview.with
(modelbuilder
.nmodules
, self.opt_nodot
.value
, destinationdir
.to_s
)
105 overviewpage
.save
("{destinationdir.to_s}/index.html")
109 var fullindex
= new NitdocFullindex.with
(model
.mmodules
)
110 fullindex
.save
("{destinationdir.to_s}/full-index.html")
114 for mod
in modelbuilder
.nmodules
do
115 var modulepage
= new NitdocModules.with
(mod
)
116 modulepage
.save
("{destinationdir.to_s}/{mod.mmodule.name}.html")
121 for amodule
in modelbuilder
.nmodules
do
122 for mclass
, aclassdef
in amodule
.mclass2nclassdef
do
123 var classpage
= new NitdocMClasses.with
(mclass
, aclassdef
)
124 classpage
.save
("{destinationdir.to_s}/{mclass.name}.html")
134 var amodules
: Array[AModule]
136 # Init with Array[AModule] to get all ifnormations about each MModule containt in a program
137 # opt_nodot to inform about the graph gen
138 # destination: to know where will be saved dot files
139 init with
(modules
: Array[AModule], opt_nodot
: Bool, destination
: String) do
140 self.amodules
= modules
141 self.opt_nodot
= opt_nodot
142 self.destinationdir
= destination
147 add
("title").text
("Overview | Nit Standard Library")
152 open
("nav").add_class
("main")
154 add
("li").add_class
("current").text
("Overview")
156 add_html
("<a href=\"full-index
.html\
">Full Index</a>")
158 open
("li").attr
("id", "liGitHub")
159 open
("a").add_class
("btn").attr
("id", "logGitHub")
160 add
("img").attr
("id", "imgGitHub").attr
("src", "resources/icons/github-icon.png")
162 open
("div").add_class
("popover bottom")
163 add
("div").add_class
("arrow").text
(" ")
164 open
("div").add_class
("githubTitle")
165 add
("h3").text
("Github Sign In")
168 add
("label").attr
("id", "lbloginGit").text
("Username")
169 add
("input").attr
("id", "loginGit").attr
("name", "login").attr
("type", "text")
170 open
("label").attr
("id", "logginMessage").text
("Hello ")
171 open
("a").attr
("id", "githubAccount")
172 add
("strong").attr
("id", "nickName").text
(" ")
177 add
("label").attr
("id", "lbpasswordGit").text
("Password")
178 add
("input").attr
("id", "passwordGit").attr
("name", "password").attr
("type", "password")
179 open
("div").attr
("id", "listBranches")
180 add
("label").attr
("id", "lbBranches").text
("Branch")
181 add
("select").add_class
("dropdown").attr
("id", "dropBranches").attr
("name", "dropBranches").attr
("tabindex", "1").text
(" ")
185 add
("label").attr
("id", "lbrepositoryGit").text
("Repository")
186 add
("input").attr
("id", "repositoryGit").attr
("name", "repository").attr
("type", "text")
189 add
("label").attr
("id", "lbbranchGit").text
("Branch")
190 add
("input").attr
("id", "branchGit").attr
("name", "branch").attr
("type", "text")
193 add
("a").attr
("id", "signIn").text
("Sign In")
204 open
("div").add_class
("page")
205 open
("div").add_class
("content fullpage")
206 add
("h1").text
("Nit Standard Library")
207 open
("article").add_class
("overview")
208 add_html
("<p>Documentation for the standard library of Nit<br />Version jenkins-component=stdlib-19<br />Date: TODAY</p>")
210 open
("article").add_class
("overview")
211 add
("h2").text
("Modules")
219 add
("footer").text
("Nit standard library. Version jenkins-component=stdlib-19.")
223 var ls
= new List[nullable MModule]
224 for amodule
in amodules
do
225 var mmodule
= amodule
.mmodule
.public_owner
226 if mmodule
!= null and not ls
.has
(mmodule
) then
228 add
("a").attr
("href", "{mmodule.name}.html").text
("{mmodule.to_s} ")
229 add_html
(amodule
.comment
)
236 fun process_generate_dot
do
238 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")
239 for amodule
in amodules
do
240 op
.append
("\"{amodule.mmodule.name}\
"[URL=\"{amodule.mmodule.name}.html\
"];\n")
241 for mmodule2
in amodule
.mmodule
.in_importation
.direct_greaters
do
242 op
.append
("\"{amodule.mmodule.name}\
"->\"{mmodule2.name}\
";\n")
246 generate_dot
(op
.to_s
, "dep", "Modules hierarchy")
251 class NitdocFullindex
254 var mmodules
: Array[MModule]
256 init with
(mmodules
: Array[MModule]) do
257 self.mmodules
= mmodules
264 add
("title").text
("Full Index | Nit Standard Library")
269 open
("nav").add_class
("main")
272 add_html
("<a href=\"index
.html\
">Overview</a>")
274 add
("li").add_class
("current").text
("Full Index")
275 open
("li").attr
("id", "liGitHub")
276 open
("a").add_class
("btn").attr
("id", "logGitHub")
277 add
("img").attr
("id", "imgGitHub").attr
("src", "resources/icons/github-icon.png")
279 open
("div").add_class
("popover bottom")
280 add
("div").add_class
("arrow").text
(" ")
281 open
("div").add_class
("githubTitle")
282 add
("h3").text
("Github Sign In")
285 add
("label").attr
("id", "lbloginGit").text
("Username")
286 add
("input").attr
("id", "loginGit").attr
("name", "login").attr
("type", "text")
287 open
("label").attr
("id", "logginMessage").text
("Hello ")
288 open
("a").attr
("id", "githubAccount")
289 add
("strong").attr
("id", "nickName").text
(" ")
294 add
("label").attr
("id", "lbpasswordGit").text
("Password")
295 add
("input").attr
("id", "passwordGit").attr
("name", "password").attr
("type", "password")
296 open
("div").attr
("id", "listBranches")
297 add
("label").attr
("id", "lbBranches").text
("Branch")
298 add
("select").add_class
("dropdown").attr
("id", "dropBranches").attr
("name", "dropBranches").attr
("tabindex", "1").text
(" ")
302 add
("label").attr
("id", "lbrepositoryGit").text
("Repository")
303 add
("input").attr
("id", "repositoryGit").attr
("name", "repository").attr
("type", "text")
306 add
("label").attr
("id", "lbbranchGit").text
("Branch")
307 add
("input").attr
("id", "branchGit").attr
("name", "branch").attr
("type", "text")
310 add
("a").attr
("id", "signIn").text
("Sign In")
321 open
("div").add_class
("page")
322 open
("div").add_class
("content fullpage")
323 add
("h1").text
("Full Index")
327 add
("footer").text
("Nit standard library. Version jenkins-component=stdlib-19.")
336 # Add to content modules column
338 var ls
= new List[nullable MModule]
339 open
("article").add_class
("modules filterable")
340 add
("h2").text
("Modules")
342 for mmodule
in mmodules
do
343 if mmodule
.public_owner
!= null and not ls
.has
(mmodule
.public_owner
) then
344 ls
.add
(mmodule
.public_owner
)
346 add
("a").attr
("href", "{mmodule.public_owner.name}.html").text
(mmodule
.public_owner
.name
)
354 # Add to content classes modules
355 fun classes_column
do
356 open
("article").add_class
("classes filterable")
357 add
("h2").text
("Classes")
360 for mclass
in mmodules
.first
.imported_mclasses
do
362 add
("a").attr
("href", "{mclass.name}.html").text
(mclass
.name
)
370 # Insert the properties column of fullindex page
371 fun properties_column
do
372 open
("article").add_class
("properties filterable")
373 add
("h2").text
("Properties")
376 for method
in mmodules
.first
.imported_methods
do
377 if method
.visibility
is none_visibility
or method
.visibility
is intrude_visibility
then continue
378 open
("li").add_class
("intro")
379 add
("span").attr
("title", "introduction").text
("I")
381 add
("a").attr
("href", "{method.local_class.name}.html").attr
("title", "").text
("{method.name} ({method.local_class.name})")
385 for method
in mmodules
.first
.redef_methods
do
386 if method
.visibility
is none_visibility
or method
.visibility
is intrude_visibility
then continue
387 open
("li").add_class
("redef")
388 add
("span").attr
("title", "redefinition").text
("R")
390 add
("a").attr
("href", "{method.local_class.name}.html").attr
("title", "").text
("{method.name} ({method.local_class.name})")
404 var modulename
: String
405 init with
(amodule
: AModule) do
406 self.amodule
= amodule
407 self.modulename
= self.amodule
.mmodule
.name
414 add
("title").text
("{modulename} module | {amodule.short_comment}")
419 open
("nav").add_class
("main")
422 add_html
("<a href=\"index
.html\
">Overview</a>")
424 add
("li").add_class
("current").text
(modulename
)
426 add_html
("<a href=\"full-index
.html\
" >Full Index</a>")
428 open
("li").attr
("id", "liGitHub")
429 open
("a").add_class
("btn").attr
("id", "logGitHub")
430 add
("img").attr
("id", "imgGitHub").attr
("src", "resources/icons/github-icon.png")
432 open
("div").add_class
("popover bottom")
433 add
("div").add_class
("arrow").text
(" ")
434 open
("div").add_class
("githubTitle")
435 add
("h3").text
("Github Sign In")
438 add
("label").attr
("id", "lbloginGit").text
("Username")
439 add
("input").attr
("id", "loginGit").attr
("name", "login").attr
("type", "text")
440 open
("label").attr
("id", "logginMessage").text
("Hello ")
441 open
("a").attr
("id", "githubAccount")
442 add
("strong").attr
("id", "nickName").text
(" ")
447 add
("label").attr
("id", "lbpasswordGit").text
("Password")
448 add
("input").attr
("id", "passwordGit").attr
("name", "password").attr
("type", "password")
449 open
("div").attr
("id", "listBranches")
450 add
("label").attr
("id", "lbBranches").text
("Branch")
451 add
("select").add_class
("dropdown").attr
("id", "dropBranches").attr
("name", "dropBranches").attr
("tabindex", "1").text
(" ")
455 add
("label").attr
("id", "lbrepositoryGit").text
("Repository")
456 add
("input").attr
("id", "repositoryGit").attr
("name", "repository").attr
("type", "text")
459 add
("label").attr
("id", "lbbranchGit").text
("Branch")
460 add
("input").attr
("id", "branchGit").attr
("name", "branch").attr
("type", "text")
463 add
("a").attr
("id", "signIn").text
("Sign In")
474 open
("div").add_class
("page")
478 add
("footer").text
("Nit standard library. Version jenkins-component=stdlib-19.")
481 # Insert all tags in content part
483 open
("div").add_class
("content")
484 add
("h1").text
(modulename
)
485 add
("div").add_class
("subtitle").text
("module {modulename}")
492 # Insert module comment in the content
493 fun module_comment
do
494 var doc
= amodule
.comment
495 open
("div").attr
("id", "description")
496 add
("pre").add_class
("text_label").text
(doc
)
497 add
("textarea").add_class
("edit").attr
("rows", "1").attr
("cols", "76").attr
("id", "fileContent").text
(" ")
498 add
("a").attr
("id", "cancelBtn").text
("Cancel")
499 add
("a").attr
("id", "commitBtn").text
("Commit")
500 add
("pre").add_class
("text_label").attr
("id", "preSave").attr
("type", "2")
505 var mmodule
= amodule
.mmodule
506 open
("div").add_class
("menu")
508 add
("h3").text
("Module Hierarchy").attr
("style","cursor: pointer;")
509 if mmodule
.in_importation
.direct_greaters
.length
> 0 then
510 add_html
("<h4>All dependencies</h4><ul>")
511 for m
in mmodule
.in_importation
.direct_greaters
do
512 if m
== mmodule
or mmodule
== m
.public_owner
then continue
514 add
("a").attr
("href", "{m.name}.html").text
(m
.name
)
519 if mmodule
.in_importation
.greaters
.length
> 0 then
520 add_html
("<h4>All clients</h4><ul>")
521 for m
in mmodule
.in_importation
.greaters
do
522 if m
== mmodule
then continue
524 add
("a").attr
("href", "{m.name}.html").text
(m
.name
)
530 if mmodule
.in_nesting
.direct_greaters
.length
> 0 then
532 add
("h3").text
("Nested Modules").attr
("style","cursor: pointer;")
534 for m
in mmodule
.in_nesting
.direct_greaters
do
536 add
("a").attr
("href", "{m.name}.html").text
(m
.name
)
547 open
("div").add_class
("module")
548 open
("article").add_class
("classes filterable")
549 add
("h2").text
("Classes")
551 for c
, state
in amodule
.mmodule
.mclasses
do
553 if state
== c_is_intro
or state
== c_is_imported
then
554 open
("li").add_class
("intro")
555 add
("span").attr
("title", "introduced in this module").text
("I ")
557 open
("li").add_class
("redef")
558 add
("span").attr
("title", "refined in this module").text
("R ")
560 add
("a").attr
("href", "{name}.html").text
(name
)
569 open
("article").add_class
("properties filterable")
570 add_html
("<h2>Properties</h2>")
572 for method
in amodule
.mmodule
.imported_methods
do
573 if method
.visibility
is none_visibility
or method
.visibility
is intrude_visibility
then continue
574 open
("li").add_class
("intro")
575 add
("span").attr
("title", "introduction").text
("I")
577 add
("a").attr
("href", "{method.local_class.name}.html").attr
("title", "").text
("{method.name} ({method.local_class.name})")
581 for method
in amodule
.mmodule
.redef_methods
do
582 if method
.visibility
is none_visibility
or method
.visibility
is intrude_visibility
then continue
583 open
("li").add_class
("redef")
584 add
("span").attr
("title", "redefinition").text
("R")
586 add
("a").attr
("href", "{method.local_class.name}.html").attr
("title", "").text
("{method.name} ({method.local_class.name})")
596 # Nit Standard Library
601 var aclassdef
: AClassdef
602 var stdclassdef
: nullable AStdClassdef
603 var public_owner
: nullable MModule
605 init with
(mclass
: MClass, aclassdef
: AClassdef) do
607 self.aclassdef
= aclassdef
608 if aclassdef
isa AStdClassdef then self.stdclassdef
= aclassdef
609 self.public_owner
= mclass
.intro_mmodule
.public_owner
616 add
("title").text
("{self.mclass.name} class | Nit Standard Library")
621 open
("nav").add_class
("main")
624 add_html
("<a href=\"index
.html\
">Overview</a>")
627 if public_owner
is null then
628 add_html
("<a href=\"{mclass.intro_mmodule.name}.html\
">{mclass.intro_mmodule.name}</a>")
630 add_html
("<a href=\"{public_owner.name}.html\
">{public_owner.name}</a>")
633 add
("li").add_class
("current").text
(mclass
.name
)
635 add_html
("<a href=\"full-index
.html\
" >Full Index</a>")
637 open
("li").attr
("id", "liGitHub")
638 open
("a").add_class
("btn").attr
("id", "logGitHub")
639 add
("img").attr
("id", "imgGitHub").attr
("src", "resources/icons/github-icon.png")
641 open
("div").add_class
("popover bottom")
642 add
("div").add_class
("arrow").text
(" ")
643 open
("div").add_class
("githubTitle")
644 add
("h3").text
("Github Sign In")
647 add
("label").attr
("id", "lbloginGit").text
("Username")
648 add
("input").attr
("id", "loginGit").attr
("name", "login").attr
("type", "text")
649 open
("label").attr
("id", "logginMessage").text
("Hello ")
650 open
("a").attr
("id", "githubAccount")
651 add
("strong").attr
("id", "nickName").text
(" ")
656 add
("label").attr
("id", "lbpasswordGit").text
("Password")
657 add
("input").attr
("id", "passwordGit").attr
("name", "password").attr
("type", "password")
658 open
("div").attr
("id", "listBranches")
659 add
("label").attr
("id", "lbBranches").text
("Branch")
660 add
("select").add_class
("dropdown").attr
("id", "dropBranches").attr
("name", "dropBranches").attr
("tabindex", "1").text
(" ")
664 add
("label").attr
("id", "lbrepositoryGit").text
("Repository")
665 add
("input").attr
("id", "repositoryGit").attr
("name", "repository").attr
("type", "text")
668 add
("label").attr
("id", "lbbranchGit").text
("Branch")
669 add
("input").attr
("id", "branchGit").attr
("name", "branch").attr
("type", "text")
672 add
("a").attr
("id", "signIn").text
("Sign In")
683 open
("div").add_class
("page")
685 add
("footer").text
("Nit standard library. Version jenkins-component=stdlib-19.")
694 var destinationdir
: String
697 add
("meta").attr
("charset", "utf-8")
698 add
("script").attr
("type", "text/javascript").attr
("src", "scripts/jquery-1.7.1.min.js")
699 add
("script").attr
("type", "text/javascript").attr
("src", "quicksearch-list.js")
700 add
("script").attr
("type", "text/javascript").attr
("src", "scripts/js-facilities.js")
701 add
("link").attr
("rel", "stylesheet").attr
("href", "styles/main.css").attr
("type", "text/css").attr
("media", "screen")
704 redef fun body
do header
707 # Generate a clickable graphviz image using a dot content
708 fun generate_dot
(dot
: String, name
: String, alt
: String) do
709 if opt_nodot
then return
710 var file
= new OFStream.open
("{self.destinationdir}/{name}.dot")
713 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 ; \}")
714 open
("article").add_class
("graph")
715 add
("img").attr
("src", "{name}.png").attr
("usemap", "#{name}").attr
("style", "margin:auto").attr
("alt", "{alt}")
717 var fmap
= new IFStream.open
("{self.destinationdir}/{name}.map")
718 add_html
(fmap
.read_all
)
725 private fun comment
: String do
727 if n_moduledecl
is null or n_moduledecl
.n_doc
is null then ret
728 if n_moduledecl
.n_doc
is null then return ""
729 for t
in n_moduledecl
.n_doc
.n_comment
do
730 ret
+= "{t.text.replace("# ", "")}"
735 private fun short_comment
: String do
737 if n_moduledecl
!= null and n_moduledecl
.n_doc
!= null then
738 var txt
= n_moduledecl
.n_doc
.n_comment
.first
.text
739 txt
= txt
.replace
("# ", "")
740 txt
= txt
.replace
("\n", "")
749 var amodule
: nullable AModule
751 # Get the list of all methods in a module
752 fun imported_methods
: Set[MMethod] do
753 var methods
= new HashSet[MMethod]
754 for mclass
in imported_mclasses
do
755 for method
in mclass
.intro_methods
do
762 # Get the list aof all refined methods in a module
763 fun redef_methods
: Set[MMethod] do
764 var methods
= new HashSet[MMethod]
765 for mclass
in redef_mclasses
do
766 for method
in mclass
.intro_methods
do
774 redef class MProperty
777 var apropdef
: nullable APropdef
779 redef init(intro_mclassdef
: MClassDef, name
: String, visibility
: MVisibility)
785 fun local_class
: MClass do
786 var classdef
= self.intro_mclassdef
787 return classdef
.mclass
790 fun class_text
: String do
791 return local_class
.name
794 fun link_anchor
: String do
795 return "{class_text}.html#{anchor}"
798 fun anchor
: String do
799 return "PROP_{c_name}"
806 # Associate all MMethods to each MModule concerns
807 fun all_methods
: HashMap[MModule, Set[MMethod]] do
808 var hm
= new HashMap[MModule, Set[MMethod]]
809 for mmodule
, childs
in concerns
do
810 if not hm
.has_key
(mmodule
) then hm
[mmodule
] = new HashSet[MMethod]
811 for prop
in intro_methods
do
812 if mmodule
== prop
.intro_mclassdef
.mmodule
then
813 prop
.is_redef
= false
814 hm
[mmodule
].add
(prop
)
817 for prop
in redef_methods
do
818 if mmodule
== prop
.intro_mclassdef
.mmodule
then
820 hm
[mmodule
].add
(prop
)
824 if childs
!= null then
825 for child
in childs
do
826 if not hm
.has_key
(child
) then hm
[child
] = new HashSet[MMethod]
827 for prop
in intro_methods
do
828 if child
== prop
.intro_mclassdef
.mmodule
then
829 prop
.is_redef
= false
833 for prop
in redef_methods
do
834 if child
== prop
.intro_mclassdef
.mmodule
then
847 # Create a tool context to handle options and paths
848 var toolcontext
= new ToolContext
849 toolcontext
.process_options
851 # Here we launch the nit index
852 var nitdoc
= new Nitdoc(toolcontext
)