rta: do not visit broken NExpr
[nit.git] / src / rapid_type_analysis.nit
index f5c1dc2..734a76a 100644 (file)
@@ -93,7 +93,7 @@ class RapidTypeAnalysis
                var mtype = callsite.recv
                var anchor = callsite.anchor
                if anchor != null then mtype = mtype.anchor_to(callsite.mmodule, anchor)
-               mtype = mtype.as_notnullable
+               mtype = mtype.undecorate
                if mtype isa MClassType then mtype = mtype.mclass.intro.bound_mtype
                var mproperty = callsite.mproperty
                var res = live_targets_cache[mtype, mproperty]
@@ -217,23 +217,26 @@ class RapidTypeAnalysis
                while not todo.is_empty do
                        var mmethoddef = todo.shift
                        var mmeth = mmethoddef.mproperty
+                       var msignature = mmethoddef.msignature
+                       if msignature == null then continue # Skip broken method
+
                        #print "# visit {mmethoddef}"
                        var v = new RapidTypeVisitor(self, mmethoddef.mclassdef.bound_mtype, mmethoddef)
 
-                       var vararg_rank = mmethoddef.msignature.vararg_rank
+                       var vararg_rank = msignature.vararg_rank
                        if vararg_rank > -1 then
                                var node = self.modelbuilder.mpropdef2node(mmethoddef)
-                               var elttype = mmethoddef.msignature.mparameters[vararg_rank].mtype
+                               var elttype = msignature.mparameters[vararg_rank].mtype
                                #elttype = elttype.anchor_to(self.mainmodule, v.receiver)
-                               var vararg = self.mainmodule.get_primitive_class("Array").get_mtype([elttype])
+                               var vararg = self.mainmodule.array_type(elttype)
                                v.add_type(vararg)
-                               var native = self.mainmodule.get_primitive_class("NativeArray").get_mtype([elttype])
+                               var native = self.mainmodule.native_array_type(elttype)
                                v.add_type(native)
                                v.add_monomorphic_send(vararg, self.modelbuilder.force_get_primitive_method(node, "with_native", vararg.mclass, self.mainmodule))
                        end
 
                        # TODO? new_msignature
