ni_nitdoc: Introduced Classes page
[nit.git] / src / ni_nitdoc.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Copyright 2008 Jean Privat <jean@pryen.org>
4 #
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
8 #
9 # http://www.apache.org/licenses/LICENSE-2.0
10 #
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.
16
17 module ni_nitdoc
18
19 import model_utils
20 import abstract_compiler
21 import html
22
23 class Nitdoc
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
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")
36
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)
45 process_options
46
47 if arguments.length < 1 then
48 toolcontext.option_context.usage
49 exit(1)
50 end
51
52 model = new Model
53 modelbuilder = new ModelBuilder(model, toolcontext)
54
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
61 end
62
63 private fun process_options do
64 if not opt_dir.value is null then
65 destinationdir = opt_dir.value
66 else
67 destinationdir = "nitdoc_directory"
68 end
69 if not opt_sharedir.value is null then
70 sharedir = opt_sharedir.value
71 else
72 var dir = "NIT_DIR".environ
73 if dir.is_empty then
74 dir = "{sys.program_name.dirname}/../share/nitdoc"
75 else
76 dir = "{dir}/share/nitdoc"
77 end
78 sharedir = dir
79 if sharedir is null then
80 print "Error: Cannot locate nitdoc share files. Uses --sharedir or envvar NIT_DIR"
81 abort
82 end
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"
86 abort
87 end
88 end
89 end
90
91 fun start do
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}/")
96 overview
97 fullindex
98 modules
99 end
100 end
101
102 fun overview do
103 var overviewpage = new NitdocOverview.with(modelbuilder.nmodules, self.opt_nodot.value, destinationdir.to_s)
104 overviewpage.save("{destinationdir.to_s}/index.html")
105 end
106
107 fun fullindex do
108 var fullindex = new NitdocFullindex.with(model.mmodules)
109 fullindex.save("{destinationdir.to_s}/full-index.html")
110 end
111
112 fun modules do
113 for mod in modelbuilder.nmodules do
114 var modulepage = new NitdocModules.with(mod)
115 modulepage.save("{destinationdir.to_s}/{mod.mmodule.name}.html")
116 end
117 end
118
119 end
120
121 class NitdocOverview
122 super NitdocPage
123
124 var amodules: Array[AModule]
125
126 # Init with Array[AModule] to get all ifnormations about each MModule containt in a program
127 # opt_nodot to inform about the graph gen
128 # destination: to know where will be saved dot files
129 init with(modules: Array[AModule], opt_nodot: Bool, destination: String) do
130 self.amodules = modules
131 self.opt_nodot = opt_nodot
132 self.destinationdir = destination
133 end
134
135 redef fun head do
136 super
137 add("title").text("Overview | Nit Standard Library")
138 end
139
140 redef fun header do
141 open("header")
142 open("nav").add_class("main")
143 open("ul")
144 add("li").add_class("current").text("Overview")
145 open("li")
146 add_html("<a href=\"full-index.html\">Full Index</a>")
147 close("li")
148 open("li").attr("id", "liGitHub")
149 open("a").add_class("btn").attr("id", "logGitHub")
150 add("img").attr("id", "imgGitHub").attr("src", "resources/icons/github-icon.png")
151 close("a")
152 open("div").add_class("popover bottom")
153 add("div").add_class("arrow").text(" ")
154 open("div").add_class("githubTitle")
155 add("h3").text("Github Sign In")
156 close("div")
157 open("div")
158 add("label").attr("id", "lbloginGit").text("Username")
159 add("input").attr("id", "loginGit").attr("name", "login").attr("type", "text")
160 open("label").attr("id", "logginMessage").text("Hello ")
161 open("a").attr("id", "githubAccount")
162 add("strong").attr("id", "nickName").text(" ")
163 close("a")
164 close("label")
165 close("div")
166 open("div")
167 add("label").attr("id", "lbpasswordGit").text("Password")
168 add("input").attr("id", "passwordGit").attr("name", "password").attr("type", "password")
169 open("div").attr("id", "listBranches")
170 add("label").attr("id", "lbBranches").text("Branch")
171 add("select").add_class("dropdown").attr("id", "dropBranches").attr("name", "dropBranches").attr("tabindex", "1").text(" ")
172 close("div")
173 close("div")
174 open("div")
175 add("label").attr("id", "lbrepositoryGit").text("Repository")
176 add("input").attr("id", "repositoryGit").attr("name", "repository").attr("type", "text")
177 close("div")
178 open("div")
179 add("label").attr("id", "lbbranchGit").text("Branch")
180 add("input").attr("id", "branchGit").attr("name", "branch").attr("type", "text")
181 close("div")
182 open("div")
183 add("a").attr("id", "signIn").text("Sign In")
184 close("div")
185 close("div")
186 close("li")
187 close("ul")
188 close("nav")
189 close("header")
190 end
191
192 redef fun body do
193 super
194 open("div").add_class("page")
195 open("div").add_class("content fullpage")
196 add("h1").text("Nit Standard Library")
197 open("article").add_class("overview")
198 add_html("<p>Documentation for the standard library of Nit<br />Version jenkins-component=stdlib-19<br />Date: TODAY</p>")
199 close("article")
200 open("article").add_class("overview")
201 add("h2").text("Modules")
202 open("ul")
203 add_modules
204 close("ul")
205 process_generate_dot
206 close("article")
207 close("div")
208 close("div")
209 add("footer").text("Nit standard library. Version jenkins-component=stdlib-19.")
210 end
211
212 fun add_modules do
213 var ls = new List[nullable MModule]
214 for amodule in amodules do
215 var mmodule = amodule.mmodule.public_owner
216 if mmodule != null and not ls.has(mmodule) then
217 open("li")
218 add("a").attr("href", "{mmodule.name}.html").text("{mmodule.to_s} ")
219 add_html(amodule.comment)
220 close("li")
221 ls.add(mmodule)
222 end
223 end
224 end
225
226 fun process_generate_dot do
227 var op = new Buffer
228 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")
229 for amodule in amodules do
230 op.append("\"{amodule.mmodule.name}\"[URL=\"{amodule.mmodule.name}.html\"];\n")
231 for mmodule2 in amodule.mmodule.in_importation.direct_greaters do
232 op.append("\"{amodule.mmodule.name}\"->\"{mmodule2.name}\";\n")
233 end
234 end
235 op.append("\}\n")
236 generate_dot(op.to_s, "dep", "Modules hierarchy")
237 end
238
239 end
240
241 class NitdocFullindex
242 super NitdocPage
243
244 var mmodules: Array[MModule]
245
246 init with(mmodules: Array[MModule]) do
247 self.mmodules = mmodules
248 opt_nodot = false
249 destinationdir = ""
250 end
251
252 redef fun head do
253 super
254 add("title").text("Full Index | Nit Standard Library")
255 end
256
257 redef fun header do
258 open("header")
259 open("nav").add_class("main")
260 open("ul")
261 open("li")
262 add_html("<a href=\"index.html\">Overview</a>")
263 close("li")
264 add("li").add_class("current").text("Full Index")
265 open("li").attr("id", "liGitHub")
266 open("a").add_class("btn").attr("id", "logGitHub")
267 add("img").attr("id", "imgGitHub").attr("src", "resources/icons/github-icon.png")
268 close("a")
269 open("div").add_class("popover bottom")
270 add("div").add_class("arrow").text(" ")
271 open("div").add_class("githubTitle")
272 add("h3").text("Github Sign In")
273 close("div")
274 open("div")
275 add("label").attr("id", "lbloginGit").text("Username")
276 add("input").attr("id", "loginGit").attr("name", "login").attr("type", "text")
277 open("label").attr("id", "logginMessage").text("Hello ")
278 open("a").attr("id", "githubAccount")
279 add("strong").attr("id", "nickName").text(" ")
280 close("a")
281 close("label")
282 close("div")
283 open("div")
284 add("label").attr("id", "lbpasswordGit").text("Password")
285 add("input").attr("id", "passwordGit").attr("name", "password").attr("type", "password")
286 open("div").attr("id", "listBranches")
287 add("label").attr("id", "lbBranches").text("Branch")
288 add("select").add_class("dropdown").attr("id", "dropBranches").attr("name", "dropBranches").attr("tabindex", "1").text(" ")
289 close("div")
290 close("div")
291 open("div")
292 add("label").attr("id", "lbrepositoryGit").text("Repository")
293 add("input").attr("id", "repositoryGit").attr("name", "repository").attr("type", "text")
294 close("div")
295 open("div")
296 add("label").attr("id", "lbbranchGit").text("Branch")
297 add("input").attr("id", "branchGit").attr("name", "branch").attr("type", "text")
298 close("div")
299 open("div")
300 add("a").attr("id", "signIn").text("Sign In")
301 close("div")
302 close("div")
303 close("li")
304 close("ul")
305 close("nav")
306 close("header")
307 end
308
309 redef fun body do
310 super
311 open("div").add_class("page")
312 open("div").add_class("content fullpage")
313 add("h1").text("Full Index")
314 add_content
315 close("div")
316 close("div")
317 add("footer").text("Nit standard library. Version jenkins-component=stdlib-19.")
318 end
319
320 fun add_content do
321 module_column
322 classes_column
323 properties_column
324 end
325
326 # Add to content modules column
327 fun module_column do
328 var ls = new List[nullable MModule]
329 open("article").add_class("modules filterable")
330 add("h2").text("Modules")
331 open("ul")
332 for mmodule in mmodules do
333 if mmodule.public_owner != null and not ls.has(mmodule.public_owner) then
334 ls.add(mmodule.public_owner)
335 open("li")
336 add("a").attr("href", "{mmodule.public_owner.name}.html").text(mmodule.public_owner.name)
337 close("li")
338 end
339 end
340 close("ul")
341 close("article")
342 end
343
344 # Add to content classes modules
345 fun classes_column do
346 open("article").add_class("classes filterable")
347 add("h2").text("Classes")
348 open("ul")
349
350 for mclass in mmodules.first.imported_mclasses do
351 open("li")
352 add("a").attr("href", "{mclass.name}.html").text(mclass.name)
353 close("li")
354 end
355
356 close("ul")
357 close("article")
358 end
359
360 # Insert the properties column of fullindex page
361 fun properties_column do
362 open("article").add_class("properties filterable")
363 add("h2").text("Properties")
364 open("ul")
365
366 for method in mmodules.first.imported_methods do
367 if method.visibility is none_visibility or method.visibility is intrude_visibility then continue
368 open("li").add_class("intro")
369 add("span").attr("title", "introduction").text("I")
370 add_html("&nbsp;")
371 add("a").attr("href", "{method.local_class.name}.html").attr("title", "").text("{method.name} ({method.local_class.name})")
372 close("li")
373 end
374
375 for method in mmodules.first.redef_methods do
376 if method.visibility is none_visibility or method.visibility is intrude_visibility then continue
377 open("li").add_class("redef")
378 add("span").attr("title", "redefinition").text("R")
379 add_html("&nbsp;")
380 add("a").attr("href", "{method.local_class.name}.html").attr("title", "").text("{method.name} ({method.local_class.name})")
381 close("li")
382 end
383
384 close("ul")
385 close("article")
386 end
387
388 end
389
390 class NitdocModules
391 super NitdocPage
392
393 var amodule: AModule
394 var modulename: String
395 init with(amodule: AModule) do
396 self.amodule = amodule
397 self.modulename = self.amodule.mmodule.name
398 opt_nodot = false
399 destinationdir = ""
400 end
401
402 redef fun head do
403 super
404 add("title").text("{modulename} module | {amodule.short_comment}")
405 end
406
407 redef fun header do
408 open("header")
409 open("nav").add_class("main")
410 open("ul")
411 open("li")
412 add_html("<a href=\"index.html\">Overview</a>")
413 close("li")
414 add("li").add_class("current").text(modulename)
415 open("li")
416 add_html("<a href=\"full-index.html\" >Full Index</a>")
417 close("li")
418 open("li").attr("id", "liGitHub")
419 open("a").add_class("btn").attr("id", "logGitHub")
420 add("img").attr("id", "imgGitHub").attr("src", "resources/icons/github-icon.png")
421 close("a")
422 open("div").add_class("popover bottom")
423 add("div").add_class("arrow").text(" ")
424 open("div").add_class("githubTitle")
425 add("h3").text("Github Sign In")
426 close("div")
427 open("div")
428 add("label").attr("id", "lbloginGit").text("Username")
429 add("input").attr("id", "loginGit").attr("name", "login").attr("type", "text")
430 open("label").attr("id", "logginMessage").text("Hello ")
431 open("a").attr("id", "githubAccount")
432 add("strong").attr("id", "nickName").text(" ")
433 close("a")
434 close("label")
435 close("div")
436 open("div")
437 add("label").attr("id", "lbpasswordGit").text("Password")
438 add("input").attr("id", "passwordGit").attr("name", "password").attr("type", "password")
439 open("div").attr("id", "listBranches")
440 add("label").attr("id", "lbBranches").text("Branch")
441 add("select").add_class("dropdown").attr("id", "dropBranches").attr("name", "dropBranches").attr("tabindex", "1").text(" ")
442 close("div")
443 close("div")
444 open("div")
445 add("label").attr("id", "lbrepositoryGit").text("Repository")
446 add("input").attr("id", "repositoryGit").attr("name", "repository").attr("type", "text")
447 close("div")
448 open("div")
449 add("label").attr("id", "lbbranchGit").text("Branch")
450 add("input").attr("id", "branchGit").attr("name", "branch").attr("type", "text")
451 close("div")
452 open("div")
453 add("a").attr("id", "signIn").text("Sign In")
454 close("div")
455 close("div")
456 close("li")
457 close("ul")
458 close("nav")
459 close("header")
460 end
461
462 redef fun body do
463 super
464 open("div").add_class("page")
465 menu
466 add_content
467 close("div")
468 add("footer").text("Nit standard library. Version jenkins-component=stdlib-19.")
469 end
470
471 # Insert all tags in content part
472 fun add_content do
473 open("div").add_class("content")
474 add("h1").text(modulename)
475 add("div").add_class("subtitle").text("module {modulename}")
476 module_comment
477 classes
478 properties
479 close("div")
480 end
481
482 # Insert module comment in the content
483 fun module_comment do
484 var doc = amodule.comment
485 open("div").attr("id", "description")
486 add("pre").add_class("text_label").text(doc)
487 add("textarea").add_class("edit").attr("rows", "1").attr("cols", "76").attr("id", "fileContent").text(" ")
488 add("a").attr("id", "cancelBtn").text("Cancel")
489 add("a").attr("id", "commitBtn").text("Commit")
490 add("pre").add_class("text_label").attr("id", "preSave").attr("type", "2")
491 close("div")
492 end
493
494 fun menu do
495 var mmodule = amodule.mmodule
496 open("div").add_class("menu")
497 open("nav")
498 add("h3").text("Module Hierarchy").attr("style","cursor: pointer;")
499 if mmodule.in_importation.direct_greaters.length > 0 then
500 add_html("<h4>All dependencies</h4><ul>")
501 for m in mmodule.in_importation.direct_greaters do
502 if m == mmodule or mmodule == m.public_owner then continue
503 open("li")
504 add("a").attr("href", "{m.name}.html").text(m.name)
505 close("li")
506 end
507 add_html("</ul>")
508 end
509 if mmodule.in_importation.greaters.length > 0 then
510 add_html("<h4>All clients</h4><ul>")
511 for m in mmodule.in_importation.greaters do
512 if m == mmodule then continue
513 open("li")
514 add("a").attr("href", "{m.name}.html").text(m.name)
515 close("li")
516 end
517 add_html("</ul>")
518 end
519 close("nav")
520 if mmodule.in_nesting.direct_greaters.length > 0 then
521 open("nav")
522 add("h3").text("Nested Modules").attr("style","cursor: pointer;")
523 open("ul")
524 for m in mmodule.in_nesting.direct_greaters do
525 open("li")
526 add("a").attr("href", "{m.name}.html").text(m.name)
527 close("li")
528 end
529 close("ul")
530
531 close("nav")
532 end
533 close("div")
534 end
535
536 fun classes do
537 open("div").add_class("module")
538 open("article").add_class("classes filterable")
539 add("h2").text("Classes")
540 open("ul")
541 for c, state in amodule.mmodule.mclasses do
542 var name = c.name
543 if state == c_is_intro or state == c_is_imported then
544 open("li").add_class("intro")
545 add("span").attr("title", "introduced in this module").text("I ")
546 else
547 open("li").add_class("redef")
548 add("span").attr("title", "refined in this module").text("R ")
549 end
550 add("a").attr("href", "{name}.html").text(name)
551 close("li")
552 end
553 close("ul")
554 close("article")
555 close("div")
556 end
557
558 fun properties do
559 open("article").add_class("properties filterable")
560 add_html("<h2>Properties</h2>")
561 open("ul")
562 for method in amodule.mmodule.imported_methods do
563 if method.visibility is none_visibility or method.visibility is intrude_visibility then continue
564 open("li").add_class("intro")
565 add("span").attr("title", "introduction").text("I")
566 add_html("&nbsp;")
567 add("a").attr("href", "{method.local_class.name}.html").attr("title", "").text("{method.name} ({method.local_class.name})")
568 close("li")
569 end
570
571 for method in amodule.mmodule.redef_methods do
572 if method.visibility is none_visibility or method.visibility is intrude_visibility then continue
573 open("li").add_class("redef")
574 add("span").attr("title", "redefinition").text("R")
575 add_html("&nbsp;")
576 add("a").attr("href", "{method.local_class.name}.html").attr("title", "").text("{method.name} ({method.local_class.name})")
577 close("li")
578 end
579
580 close("ul")
581 close("article")
582 end
583
584 end
585
586 # Nit Standard Library
587 class NitdocMClasses
588 super NitdocPage
589
590 var mclass: MClass
591 var aclassdef: AClassdef
592 var stdclassdef: nullable AStdClassdef
593 var public_owner: nullable MModule
594
595 init with(mclass: MClass, aclassdef: AClassdef) do
596 self.mclass = mclass
597 self.aclassdef = aclassdef
598 if aclassdef isa AStdClassdef then self.stdclassdef = aclassdef
599 self.public_owner = mclass.intro_mmodule.public_owner
600 opt_nodot = false
601 destinationdir = ""
602 end
603
604 redef fun head do
605 super
606 add("title").text("{self.mclass.name} class | Nit Standard Library")
607 end
608
609 end
610
611 class NitdocPage
612 super HTMLPage
613
614 var opt_nodot: Bool
615 var destinationdir : String
616
617 redef fun head do
618 add("meta").attr("charset", "utf-8")
619 add("script").attr("type", "text/javascript").attr("src", "scripts/jquery-1.7.1.min.js")
620 add("script").attr("type", "text/javascript").attr("src", "quicksearch-list.js")
621 add("script").attr("type", "text/javascript").attr("src", "scripts/js-facilities.js")
622 add("link").attr("rel", "stylesheet").attr("href", "styles/main.css").attr("type", "text/css").attr("media", "screen")
623 end
624
625 redef fun body do header
626 fun header do end
627
628 # Generate a clickable graphviz image using a dot content
629 fun generate_dot(dot: String, name: String, alt: String) do
630 if opt_nodot then return
631 var file = new OFStream.open("{self.destinationdir}/{name}.dot")
632 file.write(dot)
633 file.close
634 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 ; \}")
635 open("article").add_class("graph")
636 add("img").attr("src", "{name}.png").attr("usemap", "#{name}").attr("style", "margin:auto").attr("alt", "{alt}")
637 close("article")
638 var fmap = new IFStream.open("{self.destinationdir}/{name}.map")
639 add_html(fmap.read_all)
640 fmap.close
641 end
642
643 end
644
645 redef class AModule
646 private fun comment: String do
647 var ret = ""
648 if n_moduledecl is null or n_moduledecl.n_doc is null then ret
649 if n_moduledecl.n_doc is null then return ""
650 for t in n_moduledecl.n_doc.n_comment do
651 ret += "{t.text.replace("# ", "")}"
652 end
653 return ret
654 end
655
656 private fun short_comment: String do
657 var ret = ""
658 if n_moduledecl != null and n_moduledecl.n_doc != null then
659 var txt = n_moduledecl.n_doc.n_comment.first.text
660 txt = txt.replace("# ", "")
661 txt = txt.replace("\n", "")
662 ret += txt
663 end
664 return ret
665 end
666 end
667
668 redef class MModule
669
670 var amodule: nullable AModule
671
672 # Get the list of all methods in a module
673 fun imported_methods: Set[MMethod] do
674 var methods = new HashSet[MMethod]
675 for mclass in imported_mclasses do
676 for method in mclass.intro_methods do
677 methods.add(method)
678 end
679 end
680 return methods
681 end
682
683 # Get the list aof all refined methods in a module
684 fun redef_methods: Set[MMethod] do
685 var methods = new HashSet[MMethod]
686 for mclass in redef_mclasses do
687 for method in mclass.intro_methods do
688 methods.add(method)
689 end
690 end
691 return methods
692 end
693 end
694
695 redef class MProperty
696
697 var is_redef: Bool
698 var apropdef: nullable APropdef
699
700 redef init(intro_mclassdef: MClassDef, name: String, visibility: MVisibility)
701 do
702 super
703 is_redef = false
704 end
705
706 fun local_class: MClass do
707 var classdef = self.intro_mclassdef
708 return classdef.mclass
709 end
710
711 end
712
713 redef class MClass
714
715 # Associate all MMethods to each MModule concerns
716 fun all_methods: HashMap[MModule, Set[MMethod]] do
717 var hm = new HashMap[MModule, Set[MMethod]]
718 for mmodule, childs in concerns do
719 if not hm.has_key(mmodule) then hm[mmodule] = new HashSet[MMethod]
720 for prop in intro_methods do
721 if mmodule == prop.intro_mclassdef.mmodule then
722 prop.is_redef = false
723 hm[mmodule].add(prop)
724 end
725 end
726 for prop in redef_methods do
727 if mmodule == prop.intro_mclassdef.mmodule then
728 prop.is_redef = true
729 hm[mmodule].add(prop)
730 end
731 end
732
733 if childs != null then
734 for child in childs do
735 if not hm.has_key(child) then hm[child] = new HashSet[MMethod]
736 for prop in intro_methods do
737 if child == prop.intro_mclassdef.mmodule then
738 prop.is_redef = false
739 hm[child].add(prop)
740 end
741 end
742 for prop in redef_methods do
743 if child == prop.intro_mclassdef.mmodule then
744 prop.is_redef = true
745 hm[child].add(prop)
746 end
747 end
748 end
749 end
750 end
751 return hm
752 end
753
754 end
755
756 # Create a tool context to handle options and paths
757 var toolcontext = new ToolContext
758 toolcontext.process_options
759
760 # Here we launch the nit index
761 var nitdoc = new Nitdoc(toolcontext)
762 nitdoc.start