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