src: Update init
authorFlorian Deljarry <deljarry.florian@gmail.com>
Wed, 13 Nov 2019 23:29:22 +0000 (18:29 -0500)
committerFlorian Deljarry <deljarry.florian@gmail.com>
Sat, 21 Dec 2019 11:29:08 +0000 (06:29 -0500)
Remove useless init and add old_style_init if it's necessary

Signed-off-by: Florian Deljarry <deljarry.florian@gmail.com>

src/compiler/abstract_compiler.nit
src/interpreter/naive_interpreter.nit
src/metrics/ast_metrics.nit
src/metrics/static_types_metrics.nit
src/model/model.nit
src/modelize/modelize_property.nit
src/nitni/nitni_callbacks.nit
src/nitni/nitni_utilities.nit
src/rapid_type_analysis.nit
src/semantize/auto_super_init.nit
src/semantize/typing.nit

index 44cad4f..1f26f6e 100644 (file)
@@ -3687,12 +3687,11 @@ redef class AClassdef
                                v.supercall(mpropdef, arguments.first.mtype.as(MClassType), arguments)
                        end
                        return
-               else if mclassdef.auto_init == mpropdef then
+               else if mclassdef.default_init == mpropdef then
                        var recv = arguments.first
                        var initializers = mpropdef.initializers
                        var no_init = false
-                       if not initializers.is_empty then
-
+                       if not initializers.is_empty and not mpropdef.is_old_style_init then
                                var i = 1
                                for p in initializers do
                                        if p isa MMethod then
index 4125cfa..527f16e 100644 (file)
@@ -1635,11 +1635,11 @@ redef class AClassdef
                                v.call(superpd, arguments)
                        end
                        return null
-               else if mclassdef.auto_init == mpropdef then
+               else if mclassdef.default_init == mpropdef then
                        var recv = arguments.first
                        var initializers = mpropdef.initializers
                        var no_init = false
-                       if not initializers.is_empty then
+                       if not initializers.is_empty and not mpropdef.is_old_style_init then
                                var i = 1
                                for p in initializers do
                                        if p isa MMethod then
index d34899e..e5f1e10 100644 (file)
@@ -49,7 +49,6 @@ private class AstMetricsVisitor
        super Visitor
 
        var phase: AstMetricsPhase
-       init(phase: AstMetricsPhase) do self.phase = phase
 
        redef fun visit(n)
        do
index 45c429b..4dd38d0 100644 (file)
@@ -41,14 +41,6 @@ private class ATypeCounterVisitor
 
        var typecount: Counter[MType]
 
-       # Get a new visitor on a classef to add type count in `typecount`.
-       init(modelbuilder: ModelBuilder, nclassdef: AClassdef, typecount: Counter[MType])
-       do
-               self.modelbuilder = modelbuilder
-               self.nclassdef = nclassdef
-               self.typecount = typecount
-       end
-
        redef fun visit(n)
        do
                if n isa AAnnotation then return
index c60a8fa..3331d6d 100644 (file)
@@ -778,8 +778,8 @@ class MClassDef
        # All property introductions and redefinitions in `self` (not inheritance).
        var mpropdefs = new Array[MPropDef]
 
-       # The special autoinit constructor
-       var auto_init: nullable MMethodDef = null is writable
+       # The special default_init constructor
+       var default_init: nullable MMethodDef = null is writable
 
        # All property introductions and redefinitions (not inheritance) in `self` by its associated property.
        var mpropdefs_by_property = new HashMap[MProperty, MPropDef]
@@ -2636,6 +2636,10 @@ class MMethodDef
        # using this information prevents to call `init` twice.
        var is_calling_init = false is writable
 
+       # Does the method is a old_style_init?
+       #
+       var is_old_style_init = false is writable
+
        # Is the method definition abstract?
        var is_abstract: Bool = false is writable
 
index c236170..8529ed6 100644 (file)
@@ -173,15 +173,13 @@ redef class ModelBuilder
                        if mpropdef.mproperty.is_root_init then
                                assert defined_init == null
                                defined_init = mpropdef
