modelbuilder_base: Refactor the signature of `resolve_mtype*`
authorJean-Christophe Beaupré <jcbrinfo@users.noreply.github.com>
Fri, 2 Jun 2017 15:04:43 +0000 (11:04 -0400)
committerJean-Christophe Beaupré <jcbrinfo@users.noreply.github.com>
Fri, 2 Jun 2017 15:05:28 +0000 (11:05 -0400)
Only `modelize_mclass` require support for partial context. Furthermore, in
a future PR, it may need to resolve types just before modeling the class
definition (in a place where the `MClass` is available and must be used).

Signed-off-by: Jean-Christophe Beaupré <jcbrinfo@users.noreply.github.com>

src/metrics/static_types_metrics.nit
src/modelbuilder_base.nit
src/modelize/modelize_class.nit
src/modelize/modelize_property.nit
src/nitni/nitni_callbacks.nit
src/semantize/typing.nit

index b94ca13..5276632 100644 (file)
@@ -54,8 +54,8 @@ private class ATypeCounterVisitor
                if n isa AAnnotation then return
 
                if n isa AType then
-                       var mclassdef = self.nclassdef.mclassdef
-                       var mtype = modelbuilder.resolve_mtype(mclassdef.mmodule, mclassdef, n)
+                       var mclassdef = self.nclassdef.mclassdef.as(not null)
+                       var mtype = modelbuilder.resolve_mtype(mclassdef, n)
                        if mtype != null then
                                self.typecount.inc(mtype)
                        end
index 1d7b074..0db4b4b 100644 (file)
@@ -260,18 +260,50 @@ class ModelBuilder
        end
 
        # Return the static type associated to the node `ntype`.
-       # `mmodule` and `mclassdef` is the context where the call is made (used to understand formal types)
+       #
+       # `mclassdef` is the context where the call is made (used to understand
+       # formal types).
        # In case of problem, an error is displayed on `ntype` and null is returned.
-       # FIXME: the name "resolve_mtype" is awful
-       fun resolve_mtype_unchecked(mmodule: MModule, mclassdef: nullable MClassDef, ntype: AType, with_virtual: Bool): nullable MType
+       #
+       # Same as `resolve_mtype_unchecked3`, but get the context (module, class and
+       # anchor) from `mclassdef`.
+       #
+       # SEE: `resolve_mtype`
+       # SEE: `resolve_mtype3_unchecked`
+       #
+       # FIXME: Find a better name for this method.
+       fun resolve_mtype_unchecked(mclassdef: MClassDef, ntype: AType, with_virtual: Bool): nullable MType
+       do
+               return resolve_mtype3_unchecked(
+                       mclassdef.mmodule,
+                       mclassdef.mclass,
+                       mclassdef.bound_mtype,
+                       ntype,
+                       with_virtual
+               )
+       end
+
+       # Return the static type associated to the node `ntype`.
+       #
+       # `mmodule`, `mclass` and `anchor` compose the context where the call is
+       # made (used to understand formal types).
+       # In case of problem, an error is displayed on `ntype` and null is returned.
+       #
+       # Note: The “3” is for 3 contextual parameters.
+       #
+       # SEE: `resolve_mtype`
+       # SEE: `resolve_mtype_unchecked`
+       #
+       # FIXME: Find a better name for this method.
+       fun resolve_mtype3_unchecked(mmodule: MModule, mclass: nullable MClass, anchor: nullable MClassType, ntype: AType, with_virtual: Bool): nullable MType
        do
                var qid = ntype.n_qid
                var name = qid.n_id.text
                var res: MType
 
                # Check virtual type
-               if mclassdef != null and with_virtual then
-                       var prop = try_get_mproperty_by_name(ntype, mclassdef, name).as(nullable MVirtualTypeProp)
+               if anchor != null and with_virtual then
+                       var prop = try_get_mproperty_by_name2(ntype, mmodule, anchor, name).as(nullable MVirtualTypeProp)
                        if prop != null then
                                if not ntype.n_types.is_empty then
                                        error(ntype, "Type Error: formal type `{name}` cannot have formal parameters.")
@@ -284,8 +316,8 @@ class ModelBuilder
                end
 
                # Check parameter type
-               if mclassdef != null then
-                       for p in mclassdef.mclass.mparameters do
+               if mclass != null then
+                       for p in mclass.mparameters do
                                if p.name != name then continue
 
                                if not ntype.n_types.is_empty then
@@ -321,7 +353,7 @@ class ModelBuilder
                        else
                                var mtypes = new Array[MType]
                                for nt in ntype.n_types do
