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 attr _dir
: String
31 # Content of a generated file
32 attr _stage_context
: StageContext = new StageContext(null)
34 # Add a string in the content
35 meth add
(s
: String) do
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 meth stage
(s
: String) do _stage_context
.content
.add
(s
)
43 # Create a new stage in the content
44 meth 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
)
57 # Write the content to a new file
58 meth write_to
(filename
: String)
60 print
"Generate {filename}"
61 var f
= new OFStream.open
(filename
)
62 for s
in _stage_context
.content
do
68 # Currently computed module
69 readable attr _module
: MMSrcModule
71 # Is the current directory module computed as a simple modude ?
72 readable writable attr _inside_mode
: Bool
74 # Is the current module computed as a intruded one ?
75 readable writable attr _intrude_mode
: Bool
77 # Compued introducing entities (for the index)
78 attr _entities
: Array[MMEntity] = new Array[MMEntity]
80 # Register an entity (for the index)
81 meth register
(e
: MMEntity)
84 if e
isa MMSrcModule then
92 _stage_context
= new StageContext(null)
95 # Generate common files (frames, index, overview)
96 meth extract_other_doc
102 add
("<html><body>\n")
103 add
("<a href=\"overview
.html\
" target=\"mainFrame\
">Overview</a><br/>\n")
104 add
("<a href=\"index-1
.html\
" target=\"mainFrame\
">Index</a><br/>\n")
105 var modules
= modules
.to_a
108 var rootdirs
= new Array[MMDirectory]
111 if md
.parent
== null and not rootdirs
.has
(md
) then
116 var done
= new Array[MMModule]
117 for root
in rootdirs
do
118 var dirstack
= [root
]
120 add
("{root.name}<br/>\n")
121 var indent
= " "
122 while not dirstack
.is_empty
do
125 if done
.has
(m
) then continue
127 if md
.owner
== m
and md
.parent
== curdir
then
128 # It's a directory module
129 add
("{indent}<a href=\"{m}.html\
" target=\"mainFrame\
">{m}</a><br/>\n")
131 dirstack
.push
(curdir
)
132 indent
= "  " * dirstack
.length
134 break # restart to preserve alphabetic order
135 else if md
== curdir
then
136 if md
.owner
== m
then
137 add
("{indent}<a href=\"{m}_
.html\
" target=\"mainFrame\
">{m}</a><br/>\n")
139 add
("{indent}<a href=\"{m}.html\
" target=\"mainFrame\
">{m}</a><br/>\n")
147 if not dirstack
.is_empty
then
148 curdir
= dirstack
[dirstack
.length-1
]
149 indent
= "  " * dirstack
.length
154 add
("</body></html>\n")
155 write_to
("{dir}/menu-frame.html")
161 for e
in _entities
do
162 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")
164 add
("</dl></body></html>\n")
165 write_to
("{dir}/index-1.html")
168 add_header
("Overview")
169 add
("<table border=\"1\
" width=\"100%\
" cellpadding=\"3\
" cellspacing=\"0\
">\n")
170 add
("<tr bgcolor=\"#CCCCFF\"><th colspan=\"2\"><big>Overview of all Modules</big></th><tr>\n")
172 add
("<tr><td width=\"20%\
" align=\"right\
">{m.html_link(self)}</td><td>{m.short_doc}</td><tr>\n")
174 add
("</table></body></html>\n")
175 write_to
("{dir}/overview.html")
178 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")
179 write_to
("{dir}/index.html")
182 meth add_header
(title
: String)
184 add
("<html><head><title>{title}</title></head>\n<body>\n")
185 add
("<table border=\"0\
" width=\"100%\
" cellpadding=\"1\
" cellspacing=\"0\
"><tr><td bgcolor=\"#eeeeff\">\n")
186 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")
187 add
("</td></tr></table>")
189 if (not inside_mode
and not intrude_mode
) or module == null then
190 add
("<b>Public</b> ")
192 add
("<a href=\"{module}.html\
"><b>Public</b></a> ")
194 if inside_mode
or module == null then
195 add
("<b>Inside</b> ")
196 else if module.directory
.owner
!= module then
197 add
("<strike><b>Inside</b></strike> ")
199 add
("<a href=\"{module}_
.html\
"><b>Inside</b></a> ")
201 if intrude_mode
or module == null then
202 add
("<b>Intrude</b> ")
204 add
("<a href=\"{module}__
.html\
"><b>Intrude</b></a> ")
209 # Sorter of entities in alphabetical order
210 attr _sorter
: AlphaSorter[MMEntity] = new AlphaSorter[MMEntity]
212 # Sort entities in the alphabetical order
213 meth sort
(array
: Array[MMEntity])
218 readable writable attr _owned_modules
: Array[MMModule]
220 # Return the known_owner for current module
221 # if inside_mode is set, it could be a different result
222 meth known_owner_of
(m
: MMModule): MMModule
224 if module == null then return m
225 var res
= module.known_owner_of
(m
)
226 if not inside_mode
and not intrude_mode
and res
.directory
.owner
== module then
233 readable attr _opt_dir
: OptionString = new OptionString("Directory where doc is generated", "-d", "--dir")
235 redef meth perform_work
(mods
)
239 for mod
in modules
do
240 assert mod
isa MMSrcModule
241 mod
.extract_module_doc
(self)
243 self.extract_other_doc
249 option_context
.add_option
(opt_dir
)
252 redef meth process_options
256 if dir
== null then dir
= "."
260 # Conditionnal part of the text content of a DocContext
262 # Content of the current stage
263 readable attr _content
: Array[String] = new Array[String]
265 # Is a normal string already added?
266 readable writable attr _validate
: Bool
268 # Parent stage is any
269 readable attr _parent
: StageContext
271 init(parent
: StageContext) do _parent
= parent
275 # Efficiently sort object with their to_s method
276 class AlphaSorter[E
: Object]
277 special AbstractSorter[E
]
278 redef meth compare
(a
, b
)
298 # Keep track of to_s values
299 attr _dico
: HashMap[Object, String] = new HashMap[Object, String]
304 # Generalization of metamodel entities
307 meth html_link
(dctx
: DocContext): String is abstract
309 # Is the entity should appear in the generaed doc
310 meth need_doc
(dctx
: DocContext): Bool is abstract
312 # Return a one liner description
313 meth short_doc
: String do return " "
315 # The doc node from the AST
316 # Return null is none
317 meth doc
: ADoc do return null
319 # Human redable location of the entity (module/class/property)
320 meth locate
(dctx
: DocContext): String do return ""
322 # Part of the prototype before the name (kind, modifiers, qualifier)
323 meth prototype_head
(dctx
: DocContext): String is abstract
325 # Part of the property after the name (signature, modifiers)
326 meth prototype_body
(dctx
: DocContext): String do return ""
331 redef meth html_link
(dctx
) do
332 if dctx
.module == self then
335 return "<a href=\"{self}.html\
">{self}</a>"
338 redef meth need_doc
(dctx
) do return true
339 redef meth prototype_head
(dctx
) do return "module "
341 attr _known_owner_of_cache
: Map[MMModule, MMModule] = new HashMap[MMModule, MMModule]
342 meth known_owner_of
(module: MMModule): MMModule
344 if _known_owner_of_cache
.has_key
(module) then return _known_owner_of_cache
[module]
346 if mhe
< module and visibility_for
(module) != 0 then
347 res
= known_owner_of_intern
(module, self, false)
349 res
= module.owner
(self)
351 _known_owner_of_cache
[module] = res
355 # Return the most general module that own self
356 meth owner
(from
: MMModule): MMModule
360 while d
!= null and d
!= from
.directory
do
362 if o
!= null and o
.mhe
<= res
then res
= o
368 private meth known_owner_of_intern
(module: MMModule, from
: MMModule, as_owner
: Bool): MMModule
370 if module == self then return self
371 var candidates
= new Array[MMModule]
372 for m
in explicit_imported_modules
do
373 if from
.visibility_for
(m
) == 0 then continue
374 if not m
.mhe
<= module then continue
375 candidates
.add
(m
.known_owner_of_intern
(module, from
, true))
377 assert not candidates
.is_empty
378 var max
= candidates
.first
379 for m
in candidates
do
380 if max
.mhe
< m
then max
= m
382 if as_owner
and max
.directory
.owner
== self then
391 redef class MMLocalProperty
393 # Anchor of the property description in the module html file
394 meth html_anchor
: String
396 return "PROP_{local_class}_{cmangle(name)}"
399 redef meth html_link
(dctx
)
402 if not need_doc
(dctx
) then m
= global
.intro
.module
403 var m
= dctx
.known_owner_of
(m
)
404 if m
== dctx
.module then
405 return "<a href=\"#{html_anchor}\">{self}</a>"
407 return "<a href=\"{m}.html
#{html_anchor}\">{self}</a>"
411 # Kind of property (meth, attr, etc.)
412 meth kind
: String is abstract
414 redef meth locate
(dctx
)
416 return "in {module.html_link(dctx)}::{local_class.html_link(dctx)}"
419 meth known_intro_class
(dctx
: DocContext): MMLocalClass
421 var mod
= dctx
.known_owner_of
(global
.intro
.local_class
.module)
422 var cla
= mod
[global
.intro
.local_class
.global
]
426 redef meth prototype_head
(dctx
)
429 var intro_class
= known_intro_class
(dctx
)
430 var is_redef
= local_class
!= intro_class
432 if is_redef
then res
.append
("redef ")
433 if global
.visibility_level
== 2 then
434 res
.append
("protected ")
435 else if global
.visibility_level
== 3 then
436 res
.append
("private ")
440 var gp
= global
.intro
441 if intro_class
.global
!= local_class
.global
then
442 res
.append
(" {module[intro_class.global].html_link(dctx)}::")
443 else if intro_class
.module != module then
444 res
.append
(" {intro_class.module.html_link(dctx)}::")
450 redef meth prototype_body
(dctx
)
453 res
.append
(signature
.to_html
(dctx
))
455 if s
.node
!= null then
456 if s
.node
isa ADeferredMethPropdef then
457 res
.append
(" is abstract")
458 else if s
.node
isa AInternMethPropdef then
459 res
.append
(" is intern")
465 redef meth need_doc
(dctx
)
467 if global
.visibility_level
>= 3 or self isa MMAttribute then
468 if not dctx
.intrude_mode
then return false
469 if dctx
.module.visibility_for
(module) == 0 then return false
471 if global
.intro
== self then
482 else if global
.intro
== self then
485 return global
.intro
.short_doc
492 if n
== null or not node
isa PPropdef then
495 assert n
isa PPropdef
501 if d
.n_comment
.is_empty
then
509 redef meth kind
do return if global
.is_init
then "init" else "meth"
511 redef class MMAttribute
512 redef meth kind
do return "attr"
514 redef class MMTypeProperty
515 redef meth kind
do return "type"
518 redef class MMSrcModule
519 # Extract and generate html file for the module
520 meth extract_module_doc
(dctx
: DocContext)
525 extract_module_doc_inside
(dctx
)
526 dctx
.write_to
("{dctx.dir}/{name}.html")
528 dctx
.intrude_mode
= true
530 extract_module_doc_inside
(dctx
)
531 dctx
.write_to
("{dctx.dir}/{name}__.html")
532 dctx
.intrude_mode
= false
534 if directory
.owner
== self then
535 dctx
.inside_mode
= true
537 extract_module_doc_inside
(dctx
)
538 dctx
.write_to
("{dctx.dir}/{name}_.html")
539 dctx
.inside_mode
= false
543 meth extract_module_doc_inside
(dctx
: DocContext)
545 dctx
.add_header
("Module {self}")
546 dctx
.add
("<h1>Module {self}</h1>\n<dl>")
550 if d
.owner
!= null and (d
.owner
!= self or dctx
.inside_mode
or dctx
.intrude_mode
) then
551 s
= "{d.owner.html_link(dctx)}::{s}"
555 dctx
.add
("{s}<br/>{prototype_head(dctx)}<b>{self}</b>{prototype_body(dctx)}<br/>\n")
557 var strs
= new Array[String]
558 var intrude_modules
= new Array[MMModule]
559 var public_modules
= new Array[MMModule]
560 var private_modules
= new Array[MMModule]
561 var owned_modules
= new Array[MMModule]
562 dctx
.owned_modules
= owned_modules
563 for m
in mhe
.greaters
do
564 var v
= visibility_for
(m
)
565 if not dctx
.inside_mode
and not dctx
.intrude_mode
and m
.directory
.owner
== self then
566 if v
>= 2 then owned_modules
.add
(m
)
570 intrude_modules
.add
(m
)
572 public_modules
.add
(m
)
574 private_modules
.add
(m
)
577 if not intrude_modules
.is_empty
then
578 var mods
= mhe
.order
.select_smallests
(intrude_modules
)
579 for i
in mods
do strs
.add
(i
.html_link
(dctx
))
580 dctx
.add
("<dt>Intruded modules: <dd>{strs.join(", ")}\n")
582 if not public_modules
.is_empty
then
584 var mods
= mhe
.order
.select_smallests
(public_modules
)
585 for i
in mods
do strs
.add
(i
.html_link
(dctx
))
586 dctx
.add
("<dt>Imported modules: <dd>{strs.join(", ")}\n")
588 if not private_modules
.is_empty
then
590 var mods
= mhe
.order
.select_smallests
(private_modules
)
591 for i
in mods
do strs
.add
(i
.html_link
(dctx
))
592 dctx
.add
("<dt>Privatly imported modules: <dd>{strs.join(", ")}\n")
597 if doc
!= null then dctx
.add
("<pre>{doc.to_html}</pre>\n")
599 var new_classes
= new Array[MMLocalClass]
600 for c
in local_classes
do
601 if c
.need_doc
(dctx
) then
603 if c
.global
.intro
== c
then
607 for m
in owned_modules
do
609 if mc
!= null and mc
.need_doc
(dctx
) then
617 if not new_classes
.is_empty
then
618 dctx
.sort
(new_classes
)
619 dctx
.add
("<table border=\"1\
" width=\"100%\
" cellpadding=\"3\
" cellspacing=\"0\
">\n")
620 dctx
.add
("<tr bgcolor=\"#CCCCFF\"><th colspan=\"2\"><big>Class Summary of {self}</big></th><tr>\n")
621 for c
in new_classes
do
622 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")
624 dctx
.add
("</table><br/>\n")
627 if not new_classes
.is_empty
then
628 dctx
.add
("<table border=\"1\
" width=\"100%\
" cellpadding=\"3\
" cellspacing=\"0\
">\n")
629 dctx
.add
("<tr bgcolor=\"#CCCCFF\"><th><big>Class Detail of {self}</big></th><tr>\n")
630 dctx
.add
("</table>\n")
632 for c
in new_classes
do
633 c
.extract_class_doc
(dctx
)
637 dctx
.add
("</body></html>\n")
653 if not n
isa AModule then
657 if n
.n_packagedecl
== null then
660 var np
= n
.n_packagedecl
661 assert np
isa APackagedecl
667 if d
.n_comment
.is_empty
then
676 # Html transcription of the doc
680 for c
in n_comment
do
681 res
.append
(c
.text
.substring_from
(1))
686 # Oneliner transcription of the doc
689 return n_comment
.first
.text
.substring_from
(1)
693 redef class MMLocalClass
695 # Anchor of the class description in the module html file
696 meth html_anchor
: String do return "CLASS_{self}"
698 redef meth html_link
(dctx
)
701 if not need_doc
(dctx
) then m
= global
.module
702 var m
= dctx
.known_owner_of
(m
)
703 if m
== dctx
.module then
704 return "<a href=\"#{html_anchor}\">{self}</a>"
706 return "<a href=\"{m}.html
#{html_anchor}\">{self}</a>"
710 redef meth short_doc
do return global
.intro
.short_doc
712 redef meth doc
do return global
.intro
.doc
714 redef meth need_doc
(dctx
) do
715 if module == dctx
.module then
716 for m
in dctx
.owned_modules
do
718 if c
!= null and c
.need_doc
(dctx
) then return true
724 redef meth locate
(dctx
) do return "in {module.html_link(dctx)}"
726 meth known_intro
(dctx
: DocContext): MMLocalClass do return dctx
.known_owner_of
(global
.intro
.module)[global
]
728 redef meth prototype_head
(dctx
)
731 var ki
= known_intro
(dctx
)
732 var is_redef
= ki
!= self
733 if is_redef
then res
.append
("redef ")
734 if global
.visibility_level
== 3 then res
.append
("private ")
736 if is_redef
then res
.append
("{ki.module.html_link(dctx)}::")
740 redef meth prototype_body
(dctx
)
745 for i
in [0..arity
[ do
746 var t
= get_formal
(i
)
747 res
.append
(t
.name
.to_s
)
749 res
.append
(t
.bound
.html_link
(dctx
))
756 # Extract the doc of a class
757 meth extract_class_doc
(dctx
: DocContext)
759 dctx
.add
("<a name=\"{html_anchor}\
"></a><h2>{self}</h2><small>{module.html_link(dctx)}::</small><br/>{prototype_head(dctx)}<b>{self}</b>{prototype_body(dctx)}\n")
760 dctx
.add
("<blockquote>\n")
763 var sup2
= new Array[String]
764 var intro_module
= dctx
.known_owner_of
(global
.module)
765 if intro_module
!= module then
766 dctx
.add
("<dt>Refine {self} from: <dd>{intro_module.html_link(dctx)}\n")
768 var mods
= new Array[MMModule]
769 for c
in crhe
.greaters
do
770 if c
.need_doc
(dctx
) then
771 var km
= dctx
.known_owner_of
(c
.module)
772 if km
!= module and km
!= intro_module
and not mods
.has
(km
) then
777 for c
in crhe
.linear_extension
do
778 if mods
.has
(c
.module) then sup2
.add
(c
.module.html_link
(dctx
))
780 if not sup2
.is_empty
then dctx
.add
("<dt>Previous refinements in: <dd>{sup2.join(", ")}\n")
782 if not cshe
.greaters
.is_empty
then
784 var clas
= new Array[MMLocalClass]
785 for c
in cshe
.direct_greaters
do
786 sup2
.add
(c
.html_link
(dctx
))
788 dctx
.add
("<dt>Direct superclasses: <dd>{sup2.join(", ")}\n")
790 for c
in cshe
.linear_extension
do
791 if c
!= self then sup2
.add
(c
.html_link
(dctx
))
793 dctx
.add
("<dt>All superclasses: <dd>{sup2.join(", ")}\n")
795 if not cshe
.direct_smallers
.is_empty
then
797 for c
in cshe
.direct_smallers
do
798 sup2
.add
(c
.html_link
(dctx
))
800 dctx
.add
("<dt>Direct subclasses: <dd>{sup2.join(", ")}\n")
803 for c
in crhe
.smallers
do
804 c
.compute_super_classes
805 for c2
in c
.module.local_classes
do
806 if not c2
isa MMConcreteClass then continue
807 c2
.compute_super_classes
809 c2
.inherit_global_properties
811 for c2
in c
.cshe
.direct_smallers
do
812 if c2
.global
.intro
== c2
then
813 sup2
.add
("{c2.html_link(dctx)}")
817 if not sup2
.is_empty
then
818 dctx
.add
("<dt>Other direct subclasses in known modules: <dd>{sup2.join(", ")}\n")
821 for c
in crhe
.order
do
822 if not module.mhe
<= c
.module and c
.need_doc
(dctx
) then
823 sup2
.add
(c
.module.html_link
(dctx
))
826 if not sup2
.is_empty
then
827 dctx
.add
("<dt>Refinements in known modules: <dd>{sup2.join(", ")}\n")
833 dctx
.add
("<pre>{doc.to_html}</pre>\n")
836 var details
= new Array[Array[MMLocalProperty]]
837 for i
in [0..4[ do details
.add
(property_summary
(dctx
, i
))
838 for i
in [0..4[ do property_detail
(dctx
, i
, details
[i
])
840 dctx
.add
("</blockquote><hr/>\n")
843 meth pass_name
(pass
: Int): String
845 var names
= once
["Virtual Types", "Consructors", "Methods", "Attributes"]
849 meth accept_prop
(p
: MMLocalProperty, pass
: Int): Bool
852 return p
isa MMTypeProperty
853 else if pass
== 1 then
854 return p
.global
.is_init
855 else if pass
== 2 then
856 return p
isa MMMethod and not p
.global
.is_init
857 else if pass
== 3 then
858 return p
isa MMAttribute
863 meth property_summary
(dctx
: DocContext, pass
: Int): Array[MMLocalProperty]
865 var passname
= pass_name
(pass
)
867 dctx
.stage
("<table border=\"1\
" width=\"100%\
" cellpadding=\"3\
" cellspacing=\"0\
">\n")
868 dctx
.stage
("<tr bgcolor=\"#CCCCFF\"><th colspan=\"2\">{passname} Summary of {self}</th></tr>\n")
870 var new_props
= new Array[MMLocalProperty]
871 for g
in global_properties
do
872 if not accept_prop
(g
.intro
, pass
) then continue
873 if module.visibility_for
(g
.intro
.module) < g
.visibility_level
then continue
875 if p
.local_class
!= self or not p
.need_doc
(dctx
) then
876 var cla
= new Array[MMLocalClass]
877 for m
in dctx
.owned_modules
do
879 if c
== null or not c
isa MMConcreteClass then continue
881 if p2
== null or p2
.local_class
!= c
or not p2
.need_doc
(dctx
) then continue
884 if cla
.is_empty
then continue
885 cla
= crhe
.order
.select_smallests
(cla
)
889 if p
.global
.intro
== p
then
894 for p
in new_props
do
895 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")
897 dctx
.stage
("</table><br/>\n")
900 dctx
.stage
("<table border=\"1\
" width=\"100%\
" cellpadding=\"3\
" cellspacing=\"0\
">\n")
902 # skip pass 1 because constructors are not inherited
903 var cmap
= new HashMap[MMLocalClass, Array[MMLocalProperty]]
904 var mmap
= new HashMap[MMModule, Array[MMLocalProperty]]
905 var props
= new Array[MMLocalClass]
906 for c
in che
.greaters
do
907 if c
isa MMSrcLocalClass then
908 var km
= dctx
.known_owner_of
(c
.module)
909 var kc
= km
[c
.global
]
910 if kc
== self or not c
isa MMConcreteClass then continue
911 var props
: Array[MMLocalProperty]
913 if cmap
.has_key
(kc
) then
916 props
= new Array[MMLocalProperty]
920 if mmap
.has_key
(km
) then
923 props
= new Array[MMLocalProperty]
927 for g
in c
.global_properties
do
929 if p
.local_class
== c
and p
.need_doc
(dctx
) and accept_prop
(p
, pass
) then
936 dctx
.stage
("<tr bgcolor=\"#EEEEFF\"><th colspan=\"2\"><small>Inherited {passname}</small></th><tr>\n")
937 for c
in cshe
.linear_extension
do
938 if not cmap
.has_key
(c
) then continue
940 if props
.is_empty
then continue
942 var properties
= new Array[String]
943 for p
in props
do properties
.add
(p
.html_link
(dctx
))
944 dctx
.add
("<tr><td width=\"20%\
"><small>from {c.html_link(dctx)}</small></td><td><small>{properties.join(", ")}</small></td><tr>\n")
949 dctx
.stage
("<tr bgcolor=\"#EEEEFF\"><th colspan=\"2\"><small>Imported {passname}</small></th><tr>\n")
950 for m
in module.mhe
.linear_extension
do
951 if not mmap
.has_key
(m
) then continue
953 if props
.is_empty
then continue
955 var properties
= new Array[String]
956 for p
in props
do properties
.add
(p
.html_link
(dctx
))
957 dctx
.add
("<tr><td width=\"20%\
"><small>from {m.html_link(dctx)}</small></td><td><small>{properties.join(", ")}</small></td><tr>\n")
962 var mmap
= new HashMap[MMModule, Array[MMLocalProperty]]
963 var props
= new Array[MMLocalClass]
964 for c
in crhe
.order
do
965 if module.mhe
<= c
.module or dctx
.owned_modules
.has
(c
.module) or not c
isa MMSrcLocalClass then continue
966 var km
= dctx
.known_owner_of
(c
.module)
967 if module.mhe
<= km
then continue
968 var kc
= km
[c
.global
]
969 var props
: Array[MMLocalProperty]
970 if mmap
.has_key
(km
) then
973 props
= new Array[MMLocalProperty]
976 for g
in c
.global_properties
do
978 if p
.local_class
== c
and p
.need_doc
(dctx
) and accept_prop
(p
, pass
) then
980 if not props
.has
(kp
) then props
.add
(kp
)
983 # c.properties_inherited_from(dctx, self, pass)
986 dctx
.stage
("<tr bgcolor=\"#EEEEFF\"><th colspan=\"2\"><small>Added {passname} in known modules</small></th><tr>\n")
987 for c
in crhe
.order
do
989 if not mmap
.has_key
(m
) then continue
991 if props
.is_empty
then continue
993 var properties
= new Array[String]
994 for p
in props
do properties
.add
(p
.html_link
(dctx
))
995 dctx
.add
("<tr><td width=\"20%\
"><small>in {m.html_link(dctx)}</small></td><td><small>{properties.join(", ")}</small></td><tr>\n")
998 dctx
.stage
("</table><br/><br/>\n")
1005 meth property_detail
(dctx
: DocContext, pass
: Int, new_props
: Array[MMLocalProperty])
1007 var passname
= pass_name
(pass
)
1009 dctx
.stage
("<table border=\"1\
" width=\"100%\
" cellpadding=\"3\
" cellspacing=\"0\
">\n")
1010 dctx
.stage
("<tr bgcolor=\"#CCCCFF\"><th>{passname} Detail of {self}</th><tr>\n")
1011 dctx
.stage
("</table>\n")
1014 for p
in new_props
do
1015 dctx
.add
("<a name=\"{p.html_anchor}\
"></a><h3>{p}</h3><p><small>{p.module.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")
1016 dctx
.add
("<blockquote>")
1019 dctx
.add
("<pre>{doc.to_html}</pre>\n")
1021 dctx
.stage
("</blockquote>\n")
1025 dctx
.stage
("<hr/>\n")
1032 # Add rows for properties inheriterd to some heirs
1033 meth properties_inherited_from
(dctx
: DocContext, heir
: MMLocalClass, pass
: Int)
1035 var properties
= new Array[String]
1036 for g
in global_properties
do
1038 if p
.local_class
== self and p
.need_doc
(dctx
) and accept_prop
(p
, pass
) then
1039 properties
.add
(p
.html_link
(dctx
))
1042 if not properties
.is_empty
then
1044 if heir
.global
== global
then
1045 s
= module.html_link
(dctx
)
1047 s
= self.html_link
(dctx
)
1049 dctx
.add
("<tr><td width=\"20%\
"><small>in {s}</small></td><td><small>{properties.join(", ")}</small></td><tr>\n")
1054 redef class MMSrcLocalClass
1055 redef meth short_doc
1060 else if global
.intro
== self then
1063 var bc
= global
.intro
1071 if not n
isa AClassdef then
1074 assert n
isa AClassdef
1080 if d
.n_comment
.is_empty
then
1087 redef meth need_doc
(dctx
)
1089 if global
.visibility_level
>= 3 then
1090 if not dctx
.intrude_mode
then return false
1091 if dctx
.module.visibility_for
(module) == 0 then return false
1093 if global
.intro
== self then
1096 for p
in src_local_properties
do
1097 if p
.need_doc
(dctx
) then
1105 redef class MMSignature
1106 # Htlm transcription of the signature (with nested links)
1107 meth to_html
(dctx
: DocContext): String
1109 var res
= new Buffer
1112 res
.append
(self[0].html_link
(dctx
))
1113 for i
in [1..arity
[ do
1115 res
.append
(self[i
].html_link
(dctx
))
1119 if return_type
!= null then
1121 res
.append
(return_type
.html_link
(dctx
))
1128 # Htlm transcription of the type (with nested links)
1129 meth html_link
(dctx
: DocContext): String do return to_s
1132 redef class MMTypeSimpleClass
1133 redef meth html_link
(dctx
) do return local_class
.html_link
(dctx
)
1136 redef class MMTypeGeneric
1137 redef meth html_link
(dctx
)
1139 var res
= new Buffer
1140 res
.append
(local_class
.html_link
(dctx
))
1142 res
.append
(params
[0].html_link
(dctx
))
1143 for i
in [1..params
.length
[ do
1145 res
.append
(params
[i
].html_link
(dctx
))
1152 var c
= new DocContext