lib/standard/stream: Renamed streams for more explicit denomination
[nit.git] / src / metrics / model_hyperdoc.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Copyright 2012 Jean Privat <jean@pryen.org>
4 #
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
8 #
9 # http://www.apache.org/licenses/LICENSE-2.0
10 #
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
16
17 # Dump of Nit model into hypertext human-readable format.
18 module model_hyperdoc
19
20 import metrics_base
21
22 redef class ToolContext
23 var model_hyperdoc_phase: Phase = new ModelHyperdocPhase(self, null)
24 end
25
26 private class ModelHyperdocPhase
27 super Phase
28 redef fun process_mainmodule(mainmodule, given_mmodules)
29 do
30 if not toolcontext.opt_generate_hyperdoc.value and not toolcontext.opt_all.value then return
31 generate_model_hyperdoc(toolcontext, toolcontext.modelbuilder.model)
32 end
33 end
34
35 # Genetate a HTML file for the model.
36 # The generated file contains the description of each entity of the model
37 fun generate_model_hyperdoc(toolcontext: ToolContext, model: Model)
38 do
39 var buf = new FlatBuffer
40 buf.append("<html>\n<body>\n")
41 buf.append("<h1>Model</h1>\n")
42
43 buf.append("<h2>Projects</h2>\n")
44 for mproject in model.mprojects do
45 buf.append("<h3 id='project-{mproject}'>Project {mproject}</h3>\n")
46 buf.append("<dl>\n")
47 buf.append("<dt>groups</dt>\n")
48 for x in mproject.mgroups do
49 buf.append("<dd>{linkto(x)}</dd>\n")
50 end
51 buf.append("</dl>\n")
52 end
53
54 buf.append("<h2>Groups</h2>\n")
55 for mproject in model.mprojects do
56 for mgroup in mproject.mgroups do
57 buf.append("<h3 id='group-{mgroup}'>Group {mgroup}</h3>\n")
58 buf.append("<dl>\n")
59 buf.append("<dt>project</dt>\n")
60 buf.append("<dd>{linkto(mproject)}</dd>\n")
61 buf.append("<dt>filepath</dt>\n")
62 buf.append("<dd>{mgroup.filepath.to_s}</dd>\n")
63 var p = mgroup.parent
64 if p != null then
65 buf.append("<dt>parent group</dt>\n")
66 buf.append("<dd>{linkto(p)}</dd>\n")
67 end
68 buf.append("<dt>nested groups</dt>\n")
69 for x in mgroup.in_nesting.direct_smallers do
70 buf.append("<dd>{linkto(x)}</dd>\n")
71 end
72 buf.append("<dt>modules</dt>\n")
73 for x in mgroup.mmodules do
74 buf.append("<dd>{linkto(x)}</dd>\n")
75 end
76 end
77 buf.append("</dl>\n")
78 end
79
80 buf.append("<h2>Modules</h2>\n")
81 for mmodule in model.mmodules do
82 buf.append("<h3 id='module-{mmodule}'>{mmodule}</h3>\n")
83 buf.append("<dl>\n")
84 buf.append("<dt>group</dt>\n")
85 var grp = mmodule.mgroup
86 if grp != null then buf.append("<dd>{linkto(grp)}</dd>\n")
87 buf.append("<dt>direct import</dt>\n")
88 for x in mmodule.in_importation.direct_greaters do
89 buf.append("<dd>{linkto(x)}</dd>\n")
90 end
91 buf.append("<dt>direct clients</dt>\n")
92 for x in mmodule.in_importation.direct_smallers do
93 buf.append("<dd>{linkto(x)}</dd>\n")
94 end
95 buf.append("<dt>introduced classes</dt>\n")
96 for x in mmodule.mclassdefs do
97 if not x.is_intro then continue
98 buf.append("<dd>{linkto(x.mclass)} by {linkto(x)}</dd>\n")
99 end
100 buf.append("<dt>refined classes</dt>\n")
101 for x in mmodule.mclassdefs do
102 if x.is_intro then continue
103 buf.append("<dd>{linkto(x.mclass)} by {linkto(x)}</dd>\n")
104 end
105 buf.append("</dl>\n")
106 end
107 buf.append("<h2>Classes</h2>\n")
108 for mclass in model.mclasses do
109 buf.append("<h3 id='class-{mclass}'>{mclass}</h3>\n")
110 buf.append("<dl>\n")
111 buf.append("<dt>module of introduction</dt>\n")
112 buf.append("<dd>{linkto(mclass.intro_mmodule)}</dd>\n")
113 buf.append("<dt>class definitions</dt>\n")
114 for x in mclass.mclassdefs do
115 buf.append("<dd>{linkto(x)} in {linkto(x.mmodule)}</dd>\n")
116 end
117 buf.append("</dl>\n")
118 end
119 buf.append("<h2>Class Definitions</h2>\n")
120 for mclass in model.mclasses do
121 for mclassdef in mclass.mclassdefs do
122 buf.append("<h3 id='classdef-{mclassdef}'>{mclassdef}</h3>\n")
123 buf.append("<dl>\n")
124 buf.append("<dt>module</dt>\n")
125 buf.append("<dd>{linkto(mclassdef.mmodule)}</dd>\n")
126 buf.append("<dt>class</dt>\n")
127 buf.append("<dd>{linkto(mclassdef.mclass)}</dd>\n")
128 buf.append("<dt>direct refinements</dt>\n")
129 for x in mclassdef.in_hierarchy.direct_greaters do
130 if x.mclass != mclass then continue
131 buf.append("<dd>{linkto(x)} in {linkto(x.mmodule)}</dd>\n")
132 end
133 buf.append("<dt>direct refinemees</dt>\n")
134 for x in mclassdef.in_hierarchy.direct_smallers do
135 if x.mclass != mclass then continue
136 buf.append("<dd>{linkto(x)} in {linkto(x.mmodule)}</dd>\n")
137 end
138 buf.append("<dt>direct superclasses</dt>\n")
139 for x in mclassdef.supertypes do
140 buf.append("<dd>{linkto(x.mclass)} by {x}</dd>\n")
141 end
142 buf.append("<dt>introduced properties</dt>\n")
143 for x in mclassdef.mpropdefs do
144 if not x.is_intro then continue
145 buf.append("<dd>{linkto(x.mproperty)} by {linkto(x)}</dd>\n")
146 end
147 buf.append("<dt>redefined properties</dt>\n")
148 for x in mclassdef.mpropdefs do
149 if x.is_intro then continue
150 buf.append("<dd>{linkto(x.mproperty)} by {linkto(x)}</dd>\n")
151 end
152 buf.append("</dl>\n")
153 end
154 end
155 buf.append("<h2>Properties</h2>\n")
156 for mprop in model.mproperties do
157 buf.append("<h3 id='property-{mprop}'>{mprop}</h3>\n")
158 buf.append("<dl>\n")
159 buf.append("<dt>module of introdcution</dt>\n")
160 buf.append("<dd>{linkto(mprop.intro_mclassdef.mmodule)}</dd>\n")
161 buf.append("<dt>class of introduction</dt>\n")
162 buf.append("<dd>{linkto(mprop.intro_mclassdef.mclass)}</dd>\n")
163 buf.append("<dt>class definition of introduction</dt>\n")
164 buf.append("<dd>{linkto(mprop.intro_mclassdef)}</dd>\n")
165 buf.append("<dt>property definitions</dt>\n")
166 for x in mprop.mpropdefs do
167 buf.append("<dd>{linkto(x)} in {linkto(x.mclassdef)}</dd>\n")
168 end
169 buf.append("</dl>\n")
170 end
171 buf.append("<h2>Property Definitions</h2>\n")
172 for mprop in model.mproperties do
173 for mpropdef in mprop.mpropdefs do
174 buf.append("<h3 id='propdef-{mpropdef}'>{mpropdef}</h3>\n")
175 buf.append("<dl>\n")
176 buf.append("<dt>module</dt>\n")
177 buf.append("<dd>{linkto(mpropdef.mclassdef.mmodule)}</dd>\n")
178 buf.append("<dt>class</dt>\n")
179 buf.append("<dd>{linkto(mpropdef.mclassdef.mclass)}</dd>\n")
180 buf.append("<dt>class definition</dt>\n")
181 buf.append("<dd>{linkto(mpropdef.mclassdef)}</dd>\n")
182 buf.append("<dt>super definitions</dt>\n")
183 for x in mpropdef.mproperty.lookup_super_definitions(mpropdef.mclassdef.mmodule, mpropdef.mclassdef.bound_mtype) do
184 buf.append("<dd>{linkto(x)} in {linkto(x.mclassdef)}</dd>\n")
185 end
186 end
187 end
188 buf.append("</body></html>\n")
189 var f = new FileWriter.open(toolcontext.output_dir.join_path("model.html"))
190 f.write(buf.to_s)
191 f.close
192 end
193
194 private fun linkto(o: Object): String
195 do
196 if o isa MProject then
197 return "<a href='#project-{o}'>{o}</a>"
198 else if o isa MGroup then
199 return "<a href='#group-{o}'>{o}</a>"
200 else if o isa MModule then
201 return "<a href='#module-{o}'>{o}</a>"
202 else if o isa MClass then
203 return "<a href='#class-{o}'>{o}</a>"
204 else if o isa MClassDef then
205 return "<a href='#classdef-{o}'>{o}</a>"
206 else if o isa MProperty then
207 return "<a href='#property-{o}'>{o}</a>"
208 else if o isa MPropDef then
209 return "<a href='#propdef-{o}'>{o}</a>"
210 else
211 print "cannot linkto {o.class_name}"
212 abort
213 end
214 end