neo: Forces MParameter ranking in MSignatures
authorAlexandre Terrasa <alexandre@moz-code.org>
Mon, 8 Sep 2014 18:34:48 +0000 (14:34 -0400)
committerAlexandre Terrasa <alexandre@moz-code.org>
Mon, 8 Sep 2014 18:34:48 +0000 (14:34 -0400)
Also update corresponding test and make test sav more easy to read.

Fixes #725

Signed-off-by: Alexandre Terrasa <alexandre@moz-code.org>

src/neo.nit
src/test_neo.nit
tests/sav/test_neo_args1.res

index f7ab770..9ebdd01 100644 (file)
 # * `(:MSignature)-[:PARAMETER]->(:MParameter)`
 # * `(:MSignature)-[:RETURNTYPE]->(: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.
+#
+# 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)`
+#
+# 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 +638,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 +687,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")
index 37adf04..45015a7 100644 (file)
@@ -57,34 +57,49 @@ read_model.load(neo_model)
 # Compare model
 var sorter = new MEntityNameSorter
 
-print "mprojects:"
+print "# mprojects:"
 var org_mprojects = org_model.mprojects.to_a
 sorter.sort org_mprojects
 print org_mprojects.join(" ")
+print "------------------------------------"
 var neo_mprojects = neo_model.mprojects.to_a
 sorter.sort neo_mprojects
 print neo_mprojects.join(" ")
 
-print "mmodules:"
+print "\n# mmodules:"
 var org_mmodules = org_model.mmodules.to_a
 sorter.sort org_mmodules
 print org_mmodules.join(" ")
+print "------------------------------------"
 var neo_mmodules = neo_model.mmodules.to_a
 sorter.sort neo_mmodules
 print neo_mmodules.join(" ")
 
-print "mclasses:"
+print "\n# mclasses:"
 var org_mclasses = org_model.mclasses.to_a
 sorter.sort org_mclasses
 print org_mclasses.join(" ")
+print "------------------------------------"
 var neo_mclasses = neo_model.mclasses.to_a
 sorter.sort neo_mclasses
 print neo_mclasses.join(" ")
 
-print "mproperties:"
+print "\n# mproperties:"
 var org_mproperties = org_model.mproperties.to_a
 sorter.sort org_mproperties
 print org_mproperties.join(" ")
+print "------------------------------------"
 var neo_mproperties = neo_model.mproperties.to_a
 sorter.sort neo_mproperties
 print neo_mproperties.join(" ")
+
+print "\n# msignatures:"
+for org_mprop in org_mproperties do
+       if not org_mprop isa MMethod then continue
+       print "{org_mprop.name}{org_mprop.intro.msignature or else ""}"
+end
+print "------------------------------------"
+for neo_mprop in neo_mproperties do
+       if not neo_mprop isa MMethod then continue
+       print "{neo_mprop.name}{neo_mprop.intro.msignature or else ""}"
+end
index 5291a1e..6106689 100644 (file)
-mprojects:
+# mprojects:
 test_prog
+------------------------------------
 test_prog
-mmodules:
+
+# mmodules:
 careers character combat game platform races rpg test_prog
+------------------------------------
 careers character combat game platform races rpg test_prog
-mclasses:
+
+# mclasses:
 Alcoholic Bool Career Character Combatable Dwarf Elf Float Game Human Int List Magician Object Race Starter String Sys Warrior Weapon
+------------------------------------
 Alcoholic Bool Career Character Combatable Dwarf Elf Float Game Human Int List Magician Object Race Starter String Sys Warrior Weapon
-mproperties:
+
+# mproperties:
 != * * + + - - / / == > > OTHER _age _base_endurance _base_intelligence _base_strength _career _endurance_bonus _health _intelligence_bonus _name _race _sex _strength_bonus age age= attack base_endurance base_endurance= base_intelligence base_intelligence= base_strength base_strength= career career= computer_characters defend direct_attack dps endurance_bonus endurance_bonus= health health= hit_points init intelligence_bonus intelligence_bonus= is_dead main max_health name name= pause_game player_characters quit race race= sex sex= start start_game stop_game strength_bonus strength_bonus= to_f total_endurance total_intelligence total_strengh unary -
