modelize: add and use method mpropdef2node
authorJean Privat <jean@pryen.org>
Thu, 4 Dec 2014 19:32:27 +0000 (14:32 -0500)
committerJean Privat <jean@pryen.org>
Thu, 4 Dec 2014 19:32:27 +0000 (14:32 -0500)
Signed-off-by: Jean Privat <jean@pryen.org>

src/compiler/abstract_compiler.nit
src/interpreter/debugger.nit
src/interpreter/naive_interpreter.nit
src/modelize/modelize_property.nit
src/rapid_type_analysis.nit

index abfbf3f..a6d6d86 100644 (file)
@@ -1857,10 +1857,10 @@ redef class MMethodDef
        do
                if is_abstract then return true
                var modelbuilder = v.compiler.modelbuilder
-               if modelbuilder.mpropdef2npropdef.has_key(self) then
-                       var npropdef = modelbuilder.mpropdef2npropdef[self]
-                       return npropdef.can_inline
-               else if self.mproperty.is_root_init then
+               var node = modelbuilder.mpropdef2node(self)
+               if node isa APropdef then
+                       return node.can_inline
+               else if node isa AClassdef then
                        # Automatic free init is always inlined since it is empty or contains only attribtes assigments
                        return true
                else
@@ -1873,19 +1873,18 @@ redef class MMethodDef
        do
                var modelbuilder = v.compiler.modelbuilder
                var val = constant_value
-               if modelbuilder.mpropdef2npropdef.has_key(self) then
-                       var npropdef = modelbuilder.mpropdef2npropdef[self]
+               var node = modelbuilder.mpropdef2node(self)
+               if node isa APropdef then
                        var oldnode = v.current_node
-                       v.current_node = npropdef
+                       v.current_node = node
                        self.compile_parameter_check(v, arguments)
-                       npropdef.compile_to_c(v, self, arguments)
+                       node.compile_to_c(v, self, arguments)
                        v.current_node = oldnode
-               else if self.mproperty.is_root_init then
-                       var nclassdef = modelbuilder.mclassdef2nclassdef[self.mclassdef]
+               else if node isa AClassdef then
                        var oldnode = v.current_node
-                       v.current_node = nclassdef
+                       v.current_node = node
                        self.compile_parameter_check(v, arguments)
-                       nclassdef.compile_to_c(v, self, arguments)
+                       node.compile_to_c(v, self, arguments)
                        v.current_node = oldnode
                else if val != null then
                        v.ret(v.value_instance(val))
index 684ea87..58a49d1 100644 (file)
@@ -280,20 +280,13 @@ class Debugger
                assert args.length == mpropdef.msignature.arity + 1 else debug("Invalid arity for {mpropdef}. {args.length} arguments given.")
 
                # Look for the AST node that implements the property
-               var mproperty = mpropdef.mproperty
-               if self.modelbuilder.mpropdef2npropdef.has_key(mpropdef) then
-                       var npropdef = self.modelbuilder.mpropdef2npropdef[mpropdef]
-                       self.parameter_check(npropdef, mpropdef, args)
-                       if npropdef isa AMethPropdef then
-                               return npropdef.rt_call(self, mpropdef, args)
-                       else
-                               print "Error, invalid propdef to call at runtime !"
-                               return null
-                       end
-               else if mproperty.is_root_init then
-                       var nclassdef = self.modelbuilder.mclassdef2nclassdef[mpropdef.mclassdef]
-                       self.parameter_check(nclassdef, mpropdef, args)
-                       return nclassdef.call(self, mpropdef, args)
+               var node = modelbuilder.mpropdef2node(mpropdef)
+               if node isa AMethPropdef then
+                       self.parameter_check(node, mpropdef, args)
+                       return node.rt_call(self, mpropdef, args)
+               else if node isa AClassdef then
+                       self.parameter_check(node, mpropdef, args)
+                       return node.call(self, mpropdef, args)
                else
                        fatal("Fatal Error: method {mpropdef} not found in the AST")
                        abort
index 476608c..da8d02e 100644 (file)
@@ -383,16 +383,18 @@ class NaiveInterpreter
                assert args.length == mpropdef.msignature.arity + 1 else debug("Invalid arity for {mpropdef}. {args.length} arguments given.")
 
                # Look for the AST node that implements the property
-               var mproperty = mpropdef.mproperty
                var val = mpropdef.constant_value
