model_json: update ModelView
[nit.git] / src / model / model_json.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 # Make model entities Serializable.
16 #
17 # To avoid cycles, every reference from a MEntity to another is replaced by a
18 # MEntityRef.
19 #
20 # How subobjects are retrieved using the MEntityRef is the responsability of the
21 # client. Json objects can be returned as this or inflated with concrete objet
22 # rather than the refs.
23 #
24 # TODO consider serialization module?
25 module model_json
26
27 import model::model_collect
28 import json::static
29 import json::serialization_write
30 import loader
31
32 # A reference to another mentity.
33 class MEntityRef
34 super MEntity
35
36 # MEntity to link to.
37 var mentity: MEntity
38
39 redef fun core_serialize_to(v) do
40 v.serialize_attribute("full_name", mentity.full_name)
41 end
42 end
43
44 redef class MEntity
45 serialize
46
47 redef fun core_serialize_to(v) do
48 v.serialize_attribute("name", name)
49 v.serialize_attribute("class_name", class_name)
50 v.serialize_attribute("full_name", full_name)
51 v.serialize_attribute("mdoc", mdoc_or_fallback)
52 v.serialize_attribute("visibility", visibility.to_s)
53 v.serialize_attribute("modifiers", collect_modifiers)
54 v.serialize_attribute("location", location)
55 end
56
57 # Serialize the full version of `self` to JSON
58 #
59 # See: `FullJsonSerializer`
60 fun serialize_to_full_json(mainmodule: MModule, plain, pretty: nullable Bool): String do
61 var stream = new StringWriter
62 var serializer = new FullJsonSerializer(stream, mainmodule)
63 serializer.plain_json = plain or else false
64 serializer.pretty_json = pretty or else false
65 serializer.serialize self
66 stream.close
67 return stream.to_s
68 end
69
70 # Return the full json representation of `self` with references.
71 #
72 # By default, every reference to another MEntity is replaced by a pointer
73 # to the MEntity::json_id.
74 # Use this method to obtain a full object with mentities instead of pointers.
75 fun to_full_json(mainmodule: MModule): String do
76 return serialize_to_full_json(mainmodule, plain=true)
77 end
78
79 # Same as `to_full_json` but with pretty json.
80 fun to_pretty_full_json(mainmodule: MModule): String do
81 return serialize_to_full_json(mainmodule, plain=true, pretty=true)
82 end
83
84 # Sort mentities by name
85 private fun sort_entities(mentities: Collection[MEntity]): Array[MEntity] do
86 var sorter = new MEntityNameSorter
87 var sorted = mentities.to_a
88 sorter.sort(sorted)
89 return sorted
90 end
91 end
92
93 redef class MDoc
94 serialize
95
96 redef fun core_serialize_to(v) do
97 super
98 v.serialize_attribute("content", content.join("\n"))
99 v.serialize_attribute("location", location)
100 end
101 end
102
103 redef class nitc::Location
104 serialize
105
106 redef fun core_serialize_to(v) do
107 v.serialize_attribute("column_end", column_end)
108 v.serialize_attribute("column_start", column_start)
109 v.serialize_attribute("line_end", line_end)
110 v.serialize_attribute("line_start", line_start)
111 var file = self.file
112 if file != null then
113 v.serialize_attribute("file", file.filename)
114 end
115 end
116 end
117
118 redef class MPackage
119 redef fun core_serialize_to(v) do
120 super
121 if v isa FullJsonSerializer then
122 v.serialize_attribute("root", to_mentity_ref(root))
123 v.serialize_attribute("mgroups", to_mentity_refs(sort_entities(mgroups)))
124 var ini = self.ini
125 if ini != null then v.serialize_attribute("ini", ini.to_map)
126 end
127 end
128 end
129
130 redef class MGroup
131 redef fun core_serialize_to(v) do
132 super
133 if v isa FullJsonSerializer then
134 v.serialize_attribute("is_root", is_root)
135 v.serialize_attribute("mpackage", to_mentity_ref(mpackage))
136 v.serialize_attribute("default_mmodule", to_mentity_ref(default_mmodule))
137 v.serialize_attribute("parent", to_mentity_ref(parent))
138 v.serialize_attribute("mmodules", to_mentity_refs(sort_entities(mmodules)))
139 v.serialize_attribute("mgroups", to_mentity_refs(sort_entities(in_nesting.direct_smallers)))
140 end
141 end
142 end
143
144 redef class MModule
145 redef fun core_serialize_to(v) do
146 super
147 if v isa FullJsonSerializer then
148 var view = new ModelView(model, v.mainmodule)
149 v.serialize_attribute("mpackage", to_mentity_ref(mpackage))
150 v.serialize_attribute("mgroup", to_mentity_ref(mgroup))
151 v.serialize_attribute("intro_mclasses", to_mentity_refs(sort_entities(intro_mclasses)))
152 v.serialize_attribute("mclassdefs", to_mentity_refs(sort_entities(mclassdefs)))
153 v.serialize_attribute("intro_mclassdefs", to_mentity_refs(sort_entities(collect_intro_mclassdefs(view))))
154 v.serialize_attribute("redef_mclassdefs", to_mentity_refs(sort_entities(collect_redef_mclassdefs(view))))
155 v.serialize_attribute("imports", to_mentity_refs(in_importation.direct_greaters))
156 end
157 end
158 end
159
160 redef class MClass
161 redef fun core_serialize_to(v) do
162 super
163 v.serialize_attribute("mparameters", mparameters)
164 if v isa FullJsonSerializer then
165 var view = new ModelView(model, v.mainmodule)
166 v.serialize_attribute("intro", to_mentity_ref(intro))
167 v.serialize_attribute("intro_mmodule", to_mentity_ref(intro_mmodule))
168 v.serialize_attribute("mpackage", to_mentity_ref(intro_mmodule.mpackage))
169 v.serialize_attribute("mclassdefs", to_mentity_refs(mclassdefs))
170 v.serialize_attribute("all_mproperties", to_mentity_refs(sort_entities(collect_accessible_mproperties(view))))
171 v.serialize_attribute("intro_mproperties", to_mentity_refs(sort_entities(collect_intro_mproperties(view))))
172 v.serialize_attribute("redef_mproperties", to_mentity_refs(sort_entities(collect_redef_mproperties(view))))
173 v.serialize_attribute("parents", to_mentity_refs(sort_entities(collect_parents(view))))
174 end
175 end
176 end
177
178 redef class MClassDef
179 redef fun core_serialize_to(v) do
180 super
181 v.serialize_attribute("is_intro", is_intro)
182 v.serialize_attribute("mparameters", mclass.mparameters)
183 if v isa FullJsonSerializer then
184 var view = new ModelView(model, v.mainmodule)
185 v.serialize_attribute("mmodule", to_mentity_ref(mmodule))
186 v.serialize_attribute("mclass", to_mentity_ref(mclass))
187 v.serialize_attribute("mpropdefs", to_mentity_refs(sort_entities(mpropdefs)))
188 v.serialize_attribute("intro_mproperties", to_mentity_refs(sort_entities(intro_mproperties)))
189 v.serialize_attribute("intro", to_mentity_ref(mclass.intro))
190 v.serialize_attribute("mpackage", to_mentity_ref(mmodule.mpackage))
191 v.serialize_attribute("intro_mpropdefs", to_mentity_refs(sort_entities(collect_intro_mpropdefs(view))))
192 v.serialize_attribute("redef_mpropdefs", to_mentity_refs(sort_entities(collect_redef_mpropdefs(view))))
193 end
194 end
195 end
196
197 redef class MProperty
198 redef fun core_serialize_to(v) do
199 super
200 if v isa FullJsonSerializer then
201 v.serialize_attribute("intro", to_mentity_ref(intro))
202 v.serialize_attribute("intro_mclassdef", to_mentity_ref(intro_mclassdef))
203 v.serialize_attribute("mpropdefs", to_mentity_refs(sort_entities(mpropdefs)))
204 v.serialize_attribute("intro_mclass", to_mentity_ref(intro_mclassdef.mclass))
205 v.serialize_attribute("mpackage", to_mentity_ref(intro_mclassdef.mmodule.mpackage))
206 end
207 end
208 end
209
210 redef class MMethod
211 redef fun core_serialize_to(v) do
212 super
213 v.serialize_attribute("is_init", is_init)
214 v.serialize_attribute("msignature", intro.msignature)
215 end
216 end
217
218 redef class MAttribute
219 redef fun core_serialize_to(v) do
220 super
221 v.serialize_attribute("static_mtype", to_mentity_ref(intro.static_mtype))
222 end
223 end
224
225 redef class MVirtualTypeProp
226 redef fun core_serialize_to(v) do
227 super
228 v.serialize_attribute("mvirtualtype", to_mentity_ref(mvirtualtype))
229 v.serialize_attribute("bound", to_mentity_ref(intro.bound))
230 end
231 end
232
233 redef class MPropDef
234 redef fun core_serialize_to(v) do
235 super
236 v.serialize_attribute("is_intro", is_intro)
237 if v isa FullJsonSerializer then
238 v.serialize_attribute("mclassdef", to_mentity_ref(mclassdef))
239 v.serialize_attribute("mproperty", to_mentity_ref(mproperty))
240 v.serialize_attribute("intro", to_mentity_ref(mproperty.intro))
241 v.serialize_attribute("intro_mclassdef", to_mentity_ref(mproperty.intro.mclassdef))
242 v.serialize_attribute("mmodule", to_mentity_ref(mclassdef.mmodule))
243 v.serialize_attribute("mgroup", to_mentity_ref(mclassdef.mmodule.mgroup))
244 v.serialize_attribute("mpackage", to_mentity_ref(mclassdef.mmodule.mpackage))
245 end
246 end
247 end
248
249 redef class MMethodDef
250 redef fun core_serialize_to(v) do
251 super
252 v.serialize_attribute("msignature", msignature)
253 end
254 end
255
256 redef class MAttributeDef
257 redef fun core_serialize_to(v) do
258 super
259 v.serialize_attribute("static_mtype", to_mentity_ref(static_mtype))
260 end
261 end
262
263 redef class MVirtualTypeDef
264 redef fun core_serialize_to(v) do
265 super
266 v.serialize_attribute("bound", to_mentity_ref(bound))
267 v.serialize_attribute("is_fixed", is_fixed)
268 end
269 end
270
271 redef class MSignature
272 redef fun core_serialize_to(v) do
273 v.serialize_attribute("arity", arity)
274 v.serialize_attribute("mparams", mparameters)
275 v.serialize_attribute("return_mtype", to_mentity_ref(return_mtype))
276 v.serialize_attribute("vararg_rank", vararg_rank)
277 end
278 end
279
280 redef class MParameterType
281 redef fun core_serialize_to(v) do
282 v.serialize_attribute("name", name)
283 v.serialize_attribute("rank", rank)
284 v.serialize_attribute("mtype", to_mentity_ref(mclass.intro.bound_mtype.arguments[rank]))
285 end
286 end
287
288 redef class MParameter
289 redef fun core_serialize_to(v) do
290 v.serialize_attribute("is_vararg", is_vararg)
291 v.serialize_attribute("name", name)
292 v.serialize_attribute("mtype", to_mentity_ref(mtype))
293 end
294 end
295
296 # Create a ref to a `mentity`.
297 fun to_mentity_ref(mentity: nullable MEntity): nullable MEntityRef do
298 if mentity == null then return null
299 return new MEntityRef(mentity)
300 end
301
302 # Return a collection of `mentities` as a JsonArray of MEntityRefs.
303 fun to_mentity_refs(mentities: Collection[MEntity]): Array[MEntityRef] do
304 var array = new Array[MEntityRef]
305 for mentity in mentities do
306 var ref = to_mentity_ref(mentity)
307 if ref == null then continue
308 array.add ref
309 end
310 return array
311 end
312
313 # Use the FullJsonSerializer to generate the full json representation of a MEntity.
314 #
315 # See MEntity::to_full_json.
316 class FullJsonSerializer
317 super JsonSerializer
318
319 # FIXME tmp use of the mainmodule, a PR is comming to clean all the JSON mess
320 var mainmodule: MModule
321 end