# `MType`
#
# * labels: `MType`, `model_name` and `MEntity`. Must also have `MClassType`,
-# `MNullableType`, `MVirtualType` or `MSignature`, depending on the class of
-# the represented entity.
+# `MNullableType`, `MVirtualType`, `MRawType` or `MSignature`, depending on the
+# class of the represented entity.
#
# Additional label and relationships for `MClassType`:
#
#
# * `(:MNullableType)-[:TYPE]->(:MType)`: base type of the nullable type.
#
+# Additional attribute and relationship for `MRawType`:
+#
+# * `text`: JSON array of the parts’ text.
+# * `(:MRawType)-[:LINK]->(:MTypePart)`: the parts that link to another entity.
+#
# Additional attribute and relationships for `MSignature`:
#
# * `parameter_names`: JSON array representing the list of the parameter names.
#
# MParameters are also ranked by their position in the corresponding signature.
# Rank 0 for the first parameter, 1 for the next one and etc.
+#
+# `MTypePart`
+#
+# * labels: `MTypePart`, `model_name` and `MEntity`.
+# * `rank`: position in the `MRawType`.
+# * `(:MTypePart)-[:TARGET]->(:MEntity)`: the target of the link.
module neo
-import model
+import doc::model_ext
import neo4j
import toolcontext
end
# Mentities associated to nodes.
- private var mentities = new HashMap[NeoNode, MEntity]
+ #
+ # The key is the node’s id.
+ private var mentities = new HashMap[Int, MEntity]
# Nodes associated with MEntities.
private var nodes = new HashMap[MEntity, NeoNode]
abort
end
+ # Get the `MEntity` associated with `node`.
+ fun to_mentity(model: Model, node: NeoNode): MEntity do
+ if node.labels.has("MProject") then return to_mproject(model, node)
+ if node.labels.has("MGroup") then return to_mgroup(model, node)
+ if node.labels.has("MModule") then return to_mmodule(model, node)
+ if node.labels.has("MClass") then return to_mclass(model, node)
+ if node.labels.has("MClassDef") then return to_mclassdef(model, node)
+ if node.labels.has("MProperty") then return to_mproperty(model, node)
+ if node.labels.has("MPropDef") then return to_mpropdef(model, node)
+ if node.labels.has("MType") then return to_mtype(model, node)
+ if node.labels.has("MParameter") then return to_mparameter(model, node)
+ abort
+ end
+
# Make a new `NeoNode` based on `mentity`.
private fun make_node(mentity: MEntity): NeoNode do
var node = new NeoNode
#
# REQUIRE `node.labels.has("MProject")`
private fun to_mproject(model: Model, node: NeoNode): MProject do
- if mentities.has_key(node) then return mentities[node].as(MProject)
+ var m = mentities.get_or_null(node.id.as(Int))
+ if m isa MProject then return m
+
assert node.labels.has("MProject")
var mproject = new MProject(node["name"].to_s, model)
- mentities[node] = mproject
+ mentities[node.id.as(Int)] = mproject
set_doc(node, mproject)
mproject.root = to_mgroup(model, node.out_nodes("ROOT").first)
return mproject
#
# REQUIRE `node.labels.has("MGroup")`
private fun to_mgroup(model: Model, node: NeoNode): MGroup do
- if mentities.has_key(node) then return mentities[node].as(MGroup)
+ var m = mentities.get_or_null(node.id.as(Int))
+ if m isa MGroup then return m
+
assert node.labels.has("MGroup")
var mproject = to_mproject(model, node.out_nodes("PROJECT").first)
var parent: nullable MGroup = null
parent = to_mgroup(model, out.first)
end
var mgroup = new MGroup(node["name"].to_s, mproject, parent)
- mentities[node] = mgroup
+ mentities[node.id.as(Int)] = mgroup
set_doc(node, mgroup)
return mgroup
end
#
# REQUIRE `node.labels.has("MModule")`
private fun to_mmodule(model: Model, node: NeoNode): MModule do
- if mentities.has_key(node) then return mentities[node].as(MModule)
+ var m = mentities.get_or_null(node.id.as(Int))
+ if m isa MModule then return m
+
assert node.labels.has("MModule")
var ins = node.in_nodes("DECLARES")
var mgroup: nullable MGroup = null
var name = node["name"].to_s
var location = to_location(node["location"].to_s)
var mmodule = new MModule(model, mgroup, name, location)
- mentities[node] = mmodule
+ mentities[node.id.as(Int)] = mmodule
set_doc(node, mmodule)
var imported_mmodules = new Array[MModule]
for smod in node.out_nodes("IMPORTS") do
#
# REQUIRE `node.labels.has("MClass")`
private fun to_mclass(model: Model, node: NeoNode): MClass do
- if mentities.has_key(node) then return mentities[node].as(MClass)
+ var m = mentities.get_or_null(node.id.as(Int))
+ if m isa MClass then return m
+
assert node.labels.has("MClass")
var mmodule = to_mmodule(model, node.in_nodes("INTRODUCES").first)
var name = node["name"].to_s
end
end
var mclass = new MClass(mmodule, name, parameter_names, kind, visibility)
- mentities[node] = mclass
+ mentities[node.id.as(Int)] = mclass
set_doc(node, mclass)
return mclass
end
#
# REQUIRE `node.labels.has("MClassDef")`
private fun to_mclassdef(model: Model, node: NeoNode): MClassDef do
- if mentities.has_key(node) then return mentities[node].as(MClassDef)
+ var m = mentities.get_or_null(node.id.as(Int))
+ if m isa MClassDef then return m
+
assert node.labels.has("MClassDef")
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 mclassdef = new MClassDef(mmodule, mtype, location)
- mentities[node] = mclassdef
+ mentities[node.id.as(Int)] = mclassdef
set_doc(node, mclassdef)
var supertypes = new Array[MClassType]
for sup in node.out_nodes("INHERITS") do
#
# REQUIRE `node.labels.has("MProperty")`
private fun to_mproperty(model: Model, node: NeoNode): MProperty do
- if mentities.has_key(node) then return mentities[node].as(MProperty)
+ var m = mentities.get_or_null(node.id.as(Int))
+ if m isa MProperty then return m
+
assert node.labels.has("MProperty")
var intro_mclassdef = to_mclassdef(model, node.out_nodes("INTRO_CLASSDEF").first)
var name = node["name"].to_s
print "not yet implemented to_mproperty for {node.labels.join(",")}"
abort
end
- mentities[node] = mprop
+ mentities[node.id.as(Int)] = mprop
set_doc(node, mprop)
return mprop
end
#
# REQUIRE `node.labels.has("MPropDef")`
private fun to_mpropdef(model: Model, node: NeoNode): MPropDef do
- if mentities.has_key(node) then return mentities[node].as(MPropDef)
+ var m = mentities.get_or_null(node.id.as(Int))
+ if m isa MPropDef then return m
+
assert node.labels.has("MPropDef")
var mclassdef = to_mclassdef(model, node.in_nodes("DECLARES").first)
var mproperty = to_mproperty(model, node.out_nodes("DEFINES").first)
mpropdef.is_abstract = node["is_abstract"].as(Bool)
mpropdef.is_intern = node["is_intern"].as(Bool)
mpropdef.is_extern = node["is_extern"].as(Bool)
- mentities[node] = mpropdef
+ mentities[node.id.as(Int)] = mpropdef
mpropdef.msignature = to_mtype(model, node.out_nodes("SIGNATURE").first).as(MSignature)
else if node.labels.has("MAttributeDef") then
mpropdef = new MAttributeDef(mclassdef, mproperty.as(MAttribute), location)
- mentities[node] = mpropdef
+ mentities[node.id.as(Int)] = 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
+ mentities[node.id.as(Int)] = mpropdef
var bound = node.out_nodes("BOUND")
if not bound.is_empty then mpropdef.bound = to_mtype(model, bound.first)
end
var rank = 0
for mparameter in mtype.mparameters do
names.add mparameter.name
- var pnode = to_node(mparameter)
+ var pnode = mparameter_node(mparameter)
pnode["rank"] = rank
node.out_edges.add(new NeoEdge(node, "PARAMETER", pnode))
+ rank += 1
end
if not names.is_empty then node["parameter_names"] = names
var return_mtype = mtype.return_mtype
if return_mtype != null then
node.out_edges.add(new NeoEdge(node, "RETURNTYPE", to_node(return_mtype)))
end
+ else if mtype isa MRawType then
+ node.labels.add "MRawType"
+ var text = new JsonArray
+ var rank = 0
+ for part in mtype.parts do
+ text.add part.text
+ if part.target != null then
+ var pnode = mtypepart_node(part)
+ pnode["rank"] = rank
+ node.out_edges.add(new NeoEdge(node, "LINK", pnode))
+ end
+ rank += 1
+ end
+ if not text.is_empty then node["text"] = text
+ end
+ return node
+ end
+
+ # Build a `NeoNode` representing `mtypepart`.
+ private fun mtypepart_node(mtypepart: MTypePart): NeoNode do
+ var node = make_node(mtypepart)
+ node.labels.add "MTypePart"
+ if mtypepart.target != null then
+ var target_node = to_node(mtypepart.target.as(not null))
+ node.out_edges.add(new NeoEdge(node, "TARGET", target_node))
end
return node
end
#
# REQUIRE `node.labels.has("MType")`
private fun to_mtype(model: Model, node: NeoNode): MType do
- if mentities.has_key(node) then return mentities[node].as(MType)
+ var m = mentities.get_or_null(node.id.as(Int))
+ if m isa MType then return m
+
assert node.labels.has("MType")
if node.labels.has("MClassType") then
var mclass = to_mclass(model, node.out_nodes("CLASS").first)
args.add to_mtype(model, narg)
end
var mtype = mclass.get_mtype(args)
- mentities[node] = mtype
+ mentities[node.id.as(Int)] = mtype
return mtype
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 = mclass.mparameters[rank]
- mentities[node] = mtype
+ mentities[node.id.as(Int)] = mtype
return mtype
else if node.labels.has("MNullableType") then
var intype = to_mtype(model, node.out_nodes("TYPE").first)
var mtype = intype.as_nullable
- mentities[node] = mtype
+ mentities[node.id.as(Int)] = mtype
return mtype
else if node.labels.has("MVirtualType") then
var mproperty = to_mproperty(model, node.out_nodes("PROPERTY").first)
assert mproperty isa MVirtualTypeProp
var mtype = mproperty.mvirtualtype
- mentities[node] = mtype
+ mentities[node.id.as(Int)] = mtype
return mtype
else if node.labels.has("MSignature") then
# Get all param nodes
return_mtype = to_mtype(model, ret_nodes.first)
end
var mtype = new MSignature(mparameters, return_mtype)
- mentities[node] = mtype
+ mentities[node.id.as(Int)] = mtype
+ return mtype
+ else if node.labels.has("MRawType") then
+ var mtype = new MRawType(model)
+ var parts = node["text"]
+ if parts isa JsonArray then
+ for p in parts do
+ mtype.parts.add(new MTypePart(model, p.to_s, null))
+ end
+ for pnode in node.out_nodes("LINK") do
+ assert pnode.labels.has("MTypePart")
+ if not pnode.out_nodes("TARGET").is_empty then
+ var rank = pnode["rank"]
+ var target = to_mentity(model, pnode.out_nodes("TARGET").first)
+ assert rank isa Int
+ mtype.parts[rank] = mtype.parts[rank].link_to(target)
+ end
+ end
+ end
+ mentities[node.id.as(Int)] = mtype
return mtype
end
print "not yet implemented to_mtype for {node.labels.join(",")}"
#
# REQUIRE `node.labels.has("MParameter")`
private fun to_mparameter(model: Model, node: NeoNode): MParameter do
- if mentities.has_key(node) then return mentities[node].as(MParameter)
+ var m = mentities.get_or_null(node.id.as(Int))
+ if m isa MParameter then return m
+
assert node.labels.has("MParameter")
var name = node["name"].to_s
var mtype = to_mtype(model, node.out_nodes("TYPE").first)
var is_vararg = node["is_vararg"].as(Bool)
var mparameter = new MParameter(name, mtype, is_vararg)
- mentities[node] = mparameter
+ mentities[node.id.as(Int)] = mparameter
return mparameter
end
return protected_visibility
else if vis == private_visibility.to_s then
return private_visibility
+ else if vis == package_visibility.to_s then
+ return package_visibility
else
return none_visibility
end
return enum_kind
else if kind == extern_kind.to_s then
return extern_kind
+ else
+ return raw_kind(kind)
end
- abort
end
# Extract the `MDoc` from `node` and link it to `mentity`.