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