7c43e51058b8c2518187e84c4d405490affdadc9
[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(plain, pretty: nullable Bool): String do
61 var stream = new StringWriter
62 var serializer = new FullJsonSerializer(stream)
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: String do return serialize_to_full_json(plain=true)
76
77 # Same as `to_full_json` but with pretty json.
78 fun to_pretty_full_json: String do return serialize_to_full_json(plain=true, pretty=true)
79
80 # Sort mentities by name
81 private fun sort_entities(mentities: Collection[MEntity]): Array[MEntity] do
82 var sorter = new MEntityNameSorter
83 var sorted = mentities.to_a
84 sorter.sort(sorted)
85 return sorted
86 end
87 end
88
89 redef class MDoc
90 serialize
91
92 redef fun core_serialize_to(v) do
93 super
94 v.serialize_attribute("content", content.join("\n"))
95 v.serialize_attribute("location", location)
96 end
97 end
98
99 redef class nitc::Location
100 serialize
101
102 redef fun core_serialize_to(v) do
103 v.serialize_attribute("column_end", column_end)
104 v.serialize_attribute("column_start", column_start)
105 v.serialize_attribute("line_end", line_end)
106 v.serialize_attribute("line_start", line_start)
107 var file = self.file
108 if file != null then
109 v.serialize_attribute("file", file.filename)
110 end
111 end
112 end
113
114 redef class MPackage
115 redef fun core_serialize_to(v) do
116 super
117 if v isa FullJsonSerializer then
118 v.serialize_attribute("root", to_mentity_ref(root))
119 v.serialize_attribute("mgroups", to_mentity_refs(sort_entities(mgroups)))
120 var ini = self.ini
121 if ini != null then v.serialize_attribute("ini", ini.to_map)
122 end
123 end
124 end
125
126 redef class MGroup
127 redef fun core_serialize_to(v) do
128 super
129 if v isa FullJsonSerializer then
130 v.serialize_attribute("is_root", is_root)
131 v.serialize_attribute("mpackage", to_mentity_ref(mpackage))
132 v.serialize_attribute("default_mmodule", to_mentity_ref(default_mmodule))
133 v.serialize_attribute("parent", to_mentity_ref(parent))
134 v.serialize_attribute("mmodules", to_mentity_refs(sort_entities(mmodules)))
135 v.serialize_attribute("mgroups", to_mentity_refs(sort_entities(in_nesting.direct_smallers)))
136 end
137 end
138 end
139
140 redef class MModule
141 redef fun core_serialize_to(v) do
142 super
143 if v isa FullJsonSerializer then
144 var view = private_view
145 v.serialize_attribute("mpackage", to_mentity_ref(mpackage))
146 v.serialize_attribute("mgroup", to_mentity_ref(mgroup))
147 v.serialize_attribute("intro_mclasses", to_mentity_refs(sort_entities(intro_mclasses)))
148 v.serialize_attribute("mclassdefs", to_mentity_refs(sort_entities(mclassdefs)))
149 v.serialize_attribute("intro_mclassdefs", to_mentity_refs(sort_entities(collect_intro_mclassdefs(view))))
150 v.serialize_attribute("redef_mclassdefs", to_mentity_refs(sort_entities(collect_redef_mclassdefs(view))))
151 v.serialize_attribute("imports", to_mentity_refs(in_importation.direct_greaters))
152 end
153 end
154 end
155
156 redef class MClass
157 redef fun core_serialize_to(v) do
158 super
159 v.serialize_attribute("mparameters", mparameters)
160 if v isa FullJsonSerializer then
161 var view = private_view
162 v.serialize_attribute("intro", to_mentity_ref(intro))
163 v.serialize_attribute("intro_mmodule", to_mentity_ref(intro_mmodule))
164 v.serialize_attribute("mpackage", to_mentity_ref(intro_mmodule.mpackage))
165 v.serialize_attribute("mclassdefs", to_mentity_refs(mclassdefs))
166 v.serialize_attribute("all_mproperties", to_mentity_refs(sort_entities(collect_accessible_mproperties(view))))
167 v.serialize_attribute("intro_mproperties", to_mentity_refs(sort_entities(collect_intro_mproperties(view))))
168 v.serialize_attribute("redef_mproperties", to_mentity_refs(sort_entities(collect_redef_mproperties(view))))
169 v.serialize_attribute("parents", to_mentity_refs(sort_entities(collect_parents(view))))
170 end
171 end
172 end
173
174 redef class MClassDef
175 redef fun core_serialize_to(v) do
176 super
177 v.serialize_attribute("is_intro", is_intro)
178 v.serialize_attribute("mparameters", mclass.mparameters)
179 if v isa FullJsonSerializer then
180 var view = private_view
181 v.serialize_attribute("mmodule", to_mentity_ref(mmodule))
182 v.serialize_attribute("mclass", to_mentity_ref(mclass))
183 v.serialize_attribute("mpropdefs", to_mentity_refs(sort_entities(mpropdefs)))
184 v.serialize_attribute("intro_mproperties", to_mentity_refs(sort_entities(intro_mproperties)))
185 v.serialize_attribute("intro", to_mentity_ref(mclass.intro))
186 v.serialize_attribute("mpackage", to_mentity_ref(mmodule.mpackage))
187 v.serialize_attribute("intro_mpropdefs", to_mentity_refs(sort_entities(collect_intro_mpropdefs(view))))
188 v.serialize_attribute("redef_mpropdefs", to_mentity_refs(sort_entities(collect_redef_mpropdefs(view))))
189 end
190 end
191 end
192
193 redef class MProperty
194 redef fun core_serialize_to(v) do
195 super
196 if v isa FullJsonSerializer then
197 v.serialize_attribute("intro", to_mentity_ref(intro))
198 v.serialize_attribute("intro_mclassdef", to_mentity_ref(intro_mclassdef))
199 v.serialize_attribute("mpropdefs", to_mentity_refs(sort_entities(mpropdefs)))
200 v.serialize_attribute("intro_mclass", to_mentity_ref(intro_mclassdef.mclass))
201 v.serialize_attribute("mpackage", to_mentity_ref(intro_mclassdef.mmodule.mpackage))
202 end
203 end
204 end
205
206 redef class MMethod
207 redef fun core_serialize_to(v) do
208 super
209 v.serialize_attribute("is_init", is_init)
210 v.serialize_attribute("msignature", intro.msignature)
211 end
212 end
213
214 redef class MAttribute
215 redef fun core_serialize_to(v) do
216 super
217 v.serialize_attribute("static_mtype", to_mentity_ref(intro.static_mtype))
218 end
219 end
220
221 redef class MVirtualTypeProp
222 redef fun core_serialize_to(v) do
223 super
224 v.serialize_attribute("mvirtualtype", to_mentity_ref(mvirtualtype))
225 v.serialize_attribute("bound", to_mentity_ref(intro.bound))
226 end
227 end
228
229 redef class MPropDef
230 redef fun core_serialize_to(v) do
231 super
232 v.serialize_attribute("is_intro", is_intro)
233 if v isa FullJsonSerializer then
234 v.serialize_attribute("mclassdef", to_mentity_ref(mclassdef))
235 v.serialize_attribute("mproperty", to_mentity_ref(mproperty))
236 v.serialize_attribute("intro", to_mentity_ref(mproperty.intro))
237 v.serialize_attribute("intro_mclassdef", to_mentity_ref(mproperty.intro.mclassdef))
238 v.serialize_attribute("mmodule", to_mentity_ref(mclassdef.mmodule))
239 v.serialize_attribute("mgroup", to_mentity_ref(mclassdef.mmodule.mgroup))
240 v.serialize_attribute("mpackage", to_mentity_ref(mclassdef.mmodule.mpackage))
241 end
242 end
243 end
244
245 redef class MMethodDef
246 redef fun core_serialize_to(v) do
247 super
248 v.serialize_attribute("msignature", msignature)
249 end
250 end
251
252 redef class MAttributeDef
253 redef fun core_serialize_to(v) do
254 super
255 v.serialize_attribute("static_mtype", to_mentity_ref(static_mtype))
256 end
257 end
258
259 redef class MVirtualTypeDef
260 redef fun core_serialize_to(v) do
261 super
262 v.serialize_attribute("bound", to_mentity_ref(bound))
263 v.serialize_attribute("is_fixed", is_fixed)
264 end
265 end
266
267 redef class MSignature
268 redef fun core_serialize_to(v) do
269 v.serialize_attribute("arity", arity)
270 v.serialize_attribute("mparams", mparameters)
271 v.serialize_attribute("return_mtype", to_mentity_ref(return_mtype))
272 v.serialize_attribute("vararg_rank", vararg_rank)
273 end
274 end
275
276 redef class MParameterType
277 redef fun core_serialize_to(v) do
278 v.serialize_attribute("name", name)
279 v.serialize_attribute("rank", rank)
280 v.serialize_attribute("mtype", to_mentity_ref(mclass.intro.bound_mtype.arguments[rank]))
281 end
282 end
283
284 redef class MParameter
285 redef fun core_serialize_to(v) do
286 v.serialize_attribute("is_vararg", is_vararg)
287 v.serialize_attribute("name", name)
288 v.serialize_attribute("mtype", to_mentity_ref(mtype))
289 end
290 end
291
292 # Create a ref to a `mentity`.
293 fun to_mentity_ref(mentity: nullable MEntity): nullable MEntityRef do
294 if mentity == null then return null
295 return new MEntityRef(mentity)
296 end
297
298 # Return a collection of `mentities` as a JsonArray of MEntityRefs.
299 fun to_mentity_refs(mentities: Collection[MEntity]): Array[MEntityRef] do
300 var array = new Array[MEntityRef]
301 for mentity in mentities do
302 var ref = to_mentity_ref(mentity)
303 if ref == null then continue
304 array.add ref
305 end
306 return array
307 end
308
309 # Use the FullJsonSerializer to generate the full json representation of a MEntity.
310 #
311 # See MEntity::to_full_json.
312 class FullJsonSerializer
313 super JsonSerializer
314 end