model: add `MType::is_legal_in` to check the legality of a given complex type
authorJean Privat <jean@pryen.org>
Tue, 9 Aug 2016 15:17:53 +0000 (11:17 -0400)
committerJean Privat <jean@pryen.org>
Tue, 9 Aug 2016 15:17:53 +0000 (11:17 -0400)
Signed-off-by: Jean Privat <jean@pryen.org>

src/model/model.nit

index 973cec5..a94f5e4 100644 (file)
@@ -1058,8 +1058,17 @@ abstract class MType
        #
        # `MErrorType` are used in result with conflict or inconsistencies.
        #
+       # See `is_legal_in` to check conformity with generic bounds.
        fun is_ok: Bool do return true
 
+       # Is the type legal in a given `mmodule` (with an optional `anchor`)?
+       #
+       # A type is valid if:
+       #
+       # * it does not contain a `MErrorType` (see `is_ok`).
+       # * its generic formal arguments are within their bounds.
+       fun is_legal_in(mmodule: MModule, anchor: nullable MClassType): Bool do return is_ok
+
        # Can the type be resolved?
        #
        # In order to resolve open types, the formal types must make sence.
@@ -1364,6 +1373,18 @@ class MGenericType
                return super
        end
 
+       redef fun is_legal_in(mmodule, anchor)
+       do
+               var mtype
+               if need_anchor then
+                       assert anchor != null
+                       mtype = anchor_to(mmodule, anchor)
+               else
+                       mtype = self
+               end
+               if not mtype.is_ok then return false
+               return mtype.is_subtype(mmodule, null, mtype.mclass.intro.bound_mtype)
+       end
 
        redef fun depth
        do
@@ -1688,6 +1709,8 @@ abstract class MProxyType
 
        redef fun is_ok do return mtype.is_ok
 
+       redef fun is_legal_in(mmodule, anchor) do return mtype.is_legal_in(mmodule, anchor)
+
        redef fun lookup_fixed(mmodule, resolved_receiver)
        do
                var t = mtype.lookup_fixed(mmodule, resolved_receiver)