X-Git-Url: http://nitlanguage.org diff --git a/src/neo.nit b/src/neo.nit index 15b1de6..be92ab6 100644 --- a/src/neo.nit +++ b/src/neo.nit @@ -305,8 +305,8 @@ class NeoModel # Collect all nodes from the current `model`. private fun collect_model_nodes(model: Model): Collection[NeoNode] do for mpackage in model.mpackages do - to_node(mpackage) - for mgroup in mpackage.mgroups do to_node(mgroup) + mpackage.to_node(nodes, model_name) + for mgroup in mpackage.mgroups do mgroup.to_node(nodes, model_name) end return nodes.values end @@ -328,22 +328,6 @@ class NeoModel # Nodes associated with MEntities. private var nodes = new HashMap[MEntity, NeoNode] - # Get the `NeoNode` associated with `mentity`. - # `mentities` are stored locally to avoid duplication. - fun to_node(mentity: MEntity): NeoNode do - if nodes.has_key(mentity) then return nodes[mentity] - if mentity isa MPackage then return mpackage_node(mentity) - if mentity isa MGroup then return mgroup_node(mentity) - if mentity isa MModule then return mmodule_node(mentity) - if mentity isa MClass then return mclass_node(mentity) - if mentity isa MClassDef then return mclassdef_node(mentity) - if mentity isa MProperty then return mproperty_node(mentity) - if mentity isa MPropDef then return mpropdef_node(mentity) - if mentity isa MType then return mtype_node(mentity) - if mentity isa MParameter then return mparameter_node(mentity) - abort - end - # Get the `MEntity` associated with `node`. fun to_mentity(model: Model, node: NeoNode): MEntity do if node.labels.has("MPackage") then return to_mpackage(model, node) @@ -358,36 +342,6 @@ class NeoModel abort end - # Make a new `NeoNode` based on `mentity`. - private fun make_node(mentity: MEntity): NeoNode do - var node = new NeoNode - nodes[mentity] = node - node.labels.add "MEntity" - node.labels.add model_name - node["name"] = mentity.name - if not mentity isa MSignature then - #FIXME: MSignature is a MEntity, but has no model :/ - node["location"] = mentity.location.to_s - end - var mdoc = mentity.mdoc - if mdoc != null then - node["mdoc"] = new JsonArray.from(mdoc.content) - node["mdoc_location"] = mdoc.location.to_s - end - return node - end - - # Build a `NeoNode` representing `mpackage`. - private fun mpackage_node(mpackage: MPackage): NeoNode do - var node = make_node(mpackage) - node.labels.add "MPackage" - var root = mpackage.root - if root != null then - node.out_edges.add(new NeoEdge(node, "ROOT", to_node(root))) - end - return node - end - # Build a new `MPackage` from a `node`. # # REQUIRE `node.labels.has("MPackage")` @@ -404,24 +358,6 @@ class NeoModel return mpackage end - # Build a `NeoNode` representing `mgroup`. - private fun mgroup_node(mgroup: MGroup): NeoNode do - var node = make_node(mgroup) - node.labels.add "MGroup" - var parent = mgroup.parent - node.out_edges.add(new NeoEdge(node, "PROJECT", to_node(mgroup.mpackage))) - if parent != null then - node.out_edges.add(new NeoEdge(node, "PARENT", to_node(parent))) - end - for mmodule in mgroup.mmodules do - node.out_edges.add(new NeoEdge(node, "DECLARES", to_node(mmodule))) - end - for subgroup in mgroup.in_nesting.direct_smallers do - node.in_edges.add(new NeoEdge(node, "NESTS", to_node(subgroup))) - end - return node - end - # Build a new `MGroup` from a `node`. # # REQUIRE `node.labels.has("MGroup")` @@ -443,22 +379,6 @@ class NeoModel return mgroup end - # Build a `NeoNode` representing `mmodule`. - private fun mmodule_node(mmodule: MModule): NeoNode do - var node = make_node(mmodule) - node.labels.add "MModule" - for parent in mmodule.in_importation.direct_greaters do - node.out_edges.add(new NeoEdge(node, "IMPORTS", to_node(parent))) - end - for mclass in mmodule.intro_mclasses do - node.out_edges.add(new NeoEdge(node, "INTRODUCES", to_node(mclass))) - end - for mclassdef in mmodule.mclassdefs do - node.out_edges.add(new NeoEdge(node, "DEFINES", to_node(mclassdef))) - end - return node - end - # Build a new `MModule` from a `node`. # # REQUIRE `node.labels.has("MModule")` @@ -485,21 +405,6 @@ class NeoModel return mmodule end - # Build a `NeoNode` representing `mclass`. - private fun mclass_node(mclass: MClass): NeoNode do - var node = make_node(mclass) - node.labels.add "MClass" - 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 - # Build a new `MClass` from a `node`. # # REQUIRE `node.labels.has("MClass")` @@ -525,24 +430,6 @@ class NeoModel return mclass end - # Build a `NeoNode` representing `mclassdef`. - private fun mclassdef_node(mclassdef: MClassDef): NeoNode do - var node = make_node(mclassdef) - node.labels.add "MClassDef" - 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 - node.out_edges.add(new NeoEdge(node, "INTRODUCES", to_node(mproperty))) - end - for mpropdef in mclassdef.mpropdefs do - node.out_edges.add(new NeoEdge(node, "DECLARES", to_node(mpropdef))) - end - for sup in mclassdef.supertypes do - node.out_edges.add(new NeoEdge(node, "INHERITS", to_node(sup))) - end - return node - end - # Build a new `MClassDef` from a `node`. # # REQUIRE `node.labels.has("MClassDef")` @@ -566,26 +453,6 @@ class NeoModel return mclassdef end - # Build a `NeoNode` representing `mproperty`. - private fun mproperty_node(mproperty: MProperty): NeoNode do - var node = make_node(mproperty) - node.labels.add "MProperty" - node["visibility"] = mproperty.visibility.to_s - if mproperty isa MMethod then - node.labels.add "MMethod" - node["is_init"] = mproperty.is_init - else if mproperty isa MAttribute then - node.labels.add "MAttribute" - else if mproperty isa MVirtualTypeProp then - node.labels.add "MVirtualTypeProp" - else if mproperty isa MInnerClass then - node.labels.add "MInnerClass" - node.out_edges.add(new NeoEdge(node, "NESTS", to_node(mproperty.inner))) - end - node.out_edges.add(new NeoEdge(node, "INTRO_CLASSDEF", to_node(mproperty.intro_mclassdef))) - return node - end - # Build a new `MProperty` from a `node`. # # REQUIRE `node.labels.has("MProperty")` @@ -619,39 +486,6 @@ class NeoModel return mprop end - # Build a `NeoNode` representing `mpropdef`. - private fun mpropdef_node(mpropdef: MPropDef): NeoNode do - var node = make_node(mpropdef) - node.labels.add "MPropDef" - node.out_edges.add(new NeoEdge(node, "DEFINES", to_node(mpropdef.mproperty))) - if mpropdef isa MMethodDef then - node.labels.add "MMethodDef" - node["is_abstract"] = mpropdef.is_abstract - node["is_intern"] = mpropdef.is_intern - node["is_extern"] = mpropdef.is_extern - var msignature = mpropdef.msignature - if msignature != null then - node.out_edges.add(new NeoEdge(node, "SIGNATURE", to_node(msignature))) - 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 - if bound != null then - node.out_edges.add(new NeoEdge(node, "BOUND", to_node(bound))) - end - else if mpropdef isa MInnerClassDef then - node.labels.add "MInnerClassDef" - node.out_edges.add(new NeoEdge(node, "NESTS", to_node(mpropdef.inner))) - end - return node - end - # Build a new `MPropDef` from a `node`. # # REQUIRE `node.labels.has("MPropDef")` @@ -695,74 +529,6 @@ class NeoModel return mpropdef end - # Build a `NeoNode` representing `mtype`. - private fun mtype_node(mtype: MType): NeoNode do - var node = make_node(mtype) - node.labels.add "MType" - if mtype isa MClassType then - node.labels.add "MClassType" - node.out_edges.add(new NeoEdge(node, "CLASS", to_node(mtype.mclass))) - for arg in mtype.arguments do - node.out_edges.add(new NeoEdge(node, "ARGUMENT", to_node(arg))) - end - if mtype isa MGenericType then - node.labels.add "MGenericType" - end - else if mtype isa MVirtualType then - node.labels.add "MVirtualType" - node.out_edges.add(new NeoEdge(node, "PROPERTY", to_node(mtype.mproperty))) - else if mtype isa MParameterType then - node.labels.add "MParameterType" - node["rank"] = mtype.rank - node.out_edges.add(new NeoEdge(node, "CLASS", to_node(mtype.mclass))) - else if mtype isa MNullableType then - node.labels.add "MNullableType" - node.out_edges.add(new NeoEdge(node, "TYPE", to_node(mtype.mtype))) - else if mtype isa MSignature then - node.labels.add "MSignature" - var names = new JsonArray - var rank = 0 - for mparameter in mtype.mparameters do - names.add mparameter.name - var pnode = to_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 - # Build a new `MType` from a `node`. # # REQUIRE `node.labels.has("MType")` @@ -845,16 +611,6 @@ class NeoModel abort end - # Build a `NeoNode` representing `mparameter`. - private fun mparameter_node(mparameter: MParameter): NeoNode do - var node = make_node(mparameter) - node.labels.add "MParameter" - node["name"] = mparameter.name - node["is_vararg"] = mparameter.is_vararg - node.out_edges.add(new NeoEdge(node, "TYPE", to_node(mparameter.mtype))) - return node - end - # Build a new `MParameter` from `node`. # # REQUIRE `node.labels.has("MParameter")` @@ -925,3 +681,334 @@ class NeoModel end end end + +redef class MPackage + redef fun to_node(nodes: HashMap[MEntity, NeoNode], model_name: nullable String): NeoNode do + if nodes.has_key(self) then return nodes[self] + var node = super + var root = root + if root != null then + node.out_edges.add(new NeoEdge(node, "ROOT", root.to_node(nodes, model_name))) + end + return node + end +end + +redef class MGroup + redef fun to_node(nodes: HashMap[MEntity, NeoNode], model_name: nullable String): NeoNode do + if nodes.has_key(self) then return nodes[self] + var node = super + var parent = parent + node.out_edges.add(new NeoEdge(node, "PROJECT", mpackage.to_node(nodes, model_name))) + if parent != null then + node.out_edges.add(new NeoEdge(node, "PARENT", parent.to_node(nodes, model_name))) + end + for mmodule in mmodules do + node.out_edges.add(new NeoEdge(node, "DECLARES", mmodule.to_node(nodes, model_name))) + end + for subgroup in in_nesting.direct_smallers do + node.in_edges.add(new NeoEdge(node, "NESTS", subgroup.to_node(nodes, model_name))) + end + return node + end +end + +redef class MModule + redef fun to_node(nodes: HashMap[MEntity, NeoNode], model_name: nullable String): NeoNode do + if nodes.has_key(self) then return nodes[self] + var node = super + for parent in in_importation.direct_greaters do + node.out_edges.add(new NeoEdge(node, "IMPORTS", parent.to_node(nodes, model_name))) + end + for mclass in intro_mclasses do + node.out_edges.add(new NeoEdge(node, "INTRODUCES", mclass.to_node(nodes, model_name))) + end + for mclassdef in mclassdefs do + node.out_edges.add(new NeoEdge(node, "DEFINES", mclassdef.to_node(nodes, model_name))) + end + return node + end +end + +redef class MClass + redef fun to_node(nodes: HashMap[MEntity, NeoNode], model_name: nullable String): NeoNode do + if nodes.has_key(self) then return nodes[self] + var node = super + node["kind"] = kind.to_s + node["visibility"] = visibility.to_s + if not mparameters.is_empty then + var parameter_names = new Array[String] + for p in mparameters do parameter_names.add(p.name) + node["parameter_names"] = new JsonArray.from(parameter_names) + end + node.out_edges.add(new NeoEdge(node, "CLASSTYPE", mclass_type.to_node(nodes, model_name))) + return node + end +end + +redef class MClassDef + redef fun to_node(nodes: HashMap[MEntity, NeoNode], model_name: nullable String): NeoNode do + if nodes.has_key(self) then return nodes[self] + var node = super + node.out_edges.add(new NeoEdge(node, "BOUNDTYPE", bound_mtype.to_node(nodes, model_name))) + node.out_edges.add(new NeoEdge(node, "MCLASS", mclass.to_node(nodes, model_name))) + for mproperty in intro_mproperties do + node.out_edges.add(new NeoEdge(node, "INTRODUCES", mproperty.to_node(nodes, model_name))) + end + for mpropdef in mpropdefs do + node.out_edges.add(new NeoEdge(node, "DECLARES", mpropdef.to_node(nodes, model_name))) + end + for sup in supertypes do + node.out_edges.add(new NeoEdge(node, "INHERITS", sup.to_node(nodes, model_name))) + end + return node + end +end + +redef class MProperty + redef fun to_node(nodes: HashMap[MEntity, NeoNode], model_name: nullable String): NeoNode do + if nodes.has_key(self) then return nodes[self] + var node = make_node(nodes, model_name) + node.labels.add "MProperty" + node["visibility"] = visibility.to_s + node.out_edges.add(new NeoEdge(node, "INTRO_CLASSDEF", intro_mclassdef.to_node(nodes, model_name))) + node.labels.add self.class_name + return node + end +end + +redef class MMethod + redef fun to_node(nodes: HashMap[MEntity, NeoNode], model_name: nullable String): NeoNode do + if nodes.has_key(self) then return nodes[self] + var node = super + node["is_init"] = is_init + return node + end +end + +redef class MInnerClass + redef fun to_node(nodes: HashMap[MEntity, NeoNode], model_name: nullable String): NeoNode do + if nodes.has_key(self) then return nodes[self] + var node = super + node.out_edges.add(new NeoEdge(node, "NESTS", inner.to_node(nodes, model_name))) + return node + end +end + +redef class MPropDef + redef fun to_node(nodes: HashMap[MEntity, NeoNode], model_name: nullable String): NeoNode do + if nodes.has_key(self) then return nodes[self] + var node = make_node(nodes, model_name) + node.labels.add "MPropDef" + node.out_edges.add(new NeoEdge(node, "DEFINES", mproperty.to_node(nodes, model_name))) + node.labels.add self.class_name + return node + end +end + +redef class MMethodDef + redef fun to_node(nodes: HashMap[MEntity, NeoNode], model_name: nullable String): NeoNode do + if nodes.has_key(self) then return nodes[self] + var node = super + node["is_abstract"] = is_abstract + node["is_intern"] = is_intern + node["is_extern"] = is_extern + var msignature = msignature + if msignature != null then + node.out_edges.add(new NeoEdge(node, "SIGNATURE", msignature.to_node(nodes, model_name))) + end + return node + end +end + +redef class MAttributeDef + redef fun to_node(nodes: HashMap[MEntity, NeoNode], model_name: nullable String): NeoNode do + if nodes.has_key(self) then return nodes[self] + var node = super + var static_mtype = static_mtype + if static_mtype != null then + node.out_edges.add(new NeoEdge(node, "TYPE", static_mtype.to_node(nodes, model_name))) + end + return node + end +end + +redef class MVirtualTypeDef + redef fun to_node(nodes: HashMap[MEntity, NeoNode], model_name: nullable String): NeoNode do + if nodes.has_key(self) then return nodes[self] + var node = super + var bound = bound + if bound != null then + node.out_edges.add(new NeoEdge(node, "BOUND", bound.to_node(nodes, model_name))) + end + return node + end +end + +redef class MInnerClassDef + redef fun to_node(nodes: HashMap[MEntity, NeoNode], model_name: nullable String): NeoNode do + if nodes.has_key(self) then return nodes[self] + var node = super + node.out_edges.add(new NeoEdge(node, "NESTS", inner.to_node(nodes, model_name))) + return node + end +end + +redef class MTypePart + redef fun to_node(nodes: HashMap[MEntity, NeoNode], model_name: nullable String): NeoNode do + if nodes.has_key(self) then return nodes[self] + var node = super + if self.target != null then + var target_node = self.target.as(not null).to_node(nodes, model_name) + node.out_edges.add(new NeoEdge(node, "TARGET", target_node)) + end + return node + end +end + +redef class MParameter + redef fun to_node(nodes: HashMap[MEntity, NeoNode], model_name: nullable String): NeoNode do + if nodes.has_key(self) then return nodes[self] + var node = super + node["name"] = self.name + node["is_vararg"] = self.is_vararg + node.out_edges.add(new NeoEdge(node, "TYPE", self.mtype.to_node(nodes, model_name))) + return node + end +end + +redef class MClassType + redef fun to_node(nodes: HashMap[MEntity, NeoNode], model_name: nullable String): NeoNode do + if nodes.has_key(self) then return nodes[self] + var node = super + node.labels.add "MClassType" + node.out_edges.add(new NeoEdge(node, "CLASS", mclass.to_node(nodes, model_name))) + for arg in arguments do + node.out_edges.add(new NeoEdge(node, "ARGUMENT", arg.to_node(nodes, model_name))) + end + return node + end +end + + +redef class MGenericType + redef fun to_node(nodes: HashMap[MEntity, NeoNode], model_name: nullable String): NeoNode do + if nodes.has_key(self) then return nodes[self] + var node = super + node.labels.add "MGenericType" + return node + end +end + +redef class MVirtualType + redef fun to_node(nodes: HashMap[MEntity, NeoNode], model_name: nullable String): NeoNode do + if nodes.has_key(self) then return nodes[self] + var node = super + node.labels.add "MVirtualType" + node.out_edges.add(new NeoEdge(node, "PROPERTY", mproperty.to_node(nodes, model_name))) + return node + end +end + +redef class MParameterType + redef fun to_node(nodes: HashMap[MEntity, NeoNode], model_name: nullable String): NeoNode do + if nodes.has_key(self) then return nodes[self] + var node = super + node.labels.add "MParameterType" + node["rank"] = rank + node.out_edges.add(new NeoEdge(node, "CLASS", mclass.to_node(nodes, model_name))) + return node + end +end + +redef class MNullableType + redef fun to_node(nodes: HashMap[MEntity, NeoNode], model_name: nullable String): NeoNode do + if nodes.has_key(self) then return nodes[self] + var node = super + node.labels.add "MNullableType" + node.out_edges.add(new NeoEdge(node, "TYPE", mtype.to_node(nodes, model_name))) + return node + end +end + +redef class MSignature + redef fun to_node(nodes: HashMap[MEntity, NeoNode], model_name: nullable String): NeoNode do + if nodes.has_key(self) then return nodes[self] + var node = super + node.labels.add "MSignature" + var names = new JsonArray + var rank = 0 + for mparameter in mparameters do + names.add mparameter.name + var pnode = mparameter.to_node(nodes, model_name) + 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 = return_mtype + if return_mtype != null then + node.out_edges.add(new NeoEdge(node, "RETURNTYPE", return_mtype.to_node(nodes, model_name))) + end + return node + end +end + +redef class MRawType + redef fun to_node(nodes: HashMap[MEntity, NeoNode], model_name: nullable String): NeoNode do + if nodes.has_key(self) then return nodes[self] + var node = super + node.labels.add "MRawType" + var text = new JsonArray + var rank = 0 + for part in self.parts do + text.add part.text + if part.target != null then + var pnode = part.to_node(nodes, model_name) + 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 + return node + end +end + +redef class MType + redef fun to_node(nodes: HashMap[MEntity, NeoNode], model_name: nullable String): NeoNode do + if nodes.has_key(self) then return nodes[self] + var node = make_node(nodes, model_name) + node.labels.add "MType" + return node + end +end + +redef class MEntity + # Build a `NeoNode` representing `self`. + private fun to_node(nodes: HashMap[MEntity, NeoNode], model_name: nullable String): NeoNode do + if nodes.has_key(self) then return nodes[self] + var node = make_node(nodes, model_name) + node.labels.add self.class_name + return node + end + + # Make a new `NeoNode` based on `mentity`. + private fun make_node(nodes: HashMap[MEntity, NeoNode], model_name: nullable String): NeoNode do + var node = new NeoNode + nodes[self] = node + node.labels.add "MEntity" + if model_name != null then node.labels.add model_name + node["name"] = self.name + if not self isa MSignature then + #FIXME: MSignature is a MEntity, but has no model :/ + node["location"] = self.location.to_s + end + var mdoc = self.mdoc + if mdoc != null then + node["mdoc"] = new JsonArray.from(mdoc.content) + node["mdoc_location"] = mdoc.location.to_s + end + return node + end +end