Merge: Not null types
[nit.git] / src / model / model.nit
index a391ea4..62c3db4 100644 (file)
@@ -251,7 +251,9 @@ redef class MModule
        fun get_primitive_class(name: String): MClass
        do
                var cla = self.model.get_mclasses_by_name(name)
-               if cla == null then
+               # Filter classes by introducing module
+               if cla != null then cla = [for c in cla do if self.in_importation <= c.intro_mmodule then c]
+               if cla == null or cla.is_empty then
                        if name == "Bool" and self.model.get_mclasses_by_name("Object") != null then
                                # Bool is injected because it is needed by engine to code the result
                                # of the implicit casts.
@@ -261,11 +263,11 @@ redef class MModule
                                cladef.add_in_hierarchy
                                return c
                        end
-                       print("Fatal Error: no primitive class {name}")
+                       print("Fatal Error: no primitive class {name} in {self}")
                        exit(1)
                end
                if cla.length != 1 then
-                       var msg = "Fatal Error: more than one primitive class {name}:"
+                       var msg = "Fatal Error: more than one primitive class {name} in {self}:"
                        for c in cla do msg += " {c.full_name}"
                        print msg
                        #exit(1)
@@ -433,8 +435,17 @@ class MClass
        #
        # Warning: such a definition may not exist in the early life of the object.
        # In this case, the method will abort.
+       #
+       # Use `try_intro` instead
        var intro: MClassDef is noinit
 
+       # The definition that introduces the class or null if not yet known.
+       #
+       # See `intro`
+       fun try_intro: nullable MClassDef do
+               if isset _intro then return _intro else return null
+       end
+
        # Return the class `self` in the class hierarchy of the module `mmodule`.
        #
        # SEE: `MModule::flatten_mclass_hierarchy`
@@ -627,7 +638,7 @@ class MClassDef
        var in_hierarchy: nullable POSetElement[MClassDef] = null
 
        # Is the definition the one that introduced `mclass`?
-       fun is_intro: Bool do return mclass.intro == self
+       fun is_intro: Bool do return isset mclass._intro and mclass.intro == self
 
        # All properties introduced by the classdef
        var intro_mproperties = new Array[MProperty]
@@ -998,12 +1009,14 @@ abstract class MType
                return res
        end
 
-       # Return the not nullable version of the type
-       # Is the type is already not nullable, then self is returned.
+       # Remove the base type of a decorated (proxy) type.
+       # Is the type is not decorated, then self is returned.
        #
-       # Note: this just remove the `nullable` notation, but the result can still contains null.
+       # Most of the time it is used to return the not nullable version of a nullable type.
+       # In this case, this just remove the `nullable` notation, but the result can still contains null.
        # For instance if `self isa MNullType` or self is a formal type bounded by a nullable type.
-       fun as_notnullable: MType
+       # If you really want to exclude the `null` value, then use `as_notnull`
+       fun undecorate: MType
        do
                return self
        end
@@ -1329,7 +1342,7 @@ class MVirtualType
        redef fun lookup_fixed(mmodule: MModule, resolved_receiver: MType): MType
        do
                assert not resolved_receiver.need_anchor
-               resolved_receiver = resolved_receiver.as_notnullable
+               resolved_receiver = resolved_receiver.undecorate
                assert resolved_receiver isa MClassType # It is the only remaining type
 
                var prop = lookup_single_definition(mmodule, resolved_receiver)
@@ -1438,7 +1451,7 @@ class MParameterType
        redef fun lookup_bound(mmodule: MModule, resolved_receiver: MType): MType
        do
                assert not resolved_receiver.need_anchor
-               resolved_receiver = resolved_receiver.as_notnullable
+               resolved_receiver = resolved_receiver.undecorate
                assert resolved_receiver isa MClassType # It is the only remaining type
                var goalclass = self.mclass
                if resolved_receiver.mclass == goalclass then
@@ -1466,7 +1479,7 @@ class MParameterType
        redef fun lookup_fixed(mmodule: MModule, resolved_receiver: MType): MType
        do
                assert not resolved_receiver.need_anchor
-               resolved_receiver = resolved_receiver.as_notnullable
+               resolved_receiver = resolved_receiver.undecorate
                assert resolved_receiver isa MClassType # It is the only remaining type
                var res = self.resolve_for(resolved_receiver.mclass.mclass_type, resolved_receiver, mmodule, false)
                return res
@@ -1551,7 +1564,7 @@ abstract class MProxyType
        redef fun need_anchor do return mtype.need_anchor
        redef fun as_nullable do return mtype.as_nullable
        redef fun as_notnull do return mtype.as_notnull
-       redef fun as_notnullable do return mtype.as_notnullable
+       redef fun undecorate do return mtype.undecorate
        redef fun resolve_for(mtype, anchor, mmodule, cleanup_virtual)
        do
                var res = self.mtype.resolve_for(mtype, anchor, mmodule, cleanup_virtual)
@@ -1885,7 +1898,7 @@ abstract class MProperty
        fun lookup_definitions(mmodule: MModule, mtype: MType): Array[MPROPDEF]
        do
                assert not mtype.need_anchor
-               mtype = mtype.as_notnullable
+               mtype = mtype.undecorate
 
                var cache = self.lookup_definitions_cache[mmodule, mtype]
                if cache != null then return cache
@@ -1925,7 +1938,7 @@ abstract class MProperty
        fun lookup_super_definitions(mmodule: MModule, mtype: MType): Array[MPROPDEF]
        do
                assert not mtype.need_anchor
-               mtype = mtype.as_notnullable
+               mtype = mtype.undecorate
 
                # First, select all candidates
                var candidates = new Array[MPROPDEF]
@@ -2003,7 +2016,7 @@ abstract class MProperty
        # REQUIRE: `mtype.has_mproperty(mmodule, self)`
        fun lookup_all_definitions(mmodule: MModule, mtype: MType): Array[MPROPDEF]
        do
-               mtype = mtype.as_notnullable
+               mtype = mtype.undecorate
 
                var cache = self.lookup_all_definitions_cache[mmodule, mtype]
                if cache != null then return cache