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.
17 # The main module of the nitdoc program
25 # Store knowledge and facilities to generate files
27 special AbstractCompiler
28 # Destination directory
29 readable writable var _dir
: String = "."
31 # Content of a generated file
32 var _stage_context
: StageContext = new StageContext(null)
34 # Add a string in the content
36 _stage_context
.content
.add
(s
)
37 _stage_context
.validate
= true
40 # Add a string in the content iff some other string are added
41 fun stage
(s
: String) do _stage_context
.content
.add
(s
)
43 # Create a new stage in the content
44 fun open_stage
do _stage_context
= new StageContext(_stage_context
)
46 # Close the current stage in the content
49 var s
= _stage_context
.parent
50 if _stage_context
.validate
then
51 s
.content
.add_all
(_stage_context
.content
)
58 # Write the content to a new file
59 fun write_to
(filename
: String)
61 var f
= new OFStream.open
(filename
)
62 for s
in _stage_context
.content
do
68 # Currently computed mmmodule
69 readable var _mmmodule
: nullable MMSrcModule
71 # Is the current directory module computed as a simple modude ?
72 readable writable var _inside_mode
: Bool = false
74 # Is the current module computed as a intruded one ?
75 readable writable var _intrude_mode
: Bool = false
77 # Compued introducing entities (for the index)
78 var _entities
: Array[MMEntity] = new Array[MMEntity]
80 # Register an entity (for the index)
81 fun register
(e
: MMEntity)
84 if e
isa MMSrcModule then
92 _stage_context
= new StageContext(null)
95 # Generate common files (frames, index, overview)
98 info
("Generating other files",1)
103 add
("<html><body>\n")
104 add
("<a href=\"overview
.html\
" target=\"mainFrame\
">Overview</a><br/>\n")
105 add
("<a href=\"index-1
.html\
" target=\"mainFrame\
">Index</a><br/>\n")
106 var modules
= modules
.to_a
109 var rootdirs
= new Array[MMDirectory]
112 if md
.parent
== null and not rootdirs
.has
(md
) then
117 var done
= new Array[MMModule]
118 for root
in rootdirs
do
119 var dirstack
= [root
]
121 add
("{root.name}<br/>\n")
122 var indent
= " "
123 while not dirstack
.is_empty
do
126 if done
.has
(m
) then continue
128 if md
.owner
== m
and md
.parent
== curdir
then
129 # It's a directory module
130 add
("{indent}<a href=\"{m}.html\
" target=\"mainFrame\
">{m}</a><br/>\n")
132 dirstack
.push
(curdir
)
133 indent
= "  " * dirstack
.length
135 break # restart to preserve alphabetic order
136 else if md
== curdir
then
137 if md
.owner
== m
then
138 add
("{indent}<a href=\"{m}_
.html\
" target=\"mainFrame\
">{m}</a><br/>\n")
140 add
("{indent}<a href=\"{m}.html\
" target=\"mainFrame\
">{m}</a><br/>\n")
148 if not dirstack
.is_empty
then
149 curdir
= dirstack
[dirstack
.length-1
]
150 indent
= "  " * dirstack
.length
155 add
("</body></html>\n")
156 write_to
("{dir}/menu-frame.html")
162 for e
in _entities
do
163 add
("<dt><b>{e.html_link(self)}</b> - {e.prototype_head(self)} <b>{e}</b>{e.prototype_body(self)} {e.locate(self)}<dd>{e.short_doc}\n")
165 add
("</dl></body></html>\n")
166 write_to
("{dir}/index-1.html")
169 add_header
("Overview")
170 add
("<table border=\"1\
" width=\"100%\
" cellpadding=\"3\
" cellspacing=\"0\
">\n")
171 add
("<tr bgcolor=\"#CCCCFF\"><th colspan=\"2\"><big>Overview of all Modules</big></th><tr>\n")
173 add
("<tr><td width=\"20%\
" align=\"right\
">{m.html_link(self)}</td><td>{m.short_doc}</td><tr>\n")
175 add
("</table></body></html>\n")
176 write_to
("{dir}/overview.html")
179 add
("<html>\n<frameset cols=\"20%,80%\
">\n<frame src=\"menu-frame
.html\
" name=\"menuFrame\
" title=\"Menu\
">\n<frame src=\"overview
.html\
" name=\"mainFrame\
" title=\"Main\
" scrolling=\"yes\
">\n</frameset></html>\n")
180 write_to
("{dir}/index.html")
183 fun add_header
(title
: String)
185 add
("<html><head><title>{title}</title></head>\n<body>\n")
186 add
("<table border=\"0\
" width=\"100%\
" cellpadding=\"1\
" cellspacing=\"0\
"><tr><td bgcolor=\"#eeeeff\">\n")
187 add
("<a href=\"overview
.html\
"><b>Overview</b></a> <a href=\"index-1
.html\
"><b>Index</b></a> <a href=\"index
.html\
" target=\"_top\
"><b>With Frames</b></a>\n")
188 add
("</td></tr></table>")
191 if (not inside_mode
and not intrude_mode
) or mod
== null then
192 add
("<b>Public</b> ")
194 add
("<a href=\"{mod}.html\
"><b>Public</b></a> ")
196 if inside_mode
or mod
== null then
197 add
("<b>Inside</b> ")
198 else if mod
.directory
.owner
!= mod
then
199 add
("<strike><b>Inside</b></strike> ")
201 add
("<a href=\"{mod}_
.html\
"><b>Inside</b></a> ")
203 if intrude_mode
or mod
== null then
204 add
("<b>Intrude</b> ")
206 add
("<a href=\"{mod}__
.html\
"><b>Intrude</b></a> ")
211 # Sorter of entities in alphabetical order
212 var _sorter
: AlphaSorter[MMEntity] = new AlphaSorter[MMEntity]
214 # Sort entities in the alphabetical order
215 fun sort
(array
: Array[MMEntity])
220 readable writable var _owned_modules
: Array[MMModule] = new Array[MMModule]
222 # Return the known_owner for current module
223 # if inside_mode is set, it could be a different result
224 fun known_owner_of
(m
: MMModule): MMModule
227 if mod
== null then return m
228 var res
= mod
.known_owner_of
(m
)
229 if not inside_mode
and not intrude_mode
and res
.directory
.owner
== mod
then
236 readable var _opt_dir
: OptionString = new OptionString("Directory where doc is generated", "-d", "--dir")
238 redef fun perform_work
(mods
)
242 for mod
in modules
do
243 assert mod
isa MMSrcModule
244 mod
.extract_module_doc
(self)
246 self.extract_other_doc
253 option_context
.add_option
(opt_dir
)
256 redef fun process_options
259 var d
= opt_dir
.value
260 if d
!= null then dir
= d
264 # Conditionnal part of the text content of a DocContext
266 # Content of the current stage
267 readable var _content
: Array[String] = new Array[String]
269 # Is a normal string already added?
270 readable writable var _validate
: Bool = false
272 # Parent stage is any
273 readable var _parent
: nullable StageContext = null
275 init(parent
: nullable StageContext) do _parent
= parent
279 # Efficiently sort object with their to_s method
280 class AlphaSorter[E
: Object]
281 special AbstractSorter[E
]
282 redef fun compare
(a
, b
)
302 # Keep track of to_s values
303 var _dico
: HashMap[Object, String] = new HashMap[Object, String]
308 # Generalization of metamodel entities
311 fun html_link
(dctx
: DocContext): String is abstract
313 # Is the entity should appear in the generaed doc
314 fun need_doc
(dctx
: DocContext): Bool is abstract
316 # Return a one liner description
317 fun short_doc
: String do return " "
319 # The doc node from the AST
320 # Return null is none
321 fun doc
: nullable ADoc do return null
323 # Human redable location of the entity (module/class/property)
324 fun locate
(dctx
: DocContext): String do return ""
326 # Part of the prototype before the name (kind, modifiers, qualifier)
327 fun prototype_head
(dctx
: DocContext): String is abstract
329 # Part of the property after the name (signature, modifiers)
330 fun prototype_body
(dctx
: DocContext): String do return ""
335 redef fun html_link
(dctx
) do
336 if dctx
.mmmodule
== self then
339 return "<a href=\"{self}.html\
">{self}</a>"
342 redef fun need_doc
(dctx
) do return true
343 redef fun prototype_head
(dctx
) do return "module "
345 var _known_owner_of_cache
: Map[MMModule, MMModule] = new HashMap[MMModule, MMModule]
347 # Return the owner of `module` from the point of view of `self`
348 fun known_owner_of
(mod
: MMModule): MMModule
350 if _known_owner_of_cache
.has_key
(mod
) then return _known_owner_of_cache
[mod
]
352 # is module is publicly imported by self?
353 if mhe
< mod
and visibility_for
(mod
) != 0 then
354 res
= known_owner_of_intern
(mod
, self, false)
356 # Return the canonnical owner of module from the point of view of self
357 res
= mod
.owner
(self)
359 _known_owner_of_cache
[mod
] = res
363 # Return the most general module that own self
364 fun owner
(from
: MMModule): MMModule
367 var d
: nullable MMDirectory = directory
368 while d
!= null and d
!= from
.directory
do
370 if o
!= null and o
.mhe
<= res
then res
= o
377 private fun known_owner_of_intern
(mod
: MMModule, from
: MMModule, as_owner
: Bool): MMModule
379 if mod
== self then return self
380 var candidates
= new Array[MMModule]
381 for m
in explicit_imported_modules
do
382 if from
.visibility_for
(m
) == 0 then continue
383 if not m
.mhe
<= mod
then continue
384 candidates
.add
(m
.known_owner_of_intern
(mod
, from
, true))
386 # FIXME: I do not know what this does
387 if candidates
.is_empty
then return mod
.owner
(from
)
388 var max
= candidates
.first
389 for m
in candidates
do
390 if max
.mhe
< m
then max
= m
392 if as_owner
and max
.directory
.owner
== self then
401 redef class MMLocalProperty
403 # Anchor of the property description in the module html file
404 fun html_anchor
: String
406 return "PROP_{local_class}_{cmangle(name)}"
409 redef fun html_link
(dctx
)
412 if not need_doc
(dctx
) then m
= global
.intro
.mmmodule
413 m
= dctx
.known_owner_of
(m
)
414 if m
== dctx
.mmmodule
then
415 return "<a href=\"#{html_anchor}\">{self}</a>"
417 return "<a href=\"{m}.html
#{html_anchor}\">{self}</a>"
421 # Kind of property (fun, attr, etc.)
422 fun kind
: String is abstract
424 redef fun locate
(dctx
)
426 return "in {mmmodule.html_link(dctx)}::{local_class.html_link(dctx)}"
429 fun known_intro_class
(dctx
: DocContext): MMLocalClass
431 var mod
= dctx
.known_owner_of
(global
.intro
.local_class
.mmmodule
)
432 var cla
= mod
[global
.intro
.local_class
.global
]
436 redef fun prototype_head
(dctx
)
439 var intro_class
= known_intro_class
(dctx
)
440 var is_redef
= local_class
!= intro_class
442 if is_redef
then res
.append
("redef ")
443 if global
.visibility_level
== 2 then
444 res
.append
("protected ")
445 else if global
.visibility_level
== 3 then
446 res
.append
("private ")
450 var gp
= global
.intro
451 if intro_class
.global
!= local_class
.global
then
452 res
.append
(" {mmmodule[intro_class.global].html_link(dctx)}::")
453 else if intro_class
.mmmodule
!= mmmodule
then
454 res
.append
(" {intro_class.mmmodule.html_link(dctx)}::")
460 redef fun prototype_body
(dctx
)
463 res
.append
(signature
.to_html
(dctx
, true))
465 if s
isa MMMethod then
466 if s
.is_abstract
then
467 res
.append
(" is abstract")
468 else if s
.is_intern
then
469 res
.append
(" is intern")
475 redef fun need_doc
(dctx
)
477 if global
.visibility_level
>= 3 or self isa MMAttribute then
478 if not dctx
.intrude_mode
then return false
479 if dctx
.mmmodule
.visibility_for
(mmmodule
) == 0 then return false
481 if global
.intro
== self then
492 else if global
.intro
== self then
495 return global
.intro
.short_doc
502 if n
== null or not n
isa APropdef then
509 if d
.n_comment
.is_empty
then
517 redef fun kind
do return if global
.is_init
then "init" else "fun"
519 redef class MMAttribute
520 redef fun kind
do return "var"
522 redef class MMTypeProperty
523 redef fun kind
do return "type"
526 redef class MMSrcModule
527 # Extract and generate html file for the module
528 fun extract_module_doc
(dctx
: DocContext)
530 dctx
.info
("Generating HTML for module {name}",1)
534 extract_module_doc_inside
(dctx
)
535 dctx
.write_to
("{dctx.dir}/{name}.html")
537 dctx
.intrude_mode
= true
539 extract_module_doc_inside
(dctx
)
540 dctx
.write_to
("{dctx.dir}/{name}__.html")
541 dctx
.intrude_mode
= false
543 if directory
.owner
== self then
544 dctx
.inside_mode
= true
546 extract_module_doc_inside
(dctx
)
547 dctx
.write_to
("{dctx.dir}/{name}_.html")
548 dctx
.inside_mode
= false
552 fun extract_module_doc_inside
(dctx
: DocContext)
554 dctx
.add_header
("Module {self}")
555 dctx
.add
("<h1>Module {self}</h1>\n<dl>")
557 var d
: nullable MMDirectory = directory
559 if d
.owner
!= null and (d
.owner
!= self or dctx
.inside_mode
or dctx
.intrude_mode
) then
560 s
= "{d.owner.html_link(dctx)}::{s}"
564 dctx
.add
("{s}<br/>{prototype_head(dctx)}<b>{self}</b>{prototype_body(dctx)}<br/>\n")
566 var strs
= new Array[String]
567 var intrude_modules
= new Array[MMModule]
568 var public_modules
= new Array[MMModule]
569 var private_modules
= new Array[MMModule]
570 var owned_modules
= dctx
.owned_modules
572 for m
in mhe
.greaters
do
573 var v
= visibility_for
(m
)
574 if not dctx
.inside_mode
and not dctx
.intrude_mode
and m
.directory
.owner
== self then
575 if v
>= 2 then owned_modules
.add
(m
)
579 intrude_modules
.add
(m
)
581 public_modules
.add
(m
)
583 private_modules
.add
(m
)
586 if not intrude_modules
.is_empty
then
587 var mods
= mhe
.order
.select_smallests
(intrude_modules
)
588 for i
in mods
do strs
.add
(i
.html_link
(dctx
))
589 dctx
.add
("<dt>Intruded modules: <dd>{strs.join(", ")}\n")
591 if not public_modules
.is_empty
then
593 var mods
= mhe
.order
.select_smallests
(public_modules
)
594 for i
in mods
do strs
.add
(i
.html_link
(dctx
))
595 dctx
.add
("<dt>Imported modules: <dd>{strs.join(", ")}\n")
597 if not private_modules
.is_empty
then
599 var mods
= mhe
.order
.select_smallests
(private_modules
)
600 for i
in mods
do strs
.add
(i
.html_link
(dctx
))
601 dctx
.add
("<dt>Privatly imported modules: <dd>{strs.join(", ")}\n")
606 if doc
!= null then dctx
.add
("<pre>{doc.to_html}</pre>\n")
608 var new_classes
= new Array[MMLocalClass]
609 for c
in local_classes
do
610 if c
.need_doc
(dctx
) then
612 if c
.global
.intro
== c
then
616 for m
in owned_modules
do
617 if m
.global_classes
.has
(c
.global
) then
619 if mc
.need_doc
(dctx
) then
628 if not new_classes
.is_empty
then
629 dctx
.sort
(new_classes
)
630 dctx
.add
("<table border=\"1\
" width=\"100%\
" cellpadding=\"3\
" cellspacing=\"0\
">\n")
631 dctx
.add
("<tr bgcolor=\"#CCCCFF\"><th colspan=\"2\"><big>Class Summary of {self}</big></th><tr>\n")
632 for c
in new_classes
do
633 dctx
.add
("<tr><td width=\"20%\
" align=\"right\
">{c.prototype_head(dctx)}</td><td><b>{c.html_link(dctx)}</b>{c.prototype_body(dctx)}<br/>{c.short_doc}</td><tr>\n")
635 dctx
.add
("</table><br/>\n")
638 if not new_classes
.is_empty
then
639 dctx
.add
("<table border=\"1\
" width=\"100%\
" cellpadding=\"3\
" cellspacing=\"0\
">\n")
640 dctx
.add
("<tr bgcolor=\"#CCCCFF\"><th><big>Class Detail of {self}</big></th><tr>\n")
641 dctx
.add
("</table>\n")
643 for c
in new_classes
do
644 c
.extract_class_doc
(dctx
)
648 dctx
.add
("</body></html>\n")
664 if n
.n_moduledecl
== null then
667 var np
= n
.n_moduledecl
672 if d
.n_comment
.is_empty
then
681 # Html transcription of the doc
685 for c
in n_comment
do
686 res
.append
(c
.text
.substring_from
(1))
691 # Oneliner transcription of the doc
694 return n_comment
.first
.text
.substring_from
(1)
698 redef class MMLocalClass
700 # Anchor of the class description in the module html file
701 fun html_anchor
: String do return "CLASS_{self}"
703 redef fun html_link
(dctx
)
706 if not need_doc
(dctx
) then m
= global
.mmmodule
707 m
= dctx
.known_owner_of
(m
)
708 if m
== dctx
.mmmodule
then
709 return "<a href=\"#{html_anchor}\">{self}</a>"
711 return "<a href=\"{m}.html
#{html_anchor}\">{self}</a>"
715 redef fun short_doc
do return global
.intro
.short_doc
717 redef fun doc
do return global
.intro
.doc
719 redef fun need_doc
(dctx
) do
720 if mmmodule
== dctx
.mmmodule
then
721 for m
in dctx
.owned_modules
do
722 if m
.global_classes
.has
(global
) then
724 if c
.need_doc
(dctx
) then return true
731 redef fun locate
(dctx
) do return "in {mmmodule.html_link(dctx)}"
733 fun known_intro
(dctx
: DocContext): MMLocalClass do return dctx
.known_owner_of
(global
.intro
.mmmodule
)[global
]
735 redef fun prototype_head
(dctx
)
738 var ki
= known_intro
(dctx
)
739 var is_redef
= ki
!= self
740 if is_redef
then res
.append
("redef ")
741 if global
.visibility_level
== 3 then res
.append
("private ")
743 if is_redef
then res
.append
("{ki.mmmodule.html_link(dctx)}::")
747 redef fun prototype_body
(dctx
)
752 for i
in [0..arity
[ do
753 var t
= get_formal
(i
)
754 res
.append
(t
.name
.to_s
)
756 res
.append
(t
.bound
.html_link
(dctx
))
763 # Extract the doc of a class
764 fun extract_class_doc
(dctx
: DocContext)
766 dctx
.add
("<a name=\"{html_anchor}\
"></a><h2>{self}</h2><small>{mmmodule.html_link(dctx)}::</small><br/>{prototype_head(dctx)}<b>{self}</b>{prototype_body(dctx)}\n")
767 dctx
.add
("<blockquote>\n")
770 var sup2
= new Array[String]
771 var intro_module
= dctx
.known_owner_of
(global
.mmmodule
)
772 if intro_module
!= mmmodule
then
773 dctx
.add
("<dt>Refine {self} from: <dd>{intro_module.html_link(dctx)}\n")
775 var mods
= new Array[MMModule]
776 for c
in crhe
.greaters
do
777 if c
.need_doc
(dctx
) then
778 var km
= dctx
.known_owner_of
(c
.mmmodule
)
779 if km
!= mmmodule
and km
!= intro_module
and not mods
.has
(km
) then
784 for c
in crhe
.linear_extension
do
785 if mods
.has
(c
.mmmodule
) then sup2
.add
(c
.mmmodule
.html_link
(dctx
))
787 if not sup2
.is_empty
then dctx
.add
("<dt>Previous refinements in: <dd>{sup2.join(", ")}\n")
789 if not cshe
.greaters
.is_empty
then
791 var clas
= new Array[MMLocalClass]
792 for c
in cshe
.direct_greaters
do
793 sup2
.add
(c
.html_link
(dctx
))
795 dctx
.add
("<dt>Direct superclasses: <dd>{sup2.join(", ")}\n")
797 for c
in cshe
.linear_extension
do
798 if c
!= self then sup2
.add
(c
.html_link
(dctx
))
800 dctx
.add
("<dt>All superclasses: <dd>{sup2.join(", ")}\n")
802 if not cshe
.direct_smallers
.is_empty
then
804 for c
in cshe
.direct_smallers
do
805 sup2
.add
(c
.html_link
(dctx
))
807 dctx
.add
("<dt>Direct subclasses: <dd>{sup2.join(", ")}\n")
810 for c
in crhe
.smallers
do
811 c
.compute_super_classes
812 for c2
in c
.mmmodule
.local_classes
do
813 if not c2
isa MMConcreteClass then continue
814 c2
.compute_super_classes
817 for c2
in c
.cshe
.direct_smallers
do
818 if c2
.global
.intro
== c2
then
819 sup2
.add
("{c2.html_link(dctx)}")
823 if not sup2
.is_empty
then
824 dctx
.add
("<dt>Other direct subclasses in known modules: <dd>{sup2.join(", ")}\n")
827 for c
in crhe
.order
do
828 if not mmmodule
.mhe
<= c
.mmmodule
and c
.need_doc
(dctx
) then
829 sup2
.add
(c
.mmmodule
.html_link
(dctx
))
832 if not sup2
.is_empty
then
833 dctx
.add
("<dt>Refinements in known modules: <dd>{sup2.join(", ")}\n")
839 dctx
.add
("<pre>{doc.to_html}</pre>\n")
842 var details
= new Array[Array[MMLocalProperty]]
843 for i
in [0..4[ do details
.add
(property_summary
(dctx
, i
))
844 for i
in [0..4[ do property_detail
(dctx
, i
, details
[i
])
846 dctx
.add
("</blockquote><hr/>\n")
849 fun pass_name
(pass
: Int): String
851 var names
= once
["Virtual Types", "Consructors", "Methods", "Attributes"]
855 fun accept_prop
(p
: MMLocalProperty, pass
: Int): Bool
858 return p
isa MMTypeProperty
859 else if pass
== 1 then
860 return p
.global
.is_init
861 else if pass
== 2 then
862 return p
isa MMMethod and not p
.global
.is_init
863 else if pass
== 3 then
864 return p
isa MMAttribute
869 fun property_summary
(dctx
: DocContext, pass
: Int): Array[MMLocalProperty]
871 var passname
= pass_name
(pass
)
873 dctx
.stage
("<table border=\"1\
" width=\"100%\
" cellpadding=\"3\
" cellspacing=\"0\
">\n")
874 dctx
.stage
("<tr bgcolor=\"#CCCCFF\"><th colspan=\"2\">{passname} Summary of {self}</th></tr>\n")
876 var new_props
= new Array[MMLocalProperty]
877 for g
in global_properties
do
878 if not accept_prop
(g
.intro
, pass
) then continue
879 if mmmodule
.visibility_for
(g
.intro
.mmmodule
) < g
.visibility_level
then continue
881 if p
.local_class
!= self or not p
.need_doc
(dctx
) then
882 var cla
= new Array[MMLocalClass]
883 for m
in dctx
.owned_modules
do
884 if not m
.global_classes
.has
(global
) then continue
886 if not c
isa MMConcreteClass then continue
887 if not c
.has_global_property
(g
) then continue
889 if p2
.local_class
!= c
or not p2
.need_doc
(dctx
) then continue
892 if cla
.is_empty
then continue
893 cla
= crhe
.order
.select_smallests
(cla
)
897 if p
.global
.intro
== p
then
902 for p
in new_props
do
903 dctx
.add
("<tr><td width=\"20%\
" align=\"right\
">{p.prototype_head(dctx)}</td><td><b>{p.html_link(dctx)}</b>{p.prototype_body(dctx)}<br/> {p.short_doc}</td></tr>\n")
905 dctx
.stage
("</table><br/>\n")
908 dctx
.stage
("<table border=\"1\
" width=\"100%\
" cellpadding=\"3\
" cellspacing=\"0\
">\n")
910 # skip pass 1 because constructors are not inherited
911 var cmap
= new HashMap[MMLocalClass, Array[MMLocalProperty]]
912 var mmap
= new HashMap[MMModule, Array[MMLocalProperty]]
913 for c
in che
.greaters
do
914 if c
isa MMSrcLocalClass then
915 var km
= dctx
.known_owner_of
(c
.mmmodule
)
916 var kc
= km
[c
.global
]
917 if kc
== self then continue
918 var props
: Array[MMLocalProperty]
919 if km
== mmmodule
then
920 if cmap
.has_key
(kc
) then
923 props
= new Array[MMLocalProperty]
927 if mmap
.has_key
(km
) then
930 props
= new Array[MMLocalProperty]
934 for g
in c
.global_properties
do
936 if p
.local_class
== c
and p
.need_doc
(dctx
) and accept_prop
(p
, pass
) then
943 dctx
.stage
("<tr bgcolor=\"#EEEEFF\"><th colspan=\"2\"><small>Inherited {passname}</small></th><tr>\n")
944 for c
in cshe
.linear_extension
do
945 if not cmap
.has_key
(c
) then continue
947 if props
.is_empty
then continue
949 var properties
= new Array[String]
950 for p
in props
do properties
.add
(p
.html_link
(dctx
))
951 dctx
.add
("<tr><td width=\"20%\
"><small>from {c.html_link(dctx)}</small></td><td><small>{properties.join(", ")}</small></td><tr>\n")
956 dctx
.stage
("<tr bgcolor=\"#EEEEFF\"><th colspan=\"2\"><small>Imported {passname}</small></th><tr>\n")
957 for m
in mmmodule
.mhe
.linear_extension
do
958 if not mmap
.has_key
(m
) then continue
960 if props
.is_empty
then continue
962 var properties
= new Array[String]
963 for p
in props
do properties
.add
(p
.html_link
(dctx
))
964 dctx
.add
("<tr><td width=\"20%\
"><small>from {m.html_link(dctx)}</small></td><td><small>{properties.join(", ")}</small></td><tr>\n")
969 var mmap
= new HashMap[MMModule, Array[MMLocalProperty]]
970 for c
in crhe
.order
do
971 if mmmodule
.mhe
<= c
.mmmodule
or dctx
.owned_modules
.has
(c
.mmmodule
) or not c
isa MMSrcLocalClass then continue
972 var km
= dctx
.known_owner_of
(c
.mmmodule
)
973 if mmmodule
.mhe
<= km
then continue
974 var kc
= km
[c
.global
]
975 var props
: Array[MMLocalProperty]
976 if mmap
.has_key
(km
) then
979 props
= new Array[MMLocalProperty]
982 for g
in c
.global_properties
do
984 if p
.local_class
== c
and p
.need_doc
(dctx
) and accept_prop
(p
, pass
) then
986 if not props
.has
(kp
) then props
.add
(kp
)
989 # c.properties_inherited_from(dctx, self, pass)
992 dctx
.stage
("<tr bgcolor=\"#EEEEFF\"><th colspan=\"2\"><small>Added {passname} in known modules</small></th><tr>\n")
993 for c
in crhe
.order
do
995 if not mmap
.has_key
(m
) then continue
997 if props
.is_empty
then continue
999 var properties
= new Array[String]
1000 for p
in props
do properties
.add
(p
.html_link
(dctx
))
1001 dctx
.add
("<tr><td width=\"20%\
"><small>in {m.html_link(dctx)}</small></td><td><small>{properties.join(", ")}</small></td><tr>\n")
1004 dctx
.stage
("</table><br/><br/>\n")
1011 fun property_detail
(dctx
: DocContext, pass
: Int, new_props
: Array[MMLocalProperty])
1013 var passname
= pass_name
(pass
)
1015 dctx
.stage
("<table border=\"1\
" width=\"100%\
" cellpadding=\"3\
" cellspacing=\"0\
">\n")
1016 dctx
.stage
("<tr bgcolor=\"#CCCCFF\"><th>{passname} Detail of {self}</th><tr>\n")
1017 dctx
.stage
("</table>\n")
1020 for p
in new_props
do
1021 dctx
.add
("<a name=\"{p.html_anchor}\
"></a><h3>{p}</h3><p><small>{p.mmmodule.html_link(dctx)}::{p.local_class.html_link(dctx)}::</small><br/>{p.prototype_head(dctx)} <b>{p.name}</b>{p.prototype_body(dctx)}</p>\n")
1022 dctx
.add
("<blockquote>")
1025 dctx
.add
("<pre>{doc.to_html}</pre>\n")
1027 dctx
.stage
("</blockquote>\n")
1031 dctx
.stage
("<hr/>\n")
1038 # Add rows for properties inheriterd to some heirs
1039 fun properties_inherited_from
(dctx
: DocContext, heir
: MMLocalClass, pass
: Int)
1041 var properties
= new Array[String]
1042 for g
in global_properties
do
1044 if p
.local_class
== self and p
.need_doc
(dctx
) and accept_prop
(p
, pass
) then
1045 properties
.add
(p
.html_link
(dctx
))
1048 if not properties
.is_empty
then
1050 if heir
.global
== global
then
1051 s
= mmmodule
.html_link
(dctx
)
1053 s
= self.html_link
(dctx
)
1055 dctx
.add
("<tr><td width=\"20%\
"><small>in {s}</small></td><td><small>{properties.join(", ")}</small></td><tr>\n")
1060 redef class MMSrcLocalClass
1066 else if global
.intro
== self then
1069 var bc
= global
.intro
1077 if not n
isa AStdClassdef then
1084 if d
.n_comment
.is_empty
then
1091 redef fun need_doc
(dctx
)
1093 if global
.visibility_level
>= 3 then
1094 if not dctx
.intrude_mode
then return false
1095 if dctx
.mmmodule
.visibility_for
(mmmodule
) == 0 then return false
1097 if global
.intro
== self then
1100 for p
in src_local_properties
do
1101 if p
.need_doc
(dctx
) then
1109 redef class MMSignature
1110 # Htlm transcription of the signature (with nested links)
1111 fun to_html
(dctx
: DocContext, with_closure
: Bool): String
1113 var res
= new Buffer
1116 res
.append
(self[0].html_link
(dctx
))
1117 for i
in [1..arity
[ do
1119 res
.append
(self[i
].html_link
(dctx
))
1123 if return_type
!= null then
1125 res
.append
(return_type
.html_link
(dctx
))
1127 if with_closure
then
1128 for c
in closures
do
1130 if c
.is_optional
then res
.append
("[")
1131 if c
.is_break
then res
.append
("break ")
1132 res
.append
("!{c.name}")
1133 res
.append
(c
.signature
.to_html
(dctx
, false))
1134 if c
.is_optional
then res
.append
("]")
1142 # Htlm transcription of the type (with nested links)
1143 fun html_link
(dctx
: DocContext): String do return to_s
1146 redef class MMTypeSimpleClass
1147 redef fun html_link
(dctx
) do return local_class
.html_link
(dctx
)
1150 redef class MMTypeGeneric
1151 redef fun html_link
(dctx
)
1153 var res
= new Buffer
1154 res
.append
(local_class
.html_link
(dctx
))
1156 res
.append
(params
[0].html_link
(dctx
))
1157 for i
in [1..params
.length
[ do
1159 res
.append
(params
[i
].html_link
(dctx
))
1166 var c
= new DocContext