-                       else if mpropdef.mproperty.name == "autoinit" then
-                               # An explicit old-style init named "init", so return
+                       end
+                       if mpropdef.name == "defaultinit" then
                                return
                        end
                end
 
-               if mclassdef.auto_init != null then
-                       return
-               end
+               if mclassdef.default_init != null then return
 
                if not nclassdef isa AStdClassdef then return
 
@@ -195,7 +193,6 @@ redef class ModelBuilder
                                if mpropdef == null then return # Skip broken method
                                var sig = mpropdef.msignature
                                if sig == null then continue # Skip broken method
-
                                mparameters.add_all sig.mparameters
                                initializers.add(mpropdef.mproperty)
                                mpropdef.mproperty.is_autoinit = true
@@ -241,7 +238,7 @@ redef class ModelBuilder
                # Look for most-specific new-stype init definitions
                var spropdefs = new ArraySet[MMethodDef]
                for x in mclassdef.in_hierarchy.direct_greaters do
-                       var y = x.mclass.intro.auto_init
+                       var y = x.mclass.intro.default_init
                        if y == null then continue
                        if y.is_broken or y.msignature == null then return
                        spropdefs.add y
@@ -299,30 +296,12 @@ redef class ModelBuilder
                                end
                        end
                else if spropdefs.not_empty then
-                       # Search for inherited manual autoinit
-                       var manual = null
-                       for s in spropdefs do
-                               if mpropdef2npropdef.has_key(s) then
-                                       self.toolcontext.info("{mclassdef} inherits a manual autoinit {s}", 3)
-                                       #mclassdef.autoinit = s
-                                       #return
-                                       manual = s
-                               end
-                       end
-
                        # Search the longest-one and checks for conflict
                        var longest = spropdefs.first
                        if spropdefs.length > 1 then
                                # part 1. find the longest list
                                for spd in spropdefs do
                                        if spd.initializers.length > longest.initializers.length then longest = spd
-                                       if spd != manual and manual != null then
-                                               self.toolcontext.info("{mclassdef} conflict between manual autoinit {manual} and automatic autoinit {spd}.", 3)
-                                       end
-                               end
-                               # conflict with manual autoinit?
-                               if longest != manual and manual != null then
-                                       self.error(nclassdef, "Error: conflict between manual autoinit {manual} and automatic autoinit {longest}.")
                                end
                                # part 2. compare
                                # Check for conflict in the order of initializers
@@ -365,13 +344,13 @@ redef class ModelBuilder
 
                # Create a specific new autoinit constructor
                do
-                       var mprop = new MMethod(mclassdef, "autoinit", nclassdef.location, public_visibility)
+                       var mprop = new MMethod(mclassdef, "defaultinit", nclassdef.location, public_visibility)
                        mprop.is_init = true
                        var mpropdef = new MMethodDef(mclassdef, mprop, nclassdef.location)
                        mpropdef.initializers.add_all(initializers)
                        var msignature = new MSignature(mparameters, null)
                        mpropdef.msignature = msignature
-                       mclassdef.auto_init = mpropdef
+                       mclassdef.default_init = mpropdef
                        self.toolcontext.info("{mclassdef} gets a free auto constructor `{mpropdef}{msignature}`. {spropdefs}", 3)
                        mclassdef.mclass.the_root_init_mmethod = the_root_init_mmethod
                end
@@ -789,12 +768,15 @@ redef class AMethPropdef
                var name: String
                var amethodid = self.n_methid
                var name_node: ANode
+               var is_old_style_init = false
                if amethodid == null then
                        if n_kwinit != null then
                                name = "init"
                                name_node = n_kwinit
-                               if self.n_signature.n_params.not_empty or get_single_annotation("old_style_init", modelbuilder) != null then
-                                       name = "autoinit"
+                               var old_style_annot = get_single_annotation("old_style_init", modelbuilder)
+                               if  old_style_annot != null or self.n_signature.n_params.not_empty then
+                                       name = "defaultinit"
+                                       if old_style_annot != null then is_old_style_init = true
                                end
                        else if n_kwnew != null then
                                name = "new"
@@ -874,9 +856,10 @@ redef class AMethPropdef
                mclassdef.mprop2npropdef[mprop] = self
 
                var mpropdef = new MMethodDef(mclassdef, mprop, self.location)
