nitdoc: display constructors list in MClass page
[nit.git] / src / doc / doc_phases / doc_structure.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 # Composes the DocComposite tree of a DocPage and organizes its content.
16 module doc_structure
17
18 import doc_concerns
19 import modelize
20
21 # StructurePhase populates the DocPage content with section and article.
22 #
23 # This phase only applies structure.
24 # The content of the structure is choosen by the rendering phases.
25 class StructurePhase
26 super DocPhase
27
28 # Used to sort ConcernsTree by rank.
29 private var concerns_sorter = new MConcernRankSorter
30
31 # Used to sort ConcernsTree by name.
32 private var name_sorter = new MEntityNameSorter
33
34 # Populates the given DocModel.
35 redef fun apply do
36 for page in doc.pages do page.apply_structure(self, doc)
37 end
38 end
39
40 redef class DocPage
41
42 # Populates `self` with structure elements like DocComposite ones.
43 #
44 # See `StructurePhase`.
45 fun apply_structure(v: StructurePhase, doc: DocModel) do end
46 end
47
48 redef class OverviewPage
49 redef fun apply_structure(v, doc) do
50 var article = new HomeArticle
51 root.add_child article
52 # Projects list
53 var mprojects = doc.model.mprojects.to_a
54 var sorter = new MConcernRankSorter
55 sorter.sort mprojects
56 var section = new ProjectsSection
57 for mproject in mprojects do
58 section.add_child new DefinitionArticle(mproject)
59 end
60 article.add_child section
61 end
62 end
63
64 redef class SearchPage
65 redef fun apply_structure(v, doc) do
66 var mmodules = doc.mmodules.to_a
67 v.name_sorter.sort(mmodules)
68 var mclasses = doc.mclasses.to_a
69 v.name_sorter.sort(mclasses)
70 var mprops = doc.mproperties.to_a
71 v.name_sorter.sort(mprops)
72 root.add_child new IndexArticle(mmodules, mclasses, mprops)
73 end
74 end
75
76 redef class MGroupPage
77 redef fun apply_structure(v, doc) do
78 var section = new MEntitySection(mentity)
79 root.add_child section
80 if mentity.is_root then
81 section.add_child new IntroArticle(mentity.mproject)
82 else
83 section.add_child new IntroArticle(mentity)
84 end
85 var concerns = self.concerns
86 if concerns == null or concerns.is_empty then return
87 # FIXME avoid diff
88 mentity.mproject.booster_rank = -1000
89 mentity.booster_rank = -1000
90 concerns.sort_with(v.concerns_sorter)
91 mentity.mproject.booster_rank = 0
92 mentity.booster_rank = 0
93 section.add_child new ConcernsArticle(mentity, concerns)
94 for mentity in concerns do
95 var ssection = new ConcernSection(mentity)
96 if mentity isa MModule then
97 ssection.add_child new DefinitionArticle(mentity)
98 end
99 section.add_child ssection
100 end
101 end
102 end
103
104 redef class MModulePage
105 redef fun apply_structure(v, doc) do
106 var section = new MEntitySection(mentity)
107 root.add_child section
108 section.add_child new IntroArticle(mentity)
109 var concerns = self.concerns
110 if concerns == null or concerns.is_empty then return
111 # FIXME avoid diff
112 mentity.mgroup.mproject.booster_rank = -1000
113 mentity.mgroup.booster_rank = -1000
114 mentity.booster_rank = -1000
115 concerns.sort_with(v.concerns_sorter)
116 mentity.mgroup.mproject.booster_rank = 0
117 mentity.mgroup.booster_rank = 0
118 mentity.booster_rank = 0
119 section.add_child new ConcernsArticle(mentity, concerns)
120 # reference list
121 for mentity in concerns do
122 var ssection = new ConcernSection(mentity)
123 if mentity isa MModule then
124 var mclasses = mclasses_for_mmodule(mentity).to_a
125 v.name_sorter.sort(mclasses)
126 for mclass in mclasses do
127 var article = new DefinitionListArticle(mclass)
128 var mclassdefs = mclassdefs_for(mclass).to_a
129 if not mclassdefs.has(mclass.intro) then
130 article.add_child(new DefinitionArticle(mclass.intro))
131 end
132 doc.mainmodule.linearize_mclassdefs(mclassdefs)
133 for mclassdef in mclassdefs do
134 article.add_child(new DefinitionArticle(mclassdef))
135 end
136 ssection.add_child article
137 end
138 end
139 section.add_child ssection
140 end
141 end
142
143 # Filters `self.mclassses` by intro `mmodule`.
144 private fun mclasses_for_mmodule(mmodule: MModule): Set[MClass] do
145 var mclasses = new HashSet[MClass]
146 for mclass in self.mclasses do
147 if mclass.intro.mmodule == mmodule then
148 mclasses.add mclass
149 end
150 end
151 return mclasses
152 end
153
154 # Filters `self.mclassdefs` by `mclass`.
155 private fun mclassdefs_for(mclass: MClass): Set[MClassDef] do
156 var mclassdefs = new HashSet[MClassDef]
157 for mclassdef in self.mclassdefs do
158 if mclassdef.mclass == mclass then
159 mclassdefs.add mclassdef
160 end
161 end
162 return mclassdefs
163 end
164 end
165
166 redef class MClassPage
167 redef fun apply_structure(v, doc) do
168 var section = new MEntitySection(mentity)
169 root.add_child section
170 section.add_child new IntroArticle(mentity)
171 var concerns = self.concerns
172 if concerns == null or concerns.is_empty then return
173 # FIXME diff hack
174 mentity.intro_mmodule.mgroup.mproject.booster_rank = -1000
175 mentity.intro_mmodule.mgroup.booster_rank = -1000
176 mentity.intro_mmodule.booster_rank = -1000
177 concerns.sort_with(v.concerns_sorter)
178 mentity.intro_mmodule.mgroup.mproject.booster_rank = 0
179 mentity.intro_mmodule.mgroup.booster_rank = 0
180 mentity.intro_mmodule.booster_rank = 0
181 var constructors = new ConstructorsSection(mentity)
182 var minit = mentity.root_init
183 if minit != null then
184 constructors.add_child new DefinitionArticle(minit)
185 end
186 section.add_child constructors
187 section.add_child new ConcernsArticle(mentity, concerns)
188 for mentity in concerns do
189 var ssection = new ConcernSection(mentity)
190 if mentity isa MModule then
191 var mprops = mproperties_for(mentity)
192 var by_kind = new PropertiesByKind.with_elements(mprops)
193 for group in by_kind.groups do
194 v.name_sorter.sort(group)
195 for mprop in group do
196 for mpropdef in mpropdefs_for(mprop, mentity) do
197 if mpropdef isa MMethodDef and mpropdef.mproperty.is_init then
198 if mpropdef == minit then continue
199 constructors.add_child new DefinitionArticle(mpropdef)
200 else
201 ssection.add_child new DefinitionArticle(mpropdef)
202 end
203 end
204 end
205 end
206 end
207 section.add_child ssection
208 end
209 end
210
211 # Filters `self.mpropdefs` by `mmodule`.
212 #
213 # FIXME diff hack
214 private fun mproperties_for(mmodule: MModule): Set[MProperty] do
215 var mprops = new HashSet[MProperty]
216 for mpropdef in self.mpropdefs do
217 if mpropdef.mclassdef.mmodule == mmodule then
218 mprops.add mpropdef.mproperty
219 end
220 end
221 return mprops
222 end
223
224 # Filters `self.mpropdefs` by `mproperty`.
225 #
226 # FIXME diff hack
227 private fun mpropdefs_for(mproperty: MProperty, mmodule: MModule): Set[MPropDef] do
228 var mpropdefs = new HashSet[MPropDef]
229 for mpropdef in self.mpropdefs do
230 if mpropdef.mproperty == mproperty and
231 mpropdef.mclassdef.mmodule == mmodule then
232 mpropdefs.add mpropdef
233 end
234 end
235 return mpropdefs
236 end
237 end
238
239 redef class MPropertyPage
240 redef fun apply_structure(v, doc) do
241 var section = new MEntitySection(mentity)
242 root.add_child section
243 section.add_child new IntroArticle(mentity)
244 var concerns = self.concerns
245 if concerns == null or concerns.is_empty then return
246 # FIXME diff hack
247 mentity.intro.mclassdef.mmodule.mgroup.mproject.booster_rank = -1000
248 mentity.intro.mclassdef.mmodule.mgroup.booster_rank = -1000
249 mentity.intro.mclassdef.mmodule.booster_rank = -1000
250 concerns.sort_with(v.concerns_sorter)
251 mentity.intro.mclassdef.mmodule.mgroup.mproject.booster_rank = 0
252 mentity.intro.mclassdef.mmodule.mgroup.booster_rank = 0
253 mentity.intro.mclassdef.mmodule.booster_rank = 0
254 section.add_child new ConcernsArticle(mentity, concerns)
255 for mentity in concerns do
256 var ssection = new ConcernSection(mentity)
257 if mentity isa MModule then
258 # Add mproperties
259 var mpropdefs = mpropdefs_for(mentity).to_a
260 v.name_sorter.sort(mpropdefs)
261 for mpropdef in mpropdefs do
262 ssection.add_child new DefinitionArticle(mpropdef)
263 end
264 end
265 section.add_child ssection
266 end
267 end
268
269 # Filters `self.mpropdefs` by `mmodule`.
270 private fun mpropdefs_for(mmodule: MModule): Set[MPropDef] do
271 var mpropdefs = new HashSet[MPropDef]
272 for mpropdef in self.mpropdefs do
273 if mpropdef.mclassdef.mmodule == mmodule then
274 mpropdefs.add mpropdef
275 end
276 end
277 return mpropdefs
278 end
279 end
280
281 # A group of sections that can be displayed together in a tab.
282 #
283 # Display the first child and hide less relevant data in other panels.
284 class TabbedGroup
285 super DocSection
286 end
287
288 # A group of sections that can be displayed together in a tab panel.
289 class PanelGroup
290 super DocSection
291
292 # The title of this group.
293 var group_title: String
294 end
295
296 # A DocComposite element about a MEntity.
297 class MEntityComposite
298 super DocComposite
299
300 # MEntity documented by this page element.
301 var mentity: MEntity
302 end
303
304 # A list of constructors.
305 class ConstructorsSection
306 super MEntitySection
307 end
308
309 # A Section about a Concern.
310 #
311 # Those sections are used to build the page summary.
312 class ConcernSection
313 super MEntityComposite
314 super DocSection
315 end
316
317 # An article about a Mentity.
318 #
319 # Used to display textual content about a MEntity.
320 abstract class MEntityArticle
321 super MEntityComposite
322 super DocArticle
323 end
324
325 # A section about a Mentity.
326 #
327 # Used to regroup content about a MEntity.
328 class MEntitySection
329 super MEntityComposite
330 super DocSection
331 end
332
333 # An introduction article about a MEntity.
334 #
335 # Used at the top of a documentation page to introduce the documented MEntity.
336 class IntroArticle
337 super MEntityComposite
338 super DocArticle
339 end
340
341 # An article that display a ConcernsTreee as a list.
342 class ConcernsArticle
343 super MEntityArticle
344
345 # Concerns to list in this article.
346 var concerns: ConcernsTree
347 end
348
349 # An article that displaus a list of definition belonging to a MEntity.
350 class DefinitionListArticle
351 super TabbedGroup
352 super MEntityArticle
353 end
354
355 # An article that display the definition text of a MEntity.
356 class DefinitionArticle
357 super MEntityArticle
358 end
359
360 # The main project article.
361 class HomeArticle
362 super DocArticle
363 end
364
365 # The project list.
366 class ProjectsSection
367 super DocArticle
368 end
369
370 # An article that display an index of mmodules, mclasses and mproperties.
371 class IndexArticle
372 super DocArticle
373
374 # List of mmodules to display.
375 var mmodules: Array[MModule]
376
377 # List of mclasses to display.
378 var mclasses: Array[MClass]
379
380 # List of mproperties to display.
381 var mprops: Array[MProperty]
382 end