+------------------------------------
 != * * + + - - / / == > > OTHER _age _base_endurance _base_intelligence _base_strength _career _endurance_bonus _health _intelligence_bonus _name _race _sex _strength_bonus age age= attack base_endurance base_endurance= base_intelligence base_intelligence= base_strength base_strength= career career= computer_characters defend direct_attack dps endurance_bonus endurance_bonus= health health= hit_points init intelligence_bonus intelligence_bonus= is_dead main max_health name name= pause_game player_characters quit race race= sex sex= start start_game stop_game strength_bonus strength_bonus= to_f total_endurance total_intelligence total_strengh unary -
+
+# msignatures:
+!=(other: OTHER): Bool
+*(f: Float): Float
+*(i: Int): Int
++(f: Float): Float
++(i: Int): Int
+-(i: Int): Int
+-(f: Float): Float
+/(f: Float): Float
+/(i: Int): Int
+==(other: OTHER): Bool
+>(f: Float): Bool
+>(i: Int): Bool
+age: Int
+age=(age: Int)
+attack(target: Combatable, weapon: Weapon): Int
+base_endurance: Int
+base_endurance=(base_endurance: Int)
+base_intelligence: Int
+base_intelligence=(base_intelligence: Int)
+base_strength: Int
+base_strength=(base_strength: Int)
+career: nullable Career
+career=(career: nullable Career)
+computer_characters: List[Character]
+defend(hit: Int): Int
+direct_attack(target: Combatable, weapon: Weapon): Int
+dps: Float
+endurance_bonus: Int
+endurance_bonus=(endurance_bonus: Int)
+health: Int
+health=(health: Int)
+hit_points: Int
+init
+intelligence_bonus: Int
+intelligence_bonus=(intelligence_bonus: Int)
+is_dead: Bool
+main
+max_health: Int
+name: String
+name=(name: String)
+pause_game
+player_characters: List[Character]
+quit
+race: Race
+race=(race: Race)
+sex: Bool
+sex=(sex: Bool)
+start
+start_game
+stop_game
+strength_bonus: Int
+strength_bonus=(strength_bonus: Int)
+to_f: Float
+total_endurance: Int
+total_intelligence: Int
+total_strengh: Int
+unary -: Int
+------------------------------------
+!=(other: OTHER): Bool
+*(f: Float): Float
+*(i: Int): Int
++(f: Float): Float
++(i: Int): Int
+-(i: Int): Int
+-(f: Float): Float
+/(f: Float): Float
+/(i: Int): Int
+==(other: OTHER): Bool
+>(f: Float): Bool
+>(i: Int): Bool
+age: Int
+age=(age: Int)
+attack(target: Combatable, weapon: Weapon): Int
+base_endurance: Int
+base_endurance=(base_endurance: Int)
+base_intelligence: Int
+base_intelligence=(base_intelligence: Int)
+base_strength: Int
+base_strength=(base_strength: Int)
+career: nullable Career
+career=(career: nullable Career)
+computer_characters: List[Character]
+defend(hit: Int): Int
+direct_attack(target: Combatable, weapon: Weapon): Int
+dps: Float
+endurance_bonus: Int
+endurance_bonus=(endurance_bonus: Int)
+health: Int
+health=(health: Int)
+hit_points: Int
+init
+intelligence_bonus: Int
+intelligence_bonus=(intelligence_bonus: Int)
+is_dead: Bool
+main
+max_health: Int
+name: String
+name=(name: String)
+pause_game
+player_characters: List[Character]
+quit
+race: Race
+race=(race: Race)
+sex: Bool
+sex=(sex: Bool)
+start
+start_game
+stop_game
+strength_bonus: Int
+strength_bonus=(strength_bonus: Int)
+to_f: Float
+total_endurance: Int
+total_intelligence: Int
+total_strengh: Int
+unary -: Int