-               if mprop.name == "autoinit" and mclassdef.is_intro then
-                       assert mclassdef.auto_init == null
-                       mclassdef.auto_init = mpropdef
+               if mpropdef.name == "defaultinit" and mclassdef.is_intro then
+                       assert mclassdef.default_init == null
+                       mpropdef.is_old_style_init = is_old_style_init
+                       mclassdef.default_init = mpropdef
                        if mpropdef.is_intro then
                                mpropdef.initializers.add mprop
                                mpropdef.is_calling_init = true
index 3962597..c9725d0 100644 (file)
@@ -219,7 +219,7 @@ class MExplicitCall
 
                        var cname
                        if mproperty.is_init then
-                               if mproperty.name == "init" or mproperty.name == "new" or mproperty.name == "autoinit" then
+                               if mproperty.name == "init" or mproperty.name == "new" or mproperty.name == "defaultinit" then
                                        cname = "new_{recv_mtype.mangled_cname}"
                                else
                                        cname = "new_{recv_mtype.mangled_cname}_{mproperty.short_cname}"
@@ -350,7 +350,7 @@ redef class AInitPropExternCall
                        mmodule, mtype, meth_name )
 
                if meth == null then
-                       meth_name = "autoinit"
+                       meth_name = "defaultinit"
                        meth = toolcontext.modelbuilder.try_get_mproperty_by_name2( self,
                                mmodule, mtype, meth_name )
                end
index d16e844..b1b5917 100644 (file)
@@ -28,7 +28,7 @@ redef class MMethod
        do
                var cname
                if self.is_init then
-                       if self.name == "init" or self.name == "new" or self.name == "autoinit" then
+                       if self.name == "init" or self.name == "new" or self.name == "defaultinit" then
                                cname = "new_{recv_mtype.mangled_cname}"
                        else
                                cname = "new_{recv_mtype.mangled_cname}_{self.short_cname}"
index 2da2a47..d5bc7d1 100644 (file)
@@ -264,8 +264,8 @@ class RapidTypeAnalysis
                                        if not mmethoddef.is_intro then
                                                self.add_super_send(v.receiver, mmethoddef)
                                        end
-                               else if mmethoddef.mclassdef.auto_init == mmethoddef then
-                                       # autoinit call
+                               else if mmethoddef.mclassdef.default_init == mmethoddef then
+                                       # default_init call
                                        for i in mmethoddef.initializers do
                                                if i isa MMethod then self.add_send(v.receiver, i)
                                        end
index 454e9fb..0be7107 100644 (file)
@@ -104,14 +104,9 @@ redef class AMethPropdef
                var auto_super_inits = new Array[CallSite]
 
                # The look for new-style super constructors (called from a old style constructor)
-               var the_root_init_mmethod = modelbuilder.the_root_init_mmethod
-               if the_root_init_mmethod != null and auto_super_inits.is_empty then
-                       var candidatedefs = the_root_init_mmethod.lookup_definitions(mmodule, anchor)
-                       if candidatedefs.is_empty then
-                               # skip broken
-                               is_broken = true
-                               return
-                       end
+               var candidatedefs = get_super_candidatedefs(modelbuilder)
+
+               if not candidatedefs.is_empty and auto_super_inits.is_empty then
 
                        var candidatedef = candidatedefs.first
                        if candidatedefs.length > 1 then
@@ -124,15 +119,31 @@ redef class AMethPropdef
                        var msignature = candidatedef.msignature
                        msignature = msignature.resolve_for(recvtype, anchor, mmodule, true)
 
-                       if msignature.arity > 0 then
+                       if msignature.arity > mpropdef.msignature.arity then
                                modelbuilder.error(self, "Error: cannot do an implicit constructor call to `{candidatedef}{msignature}`. Expected at least `{msignature.arity}` arguments.")
                                is_broken = true
                                return
                        end
 
