auto_super_init: handle the case of constructors redefinition (instead of infinitivel...
authorJean Privat <jean@pryen.org>
Sat, 16 Aug 2014 01:07:03 +0000 (21:07 -0400)
committerJean Privat <jean@pryen.org>
Sat, 16 Aug 2014 01:18:14 +0000 (21:18 -0400)
Signed-off-by: Jean Privat <jean@pryen.org>

src/abstract_compiler.nit
src/auto_super_init.nit
src/naive_interpreter.nit
src/rapid_type_analysis.nit

index 6656d5b..979832a 100644 (file)
@@ -1834,9 +1834,13 @@ redef class AMethPropdef
                                for i in [0..auto_super_init.msignature.arity+1[ do
                                        args.add(arguments[i])
                                end
+                               assert auto_super_init.mproperty != mpropdef.mproperty
                                v.compile_callsite(auto_super_init, args)
                        end
                end
+               if auto_super_call then
+                       v.supercall(mpropdef, arguments.first.mtype.as(MClassType), arguments)
+               end
 
                var n_block = n_block
                if n_block != null then
index 92ee003..513d071 100644 (file)
@@ -48,9 +48,12 @@ end
 
 
 redef class AMethPropdef
-       # In case of constructor, the list of implicit auto super init constructors invoked (if needed)
+       # In case of introduced constructor, the list of implicit auto super init constructors invoked (if needed)
        var auto_super_inits: nullable Array[CallSite] = null
 
+       # In case of redefined constructors, is an implicit call-to-super required?
+       var auto_super_call = false
+
        fun do_auto_super_init(modelbuilder: ModelBuilder)
        do
                var mclassdef = self.parent.as(AClassdef).mclassdef.as(not null)
@@ -94,6 +97,13 @@ redef class AMethPropdef
 
                if nosuper != null then return
 
+               # Still here? So it means that we must add an implicit super-call on redefinitions.
+               if not mpropdef.is_intro then
+                       auto_super_call = true
+                       mpropdef.has_supercall = true
+                       return
+               end
+
                # Still here? So it means that we must determine what super inits need to be automatically invoked
 
                var auto_super_inits = new Array[CallSite]
index 7525a00..d974e08 100644 (file)
@@ -648,9 +648,15 @@ redef class AMethPropdef
                                for i in [0..auto_super_init.msignature.arity+1[ do
                                        args.add(arguments[i])
                                end
+                               assert auto_super_init.mproperty != mpropdef.mproperty
                                v.callsite(auto_super_init, args)
                        end
                end
+               if auto_super_call then
+                       # standard call-next-method
+                       var superpd = mpropdef.lookup_next_definition(v.mainmodule, arguments.first.mtype)
+                       v.call_without_varargs(superpd, arguments)
+               end
 
                if n_block != null then
                        v.stmt(self.n_block)
index ceca71d..1585fb1 100644 (file)
@@ -247,7 +247,6 @@ class RapidTypeAnalysis
                                                        v.add_monomorphic_send(v.receiver, su)
                                                end
                                        end
-
                                else
                                        abort
                                end
@@ -263,6 +262,9 @@ class RapidTypeAnalysis
                                                v.add_callsite(auto_super_init)
                                        end
                                end
+                               if npropdef.auto_super_call then
+                                       self.add_super_send(v.receiver, mmethoddef)
+                               end
                        end
 
                        if mmeth.is_new then