import model::model_collect
import json::static
import json::serialization_write
-import loader
-
-# A reference to another mentity.
-class MEntityRef
- super MEntity
-
- # MEntity to link to.
- var mentity: MEntity
-
- redef fun core_serialize_to(v) do
- v.serialize_attribute("full_name", mentity.full_name)
- end
-end
+import catalog
+import doc_down
redef class MEntity
serialize
- redef fun core_serialize_to(v) do
+ private fun core_serialize_base(v: Serializer) do
v.serialize_attribute("name", name)
+ var mdoc = mdoc_or_fallback
+ if mdoc != null then
+ v.serialize_attribute("synopsis", mdoc.synopsis)
+ end
+ end
+
+ redef fun core_serialize_to(v) do
+ core_serialize_base(v)
+
+ v.serialize_attribute("namespace", json_namespace)
v.serialize_attribute("class_name", class_name)
v.serialize_attribute("full_name", full_name)
- v.serialize_attribute("mdoc", mdoc_or_fallback)
v.serialize_attribute("visibility", visibility.to_s)
- v.serialize_attribute("modifiers", collect_modifiers)
- v.serialize_attribute("location", location)
- end
-
- # Serialize the full version of `self` to JSON
- #
- # See: `FullJsonSerializer`
- fun serialize_to_full_json(mainmodule: MModule, plain, pretty: nullable Bool): String do
- var stream = new StringWriter
- var serializer = new FullJsonSerializer(stream, mainmodule)
- serializer.plain_json = plain or else false
- serializer.pretty_json = pretty or else false
- serializer.serialize self
- stream.close
- return stream.to_s
- end
+ var mdoc = mdoc_or_fallback
+ if mdoc != null then
+ v.serialize_attribute("html_synopsis", mdoc.html_synopsis.write_to_string)
+ end
- # Return the full json representation of `self` with references.
- #
- # By default, every reference to another MEntity is replaced by a pointer
- # to the MEntity::json_id.
- # Use this method to obtain a full object with mentities instead of pointers.
- fun to_full_json(mainmodule: MModule): String do
- return serialize_to_full_json(mainmodule, plain=true)
+ var modifiers = collect_modifiers
+ if modifiers.not_empty then
+ v.serialize_attribute("modifiers", modifiers)
+ end
end
- # Same as `to_full_json` but with pretty json.
- fun to_pretty_full_json(mainmodule: MModule): String do
- return serialize_to_full_json(mainmodule, plain=true, pretty=true)
- end
+ # Return `self.full_name` as an object that can be serialized to json.
+ fun json_namespace: JsonNamespace is abstract
- # Sort mentities by name
- private fun sort_entities(mentities: Collection[MEntity]): Array[MEntity] do
- var sorter = new MEntityNameSorter
- var sorted = mentities.to_a
- sorter.sort(sorted)
- return sorted
- end
+ # Return a new MEntityRef to `self`.
+ fun to_json_ref: MEntityRef do return new MEntityRef(self)
end
redef class MDoc
serialize
redef fun core_serialize_to(v) do
- super
- v.serialize_attribute("content", content.join("\n"))
- v.serialize_attribute("location", location)
+ var doc = html_documentation.write_to_string.trim
+ if not doc.is_empty then
+ v.serialize_attribute("html_documentation", doc)
+ end
end
end
redef class MPackage
redef fun core_serialize_to(v) do
super
- if v isa FullJsonSerializer then
- v.serialize_attribute("root", to_mentity_ref(root))
- v.serialize_attribute("mgroups", to_mentity_refs(sort_entities(mgroups)))
- var ini = self.ini
- if ini != null then v.serialize_attribute("ini", ini.to_map)
+
+ var metadata = self.metadata
+ if metadata.license != null then
+ v.serialize_attribute("license", metadata.license)
+ end
+ if metadata.maintainers.not_empty then
+ v.serialize_attribute("maintainer", metadata.maintainers.first)
+ end
+ if metadata.tags.not_empty then
+ v.serialize_attribute("tags", metadata.tags)
end
end
+
+ redef fun json_namespace do
+ var ns = new JsonNamespace
+ ns.add to_json_ref
+ return ns
+ end
end
redef class MGroup
- redef fun core_serialize_to(v) do
- super
- if v isa FullJsonSerializer then
- v.serialize_attribute("is_root", is_root)
- v.serialize_attribute("mpackage", to_mentity_ref(mpackage))
- v.serialize_attribute("default_mmodule", to_mentity_ref(default_mmodule))
- v.serialize_attribute("parent", to_mentity_ref(parent))
- v.serialize_attribute("mmodules", to_mentity_refs(sort_entities(mmodules)))
- v.serialize_attribute("mgroups", to_mentity_refs(sort_entities(in_nesting.direct_smallers)))
+ redef fun json_namespace do
+ var ns = new JsonNamespace
+ if parent != null then
+ ns.prepend parent.as(not null).json_namespace
end
+ ns.add to_json_ref
+ ns.add ">"
+ return ns
end
end
redef class MModule
- redef fun core_serialize_to(v) do
- super
- if v isa FullJsonSerializer then
- var view = new ModelView(model, v.mainmodule)
- v.serialize_attribute("mpackage", to_mentity_ref(mpackage))
- v.serialize_attribute("mgroup", to_mentity_ref(mgroup))
- v.serialize_attribute("intro_mclasses", to_mentity_refs(sort_entities(intro_mclasses)))
- v.serialize_attribute("mclassdefs", to_mentity_refs(sort_entities(mclassdefs)))
- v.serialize_attribute("intro_mclassdefs", to_mentity_refs(sort_entities(collect_intro_mclassdefs(view))))
- v.serialize_attribute("redef_mclassdefs", to_mentity_refs(sort_entities(collect_redef_mclassdefs(view))))
- v.serialize_attribute("imports", to_mentity_refs(in_importation.direct_greaters))
+ redef fun json_namespace do
+ var ns = new JsonNamespace
+ if mgroup != null then
+ ns.add_all mgroup.as(not null).mpackage.json_namespace
+ ns.add "::"
end
+ ns.add to_json_ref
+ return ns
+ end
+
+ private fun ns_for(visibility: MVisibility): JsonNamespace do
+ if visibility <= private_visibility then return json_namespace
+ var mgroup = self.mgroup
+ if mgroup == null then return json_namespace
+ return mgroup.mpackage.json_namespace
end
end
redef class MClass
redef fun core_serialize_to(v) do
super
- v.serialize_attribute("mparameters", mparameters)
- if v isa FullJsonSerializer then
- var filter = new ModelFilter(private_visibility)
- var view = new ModelView(model, v.mainmodule, filter)
- v.serialize_attribute("intro", to_mentity_ref(intro))
- v.serialize_attribute("intro_mmodule", to_mentity_ref(intro_mmodule))
- v.serialize_attribute("mpackage", to_mentity_ref(intro_mmodule.mpackage))
- v.serialize_attribute("mclassdefs", to_mentity_refs(mclassdefs))
- v.serialize_attribute("all_mproperties", to_mentity_refs(sort_entities(collect_accessible_mproperties(view))))
- v.serialize_attribute("intro_mproperties", to_mentity_refs(sort_entities(collect_intro_mproperties(view))))
- v.serialize_attribute("redef_mproperties", to_mentity_refs(sort_entities(collect_redef_mproperties(view))))
- v.serialize_attribute("parents", to_mentity_refs(sort_entities(collect_parents(view))))
+
+ if mparameters.not_empty then
+ v.serialize_attribute("mparameters", mparameters)
end
end
+
+ redef fun json_namespace do
+ var ns = new JsonNamespace
+ ns.add_all intro_mmodule.ns_for(visibility)
+ ns.add "::"
+ ns.add to_json_ref
+ return ns
+ end
end
redef class MClassDef
redef fun core_serialize_to(v) do
super
- v.serialize_attribute("is_intro", is_intro)
- v.serialize_attribute("mparameters", mclass.mparameters)
- if v isa FullJsonSerializer then
- var filter = new ModelFilter(private_visibility)
- var view = new ModelView(model, v.mainmodule, filter)
- v.serialize_attribute("mmodule", to_mentity_ref(mmodule))
- v.serialize_attribute("mclass", to_mentity_ref(mclass))
- v.serialize_attribute("mpropdefs", to_mentity_refs(sort_entities(mpropdefs)))
- v.serialize_attribute("intro_mproperties", to_mentity_refs(sort_entities(intro_mproperties)))
- v.serialize_attribute("intro", to_mentity_ref(mclass.intro))
- v.serialize_attribute("mpackage", to_mentity_ref(mmodule.mpackage))
- v.serialize_attribute("intro_mpropdefs", to_mentity_refs(sort_entities(collect_intro_mpropdefs(view))))
- v.serialize_attribute("redef_mpropdefs", to_mentity_refs(sort_entities(collect_redef_mpropdefs(view))))
+ if is_intro then
+ v.serialize_attribute("is_intro", true)
+ end
+ if mclass.mparameters.not_empty then
+ v.serialize_attribute("mparameters", mclass.mparameters)
end
end
+
+ redef fun json_namespace do
+ var ns = new JsonNamespace
+ if is_intro then
+ ns.add_all mmodule.ns_for(mclass.visibility)
+ ns.add "$"
+ ns.add mclass.to_json_ref
+ else if mclass.intro_mmodule.mpackage != mmodule.mpackage then
+ ns.add_all mmodule.json_namespace
+ ns.add "$"
+ ns.add_all mclass.json_namespace
+ else if mclass.visibility > private_visibility then
+ ns.add_all mmodule.json_namespace
+ ns.add "$"
+ ns.add mclass.to_json_ref
+ else
+ ns.add_all mmodule.json_namespace
+ ns.add "$::"
+ ns.add mclass.intro_mmodule.to_json_ref
+ ns.add "::"
+ ns.add mclass.to_json_ref
+ end
+ return ns
+ end
end
redef class MProperty
- redef fun core_serialize_to(v) do
- super
- if v isa FullJsonSerializer then
- v.serialize_attribute("intro", to_mentity_ref(intro))
- v.serialize_attribute("intro_mclassdef", to_mentity_ref(intro_mclassdef))
- v.serialize_attribute("mpropdefs", to_mentity_refs(sort_entities(mpropdefs)))
- v.serialize_attribute("intro_mclass", to_mentity_ref(intro_mclassdef.mclass))
- v.serialize_attribute("mpackage", to_mentity_ref(intro_mclassdef.mmodule.mpackage))
+ redef fun json_namespace do
+ var ns = new JsonNamespace
+ if intro_mclassdef.is_intro then
+ ns.add_all intro_mclassdef.mmodule.ns_for(visibility)
+ ns.add "::"
+ ns.add intro_mclassdef.mclass.to_json_ref
+ ns.add "::"
+ ns.add to_json_ref
+ else
+ ns.add_all intro_mclassdef.mmodule.json_namespace
+ ns.add "::"
+ ns.add intro_mclassdef.mclass.to_json_ref
+ ns.add "::"
+ ns.add to_json_ref
end
+ return ns
end
end
redef class MMethod
redef fun core_serialize_to(v) do
super
- v.serialize_attribute("is_init", is_init)
+ if is_init then
+ v.serialize_attribute("is_init", true)
+ end
v.serialize_attribute("msignature", intro.msignature)
end
end
redef class MAttribute
redef fun core_serialize_to(v) do
super
- v.serialize_attribute("static_mtype", to_mentity_ref(intro.static_mtype))
+ v.serialize_attribute("static_mtype", intro.static_mtype)
end
end
redef class MVirtualTypeProp
redef fun core_serialize_to(v) do
super
- v.serialize_attribute("mvirtualtype", to_mentity_ref(mvirtualtype))
- v.serialize_attribute("bound", to_mentity_ref(intro.bound))
+ v.serialize_attribute("bound", intro.bound)
end
end
redef class MPropDef
redef fun core_serialize_to(v) do
super
- v.serialize_attribute("is_intro", is_intro)
- if v isa FullJsonSerializer then
- v.serialize_attribute("mclassdef", to_mentity_ref(mclassdef))
- v.serialize_attribute("mproperty", to_mentity_ref(mproperty))
- v.serialize_attribute("intro", to_mentity_ref(mproperty.intro))
- v.serialize_attribute("intro_mclassdef", to_mentity_ref(mproperty.intro.mclassdef))
- v.serialize_attribute("mmodule", to_mentity_ref(mclassdef.mmodule))
- v.serialize_attribute("mgroup", to_mentity_ref(mclassdef.mmodule.mgroup))
- v.serialize_attribute("mpackage", to_mentity_ref(mclassdef.mmodule.mpackage))
+ if is_intro then
+ v.serialize_attribute("is_intro", true)
end
end
+
+ redef fun json_namespace do
+ var res = new JsonNamespace
+ res.add_all mclassdef.json_namespace
+ res.add "$"
+
+ if mclassdef.mclass == mproperty.intro_mclassdef.mclass then
+ res.add to_json_ref
+ else
+ if mclassdef.mmodule.mpackage != mproperty.intro_mclassdef.mmodule.mpackage then
+ res.add_all mproperty.intro_mclassdef.mmodule.ns_for(mproperty.visibility)
+ res.add "::"
+ else if mproperty.visibility <= private_visibility then
+ if mclassdef.mmodule.namespace_for(mclassdef.mclass.visibility) != mproperty.intro_mclassdef.mmodule.mpackage then
+ res.add "::"
+ res.add mproperty.intro_mclassdef.mmodule.to_json_ref
+ res.add "::"
+ end
+ end
+ if mclassdef.mclass != mproperty.intro_mclassdef.mclass then
+ res.add mproperty.intro_mclassdef.to_json_ref
+ res.add "::"
+ end
+ res.add to_json_ref
+ end
+ return res
+ end
end
redef class MMethodDef
redef class MAttributeDef
redef fun core_serialize_to(v) do
super
- v.serialize_attribute("static_mtype", to_mentity_ref(static_mtype))
+ v.serialize_attribute("static_mtype", static_mtype)
end
end
redef class MVirtualTypeDef
redef fun core_serialize_to(v) do
super
- v.serialize_attribute("bound", to_mentity_ref(bound))
- v.serialize_attribute("is_fixed", is_fixed)
+ v.serialize_attribute("bound", bound)
+ end
+end
+
+redef class MType
+ redef fun core_serialize_to(v) do
+ v.serialize_attribute("name", name)
+
+ var mdoc = mdoc_or_fallback
+ if mdoc != null then
+ v.serialize_attribute("synopsis", mdoc.synopsis)
+ v.serialize_attribute("html_synopsis", mdoc.html_synopsis.write_to_string)
+ end
end
end
+
redef class MSignature
redef fun core_serialize_to(v) do
v.serialize_attribute("arity", arity)
- v.serialize_attribute("mparams", mparameters)
- v.serialize_attribute("return_mtype", to_mentity_ref(return_mtype))
- v.serialize_attribute("vararg_rank", vararg_rank)
+ v.serialize_attribute("mparameters", mparameters)
+ v.serialize_attribute("return_mtype", return_mtype)
end
end
redef class MParameterType
redef fun core_serialize_to(v) do
v.serialize_attribute("name", name)
- v.serialize_attribute("rank", rank)
- v.serialize_attribute("mtype", to_mentity_ref(mclass.intro.bound_mtype.arguments[rank]))
+ v.serialize_attribute("mtype", mclass.intro.bound_mtype.arguments[rank])
end
end
redef fun core_serialize_to(v) do
v.serialize_attribute("is_vararg", is_vararg)
v.serialize_attribute("name", name)
- v.serialize_attribute("mtype", to_mentity_ref(mtype))
+ v.serialize_attribute("mtype", mtype)
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)
+# Fullname representation that can be used to build decorated links
+#
+# * MPackage: `mpackage_name`
+# * MGroup: `(mpackage_name::)mgroup_name`
+class JsonNamespace
+ super Array[nullable JsonRef]
+ serialize
+
+ redef fun to_s do return self.join("")
+ redef fun serialize_to(v) do to_a.serialize_to(v)
+end
+
+# Something that goes in a JsonNamespace
+#
+# Can be either:
+# * a `RefToken` for tokens like `::`, `>` and `$`
+# * a `MEntityRef` for references to mentities
+interface JsonRef
+ super Serializable
end
-# Return a collection of `mentities` as a JsonArray of MEntityRefs.
-fun to_mentity_refs(mentities: Collection[MEntity]): Array[MEntityRef] do
- var array = new Array[MEntityRef]
- for mentity in mentities do
- var ref = to_mentity_ref(mentity)
- if ref == null then continue
- array.add ref
+# A reference to another mentity.
+class MEntityRef
+ super JsonRef
+
+ # MEntity to link to.
+ var mentity: MEntity
+
+ redef fun core_serialize_to(v) do
+ mentity.core_serialize_base(v)
end
- return array
end
-# Use the FullJsonSerializer to generate the full json representation of a MEntity.
+# A namespace token representation
#
-# See MEntity::to_full_json.
-class FullJsonSerializer
- super JsonSerializer
-
- # FIXME tmp use of the mainmodule, a PR is comming to clean all the JSON mess
- var mainmodule: MModule
+# Used for namespace tokens like `::`, `>` and `$`
+redef class String
+ super JsonRef
end