model: introduce model_json
authorAlexandre Terrasa <alexandre@moz-code.org>
Tue, 17 May 2016 16:03:18 +0000 (12:03 -0400)
committerAlexandre Terrasa <alexandre@moz-code.org>
Tue, 17 May 2016 18:22:23 +0000 (14:22 -0400)
Translates model entites to plain json

Signed-off-by: Alexandre Terrasa <alexandre@moz-code.org>

src/model/model_json.nit [new file with mode: 0644]

diff --git a/src/model/model_json.nit b/src/model/model_json.nit
new file mode 100644 (file)
index 0000000..fc4b101
--- /dev/null
@@ -0,0 +1,304 @@
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Make model entities Jsonable.
+#
+# To avoid cycles, every reference from a MEntity to another is replaced by a
+# MEntityRef.
+#
+# How subobjects are retrieved using the MEntityRef is the responsability of the
+# client. Json objects can be returned as this or inflated with concrete objet
+# rather than the refs.
+#
+# TODO consider serialization module?
+module model_json
+
+import model::model_collect
+import json
+import loader
+
+# A reference to another mentity.
+class MEntityRef
+       super MEntity
+
+       # MEntity to link to.
+       var mentity: MEntity
+
+       # Return `self` as a Json Object.
+       #
+       # By default, MEntity references contain only the `full_name` of the Mentity.
+       # You should redefine this method in your client to implement a different behavior.
+       redef fun json do
+               var obj = new JsonObject
+               obj["full_name"] = mentity.full_name
+               return obj
+       end
+end
+
+redef class MEntity
+       super Jsonable
+
+       # Return `self` as a JsonObject.
+       #
+       # By default, every reference to another MEntity is replaced by a pointer
+       # to the MEntity::json_id.
+       fun json: JsonObject do
+               var obj = new JsonObject
+               obj["name"] = name
+               obj["class_name"] = class_name
+               obj["full_name"] = full_name
+               obj["mdoc"] = mdoc_or_fallback
+               var modifiers = new JsonArray
+               for modifier in collect_modifiers do
+                       modifiers.add modifier
+               end
+               obj["modifiers"] = modifiers
+               return obj
+       end
+
+       redef fun to_json do return json.to_json
+end
+
+redef class MDoc
+       super Jsonable
+
+       # Return `self` as a JsonObject.
+       fun json: JsonObject do
+               var obj = new JsonObject
+               obj["content"] = content.join("\n")
+               obj["location"] = location
+               return obj
+       end
+
+       redef fun to_json do return json.to_json
+end
+
+redef class Location
+       super Jsonable
+
+       # Return `self` as a JsonObject.
+       fun json: JsonObject do
+               var obj = new JsonObject
+               obj["column_end"] = column_end
+               obj["column_start"] = column_start
+               obj["line_end"] = line_end
+               obj["line_start"] = line_start
+               var file = self.file
+               if file != null then
+                       obj["file"] = file.filename
+               end
+               return obj
+       end
+
+       redef fun to_json do return json.to_json
+end
+
+redef class MVisibility
+       super Jsonable
+
+       redef fun to_json do return to_s.to_json
+end
+
+redef class MPackage
+
+       redef fun json do
+               var obj = super
+               obj["visibility"] = public_visibility
+               if ini != null then
+                       obj["ini"] = new JsonObject.from(ini.as(not null).to_map)
+               end
+               obj["root"] = to_mentity_ref(root)
+               obj["mgroups"] = to_mentity_refs(mgroups)
+               return obj
+       end
+end
+
+redef class MGroup
+       redef fun json do
+               var obj = super
+               obj["visibility"] = public_visibility
+               obj["is_root"] = is_root
+               obj["mpackage"] = to_mentity_ref(mpackage)
+               obj["default_mmodule"] = to_mentity_ref(default_mmodule)
+               obj["parent"] = to_mentity_ref(parent)
+               obj["mmodules"] = to_mentity_refs(mmodules)
+               obj["mgroups"] = to_mentity_refs(in_nesting.direct_smallers)
+               return obj
+       end
+end
+
+redef class MModule
+       redef fun json do
+               var obj = super
+               obj["location"] = location
+               obj["visibility"] = public_visibility
+               obj["mpackage"] = to_mentity_ref(mpackage)
+               obj["mgroup"] = to_mentity_ref(mgroup)
+               obj["intro_mclasses"] = to_mentity_refs(intro_mclasses)
+               obj["mclassdefs"] = to_mentity_refs(mclassdefs)
+               return obj
+       end
+end
+
+redef class MClass
+       redef fun json do
+               var obj = super
+               obj["visibility"] = visibility
+               var arr = new JsonArray
+               for mparameter in mparameters do arr.add mparameter
+               obj["mparameters"] = arr
+               obj["intro"] = to_mentity_ref(intro)
+               obj["intro_mmodule"] = to_mentity_ref(intro_mmodule)
+               obj["mpackage"] = to_mentity_ref(intro_mmodule.mpackage)
+               obj["mclassdefs"] = to_mentity_refs(mclassdefs)
+               return obj
+       end
+end
+
+redef class MClassDef
+       redef fun json do
+               var obj = super
+               obj["visibility"] = mclass.visibility
+               obj["location"] = location
+               obj["is_intro"] = is_intro
+               var arr = new JsonArray
+               for mparameter in mclass.mparameters do arr.add mparameter
+               obj["mparameters"] = arr
+               obj["mmodule"] = to_mentity_ref(mmodule)
+               obj["mclass"] = to_mentity_ref(mclass)
+               obj["mpropdefs"] = to_mentity_refs(mpropdefs)
+               obj["intro_mproperties"] = to_mentity_refs(intro_mproperties)
+               return obj
+       end
+end
+
+redef class MProperty
+       redef fun json do
+               var obj = super
+               obj["visibility"] = visibility
+               obj["intro"] = to_mentity_ref(intro)
+               obj["intro_mclassdef"] = to_mentity_ref(intro_mclassdef)
+               obj["mpropdefs"] = to_mentity_refs(mpropdefs)
+               return obj
+       end
+end
+
+redef class MMethod
+       redef fun json do
+               var obj = super
+               obj["is_init"] = is_init
+               obj["msignature"] = intro.msignature
+               return obj
+       end
+end
+
+redef class MAttribute
+       redef fun json do
+               var obj = super
+               obj["static_mtype"] = to_mentity_ref(intro.static_mtype)
+               return obj
+       end
+end
+
+redef class MVirtualTypeProp
+       redef fun json do
+               var obj = super
+               obj["mvirtualtype"] = to_mentity_ref(mvirtualtype)
+               obj["bound"] = to_mentity_ref(intro.bound)
+               return obj
+       end
+end
+
+redef class MPropDef
+       redef fun json do
+               var obj = super
+               obj["visibility"] = mproperty.visibility
+               obj["location"] = location
+               obj["is_intro"] = is_intro
+               obj["mclassdef"] = to_mentity_ref(mclassdef)
+               obj["mproperty"] = to_mentity_ref(mproperty)
+               return obj
+       end
+end
+
+redef class MMethodDef
+       redef fun json do
+               var obj = super
+               obj["msignature"] = msignature
+               return obj
+       end
+end
+
+redef class MAttributeDef
+       redef fun json do
+               var obj = super
+               obj["static_mtype"] = to_mentity_ref(static_mtype)
+               return obj
+       end
+end
+
+redef class MVirtualTypeDef
+       redef fun json do
+               var obj = super
+               obj["bound"] = to_mentity_ref(bound)
+               obj["is_fixed"] = is_fixed
+               return obj
+       end
+end
+
+redef class MSignature
+       redef fun json do
+               var obj = new JsonObject
+               obj["arity"] = arity
+               var arr = new JsonArray
+               for mparam in mparameters do arr.add mparam
+               obj["mparams"] = arr
+               obj["return_mtype"] = to_mentity_ref(return_mtype)
+               obj["vararg_rank"] = vararg_rank
+               return obj
+       end
+end
+
+redef class MParameterType
+       redef fun json do
+               var obj = new JsonObject
+               obj["name"] = name
+               obj["rank"] = rank
+               obj["mtype"] = to_mentity_ref(mclass.intro.bound_mtype.arguments[rank])
+               return obj
+       end
+end
+
+redef class MParameter
+       redef fun json do
+               var obj = new JsonObject
+               obj["is_vararg"] = is_vararg
+               obj["name"] = name
+               obj["mtype"] = to_mentity_ref(mtype)
+               return obj
+       end
+end
+
+# Create a ref to a `mentity`.
+fun to_mentity_ref(mentity: nullable MEntity): nullable MEntityRef do
+       if mentity == null then return null
+       return new MEntityRef(mentity)
+end
+
+# Return a collection of `mentities` as a JsonArray of MEntityRefs.
+fun to_mentity_refs(mentities: Collection[MEntity]): JsonArray do
+       var array = new JsonArray
+       for mentity in mentities do array.add to_mentity_ref(mentity)
+       return array
+end