X-Git-Url: http://nitlanguage.org diff --git a/src/neo.nit b/src/neo.nit index f7ab770..c3273a7 100644 --- a/src/neo.nit +++ b/src/neo.nit @@ -15,7 +15,8 @@ # Save and load `Model` from/to Neo4j base. # # Nit models are composed by MEntities. -# This module creates NeoNode for each MEntity found in a `Model` and save them into Neo4j database. +# This module creates NeoNode for each MEntity found in a `Model` and save them +# into Neo4j database. # # see `Neo4jClient`. # @@ -23,92 +24,160 @@ # # Structure of the nit `Model` in base: # +# Note : Any null or empty attribute will not be saved in the database. +# +# For any `MEntity` (in addition to specific data): +# +# * labels: model name (`model_name`) and `MEntity`. +# * `name`: short (unqualified) name. +# * `mdoc`: JSON array representing the associated Markdown documentation +# (one item by line). +# +# Note : All nodes described here are MEntities. +# # `MProject` # -# * labels: `model_name`, `MEntity`, `MProject` -# * `(:MProject)-[:ROOT]->(:MGroup)` +# * labels: `MProject`, `model_name` and `MEntity`. +# * `(:MProject)-[:ROOT]->(:MGroup)`: root of the group tree. # # `MGroup` # -# * labels: `model_name`, `MEntity`, `MGroup` -# * `(:MGroup)-[:PROJECT]->(:MProject)` -# * `(:MGroup)-[:PARENT]->(:MGroup)` +# * labels: `MGroup`, `model_name` and `MEntity`. +# * `full_name`: fully qualified name. +# * `(:MGroup)-[:PROJECT]->(:MProject)`: associated project. +# * `(:MGroup)-[:PARENT]->(:MGroup)`: parent group. Does not exist for the root +# group. +# * `(:MGroup)-[:DECLARES]->(:MModule)`: modules that are direct children of +# this group. +# * `(:MGroup)-[:NESTS]->(:MGroup)`: nested groups that are direct children of +# this group. # # `MModule` # -# * labels: `model_name`, `MEntity`, `MModule` -# * `(:MModule)-[:IMPORTS]->(:MModule)` -# * `(:MModule)-[:INTRODUCES]->(:MClass)` -# * `(:MModule)-[:DEFINES]->(:MClassDef)` +# * labels: `MModule`, `model_name` and `MEntity`. +# * `full_name`: fully qualified name. +# * `location`: origin of the definition. SEE: `Location.to_s` +# * `(:MModule)-[:IMPORTS]->(:MModule)`: modules that are imported directly. +# * `(:MModule)-[:INTRODUCES]->(:MClass)`: all by classes introduced by this +# module. +# * `(:MModule)-[:DEFINES]->(:MClassDef)`: all class definitons contained in +# this module. # # `MClass` # -# * labels: `model_name`, `MEntity`, `MClass` -# * `(:MClass)-[:CLASSTYPE]->(:MClassType)` +# * 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. +# * `(:MClass)-[:CLASSTYPE]->(:MClassType)`: SEE: `MClass.mclass_type` # # `MClassDef` # -# * labels: `model_name`, `MEntity`, `MClassDef` -# * `(:MClassDef)-[:BOUNDTYPE]->(:MClassType)` -# * `(:MClassDef)-[:MCLASS]->(:MClass)` -# * `(:MClassDef)-[:INTRODUCES]->(:MProperty)` -# * `(:MClassDef)-[:DECLARES]->(:MPropDef)` +# * 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`. +# * `(:MClassDef)-[:INTRODUCES]->(:MProperty)`: all properties introduced by +# the classdef. +# * `(:MClassDef)-[:DECLARES]->(:MPropDef)`: all property definitions in the +# classdef (introductions and redefinitions). +# * `(:MClassDef)-[:INHERITS]->(:MClassType)`: all declared super-types # # `MProperty` # -# * labels: `model_name`, `MEntity`, `MProperty` -# * `(:MProperty)-[:INTRO_CLASSDEF]->(:MClassDef)` -# -# MProperties can also have labels `MMethod`, `MAttribute`, `MVirtualTypeProp`. +# * labels: `MProperty`, `model_name` and `MEntity`. Must also have `MMethod`, +# `MAttribute` or `MVirtualTypeProp`, depending on the class of the represented +# entity. +# * `full_name`: fully qualified name. +# * `visibility`: visibility of the property. +# * `is_init`: Indicates if the property is a constructor. Exists only if the +# node is a `MMethod`. +# * `(:MProperty)-[:INTRO_CLASSDEF]->(:MClassDef)`: classdef that introduces +# the property. # # `MPropDef` # -# * labels: `model_name`, `MEntity`, `MPropDef` -# * `(:MPropDef)-[:DEFINES]->(:MProperty)` -# -# MPropdefs can also have labels `MMethodDef`, `MAttributeDef`, `MVirtualTypeDef`. +# * labels: `MPropDef`, `model_name` and `MEntity`. Must also have `MMethodDef`, +# `MAttributeDef` or `MVirtualTypeDef`, depending on the class of the +# represented entity. +# * `is_intro`: Does this definition introduce the property? +# * `location`: origin of the definition. SEE: `Location.to_s`. +# * `(:MPropDef)-[:DEFINES]->(:MProperty)`: associated property. # -# `MMethodDef` are linked to a `MSignature`: +# Additional attributes and relationship for `MMethodDef`: # -# * `(:MMethodDef)-[:SIGNATURE]->(:MSignature)` +# * `is_abstract`: Is the method definition abstract? +# * `is_intern`: Is the method definition intern? +# * `is_extern`: Is the method definition extern? +# * `(:MMethodDef)-[:SIGNATURE]->(:MSignature)`: signature attached to the +# property definition. # -# `MVirtualTypeDef` are linked to a `MType` (its `bound`): +# Additional relationship for `MVirtualTypeDef`: # -# * `(:MVirtualTypeDef)-[:BOUND]->(:MType)` +# * `(:MVirtualTypeDef)-[:BOUND]->(:MType)`: type to which the virtual type +# is bound in this definition. Exists only if this definition bound the virtual +# type to an effective type. # # `MType` # -# * labels: `model_name`, `MEntity`, `MType` +# * labels: `MType`, `model_name` and `MEntity`. Must also have `MClassType`, +# `MNullableType`, `MVirtualType` or `MSignature`, depending on the class of +# the represented entity. +# +# Additional label and relationships for `MClassType`: # -# MTypes can also have labels `MClassType`, `MGenericType`, `MNullableType`, `MVirtualType` -# and `MSignature`. +# * If it is a `MGenericType`, also has the `MGenericType` label. +# * `(:MClassType)-[:CLASS]->(:MClass)`: SEE: `MClassType.mclass` +# * `(:MClassType)-[:ARGUMENT]->(:MType)`: type arguments. # -# `MClassType` and `MGenericType` both point to a `MClass` and have type `arguments`: +# Additional relationship for `MVirtualType`: # -# * `(:MClassType)-[:CLASS]->(:MClass)` -# * `(:MClassType)-[:ARGUMENT]->(:MType)` +# * `(:MVirtualType)-[:PROPERTY]->(:MProperty)`: associated property that +# determines the type (usually a `MVirtualTypeProp`). # -# `MVirtualType` points to its introducing `MProperty`: +# Additional attribute and relationship for `MParameterType`: # -# * `(:MVirtualType)-[:PROPERTY]->(:MVirtualTypeDef)` +# * `rank`: position of the parameter (0 for the first parameter). +# * `(:MParameterType)-[:CLASS]->(:MClass)`: generic class where the parameter +# belong. # -# `MParameterType` points to its introducing `MClass`: +# Additional relationship for `MNullableType`: # -# * `(:MParameterType)-[:CLASS]->(:MClass)` +# * `(:MNullableType)-[:TYPE]->(:MType)`: base type of the nullable type. # -# `MNullableType` points to its non-nullable `MType`: +# Additional attribute and relationships for `MSignature`: # -# * `(:MNullableType)-[:TYPE]->(:MType)` +# * `parameter_names`: JSON array representing the list of the parameter names. +# * `(:MSignature)-[:PARAMETER]->(:MParameter)`: parameters. +# * `(:MSignature)-[:RETURNTYPE]->(:MType)`: return type. Does not exist for +# procedures. # -# `MSignature` can have `parameters` and a `return_mtype`: +# In order to maintain the correct parameters order, each `MSignature` node +# contains an array of parameter names corresponding to the parameter order in +# the signature. # -# * `(:MSignature)-[:PARAMETER]->(:MParameter)` -# * `(:MSignature)-[:RETURNTYPE]->(:MType)` +# For example, if the source code contains: +# +# fun foo(a: A, b: B, c: C) +# +# The `MSignature` node will contain a property +# `parameter_names = ["a", "b", "c"]` so the MSignature can be reconstructed +# with the parameters in the correct order. # # `MParameter` # -# * labels: `model_name`, `MEntity`, `MParameter` -# * `(:MParameter)-[:TYPE]->(:MType)` +# * labels: `MParameter`, `model_name` and `MEntity`. +# * `is_vararg`: Is the parameter a vararg? +# * `rank`: position of the parameter (0 for the first parameter). +# * `(:MParameter)-[:TYPE]->(:MType)`: static type of the parameter. +# +# MParameters are also ranked by their position in the corresponding signature. +# Rank 0 for the first parameter, 1 for the next one and etc. module neo import model @@ -625,9 +694,15 @@ class NeoModel 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 - node.out_edges.add(new NeoEdge(node, "PARAMETER", to_node(mparameter))) + names.add mparameter.name + var pnode = to_node(mparameter) + pnode["rank"] = rank + node.out_edges.add(new NeoEdge(node, "PARAMETER", pnode)) 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))) @@ -668,9 +743,20 @@ class NeoModel mentities[node] = mtype return mtype else if node.labels.has("MSignature") then - var mparameters = new Array[MParameter] + # Get all param nodes + var mparam_nodes = new HashMap[String, MParameter] for pnode in node.out_nodes("PARAMETER") do - mparameters.add to_mparameter(model, pnode) + var mparam = to_mparameter(model, pnode) + mparam_nodes[mparam.name] = mparam + end + # Load params in the good order + var mparam_names = node["parameter_names"] + var mparameters = new Array[MParameter] + if mparam_names isa JsonArray then + for mparam_name in mparam_names do + var mparam = mparam_nodes[mparam_name.to_s] + mparameters.add mparam + end end var return_mtype: nullable MType = null var ret_nodes = node.out_nodes("RETURNTYPE")