-                                       var mt = resolve_mtype_unchecked(mmodule, mclassdef, nt, with_virtual)
+                                       var mt = resolve_mtype3_unchecked(mmodule, mclass, anchor, nt, with_virtual)
                                        if mt == null then return null # Forward error
                                        mtypes.add(mt)
                                end
@@ -415,13 +447,44 @@ class ModelBuilder
        private var bad_class_names = new MultiHashMap[MModule, String]
 
        # Return the static type associated to the node `ntype`.
-       # `mmodule` and `mclassdef` is the context where the call is made (used to understand formal types)
+       #
+       # `mclassdef` is the context where the call is made (used to understand
+       # formal types).
        # In case of problem, an error is displayed on `ntype` and null is returned.
-       # FIXME: the name "resolve_mtype" is awful
-       fun resolve_mtype(mmodule: MModule, mclassdef: nullable MClassDef, ntype: AType): nullable MType
+       #
+       # Same as `resolve_mtype3`, but get the context (module, class and ) from
+       # `mclassdef`.
+       #
+       # SEE: `resolve_mtype3`
+       # SEE: `resolve_mtype_unchecked`
+       #
+       # FIXME: Find a better name for this method.
+       fun resolve_mtype(mclassdef: MClassDef, ntype: AType): nullable MType
+       do
+               return resolve_mtype3(
+                       mclassdef.mmodule,
+                       mclassdef.mclass,
+                       mclassdef.bound_mtype,
+                       ntype
+               )
+       end
+
+       # Return the static type associated to the node `ntype`.
+       #
+       # `mmodule`, `mclass` and `anchor` compose the context where the call is
+       # made (used to understand formal types).
+       # In case of problem, an error is displayed on `ntype` and null is returned.
+       #
+       # Note: The “3” is for 3 contextual parameters.
+       #
+       # SEE: `resolve_mtype`
+       # SEE: `resolve_mtype_unchecked`
+       #
+       # FIXME: Find a better name for this method.
+       fun resolve_mtype3(mmodule: MModule, mclass: nullable MClass, anchor: nullable MClassType, ntype: AType): nullable MType
        do
                var mtype = ntype.mtype
-               if mtype == null then mtype = resolve_mtype_unchecked(mmodule, mclassdef, ntype, true)
+               if mtype == null then mtype = resolve_mtype3_unchecked(mmodule, mclass, anchor, ntype, true)
                if mtype == null then return null # Forward error
 
                if ntype.checked_mtype then return mtype
@@ -432,10 +495,8 @@ class ModelBuilder
                                if intro == null then return null # skip error
                                var bound = intro.bound_mtype.arguments[i]
                                var nt = ntype.n_types[i]
-                               var mt = resolve_mtype(mmodule, mclassdef, nt)
+                               var mt = resolve_mtype3(mmodule, mclass, anchor, nt)
                                if mt == null then return null # forward error
-                               var anchor
-                               if mclassdef != null then anchor = mclassdef.bound_mtype else anchor = null
                                if not check_subtype(nt, mmodule, anchor, mt, bound) then
                                        error(nt, "Type Error: expected `{bound}`, got `{mt}`.")
                                        return null
index 23ab906..3be6804 100644 (file)
@@ -179,7 +179,7 @@ redef class ModelBuilder
                                end
                                var nfdt = nfd.n_type
                                if nfdt != null then
-                                       var bound = resolve_mtype_unchecked(mmodule, null, nfdt, false)
+                                       var bound = resolve_mtype3_unchecked(mmodule, null, null, nfdt, false)
                                        if bound == null then return # Forward error
                                        if bound.need_anchor then
                                                # No F-bounds!
@@ -256,7 +256,7 @@ redef class ModelBuilder
                        for nsc in nclassdef.n_superclasses do
                                specobject = false
                                var ntype = nsc.n_type
