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