modelize_class: Extract the bound collection logic
authorJean-Christophe Beaupré <jcbrinfo@users.noreply.github.com>
Fri, 9 Jun 2017 16:29:57 +0000 (12:29 -0400)
committerJean-Christophe Beaupré <jcbrinfo@users.noreply.github.com>
Fri, 9 Jun 2017 17:25:31 +0000 (13:25 -0400)
Signed-off-by: Jean-Christophe Beaupré <jcbrinfo@users.noreply.github.com>

src/modelize/modelize_class.nit

index 7580dde..a2de65b 100644 (file)
@@ -149,7 +149,6 @@ redef class ModelBuilder
        private fun build_a_mclassdef(nmodule: AModule, nclassdef: AClassdef)
        do
                var mmodule = nmodule.mmodule.as(not null)
-               var objectclass = try_get_mclass_by_name(nmodule, mmodule, "Object")
                var mclass = nclassdef.mclass
                if mclass == null then return # Skip error
 
@@ -161,8 +160,45 @@ redef class ModelBuilder
                        return
                end
 
+               var bound_mtype = build_a_bound_mtype(nmodule, nclassdef)
+               if bound_mtype == null then return
+               var mclassdef = new MClassDef(mmodule, bound_mtype, nclassdef.location)
+               nclassdef.mclassdef = mclassdef
+               self.mclassdef2nclassdef[mclassdef] = nclassdef
+
+               if nclassdef isa AStdClassdef then
+                       var ndoc = nclassdef.n_doc
+                       if ndoc != null then
+                               var mdoc = ndoc.to_mdoc
+                               mclassdef.mdoc = mdoc
+                               mdoc.original_mentity = mclassdef
+                       else if mclassdef.is_intro and mclass.visibility >= public_visibility then
+                               advice(nclassdef, "missing-doc", "Documentation warning: Undocumented public class `{mclass}`")
+                       end
+               end
+
+               if mclassdef.is_intro then
+                       self.toolcontext.info("{mclassdef} introduces new {mclass.kind} {mclass.full_name}", 3)
+               else
+                       self.toolcontext.info("{mclassdef} refines {mclass.kind} {mclass.full_name}", 3)
+               end
+       end
+
+       # Determine the type parameter bounds for `nclassdef`.
+       #
+       # In case of error, return `null`.
+       #
+       # REQUIRE: `nmodule.mmodule != null`
+       # REQUIRE: `nclassdef.mclass != null`
+       private fun build_a_bound_mtype(nmodule: AModule, nclassdef: AClassdef): nullable MClassType
+       do
+               var mmodule = nmodule.mmodule.as(not null)
+               var mclass = nclassdef.mclass.as(not null)
+
                var bounds = new Array[MType]
                if nclassdef isa AStdClassdef and mclass.arity > 0 then
+                       var objectclass = try_get_mclass_by_name(nmodule, mmodule, "Object")
+
                        # Revolve bound for formal parameters
                        for i in [0..mclass.arity[ do
                                if nclassdef.n_formaldefs.is_empty then
@@ -180,7 +216,7 @@ redef class ModelBuilder
                                var nfdt = nfd.n_type
                                if nfdt != null then
                                        var bound = resolve_mtype3_unchecked(mmodule, null, null, nfdt, false)
-                                       if bound == null then return # Forward error
+                                       if bound == null then return null # Forward error
                                        if bound.need_anchor then
                                                # No F-bounds!
                                                error(nfd, "Error: formal parameter type `{pname}` bounded with a formal parameter type.")
@@ -191,7 +227,7 @@ redef class ModelBuilder
                                else if mclass.mclassdefs.is_empty then
                                        if objectclass == null then
                                                error(nfd, "Error: formal parameter type `{pname}` unbounded but no `Object` class exists.")
-                                               return
+                                               return null
                                        end
                                        # No bound, then implicitely bound by nullable Object
                                        var bound = objectclass.mclass_type.as_nullable
@@ -206,27 +242,7 @@ redef class ModelBuilder
                        end
                end
 
-               var bound_mtype = mclass.get_mtype(bounds)
-               var mclassdef = new MClassDef(mmodule, bound_mtype, nclassdef.location)
-               nclassdef.mclassdef = mclassdef
-               self.mclassdef2nclassdef[mclassdef] = nclassdef
-
-               if nclassdef isa AStdClassdef then
-                       var ndoc = nclassdef.n_doc
-                       if ndoc != null then
-                               var mdoc = ndoc.to_mdoc
-                               mclassdef.mdoc = mdoc
-                               mdoc.original_mentity = mclassdef
-                       else if mclassdef.is_intro and mclass.visibility >= public_visibility then
-                               advice(nclassdef, "missing-doc", "Documentation warning: Undocumented public class `{mclass}`")
-                       end
-               end
-
-               if mclassdef.is_intro then
-                       self.toolcontext.info("{mclassdef} introduces new {mclass.kind} {mclass.full_name}", 3)
-               else
-                       self.toolcontext.info("{mclassdef} refines {mclass.kind} {mclass.full_name}", 3)
-               end
+               return mclass.get_mtype(bounds)
        end
 
        # Visit the AST and set the super-types of the `MClassDef` objects