# See the License for the specific language governing permissions and
# limitations under the License.
-# Save and load `Model` from/to Neo4j base.
+# Save and load a `Model` to/from a Neo4j graph.
#
# Nit models are composed by MEntities.
# This module creates NeoNode for each MEntity found in a `Model` and save them
# into Neo4j database.
#
-# see `Neo4jClient`.
+# SEE: `Neo4jClient`
#
# NeoNodes can also be translated back to MEntities to rebuild a Nit `Model`.
#
-# Structure of the nit `Model` in base:
+# Structure of the nit `Model` in the graph:
#
# Note : Any null or empty attribute will not be saved in the database.
#
#
# * labels: `MClass`, `model_name` and `MEntity`.
# * `full_name`: fully qualified name.
-# * `arity`: number of generic formal parameters. 0 if the class is not generic.
# * `kind`: kind of the class (`interface`, `abstract class`, etc.)
# * `visibility`: visibility of the class.
+# * `parameter_names`: JSON array listing the name of each formal generic
+# parameter (in order of declaration).
# * `(:MClass)-[:CLASSTYPE]->(:MClassType)`: SEE: `MClass.mclass_type`
#
# Arguments in the `CLASSTYPE` are named following the `parameter_names`
# * labels: `MClassDef`, `model_name` and `MEntity`.
# * `is_intro`: Does this definition introduce the class?
# * `location`: origin of the definition. SEE: `Location.to_s`
-# * `parameter_names`: JSON array listing the name of each formal generic
-# parameter (in order of declaration).
# * `(:MClassDef)-[:BOUNDTYPE]->(:MClassType)`: bounded type associated to the
# classdef.
# * `(:MClassDef)-[:MCLASS]->(:MClass)`: associated `MClass`.
# * `(:MMethodDef)-[:SIGNATURE]->(:MSignature)`: signature attached to the
# property definition.
#
+# Additional relationship for `MAttributeDef`:
+#
+# * `(:MAttributeDef)-[:TYPE]->(:MType)`: static type of the attribute,
+# if specified.
+#
# Additional relationship for `MVirtualTypeDef`:
#
# * `(:MVirtualTypeDef)-[:BOUND]->(:MType)`: type to which the virtual type
# * `(:MClassType)-[:ARGUMENT]->(:MType)`: type arguments.
#
# Arguments are named following the `parameter_names` attribute of the
-# `MClassDef` that introduces the class referred by `CLASS`.
+# `MClass` referred by `CLASS`.
#
# Additional relationship for `MVirtualType`:
#
node.labels.add "MModule"
node["full_name"] = mmodule.full_name
node["location"] = mmodule.location.to_s
- var mgroup = mmodule.mgroup
for parent in mmodule.in_importation.direct_greaters do
node.out_edges.add(new NeoEdge(node, "IMPORTS", to_node(parent)))
end
private fun mclass_node(mclass: MClass): NeoNode do
var node = make_node(mclass)
node.labels.add "MClass"
- node["arity"] = mclass.arity
node["full_name"] = mclass.full_name
node["kind"] = mclass.kind.to_s
node["visibility"] = mclass.visibility.to_s
+ if not mclass.mparameters.is_empty then
+ var parameter_names = new Array[String]
+ for p in mclass.mparameters do parameter_names.add(p.name)
+ node["parameter_names"] = new JsonArray.from(parameter_names)
+ end
node.out_edges.add(new NeoEdge(node, "CLASSTYPE", to_node(mclass.mclass_type)))
return node
end
assert node.labels.has("MClass")
var mmodule = to_mmodule(model, node.in_nodes("INTRODUCES").first)
var name = node["name"].to_s
- var arity = node["arity"].to_s.to_i
var kind = to_kind(node["kind"].to_s)
var visibility = to_visibility(node["visibility"].to_s)
- var mclass = new MClass(mmodule, name, arity, kind, visibility)
+ var parameter_names = new Array[String]
+ if node.has_key("parameter_names") then
+ for e in node["parameter_names"].as(JsonArray) do
+ parameter_names.add e.to_s
+ end
+ end
+ var mclass = new MClass(mmodule, name, parameter_names, kind, visibility)
mentities[node] = mclass
set_doc(node, mclass)
return mclass
node.labels.add "MClassDef"
node["is_intro"] = mclassdef.is_intro
node["location"] = mclassdef.location.to_s
- if not mclassdef.parameter_names.is_empty then
- node["parameter_names"] = new JsonArray.from(mclassdef.parameter_names)
- end
node.out_edges.add(new NeoEdge(node, "BOUNDTYPE", to_node(mclassdef.bound_mtype)))
node.out_edges.add(new NeoEdge(node, "MCLASS", to_node(mclassdef.mclass)))
for mproperty in mclassdef.intro_mproperties do
var mmodule = to_mmodule(model, node.in_nodes("DEFINES").first)
var mtype = to_mtype(model, node.out_nodes("BOUNDTYPE").first).as(MClassType)
var location = to_location(node["location"].to_s)
- var parameter_names = new Array[String]
- if node.has_key("parameter_names") then
- for e in node["parameter_names"].as(JsonArray) do
- parameter_names.add e.to_s
- end
- end
- var mclassdef = new MClassDef(mmodule, mtype, location, parameter_names)
+ var mclassdef = new MClassDef(mmodule, mtype, location)
mentities[node] = mclassdef
set_doc(node, mclassdef)
var supertypes = new Array[MClassType]
end
else if mpropdef isa MAttributeDef then
node.labels.add "MAttributeDef"
+ var static_mtype = mpropdef.static_mtype
+ if static_mtype != null then
+ node.out_edges.add(new NeoEdge(node, "TYPE", to_node(static_mtype)))
+ end
else if mpropdef isa MVirtualTypeDef then
node.labels.add "MVirtualTypeDef"
var bound = mpropdef.bound
else if node.labels.has("MAttributeDef") then
mpropdef = new MAttributeDef(mclassdef, mproperty.as(MAttribute), location)
mentities[node] = mpropdef
+ var static_mtype = node.out_nodes("TYPE")
+ if not static_mtype.is_empty then mpropdef.static_mtype = to_mtype(model, static_mtype.first)
else if node.labels.has("MVirtualTypeDef") then
mpropdef = new MVirtualTypeDef(mclassdef, mproperty.as(MVirtualTypeProp), location)
mentities[node] = mpropdef
else if node.labels.has("MParameterType") then
var mclass = to_mclass(model, node.out_nodes("CLASS").first)
var rank = node["rank"].to_s.to_i
- var mtype = new MParameterType(mclass, rank)
+ var mtype = mclass.mparameters[rank]
mentities[node] = mtype
return mtype
else if node.labels.has("MNullableType") then
var intype = to_mtype(model, node.out_nodes("TYPE").first)
- var mtype = new MNullableType(intype)
+ var mtype = intype.as_nullable
mentities[node] = mtype
return mtype
else if node.labels.has("MVirtualType") then
var mproperty = to_mproperty(model, node.out_nodes("PROPERTY").first)
- var mtype = new MVirtualType(mproperty)
+ assert mproperty isa MVirtualTypeProp
+ var mtype = mproperty.mvirtualtype
mentities[node] = mtype
return mtype
else if node.labels.has("MSignature") then