Merge: introduce nit_env.sh to setup the shell environement
[nit.git] / src / uml / uml_class.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 # Provides facilities of exporting a `Model` to a UML class diagram
16 module uml_class
17
18 import uml_base
19 import model::model_collect
20
21 redef class UMLModel
22 # Generates a UML class diagram from a `Model`
23 fun generate_class_uml: Writable do
24 var tpl = new Template
25 tpl.add "digraph G \{\n"
26 tpl.add """ fontname = "Bitstream Vera Sans"
27 fontsize = 8
28 node [
29 fontname = "Bitstream Vera Sans"
30 fontsize = 8
31 shape = "record"
32 ]
33
34 edge [
35 fontname = "Bitstream Vera Sans"
36 fontsize = 8
37 ]\n"""
38 tpl.add model.tpl_class(ctx, mainmodule)
39 tpl.add "\}"
40 return tpl
41 end
42 end
43
44 redef class Model
45
46 # Generates a UML Class diagram from the entities of a `Model`
47 redef fun tpl_class(ctx, main) do
48 var t = new Template
49 for i in mclasses do
50 if not ctx.private_gen and i.visibility != public_visibility then continue
51 t.add i.tpl_class(ctx, main)
52 t.add "\n"
53 end
54 return t
55 end
56
57 end
58
59 redef class MEntity
60 # Generates a dot-compatible `Writable` UML Class diagram from `self`
61 fun tpl_class(ctx: ToolContext, main: MModule): Writable is abstract
62 end
63
64 redef class MClass
65
66 redef fun tpl_class(ctx, main) do
67 var t = new Template
68 t.add "{name} [\n label = \"\{"
69 if kind == abstract_kind then
70 t.add "abstract\\n{name}"
71 else if kind == interface_kind then
72 t.add "interface\\n{name}"
73 else
74 t.add "{name}"
75 end
76 if arity > 0 then
77 t.add "["
78 t.add mparameters.first.name
79 for i in [1 .. mparameters.length[ do
80 t.add ", "
81 t.add mparameters[i].name
82 end
83 t.add "]"
84 end
85 t.add "|"
86 var props: Collection[MProperty]
87 if ctx.private_gen then
88 props = collect_intro_mproperties(none_visibility)
89 else
90 props = collect_intro_mproperties(public_visibility)
91 end
92 for i in props do
93 if i isa MAttribute then
94 t.add i.tpl_class(ctx, main)
95 t.add "\\l"
96 end
97 end
98 t.add "|"
99 var meths
100 if ctx.private_gen then
101 meths = collect_intro_mmethods(none_visibility)
102 else
103 meths = collect_intro_mmethods(public_visibility)
104 end
105 for i in meths do
106 t.add i.tpl_class(ctx, main)
107 t.add "\\l"
108 end
109 t.add "\}\"\n]\n"
110 var g = in_hierarchy(main).direct_greaters
111 for i in g do
112 if not ctx.private_gen and i.visibility != public_visibility then continue
113 t.add "{i.name} -> {name} [dir=back"
114 if i.kind == interface_kind then
115 t.add " arrowtail=open style=dashed"
116 else
117 t.add " arrowtail=empty"
118 end
119 t.add "];\n"
120 end
121 return t
122 end
123
124 end
125
126 redef class MMethod
127 redef fun tpl_class(ctx, main) do
128 var tpl = new Template
129 tpl.add visibility.tpl_class
130 tpl.add " "
131 tpl.add name.escape_to_dot
132 tpl.add intro.msignature.tpl_class(ctx, main)
133 return tpl
134 end
135 end
136
137 redef class MSignature
138
139 redef fun tpl_class(ctx, main) do
140 var t = new Template
141 t.add "("
142 var params = new Array[MParameter]
143 for i in mparameters do
144 params.add i
145 end
146 if params.length > 0 then
147 t.add params.first.name
148 t.add ": "
149 t.add params.first.mtype.tpl_class(ctx, main)
150 for i in [1 .. params.length [ do
151 t.add ", "
152 t.add params[i].name
153 t.add ": "
154 t.add params[i].mtype.tpl_class(ctx, main)
155 end
156 end
157 t.add ")"
158 if return_mtype != null then
159 t.add ": "
160 t.add return_mtype.tpl_class(ctx, main)
161 end
162 return t
163 end
164 end
165
166 redef class MAttribute
167 redef fun tpl_class(ctx, main) do
168 var tpl = new Template
169 tpl.add visibility.tpl_class
170 tpl.add " "
171 tpl.add name
172 tpl.add ": "
173 tpl.add intro.static_mtype.tpl_class(ctx, main)
174 return tpl
175 end
176 end
177
178 redef class MVisibility
179 # Returns the visibility as a UML token
180 #
181 # assert public_visibility.tpl_class == "+"
182 # assert private_visibility.tpl_class == "-"
183 fun tpl_class: Writable do
184 if self == private_visibility then
185 return "-"
186 else if self == protected_visibility then
187 return "#"
188 else if self == public_visibility then
189 return "+"
190 else
191 return "+"
192 end
193 end
194 end
195
196 redef class MClassType
197 redef fun tpl_class(c, m) do
198 return name
199 end
200 end
201
202 redef class MGenericType
203 redef fun tpl_class(c, m) do
204 var t = new Template
205 t.add name.substring(0, name.index_of('['))
206 t.add "["
207 t.add arguments.first.tpl_class(c, m)
208 for i in [1 .. arguments.length[ do
209 t.add ", "
210 t.add arguments[i].tpl_class(c, m)
211 end
212 t.add "]"
213 return t
214 end
215 end
216
217 redef class MParameterType
218 redef fun tpl_class(c, m) do
219 return name
220 end
221 end
222
223 redef class MVirtualType
224 redef fun tpl_class(c, m) do
225 return name
226 end
227 end
228
229 redef class MNullableType
230 redef fun tpl_class(c, m) do
231 var t = new Template
232 t.add "nullable "
233 t.add mtype.tpl_class(c, m)
234 return t
235 end
236 end