model: json use filters
[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 filter = new ModelFilter(private_visibility)
166 var view = new ModelView(model, v.mainmodule, filter)
167 v.serialize_attribute("intro", to_mentity_ref(intro))
168 v.serialize_attribute("intro_mmodule", to_mentity_ref(intro_mmodule))
169 v.serialize_attribute("mpackage", to_mentity_ref(intro_mmodule.mpackage))
170 v.serialize_attribute("mclassdefs", to_mentity_refs(mclassdefs))
171 v.serialize_attribute("all_mproperties", to_mentity_refs(sort_entities(collect_accessible_mproperties(view))))
172 v.serialize_attribute("intro_mproperties", to_mentity_refs(sort_entities(collect_intro_mproperties(view))))
173 v.serialize_attribute("redef_mproperties", to_mentity_refs(sort_entities(collect_redef_mproperties(view))))
174 v.serialize_attribute("parents", to_mentity_refs(sort_entities(collect_parents(view))))
175 end
176 end
177 end
178
179 redef class MClassDef
180 redef fun core_serialize_to(v) do
181 super
182 v.serialize_attribute("is_intro", is_intro)
183 v.serialize_attribute("mparameters", mclass.mparameters)
184 if v isa FullJsonSerializer then
185 var filter = new ModelFilter(private_visibility)
186 var view = new ModelView(model, v.mainmodule, filter)
187 v.serialize_attribute("mmodule", to_mentity_ref(mmodule))
188 v.serialize_attribute("mclass", to_mentity_ref(mclass))
189 v.serialize_attribute("mpropdefs", to_mentity_refs(sort_entities(mpropdefs)))
190 v.serialize_attribute("intro_mproperties", to_mentity_refs(sort_entities(intro_mproperties)))
191 v.serialize_attribute("intro", to_mentity_ref(mclass.intro))
192 v.serialize_attribute("mpackage", to_mentity_ref(mmodule.mpackage))
193 v.serialize_attribute("intro_mpropdefs", to_mentity_refs(sort_entities(collect_intro_mpropdefs(view))))
194 v.serialize_attribute("redef_mpropdefs", to_mentity_refs(sort_entities(collect_redef_mpropdefs(view))))
195 end
196 end
197 end
198
199 redef class MProperty
200 redef fun core_serialize_to(v) do
201 super
202 if v isa FullJsonSerializer then
203 v.serialize_attribute("intro", to_mentity_ref(intro))
204 v.serialize_attribute("intro_mclassdef", to_mentity_ref(intro_mclassdef))
205 v.serialize_attribute("mpropdefs", to_mentity_refs(sort_entities(mpropdefs)))
206 v.serialize_attribute("intro_mclass", to_mentity_ref(intro_mclassdef.mclass))
207 v.serialize_attribute("mpackage", to_mentity_ref(intro_mclassdef.mmodule.mpackage))
208 end
209 end
210 end
211
212 redef class MMethod
213 redef fun core_serialize_to(v) do
214 super
215 v.serialize_attribute("is_init", is_init)
216 v.serialize_attribute("msignature", intro.msignature)
217 end
218 end
219
220 redef class MAttribute
221 redef fun core_serialize_to(v) do
222 super
223 v.serialize_attribute("static_mtype", to_mentity_ref(intro.static_mtype))
224 end
225 end
226
227 redef class MVirtualTypeProp
228 redef fun core_serialize_to(v) do
229 super
230 v.serialize_attribute("mvirtualtype", to_mentity_ref(mvirtualtype))
231 v.serialize_attribute("bound", to_mentity_ref(intro.bound))
232 end
233 end
234
235 redef class MPropDef
236 redef fun core_serialize_to(v) do
237 super
238 v.serialize_attribute("is_intro", is_intro)
239 if v isa FullJsonSerializer then
240 v.serialize_attribute("mclassdef", to_mentity_ref(mclassdef))
241 v.serialize_attribute("mproperty", to_mentity_ref(mproperty))
242 v.serialize_attribute("intro", to_mentity_ref(mproperty.intro))
243 v.serialize_attribute("intro_mclassdef", to_mentity_ref(mproperty.intro.mclassdef))
244 v.serialize_attribute("mmodule", to_mentity_ref(mclassdef.mmodule))
245 v.serialize_attribute("mgroup", to_mentity_ref(mclassdef.mmodule.mgroup))
246 v.serialize_attribute("mpackage", to_mentity_ref(mclassdef.mmodule.mpackage))
247 end
248 end
249 end
250
251 redef class MMethodDef
252 redef fun core_serialize_to(v) do
253 super
254 v.serialize_attribute("msignature", msignature)
255 end
256 end
257
258 redef class MAttributeDef
259 redef fun core_serialize_to(v) do
260 super
261 v.serialize_attribute("static_mtype", to_mentity_ref(static_mtype))
262 end
263 end
264
265 redef class MVirtualTypeDef
266 redef fun core_serialize_to(v) do
267 super
268 v.serialize_attribute("bound", to_mentity_ref(bound))
269 v.serialize_attribute("is_fixed", is_fixed)
270 end
271 end
272
273 redef class MSignature
274 redef fun core_serialize_to(v) do
275 v.serialize_attribute("arity", arity)
276 v.serialize_attribute("mparams", mparameters)
277 v.serialize_attribute("return_mtype", to_mentity_ref(return_mtype))
278 v.serialize_attribute("vararg_rank", vararg_rank)
279 end
280 end
281
282 redef class MParameterType
283 redef fun core_serialize_to(v) do
284 v.serialize_attribute("name", name)
285 v.serialize_attribute("rank", rank)
286 v.serialize_attribute("mtype", to_mentity_ref(mclass.intro.bound_mtype.arguments[rank]))
287 end
288 end
289
290 redef class MParameter
291 redef fun core_serialize_to(v) do
292 v.serialize_attribute("is_vararg", is_vararg)
293 v.serialize_attribute("name", name)
294 v.serialize_attribute("mtype", to_mentity_ref(mtype))
295 end
296 end
297
298 # Create a ref to a `mentity`.
299 fun to_mentity_ref(mentity: nullable MEntity): nullable MEntityRef do
300 if mentity == null then return null
301 return new MEntityRef(mentity)
302 end
303
304 # Return a collection of `mentities` as a JsonArray of MEntityRefs.
305 fun to_mentity_refs(mentities: Collection[MEntity]): Array[MEntityRef] do
306 var array = new Array[MEntityRef]
307 for mentity in mentities do
308 var ref = to_mentity_ref(mentity)
309 if ref == null then continue
310 array.add ref
311 end
312 return array
313 end
314
315 # Use the FullJsonSerializer to generate the full json representation of a MEntity.
316 #
317 # See MEntity::to_full_json.
318 class FullJsonSerializer
319 super JsonSerializer
320
321 # FIXME tmp use of the mainmodule, a PR is comming to clean all the JSON mess
322 var mainmodule: MModule
323 end