modelize_classes: top-level methods are defined in Sys, not Object
[nit.git] / src / modelize / modelize_class.nit
index c779df9..ae4e4c2 100644 (file)
@@ -75,20 +75,21 @@ redef class ModelBuilder
                                names.add(ptname)
                        end
 
-               else if nclassdef isa ATopClassdef then
+               else if nclassdef isa ATopClassdef and nclassdef.n_propdefs.first.as(AMethPropdef).n_methid.collect_text == "sys" then
+                       # Special case to keep `sys` in object.
+                       # Needed to keep working bootstrap and a working java FFI together.
+                       # TODO: remove once safe to remove
                        name = "Object"
                        nkind = null
                        mkind = interface_kind
                        nvisibility = null
                        mvisibility = public_visibility
-               else if nclassdef isa AMainClassdef then
+               else
                        name = "Sys"
                        nkind = null
                        mkind = concrete_kind
                        nvisibility = null
                        mvisibility = public_visibility
-               else
-                       abort
                end
 
                var mclass = try_get_mclass_by_name(nclassdef, mmodule, name)
@@ -103,7 +104,9 @@ redef class ModelBuilder
                                var mclasses = model.get_mclasses_by_name(name)
                                if mclasses != null then for other in mclasses do
                                        if other.intro_mmodule.mgroup != null and other.intro_mmodule.mgroup.mproject == mmodule.mgroup.mproject then
-                                               error(nclassdef, "Error: A class named `{other.full_name}` is already defined in module `{other.intro_mmodule}` at {other.intro.location}.")
+                                               # Skip classes that are buggy
+                                               if other.try_intro == null then continue
+                                               warning(nclassdef, "full-name-conflict", "Error: A class named `{other.full_name}` is already defined in module `{other.intro_mmodule}` at {other.intro.location}.")
                                                break
                                        end
                                end
@@ -224,11 +227,14 @@ redef class ModelBuilder
        # Visit the AST and set the super-types of the `MClassDef` objects
        private fun collect_a_mclassdef_inheritance(nmodule: AModule, nclassdef: AClassdef)
        do
-               var mmodule = nmodule.mmodule.as(not null)
+               var mmodule = nmodule.mmodule
+               if mmodule == null then return
                var objectclass = try_get_mclass_by_name(nmodule, mmodule, "Object")
                var pointerclass = try_get_mclass_by_name(nmodule, mmodule, "Pointer")
-               var mclass = nclassdef.mclass.as(not null)
-               var mclassdef = nclassdef.mclassdef.as(not null)
+               var mclass = nclassdef.mclass
+               if mclass == null then return
+               var mclassdef = nclassdef.mclassdef
+               if mclassdef == null then return
 
                # Do we need to specify Object as a super class?
                var specobject = true
@@ -274,9 +280,12 @@ redef class ModelBuilder
        # Check the validity of the specialization heirarchy
        private fun check_supertypes(nmodule: AModule, nclassdef: AClassdef)
        do
-               var mmodule = nmodule.mmodule.as(not null)
-               var mclass = nclassdef.mclass.as(not null)
-               var mclassdef = nclassdef.mclassdef.as(not null)
+               var mmodule = nmodule.mmodule
+               if mmodule == null then return
+               var mclass = nclassdef.mclass
+               if mclass == null then return
+               var mclassdef = nclassdef.mclassdef
+               if mclassdef == null then return
 
                for s in mclassdef.supertypes do
                        if s.is_subtype(mmodule, mclassdef.bound_mtype, mclassdef.bound_mtype) then
@@ -293,7 +302,8 @@ redef class ModelBuilder
                # Force building recursively
                if nmodule.build_classes_is_done then return
                nmodule.build_classes_is_done = true
-               var mmodule = nmodule.mmodule.as(not null)
+               var mmodule = nmodule.mmodule
+               if mmodule == null then return
                for imp in mmodule.in_importation.direct_greaters do
                        var nimp = mmodule2node(imp)
                        if nimp != null then build_classes(nimp)
@@ -302,7 +312,13 @@ redef class ModelBuilder
                if errcount != toolcontext.error_count then return
 
                # Create all classes
+               # process AStdClassdef before so that non-AStdClassdef classes can be attached to existing ones, if any
                for nclassdef in nmodule.n_classdefs do
+                       if not nclassdef isa AStdClassdef then continue
+                       self.build_a_mclass(nmodule, nclassdef)
+               end
+               for nclassdef in nmodule.n_classdefs do
+                       if nclassdef isa AStdClassdef then continue
                        self.build_a_mclass(nmodule, nclassdef)
                end
 
@@ -310,6 +326,11 @@ redef class ModelBuilder
 
                # Create all classdefs
                for nclassdef in nmodule.n_classdefs do
+                       if not nclassdef isa AStdClassdef then continue
+                       self.build_a_mclassdef(nmodule, nclassdef)
+               end
+               for nclassdef in nmodule.n_classdefs do
+                       if nclassdef isa AStdClassdef then continue
                        self.build_a_mclassdef(nmodule, nclassdef)
                end
 
@@ -363,7 +384,8 @@ redef class ModelBuilder
 
                # Check clash of ancestors
                for nclassdef in nmodule.n_classdefs do
-                       var mclassdef = nclassdef.mclassdef.as(not null)
+                       var mclassdef = nclassdef.mclassdef
+                       if mclassdef == null then continue
                        var superclasses = new HashMap[MClass, MClassType]
                        for scd in mclassdef.in_hierarchy.greaters do
                                for st in scd.supertypes do
@@ -387,7 +409,8 @@ redef class ModelBuilder
                # Check that the superclasses are not already known (by transitivity)
                for nclassdef in nmodule.n_classdefs do
                        if not nclassdef isa AStdClassdef then continue
-                       var mclassdef = nclassdef.mclassdef.as(not null)
+                       var mclassdef = nclassdef.mclassdef
+                       if mclassdef == null then continue
 
                        # Get the direct superclasses
                        # Since we are a mclassdef, just look at the mclassdef hierarchy