modelize_class: use the new `get_mclass_by_id` to identify class refinement
[nit.git] / src / modelize / modelize_class.nit
index 14c8e94..e020b50 100644 (file)
@@ -46,8 +46,11 @@ redef class ModelBuilder
                var mvisibility: nullable MVisibility
                var arity = 0
                var names = new Array[String]
+               var mclass
                if nclassdef isa AStdClassdef then
-                       name = nclassdef.n_id.text
+                       var qid = nclassdef.n_qid
+                       assert qid != null
+                       name = qid.n_id.text
                        nkind = nclassdef.n_classkind
                        mkind = nkind.mkind
                        nvisibility = nclassdef.n_visibility
@@ -74,6 +77,12 @@ redef class ModelBuilder
                                end
                                names.add(ptname)
                        end
+                       mclass = try_get_mclass_by_qid(qid, mmodule)
+                       if mclass == null and (qid.n_qualified != null or nclassdef.n_kwredef != null) then
+                               class_not_found(qid, mmodule)
+                               nclassdef.is_broken = true
+                               return
+                       end
 
                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.
@@ -84,15 +93,16 @@ redef class ModelBuilder
                        mkind = interface_kind
                        nvisibility = null
                        mvisibility = public_visibility
+                       mclass = try_get_mclass_by_name(nclassdef, mmodule, name)
                else
                        name = "Sys"
                        nkind = null
                        mkind = concrete_kind
                        nvisibility = null
                        mvisibility = public_visibility
+                       mclass = try_get_mclass_by_name(nclassdef, mmodule, name)
                end
 
-               var mclass = try_get_mclass_by_name(nclassdef, mmodule, name)
                if mclass == null then
                        if nclassdef isa AStdClassdef and nclassdef.n_kwredef != null then
                                error(nclassdef, "Redef Error: no imported class `{name}` to refine.")
@@ -116,12 +126,15 @@ redef class ModelBuilder
                        #print "new class {mclass}"
                else if nclassdef isa AStdClassdef and nmodule.mclass2nclassdef.has_key(mclass) then
                        error(nclassdef, "Error: a class `{name}` is already defined at line {nmodule.mclass2nclassdef[mclass].location.line_start}.")
+                       mclass.is_broken = true
                        return
                else if nclassdef isa AStdClassdef and nclassdef.n_kwredef == null then
                        error(nclassdef, "Redef Error: `{name}` is an imported class. Add the `redef` keyword to refine it.")
+                       mclass.is_broken = true
                        return
                else if arity != 0 and mclass.arity != arity then
                        error(nclassdef, "Redef Error: expected {mclass.arity} formal parameter(s) for {mclass.signature_to_s}; got {arity}.")
+                       mclass.is_broken = true
                        return
                else if nkind != null and mkind != concrete_kind and mclass.kind != mkind then
                        error(nkind, "Redef Error: refinement changed the kind from `{mclass.kind}` to `{mkind}`.")
@@ -298,7 +311,6 @@ redef class ModelBuilder
        # REQUIRE: classes of imported modules are already build. (let `phase` do the job)
        private fun build_classes(nmodule: AModule)
        do
-               var errcount = toolcontext.error_count
                # Force building recursively
                if nmodule.build_classes_is_done then return
                nmodule.build_classes_is_done = true
@@ -309,8 +321,6 @@ redef class ModelBuilder
                        if nimp != null then build_classes(nimp)
                end
 
-               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
@@ -322,8 +332,6 @@ redef class ModelBuilder
                        self.build_a_mclass(nmodule, nclassdef)
                end
 
-               if errcount != toolcontext.error_count then return
-
                # Create all classdefs
                for nclassdef in nmodule.n_classdefs do
                        if not nclassdef isa AStdClassdef then continue
@@ -334,29 +342,21 @@ redef class ModelBuilder
                        self.build_a_mclassdef(nmodule, nclassdef)
                end
 
-               if errcount != toolcontext.error_count then return
-
                # Create inheritance on all classdefs
                for nclassdef in nmodule.n_classdefs do
                        self.collect_a_mclassdef_inheritance(nmodule, nclassdef)
                end
 
-               if errcount != toolcontext.error_count then return
-
                # Create the mclassdef hierarchy
                for mclassdef in mmodule.mclassdefs do
                        mclassdef.add_in_hierarchy
                end
 
-               if errcount != toolcontext.error_count then return
-
                # Check inheritance
                for nclassdef in nmodule.n_classdefs do
                        self.check_supertypes(nmodule, nclassdef)
                end
 
-               if errcount != toolcontext.error_count then return
-
                # Check unchecked ntypes
                for nclassdef in nmodule.n_classdefs do
                        if nclassdef isa AStdClassdef then
@@ -380,8 +380,6 @@ redef class ModelBuilder
                        end
                end
 
-               if errcount != toolcontext.error_count then return
-
                # Check clash of ancestors
                for nclassdef in nmodule.n_classdefs do
                        var mclassdef = nclassdef.mclassdef
@@ -402,13 +400,11 @@ redef class ModelBuilder
                        end
                end
 
-               if errcount != toolcontext.error_count then return
-
                # TODO: Check that the super-class is not intrusive
 
                # Check that the superclasses are not already known (by transitivity)
                for nclassdef in nmodule.n_classdefs do
-                       if not nclassdef isa AStdClassdef then continue
+                       if not nclassdef isa AStdClassdef or nclassdef.is_broken then continue
                        var mclassdef = nclassdef.mclassdef
                        if mclassdef == null then continue