-                       var sig = mmethoddef.msignature.as(not null)
+                       var sig = msignature
                        var osig = mmeth.intro.msignature.as(not null)
                        for i in [0..sig.arity[ do
                                var origtype = osig.mparameters[i].mtype
@@ -254,7 +257,7 @@ class RapidTypeAnalysis
                                continue
                        else if mmethoddef.constant_value != null then
                                # Make the return type live
-                               v.add_type(mmethoddef.msignature.return_mtype.as(MClassType))
+                               v.add_type(msignature.return_mtype.as(MClassType))
                                continue
                        else if npropdef == null then
                                abort
@@ -274,7 +277,7 @@ class RapidTypeAnalysis
 
                        if mmethoddef.is_intern or mmethoddef.is_extern then
                                # UGLY: We force the "instantation" of the concrete return type if any
-                               var ret = mmethoddef.msignature.return_mtype
+                               var ret = msignature.return_mtype
                                if ret != null and ret isa MClassType and ret.mclass.kind != abstract_kind and ret.mclass.kind != interface_kind then
                                        v.add_type(ret)
                                end
@@ -296,10 +299,10 @@ class RapidTypeAnalysis
                                if not ot.can_resolve_for(t, t, mainmodule) then continue
                                var rt = ot.anchor_to(mainmodule, t)
                                if live_types.has(rt) then continue
+                               if not check_depth(rt) then continue
                                #print "{ot}/{t} -> {rt}"
                                live_types.add(rt)
                                todo_types.add(rt)
-                               check_depth(rt)
                        end
                end
                #print "MType {live_types.length}: {live_types.join(", ")}"
@@ -317,12 +320,14 @@ class RapidTypeAnalysis
                #print "cast MType {live_cast_types.length}: {live_cast_types.join(", ")}"
        end
 
-       private fun check_depth(mtype: MClassType)
+       private fun check_depth(mtype: MClassType): Bool
        do
                var d = mtype.length
                if d > 255 then
-                       self.modelbuilder.toolcontext.fatal_error(null, "Fatal error: limitation in the rapidtype analysis engine: a type depth of {d} is too important, the problematic type is {mtype}.")
+                       self.modelbuilder.toolcontext.fatal_error(null, "Fatal Error: limitation in the rapidtype analysis engine: a type depth of {d} is too important, the problematic type is `{mtype}`.")
+                       return false
                end
+               return true
        end
 
        fun add_new(recv: MClassType, mtype: MClassType)
@@ -389,7 +394,6 @@ class RapidTypeAnalysis
                if mproperty.mpropdefs.length <= 1 then return
                # If all definitions of a method are live, we can remove the definition of the totry set
                for d in mproperty.mpropdefs do
-                       if d.is_abstract then continue
                        if not live_methoddefs.has(d) then return
                end
                #print "full property: {mpropdef.mproperty} for {mpropdef.mproperty.mpropdefs.length} definitions"
@@ -450,10 +454,14 @@ class RapidTypeVisitor
 
        redef fun visit(n)
        do
-               n.accept_rapid_type_visitor(self)
                if n isa AExpr then
-                       var implicit_cast_to = n.implicit_cast_to
-                       if implicit_cast_to != null then self.add_cast_type(implicit_cast_to)
+                       if n.mtype != null or n.is_typed then
+                               n.accept_rapid_type_visitor(self)
+                               var implicit_cast_to = n.implicit_cast_to
+                               if implicit_cast_to != null then self.add_cast_type(implicit_cast_to)
+                       end
+               else
+                       n.accept_rapid_type_visitor(self)
                end
 
                # RTA does not enter in AAnnotations
@@ -466,17 +474,12 @@ class RapidTypeVisitor
        do
                mtype = mtype.anchor_to(self.analysis.mainmodule, self.receiver)
                if mtype isa MNullType then return null
-               mtype = mtype.as_notnullable
+               mtype = mtype.undecorate
                assert mtype isa MClassType
                assert not mtype.need_anchor
                return mtype
        end
 
-       fun get_class(name: String): MClass
-       do
-               return analysis.mainmodule.get_primitive_class(name)
-       end
-
        fun get_method(recv: MType, name: String): MMethod
        do
                var mtype = cleanup_type(recv)
@@ -541,18 +544,20 @@ redef class AArrayExpr
        do
                var mtype = self.mtype.as(MClassType)
                v.add_type(mtype)
-               var native = v.analysis.mainmodule.get_primitive_class("NativeArray").get_mtype([mtype.arguments.first])
+               var native = v.analysis.mainmodule.native_array_type(mtype.arguments.first)
                v.add_type(native)
                mtype = v.cleanup_type(mtype).as(not null)
                var prop = v.get_method(mtype, "with_native")
                v.add_monomorphic_send(mtype, prop)
+               v.add_callsite(with_capacity_callsite)
+               v.add_callsite(push_callsite)
        end
 end
 
 redef class AStringFormExpr
        redef fun accept_rapid_type_visitor(v)
        do
-               var native = v.get_class("NativeString").mclass_type
+               var native = v.analysis.mainmodule.native_string_type
                v.add_type(native)
                var prop = v.get_method(native, "to_s_with_length")
                v.add_monomorphic_send(native, prop)
@@ -562,13 +567,17 @@ end
 redef class ASuperstringExpr
        redef fun accept_rapid_type_visitor(v)
        do
-               var arraytype = v.get_class("Array").get_mtype([v.get_class("Object").mclass_type])
+               var mmodule = v.analysis.mainmodule
+               var object_type = mmodule.object_type
+               var arraytype = mmodule.array_type(object_type)
                v.add_type(arraytype)
-               v.add_type(v.get_class("NativeArray").get_mtype([v.get_class("Object").mclass_type]))
+               var nattype = mmodule.native_array_type(object_type)
+               v.add_type(nattype)
                var prop = v.get_method(arraytype, "join")
                v.add_monomorphic_send(arraytype, prop)
                var prop2 = v.get_method(arraytype, "with_native")
                v.add_monomorphic_send(arraytype, prop2)
+               v.add_monomorphic_send(nattype, v.get_method(nattype, "native_to_s"))
        end
 end