-                               var mtype = resolve_mtype_unchecked(mmodule, mclassdef, ntype, false)
+                               var mtype = resolve_mtype_unchecked(mclassdef, 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.")
@@ -364,11 +364,21 @@ redef class ModelBuilder
                for nclassdef in nmodule.n_classdefs do
                        if nclassdef isa AStdClassdef then
                                var mclassdef = nclassdef.mclassdef
+                               var mclass
+                               var anchor
+                               if mclassdef == null then
+                                       mclass = null
+                                       anchor = null
+                               else
+                                       mclass = mclassdef.mclass
+                                       anchor = mclassdef.bound_mtype
+                               end
+
                                # check bound of formal parameter
                                for nfd in nclassdef.n_formaldefs do
                                        var nfdt = nfd.n_type
                                        if nfdt != null and nfdt.mtype != null then
-                                               var bound = resolve_mtype(mmodule, mclassdef, nfdt)
+                                               var bound = resolve_mtype3(mmodule, mclass, anchor, nfdt)
                                                if bound == null then return # Forward error
                                        end
                                end
@@ -376,7 +386,7 @@ redef class ModelBuilder
                                for nsc in nclassdef.n_superclasses do
                                        var ntype = nsc.n_type
                                        if ntype.mtype != null then
-                                               var mtype = resolve_mtype(mmodule, mclassdef, ntype)
+                                               var mtype = resolve_mtype3(mmodule, mclass, anchor, ntype)
                                                if mtype == null then return # Forward error
                                        end
                                end
index 44d551d..a7f75ff 100644 (file)
@@ -671,14 +671,13 @@ redef class ASignature
        # Visit and fill information about a signature
        private fun visit_signature(modelbuilder: ModelBuilder, mclassdef: MClassDef): Bool
        do
-               var mmodule = mclassdef.mmodule
                var param_names = self.param_names
                var param_types = self.param_types
                for np in self.n_params do
                        param_names.add(np.n_id.text)
                        var ntype = np.n_type
                        if ntype != null then
-                               var mtype = modelbuilder.resolve_mtype_unchecked(mmodule, mclassdef, ntype, true)
+                               var mtype = modelbuilder.resolve_mtype_unchecked(mclassdef, ntype, true)
                                if mtype == null then return false # Skip error
                                for i in [0..param_names.length-param_types.length[ do
                                        param_types.add(mtype)
@@ -695,7 +694,7 @@ redef class ASignature
                end
                var ntype = self.n_type
                if ntype != null then
-                       self.ret_type = modelbuilder.resolve_mtype_unchecked(mmodule, mclassdef, ntype, true)
+                       self.ret_type = modelbuilder.resolve_mtype_unchecked(mclassdef, ntype, true)
                        if self.ret_type == null then return false # Skip error
                end
 
@@ -709,14 +708,14 @@ redef class ASignature
                for np in self.n_params do
                        var ntype = np.n_type
                        if ntype != null then
-                               if modelbuilder.resolve_mtype(mclassdef.mmodule, mclassdef, ntype) == null then
+                               if modelbuilder.resolve_mtype(mclassdef, ntype) == null then
                                        res = false
                                end
                        end
                end
                var ntype = self.n_type
                if ntype != null then
-                       if modelbuilder.resolve_mtype(mclassdef.mmodule, mclassdef, ntype) == null then
+                       if modelbuilder.resolve_mtype(mclassdef, ntype) == null then
                                res = false
                        end
                end
@@ -1348,7 +1347,7 @@ redef class AAttrPropdef
 
                var ntype = self.n_type
                if ntype != null then
-                       mtype = modelbuilder.resolve_mtype_unchecked(mmodule, mclassdef, ntype, true)
+                       mtype = modelbuilder.resolve_mtype_unchecked(mclassdef, ntype, true)
                        if mtype == null then return
                end
 
@@ -1369,9 +1368,9 @@ redef class AAttrPropdef
                if mtype == null then
                        if nexpr != null then
                                if nexpr isa ANewExpr then
-                                       mtype = modelbuilder.resolve_mtype_unchecked(mmodule, mclassdef, nexpr.n_type, true)
+                                       mtype = modelbuilder.resolve_mtype_unchecked(mclassdef, nexpr.n_type, true)
                                else if nexpr isa AAsCastExpr then
-                                       mtype = modelbuilder.resolve_mtype_unchecked(mmodule, mclassdef, nexpr.n_type, true)
+                                       mtype = modelbuilder.resolve_mtype_unchecked(mclassdef, nexpr.n_type, true)
                                else if nexpr isa AIntegerExpr then
                                        var cla: nullable MClass = null
                                        if nexpr.value isa Int then
@@ -1432,7 +1431,7 @@ redef class AAttrPropdef
                        end
                else if ntype != null and inherited_type == mtype then
                        if nexpr isa ANewExpr then
-                               var xmtype = modelbuilder.resolve_mtype_unchecked(mmodule, mclassdef, nexpr.n_type, true)
+                               var xmtype = modelbuilder.resolve_mtype_unchecked(mclassdef, nexpr.n_type, true)
                                if xmtype == mtype then
                                        modelbuilder.advice(ntype, "useless-type", "Warning: useless type definition")
                                end
@@ -1488,11 +1487,11 @@ redef class AAttrPropdef
 
                # Check types
                if ntype != null then
-                       if modelbuilder.resolve_mtype(mmodule, mclassdef, ntype) == null then return
+                       if modelbuilder.resolve_mtype(mclassdef, ntype) == null then return
                end
                var nexpr = n_expr
                if nexpr isa ANewExpr then
-                       if modelbuilder.resolve_mtype(mmodule, mclassdef, nexpr.n_type) == null then return
+                       if modelbuilder.resolve_mtype(mclassdef, nexpr.n_type) == null then return
                end
 
                # Lookup for signature in the precursor
@@ -1645,11 +1644,10 @@ redef class ATypePropdef
                var mpropdef = self.mpropdef
                if mpropdef == null then return # Error thus skipped
                var mclassdef = mpropdef.mclassdef
-               var mmodule = mclassdef.mmodule
                var mtype: nullable MType = null
 
                var ntype = self.n_type
-               mtype = modelbuilder.resolve_mtype_unchecked(mmodule, mclassdef, ntype, true)
+               mtype = modelbuilder.resolve_mtype_unchecked(mclassdef, ntype, true)
                if mtype == null then return
 
                mpropdef.bound = mtype
@@ -1671,7 +1669,7 @@ redef class ATypePropdef
                var anchor = mclassdef.bound_mtype
 
                var ntype = self.n_type
-               if modelbuilder.resolve_mtype(mmodule, mclassdef, ntype) == null then
+               if modelbuilder.resolve_mtype(mclassdef, ntype) == null then
                        mpropdef.bound = null
                        return
                end
index 823f624..6d05196 100644 (file)
@@ -304,7 +304,7 @@ redef class AFullPropExternCall
                var mmodule = npropdef.mpropdef.mclassdef.mmodule
                var mclassdef = npropdef.mpropdef.mclassdef
                var mclass_type = mclassdef.bound_mtype
-               var mtype = toolcontext.modelbuilder.resolve_mtype(mmodule, mclassdef, n_type)
+               var mtype = toolcontext.modelbuilder.resolve_mtype(mclassdef, n_type)
 
                if mtype == null then return
 
@@ -337,7 +337,7 @@ redef class AInitPropExternCall
        do
                var mmodule = npropdef.mpropdef.mclassdef.mmodule
                var mclassdef = npropdef.mpropdef.mclassdef
-               var mtype = toolcontext.modelbuilder.resolve_mtype(mmodule, mclassdef, n_type)
+               var mtype = toolcontext.modelbuilder.resolve_mtype(mclassdef, n_type)
                if mtype == null then return
 
                if not mtype isa MClassType then
@@ -398,9 +398,8 @@ redef class ACastAsExternCall
        redef fun verify_and_collect(npropdef, callback_set, toolcontext)
        do
                var mclassdef = npropdef.mpropdef.mclassdef
-               var mmodule = mclassdef.mmodule
-               toolcontext.modelbuilder.resolve_mtype_unchecked(mmodule, mclassdef, n_from_type, true)
-               toolcontext.modelbuilder.resolve_mtype_unchecked(mmodule, mclassdef, n_to_type, true)
+               toolcontext.modelbuilder.resolve_mtype_unchecked(mclassdef, n_from_type, true)
+               toolcontext.modelbuilder.resolve_mtype_unchecked(mclassdef, n_to_type, true)
                super
        end
 end
@@ -412,8 +411,7 @@ redef class AAsNullableExternCall
        redef fun verify_and_collect(npropdef, callback_set, toolcontext)
        do
                var mclassdef = npropdef.mpropdef.mclassdef
-               var mmodule = mclassdef.mmodule
-               toolcontext.modelbuilder.resolve_mtype_unchecked(mmodule, mclassdef, n_type, true)
+               toolcontext.modelbuilder.resolve_mtype_unchecked(mclassdef, n_type, true)
                super
        end
 end
@@ -429,8 +427,7 @@ redef class AAsNotNullableExternCall
        redef fun verify_and_collect(npropdef, callback_set, toolcontext)
        do
                var mclassdef = npropdef.mpropdef.mclassdef
-               var mmodule = mclassdef.mmodule
-               toolcontext.modelbuilder.resolve_mtype_unchecked(mmodule, mclassdef, n_type, true)
+               toolcontext.modelbuilder.resolve_mtype_unchecked(mclassdef, n_type, true)
                super
        end
 end
index 37a1494..8890ba9 100644 (file)
@@ -275,7 +275,7 @@ private class TypeVisitor
 
        fun resolve_mtype(node: AType): nullable MType
        do
-               return self.modelbuilder.resolve_mtype(mmodule, mclassdef, node)
+               return self.modelbuilder.resolve_mtype(mclassdef, node)
        end
 
        fun try_get_mclass(node: ANode, name: String): nullable MClass