Merge: subset: Add grammar and kind
[nit.git] / src / modelize / modelize_class.nit
index 0d1be2a..853d8ff 100644 (file)
@@ -269,6 +269,8 @@ redef class ModelBuilder
        do
                var mmodule = nmodule.mmodule.as(not null)
                var mclass = nclassdef.mclass.as(not null)
+               var name = mclass.name
+               var kind = mclass.kind
 
                var objectclass = try_get_mclass_by_name(nmodule, mmodule, "Object")
                var pointerclass = try_get_mclass_by_name(nmodule, mmodule, "Pointer")
@@ -289,20 +291,22 @@ redef class ModelBuilder
                                                ntype, false)
                                if mtype == null then continue # Skip because of error
                                if not mtype isa MClassType then
-                                       error(ntype, "Error: supertypes cannot be a formal type.")
+                                       error(ntype, "Error: a supertype cannot be a formal type.")
                                        continue
                                end
-                               if not mclass.kind.can_specialize(mtype.mclass.kind) then
-                                       error(ntype, "Error: {mclass.kind} `{mclass}` cannot specialize {mtype.mclass.kind} `{mtype.mclass}`.")
+                               var superclass = mtype.mclass
+                               var super_kind = superclass.kind
+                               if not kind.can_specialize(super_kind) then
+                                       error(ntype, "Error: {kind} `{mclass}` cannot specialize {super_kind} `{superclass}`.")
                                end
                                supertypes.add mtype
                                #print "new super : {mclass} < {mtype}"
-                               if mtype.mclass.kind == extern_kind then specpointer = false
+                               if super_kind == extern_kind then specpointer = false
                        end
                end
 
                if is_intro and objectclass != null then
-                       if mclass.kind == extern_kind and mclass.name != "Pointer" then
+                       if kind == extern_kind and name != "Pointer" then
                                # it is an extern class, but not a Pointer
                                if pointerclass == null then
                                        error(nclassdef, "Error: `Pointer` must be defined first.")
@@ -310,10 +314,10 @@ redef class ModelBuilder
                                end
                                if specpointer then supertypes.add pointerclass.mclass_type
                        else if specobject then
-                               if mclass.name != "Object" then
+                               if name != "Object" then
                                        # it is a standard class without super class (but is not Object)
                                        supertypes.add objectclass.mclass_type
-                               else if mclass.kind != interface_kind then
+                               else if kind != interface_kind then
                                        error(nclassdef, "Error: `Object` must be an {interface_kind}.")
                                end
                        end
@@ -466,8 +470,11 @@ redef class ModelBuilder
                        for nsc in nclassdef.n_superclasses do
                                var ntype = nsc.n_type
                                var mtype = ntype.mtype
-                               if mtype == null then continue
-                               assert mtype isa MClassType
+
+                               # If the supertype is `null` or don’t refer to a class, we
+                               # already raised an error.
+                               if not mtype isa MClassType then continue
+
                                var sc = mtype.mclass
                                if not parents.has(sc) or sc == objectclass then
                                        # Skip the warning on generated code
@@ -531,6 +538,9 @@ end
 redef class AExternClasskind
        redef fun mkind do return extern_kind
 end
+redef class ASubsetClasskind
+       redef fun mkind do return subset_kind
+end
 
 redef class AFormaldef
        # The associated parameter type