-                       var callsite = new CallSite(hot_location, recvtype, mmodule, anchor, true, the_root_init_mmethod, candidatedef, msignature, false)
+                       if candidatedef.mproperty != mpropdef.mproperty then
+                               var i = 0
+                               for candidat_mparameter in msignature.mparameters do
+                                       var actual_mparameter = mpropdef.msignature.mparameters[i]
+                                       if not candidat_mparameter.mtype.is_subtype(mmodule, anchor, actual_mparameter.mtype) then
+                                               modelbuilder.error(self, "Type Error: expected argument #{i} of type `{candidat_mparameter.mtype}`, got implicit argument `{candidat_mparameter.name}` of type `{actual_mparameter.mtype}`. Signature is {msignature}")
+                                               return
+                                       end
+                                       i += 1
+                               end
+                       end
+
+                       var callsite = new CallSite(hot_location, recvtype, mmodule, anchor, true, candidatedef.mproperty, candidatedef, msignature, false)
                        auto_super_inits.add(callsite)
-                       modelbuilder.toolcontext.info("Auto-super init for {mpropdef} to {the_root_init_mmethod.full_name}", 4)
+                       modelbuilder.toolcontext.info("Auto-super init for {mpropdef} to {candidatedef.full_name}", 4)
+               else if candidatedefs.is_empty then
+                       # skip broken
+                       is_broken = true
+                       return
                end
                if auto_super_inits.is_empty then
                        modelbuilder.error(self, "Error: no constructors to call implicitly in `{mpropdef}`. Call one explicitly.")
@@ -142,6 +153,34 @@ redef class AMethPropdef
                self.auto_super_inits = auto_super_inits
        end
 
+       # This method returns the list of possible candidates for the current definition.
+       #
+       # Warning this method supports super call from old_style_init to default_inits without signature verification!!!
+       private fun get_super_candidatedefs(modelbuilder: ModelBuilder): Array[MMethodDef]
+       do
+               var candidatedefs = new Array[MMethodDef]
+
+               var mclassdef = self.parent.as(AClassdef).mclassdef
+               if mclassdef == null or mclassdef.is_broken then return candidatedefs # skip error
+               var mpropdef = self.mpropdef
+               if mpropdef == null or mpropdef.is_broken then return candidatedefs # skip error
+               var mmodule = mpropdef.mclassdef.mmodule
+               var anchor = mclassdef.bound_mtype
+               var mproperty = mpropdef.mproperty
+
+               # The look for new-style super constructors (called from a old style constructor)
+               var the_root_init_mmethod = modelbuilder.the_root_init_mmethod
+
+               if mpropdef.is_old_style_init then
+                       var superprop: nullable MMethodDef = null
+                       for mclass in mclassdef.mclass.in_hierarchy(mmodule).direct_greaters do
+                               candidatedefs.add(mclass.intro.default_init.as(not null))
+                       end
+               else
+                       candidatedefs = the_root_init_mmethod.lookup_definitions(mmodule, anchor)
+               end
+               return candidatedefs
+       end
 end
 
 redef class ANode
index 8258cbf..3176e35 100644 (file)
@@ -315,7 +315,7 @@ private class TypeVisitor
 
                var mproperty = self.try_get_mproperty_by_name2(node, unsafe_type, name)
                if name == "new" and mproperty == null then
-                       name = "autoinit"
+                       name = "defaultinit"
                        mproperty = self.try_get_mproperty_by_name2(node, unsafe_type, name)
                        if mproperty == null then
                                name = "init"
@@ -1778,7 +1778,7 @@ redef class ARangeExpr
                # get the constructor
                var callsite
                if self isa ACrangeExpr then
-                       callsite = v.build_callsite_by_name(self, mtype, "autoinit", false)
+                       callsite = v.build_callsite_by_name(self, mtype, "defaultinit", false)
                else if self isa AOrangeExpr then
                        callsite = v.build_callsite_by_name(self, mtype, "without_last", false)
                else
@@ -2160,7 +2160,7 @@ redef class ABraReassignExpr
 end
 
 redef class AInitExpr
-       redef fun property_name do if n_args.n_exprs.is_empty then return "init" else return "autoinit"
+       redef fun property_name do if n_args.n_exprs.is_empty then return "init" else return "defaultinit"
        redef fun property_node do return n_kwinit
        redef fun compute_raw_arguments do return n_args.to_a
 end