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