nitdoc: Display attribute types.
[nit.git] / src / doc / doc_model.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 # Nitdoc model template parts generation
16 module doc_model
17
18 import model_utils
19 import docdown
20 import doc_templates
21 import ordered_tree
22 import model_ext
23
24
25 ################################################################################
26 # Additions to Nit entities.
27
28 redef class MDoc
29 # Comment synopsys HTML escaped
30 fun short_comment: String do return content.first.html_escape
31
32 # Full comment HTML escaped
33 fun full_comment: String do return content.join("\n").html_escape
34
35 # Synopsys in a template
36 fun tpl_short_comment: Streamable do return short_markdown
37
38 # Full comment in a template
39 fun tpl_comment: Streamable do return full_markdown
40 end
41
42 redef class Location
43 # Github url based on this location
44 fun github(gitdir: String): String do
45 var base_dir = getcwd.join_path(gitdir).simplify_path
46 var file_loc = getcwd.join_path(file.filename).simplify_path
47 var gith_loc = file_loc.substring(base_dir.length + 1, file_loc.length)
48 return "{gith_loc}:{line_start},{column_start}--{line_end},{column_end}"
49 end
50 end
51
52 redef class MEntity
53 # HTML Escaped name
54 fun nitdoc_name: String is abstract
55
56 # Used as HTML unique ids
57 fun nitdoc_id: String is abstract
58
59 # URL of this entity Nitdoc page
60 fun nitdoc_url: String is abstract
61
62 # A template link to the mentity `nitdoc_id`
63 fun tpl_anchor: TplLink do
64 var tpl = new TplLink("#{nitdoc_id}", nitdoc_name)
65 if mdoc != null then
66 tpl.title = mdoc.short_comment
67 end
68 return tpl
69 end
70
71 # A template link to the mentity `nitdoc_url`
72 fun tpl_link: TplLink do
73 var tpl = new TplLink(nitdoc_url, nitdoc_name)
74 if mdoc != null then
75 tpl.title = mdoc.short_comment
76 end
77 return tpl
78 end
79
80 # A template article that briefly describe the entity
81 fun tpl_short_article: TplArticle do
82 var tpl = tpl_article
83 if mdoc != null then
84 tpl.content = mdoc.tpl_short_comment
85 end
86 return tpl
87 end
88
89 # A template article that describe the entity
90 fun tpl_article: TplArticle do
91 var tpl = new TplArticle.with_title(nitdoc_id, tpl_title)
92 tpl.title_classes.add "signature"
93 tpl.subtitle = tpl_namespace
94 tpl.summary_title = nitdoc_name
95 return tpl
96 end
97
98 # A template signature that contains modifiers and parameters
99 fun tpl_declaration: Template is abstract
100
101 # A template namespace
102 fun tpl_namespace: Template is abstract
103
104 # A template definition of the mentity
105 # include name, sysnopsys, comment and namespace
106 fun tpl_definition: TplDefinition is abstract
107
108 # A li element that can go in a list
109 fun tpl_list_item: TplListItem do
110 var lnk = new Template
111 lnk.add new TplLabel.with_classes(tpl_css_classes)
112 lnk.add tpl_link
113 if mdoc != null then
114 lnk.add ": "
115 lnk.add mdoc.short_markdown
116 end
117 return new TplListItem.with_content(lnk)
118 end
119
120 fun tpl_css_classes: Array[String] is abstract
121
122 # Box title for this mentity
123 fun tpl_title: Template do
124 var title = new Template
125 title.add tpl_icon
126 title.add tpl_namespace
127 return title
128 end
129
130 # Icon that will be displayed before the title
131 fun tpl_icon: TplIcon do
132 var icon = new TplIcon.with_icon("tag")
133 icon.css_classes.add_all(tpl_css_classes)
134 return icon
135 end
136 end
137
138 redef class MConcern
139 # Return a li element for `self` that can be displayed in a concern list
140 private fun tpl_concern_item: TplListItem do
141 var lnk = new Template
142 lnk.add tpl_anchor
143 if mdoc != null then
144 lnk.add ": "
145 lnk.add mdoc.short_markdown
146 end
147 return new TplListItem.with_content(lnk)
148 end
149 end
150
151 redef class MProject
152 redef fun nitdoc_name do return name.html_escape
153 redef fun nitdoc_id do return nitdoc_name
154 redef fun nitdoc_url do return root.nitdoc_url
155
156 redef fun mdoc do
157 if root != null then
158 return root.mdoc
159 end
160 return super
161 end
162
163 redef fun tpl_declaration do
164 var tpl = new Template
165 tpl.add "<span>project "
166 tpl.add tpl_link
167 tpl.add "</span>"
168 return tpl
169 end
170
171 redef fun tpl_namespace do return tpl_link
172
173 redef fun tpl_definition do
174 var tpl = new TplDefinition
175 var mdoc = mdoc_or_fallback
176 if mdoc != null then
177 tpl.comment = mdoc.tpl_comment
178 end
179 return tpl
180 end
181
182 redef fun tpl_css_classes do return ["public"]
183 end
184
185 redef class MGroup
186 redef fun nitdoc_name do return name.html_escape
187
188 redef fun nitdoc_id do
189 if parent != null then
190 return "{parent.nitdoc_id}__{nitdoc_name}"
191 end
192 return "{mproject.nitdoc_id}__{nitdoc_name}"
193 end
194
195 redef fun nitdoc_url do return "group_{nitdoc_id}.html"
196
197 redef fun tpl_namespace do
198 var tpl = new Template
199 tpl.add mproject.tpl_namespace
200 if mproject.root != self then
201 tpl.add "::"
202 tpl.add tpl_link
203 end
204 return tpl
205 end
206
207 redef fun tpl_declaration do
208 var tpl = new Template
209 tpl.add "<span>group "
210 tpl.add tpl_link
211 tpl.add "</span>"
212 return tpl
213 end
214
215 redef fun tpl_definition do
216 var tpl = new TplDefinition
217 var mdoc = mdoc_or_fallback
218 if mdoc != null then
219 tpl.comment = mdoc.tpl_comment
220 end
221 return tpl
222 end
223 end
224
225 redef class MModule
226 redef fun nitdoc_name do return name.html_escape
227
228 redef fun nitdoc_id do
229 if mgroup != null then
230 return "{mgroup.nitdoc_id}__{nitdoc_name}"
231 end
232 return nitdoc_name
233 end
234
235 redef fun nitdoc_url do return "module_{nitdoc_id}.html"
236
237 redef fun tpl_declaration do
238 var tpl = new Template
239 tpl.add "<span>module "
240 tpl.add tpl_namespace
241 tpl.add "</span>"
242 return tpl
243 end
244
245 redef fun tpl_namespace do
246 var tpl = new Template
247 if mgroup != null then
248 tpl.add mgroup.tpl_namespace
249 tpl.add "::"
250 end
251 tpl.add tpl_link
252 return tpl
253 end
254
255 redef fun tpl_definition do
256 var tpl = new TplClassDefinition
257 if mdoc != null then
258 tpl.comment = mdoc.tpl_comment
259 end
260 return tpl
261 end
262
263 redef fun tpl_css_classes do return ["public"]
264 end
265
266 redef class MClass
267 redef fun nitdoc_name do return name.html_escape
268 redef fun nitdoc_id do return "{intro_mmodule.mgroup.mproject}__{name.to_cmangle}"
269 redef fun nitdoc_url do return "class_{nitdoc_id}.html"
270 redef fun mdoc do return intro.mdoc
271
272 redef fun tpl_declaration do return intro.tpl_declaration
273
274 redef fun tpl_namespace do
275 var tpl = new Template
276 tpl.add intro_mmodule.mgroup.mproject.tpl_namespace
277 tpl.add "::<span>"
278 tpl.add tpl_link
279 tpl.add "</span>"
280 return tpl
281 end
282
283 redef fun tpl_title do
284 var title = new Template
285 title.add tpl_icon
286 title.add tpl_link
287 title.add tpl_signature
288 return title
289 end
290
291 redef fun tpl_icon do return intro.tpl_icon
292
293 fun tpl_signature: Template do
294 var tpl = new Template
295 if arity > 0 then
296 tpl.add "["
297 var parameter_names = new Array[String]
298 for p in mparameters do
299 parameter_names.add(p.name)
300 end
301 tpl.add parameter_names.join(", ")
302 tpl.add "]"
303 end
304 return tpl
305 end
306
307 redef fun tpl_article do
308 var tpl = super
309 tpl.summary_title = "{nitdoc_name}{tpl_signature.write_to_string}"
310 return tpl
311 end
312
313 redef fun tpl_css_classes do return intro.tpl_css_classes
314 end
315
316 redef class MClassDef
317 redef fun nitdoc_name do return mclass.nitdoc_name
318 redef fun nitdoc_id do return "{mmodule.nitdoc_id}__{name.to_cmangle}"
319 redef fun nitdoc_url do return "{mclass.nitdoc_url}#{nitdoc_id}"
320
321 redef fun tpl_namespace do
322 var tpl = new Template
323 tpl.add mmodule.tpl_namespace
324 tpl.add "::<span>"
325 tpl.add mclass.tpl_link
326 tpl.add "</span>"
327 return tpl
328 end
329
330 redef fun tpl_article do
331 var tpl = new TplArticle(nitdoc_id)
332 tpl.summary_title = "in {mmodule.nitdoc_name}"
333 tpl.title = tpl_declaration
334 tpl.title_classes.add "signature"
335 var title = new Template
336 title.add "in "
337 title.add mmodule.tpl_namespace
338 tpl.subtitle = title
339 if mdoc != null then
340 tpl.content = mdoc.tpl_comment
341 end
342 return tpl
343 end
344
345 redef fun tpl_title do
346 var title = new Template
347 title.add tpl_icon
348 title.add tpl_link
349 title.add tpl_signature
350 return title
351 end
352
353 redef fun tpl_declaration do
354 var tpl = new Template
355 tpl.add tpl_modifiers
356 tpl.add tpl_link
357 tpl.add tpl_signature
358 return tpl
359 end
360
361 fun tpl_signature: Template do
362 var tpl = new Template
363 var mparameters = mclass.mparameters
364 if not mparameters.is_empty then
365 tpl.add "["
366 for i in [0..mparameters.length[ do
367 tpl.add "{mparameters[i].name}: "
368 tpl.add bound_mtype.arguments[i].tpl_signature
369 if i < mparameters.length - 1 then tpl.add ", "
370 end
371 tpl.add "]"
372 end
373 return tpl
374 end
375
376 redef fun tpl_definition do
377 var tpl = new TplClassDefinition
378 tpl.namespace = tpl_namespace
379 if mdoc != null then
380 tpl.comment = mdoc.tpl_comment
381 end
382 return tpl
383 end
384
385 redef fun tpl_css_classes do
386 var set = new HashSet[String]
387 if is_intro then set.add "intro"
388 set.add_all mclass.intro.modifiers
389 set.add_all modifiers
390 return set.to_a
391 end
392
393 fun tpl_modifiers: Template do
394 var tpl = new Template
395 for modifier in modifiers do
396 if modifier == "public" then continue
397 tpl.add "{modifier} "
398 end
399 return tpl
400 end
401
402 redef fun tpl_list_item do
403 var lnk = new Template
404 lnk.add new TplLabel.with_classes(tpl_css_classes)
405 lnk.add tpl_link
406 if mdoc != null then
407 lnk.add ": "
408 lnk.add mdoc.short_markdown
409 else if mclass.intro.mdoc != null then
410 lnk.add ": "
411 lnk.add mclass.intro.mdoc.short_markdown
412 end
413 return new TplListItem.with_content(lnk)
414 end
415
416 redef fun tpl_anchor: TplLink do
417 var tpl = new TplLink("#{nitdoc_id}", nitdoc_name)
418 if mdoc != null then
419 tpl.title = mdoc.short_comment
420 else if mclass.intro.mdoc != null then
421 tpl.title = mclass.intro.mdoc.short_comment
422 end
423 return tpl
424 end
425
426 redef fun tpl_link: TplLink do
427 var tpl = new TplLink(nitdoc_url, nitdoc_name)
428 if mdoc != null then
429 tpl.title = mdoc.short_comment
430 else if mclass.intro.mdoc != null then
431 tpl.title = mclass.intro.mdoc.short_comment
432 end
433 return tpl
434 end
435 end
436
437 redef class MProperty
438 redef fun nitdoc_name do return name.html_escape
439 redef fun nitdoc_id do return "{intro_mclassdef.mclass.nitdoc_id}__{name.to_cmangle}"
440 redef fun nitdoc_url do return "property_{nitdoc_id}.html"
441
442 redef fun mdoc do return intro.mdoc
443
444 redef fun tpl_namespace do
445 var tpl = new Template
446 tpl.add intro_mclassdef.mclass.tpl_namespace
447 tpl.add "::<span>"
448 tpl.add intro.tpl_link
449 tpl.add "</span>"
450 return tpl
451 end
452
453 redef fun tpl_declaration do return intro.tpl_declaration
454
455 fun tpl_signature: Template do return new Template
456
457 redef fun tpl_title do return intro.tpl_title
458
459 redef fun tpl_icon do return intro.tpl_icon
460
461 redef fun tpl_css_classes do return intro.tpl_css_classes
462 end
463
464 redef class MPropDef
465 redef fun nitdoc_name do return mproperty.nitdoc_name
466 redef fun nitdoc_id do return "{mclassdef.nitdoc_id}__{name.to_cmangle}"
467 redef fun nitdoc_url do return "{mproperty.nitdoc_url}#{nitdoc_id}"
468
469 redef fun tpl_anchor: TplLink do
470 var tpl = new TplLink("#{nitdoc_id}", nitdoc_name)
471 if mdoc != null then
472 tpl.title = mdoc.short_comment
473 else if mproperty.intro.mdoc != null then
474 tpl.title = mproperty.intro.mdoc.short_comment
475 end
476 return tpl
477 end
478
479 redef fun tpl_link: TplLink do
480 var tpl = new TplLink(nitdoc_url, nitdoc_name)
481 if mdoc != null then
482 tpl.title = mdoc.short_comment
483 else if mproperty.intro.mdoc != null then
484 tpl.title = mproperty.intro.mdoc.short_comment
485 end
486 return tpl
487 end
488
489 redef fun tpl_namespace do
490 var tpl = new Template
491 tpl.add mclassdef.tpl_namespace
492 tpl.add "::"
493 tpl.add tpl_link
494 return tpl
495 end
496
497 redef fun tpl_article do
498 var tpl = new TplArticle(nitdoc_id)
499 tpl.summary_title = "in {mclassdef.nitdoc_name}"
500 var title = new Template
501 title.add "in "
502 title.add mclassdef.tpl_link
503 tpl.title = title
504 tpl.subtitle = tpl_declaration
505 if mdoc != null then
506 tpl.content = mdoc.tpl_comment
507 end
508 return tpl
509 end
510
511 redef fun tpl_definition do
512 var tpl = new TplDefinition
513 tpl.namespace = mclassdef.tpl_namespace
514 if mdoc != null then
515 tpl.comment = mdoc.tpl_comment
516 end
517 return tpl
518 end
519
520 redef fun tpl_declaration do
521 var tpl = new Template
522 tpl.add tpl_modifiers
523 tpl.add tpl_link
524 tpl.add tpl_signature
525 return tpl
526 end
527
528 redef fun tpl_css_classes do
529 var set = new HashSet[String]
530 if is_intro then set.add "intro"
531 set.add_all mproperty.intro.modifiers
532 set.add_all modifiers
533 return set.to_a
534 end
535
536 fun tpl_modifiers: Template do
537 var tpl = new Template
538 for modifier in modifiers do
539 if modifier == "public" then continue
540 tpl.add "{modifier} "
541 end
542 return tpl
543 end
544
545 fun tpl_signature: Template do return new Template
546
547 redef fun tpl_list_item do
548 var lnk = new Template
549 lnk.add new TplLabel.with_classes(tpl_css_classes.to_a)
550 var anchor = tpl_link
551 anchor.href = "{mclassdef.mclass.nitdoc_url}#{mproperty.nitdoc_id}"
552 lnk.add anchor
553 if mdoc != null then
554 lnk.add ": "
555 lnk.add mdoc.short_markdown
556 else if mproperty.intro.mdoc != null then
557 lnk.add ": "
558 lnk.add mproperty.intro.mdoc.short_markdown
559 end
560 return new TplListItem.with_content(lnk)
561 end
562
563 fun tpl_inheritance_item: TplListItem do
564 var lnk = new Template
565 lnk.add new TplLabel.with_classes(tpl_css_classes.to_a)
566 lnk.add mclassdef.mmodule.tpl_namespace
567 lnk.add "::"
568 var anchor = mclassdef.tpl_link
569 anchor.href = "{mclassdef.mclass.nitdoc_url}#{mproperty.nitdoc_id}"
570 lnk.add anchor
571 if mdoc != null then
572 lnk.add ": "
573 lnk.add mdoc.short_markdown
574 end
575 var li = new TplListItem.with_content(lnk)
576 li.css_classes.add "signature"
577 return li
578 end
579 end
580
581 redef class MAttributeDef
582 redef fun tpl_signature do
583 var tpl = new Template
584 if static_mtype != null then
585 tpl.add ": "
586 tpl.add static_mtype.tpl_signature
587 end
588 return tpl
589 end
590 end
591
592 redef class MMethod
593 redef fun tpl_signature do
594 var tpl = new Template
595 var params = new Array[String]
596 for param in intro.msignature.mparameters do
597 params.add param.name
598 end
599 if not params.is_empty then
600 tpl.add "("
601 tpl.add params.join(", ")
602 tpl.add ")"
603 end
604 return tpl
605 end
606 end
607
608 redef class MMethodDef
609 redef fun tpl_signature do return msignature.tpl_signature
610 end
611
612 redef class MVirtualTypeProp
613 redef fun tpl_link do return mvirtualtype.tpl_link
614 redef fun tpl_signature do return tpl_link
615 end
616
617 redef class MVirtualTypeDef
618 redef fun tpl_signature do
619 var tpl = new Template
620 tpl.add ": "
621 tpl.add bound.tpl_signature
622 return tpl
623 end
624 end
625
626 redef class MInnerClass
627 redef fun nitdoc_url do return inner.nitdoc_url
628 redef fun tpl_signature do return inner.tpl_signature
629 end
630
631 redef class MInnerClassDef
632 redef fun nitdoc_url do return inner.nitdoc_url
633
634 redef fun tpl_anchor do return inner.tpl_anchor
635 redef fun tpl_link do return inner.tpl_link
636 redef fun tpl_signature do return inner.tpl_signature
637
638 redef fun tpl_definition do
639 var tpl = new TplClassDefinition
640 tpl.namespace = mclassdef.tpl_namespace
641 if mdoc != null then
642 tpl.comment = mdoc.tpl_comment
643 end
644 return tpl
645 end
646 end
647
648 redef class MType
649 fun tpl_signature: Template is abstract
650 end
651
652 redef class MClassType
653 redef fun tpl_link do return mclass.tpl_link
654 redef fun tpl_signature do return tpl_link
655 end
656
657 redef class MNullableType
658 redef fun tpl_signature do
659 var tpl = new Template
660 tpl.add "nullable "
661 tpl.add mtype.tpl_signature
662 return tpl
663 end
664 end
665
666 redef class MGenericType
667 redef fun tpl_signature do
668 var tpl = new Template
669 tpl.add tpl_link
670 tpl.add "["
671 for i in [0..arguments.length[ do
672 tpl.add arguments[i].tpl_signature
673 if i < arguments.length - 1 then tpl.add ", "
674 end
675 tpl.add "]"
676 return tpl
677 end
678 end
679
680 redef class MParameterType
681 redef fun tpl_link do
682 return new TplLink.with_title("{mclass.nitdoc_url}#FT_{name}", name, "formal type")
683 end
684 redef fun tpl_signature do return tpl_link
685 end
686
687 redef class MVirtualType
688 redef fun tpl_link do return mproperty.intro.tpl_link
689 redef fun tpl_signature do return tpl_link
690 end
691
692 redef class MSignature
693 redef fun tpl_signature do
694 var tpl = new Template
695 if not mparameters.is_empty then
696 tpl.add "("
697 for i in [0..mparameters.length[ do
698 tpl.add mparameters[i].tpl_signature
699 if i < mparameters.length - 1 then tpl.add ", "
700 end
701 tpl.add ")"
702 end
703 if return_mtype != null then
704 tpl.add ": "
705 tpl.add return_mtype.tpl_signature
706 end
707 return tpl
708 end
709 end
710
711 redef class MParameter
712 fun tpl_signature: Template do
713 var tpl = new Template
714 tpl.add "{name}: "
715 tpl.add mtype.tpl_signature
716 if is_vararg then tpl.add "..."
717 return tpl
718 end
719 end
720
721 redef class ConcernsTree
722
723 private var seen = new HashSet[MConcern]
724
725 redef fun add(p, e) do
726 if seen.has(e) then return
727 seen.add e
728 super(p, e)
729 end
730
731 fun to_tpl: TplList do
732 var lst = new TplList.with_classes(["list-unstyled", "list-definition"])
733 for r in roots do
734 var li = r.tpl_concern_item
735 lst.add_li li
736 build_list(r, li)
737 end
738 return lst
739 end
740
741 private fun build_list(e: MConcern, li: TplListItem) do
742 if not sub.has_key(e) then return
743 var subs = sub[e]
744 var lst = new TplList.with_classes(["list-unstyled", "list-definition"])
745 for e2 in subs do
746 if e2 isa MGroup and e2.is_root then
747 build_list(e2, li)
748 else
749 var sli = e2.tpl_concern_item
750 lst.add_li sli
751 build_list(e2, sli)
752 end
753 end
754 li.append lst
755 end
756 end
757
758
759 ################################################################################
760 # Additions to `model_ext`.
761
762 redef class MRawType
763 redef fun tpl_signature do
764 var tpl = new Template
765
766 for part in parts do
767 if part.target != null then
768 tpl.add part.target.as(not null).tpl_link
769 else
770 tpl.add part.text.html_escape
771 end
772 end
773 return tpl
774 end
775 end