-               if self.modelbuilder.mpropdef2npropdef.has_key(mpropdef) then
-                       var npropdef = self.modelbuilder.mpropdef2npropdef[mpropdef]
-                       self.parameter_check(npropdef, mpropdef, args)
-                       return npropdef.call(self, mpropdef, args)
-               else if mproperty.is_root_init then
-                       var nclassdef = self.modelbuilder.mclassdef2nclassdef[mpropdef.mclassdef]
-                       self.parameter_check(nclassdef, mpropdef, args)
-                       return nclassdef.call(self, mpropdef, args)
+
+               var node = modelbuilder.mpropdef2node(mpropdef)
+               if node isa APropdef then
+                       self.parameter_check(node, mpropdef, args)
+                       return node.call(self, mpropdef, args)
+               else if node isa AClassdef then
+                       self.parameter_check(node, mpropdef, args)
+                       return node.call(self, mpropdef, args)
+               else if node != null then
+                       fatal("Fatal Error: method {mpropdef} associated to unexpected AST node {node.location}")
+                       abort
                else if val != null then
                        return value_instance(val)
                else
index 757f85d..faaf149 100644 (file)
@@ -40,6 +40,21 @@ redef class ModelBuilder
        # FIXME: why not refine the `MPropDef` class with a nullable attribute?
        var mpropdef2npropdef = new HashMap[MPropDef, APropdef]
 
+       # Retrieve the associated AST node of a mpropertydef.
+       # This method is used to associate model entity with syntactic entities.
+       #
+       # If the property definition is not associated with a node, returns node.
+       fun mpropdef2node(mpropdef: MPropDef): nullable ANode
+       do
+               var res: nullable ANode = mpropdef2npropdef.get_or_null(mpropdef)
+               if res != null then return res
+               if mpropdef isa MMethodDef and mpropdef.mproperty.is_root_init then
+                       res = mclassdef2nclassdef.get_or_null(mpropdef.mclassdef)
+                       if res != null then return res
+               end
+               return null
+       end
+
        # Build the properties of `nclassdef`.
        # REQUIRE: all superclasses are built.
        private fun build_properties(nclassdef: AClassdef)
index 9f97e45..7fcb4bc 100644 (file)
@@ -215,7 +215,7 @@ class RapidTypeAnalysis
 
                        var vararg_rank = mmethoddef.msignature.vararg_rank
                        if vararg_rank > -1 then
-                               var node = self.modelbuilder.mpropdef2npropdef[mmethoddef]
+                               var node = self.modelbuilder.mpropdef2node(mmethoddef)
                                var elttype = mmethoddef.msignature.mparameters[vararg_rank].mtype
                                #elttype = elttype.anchor_to(self.mainmodule, v.receiver)
                                var vararg = self.mainmodule.get_primitive_class("Array").get_mtype([elttype])
@@ -235,27 +235,25 @@ class RapidTypeAnalysis
                                add_cast(paramtype)
                        end
 
-                       if not modelbuilder.mpropdef2npropdef.has_key(mmethoddef) then
-                               # It is an init for a class?
-                               if mmeth.is_root_init then
-                                       var nclassdef = self.modelbuilder.mclassdef2nclassdef[mmethoddef.mclassdef]
-                                       assert mmethoddef == nclassdef.mfree_init
+                       var npropdef = modelbuilder.mpropdef2node(mmethoddef)
 
-                                       if mmethoddef.mproperty.is_root_init and not mmethoddef.is_intro then
-                                               self.add_super_send(v.receiver, mmethoddef)
-                                       end
-                               else if mmethoddef.constant_value != null then
-                                       # Make the return type live
-                                       v.add_type(mmethoddef.msignature.return_mtype.as(MClassType))
-                               else
-                                       abort
+                       if npropdef isa AClassdef then
+                               # It is an init for a class
+                               assert mmethoddef == npropdef.mfree_init
+
+                               if mmethoddef.mproperty.is_root_init and not mmethoddef.is_intro then
+                                       self.add_super_send(v.receiver, mmethoddef)
                                end
                                continue
+                       else if mmethoddef.constant_value != null then
+                               # Make the return type live
+                               v.add_type(mmethoddef.msignature.return_mtype.as(MClassType))
+                               continue
+                       else if npropdef == null then
+                               abort
                        end
 
-                       var npropdef = modelbuilder.mpropdef2npropdef[mmethoddef]
-
-                       if npropdef isa AMethPropdef  then
+                       if npropdef isa AMethPropdef then
                                var auto_super_inits = npropdef.auto_super_inits
                                if auto_super_inits != null then
                                        for auto_super_init in auto_super_inits do