X-Git-Url: http://nitlanguage.org diff --git a/src/model/model.nit b/src/model/model.nit index 5301e50..03d82b14 100644 --- a/src/model/model.nit +++ b/src/model/model.nit @@ -103,6 +103,9 @@ redef class Model # The only null type var null_type = new MNullType(self) + # The only bottom type + var bottom_type: MBottomType = null_type.as_notnull + # Build an ordered tree with from `concerns` fun concerns_tree(mconcerns: Collection[MConcern]): ConcernsTree do var seen = new HashSet[MConcern] @@ -252,8 +255,8 @@ redef class MModule # The primitive type `String` var string_type: MClassType = self.get_primitive_class("String").mclass_type is lazy - # The primitive type `NativeString` - var native_string_type: MClassType = self.get_primitive_class("NativeString").mclass_type is lazy + # The primitive type `CString` + var c_string_type: MClassType = self.get_primitive_class("CString").mclass_type is lazy # A primitive type of `Array` fun array_type(elt_type: MType): MClassType do return array_class.get_mtype([elt_type]) @@ -603,7 +606,7 @@ class MClassDef # ENSURE: `bound_mtype.mclass == self.mclass` var bound_mtype: MClassType - redef var location: Location + redef var location redef fun visibility do return mclass.visibility @@ -898,15 +901,16 @@ abstract class MType # # Explanation of the example: # In H, T is set to B, because "H super G[B]", and U is bound to Y, - # because "redef type U: Y". Therefore, Map[T, U] is bound to + # because "redef type U: Y". Therefore, Map[T, U] is bound to # Map[B, Y] # + # REQUIRE: `self.need_anchor implies anchor != null` # ENSURE: `not self.need_anchor implies result == self` # ENSURE: `not result.need_anchor` - fun anchor_to(mmodule: MModule, anchor: MClassType): MType + fun anchor_to(mmodule: MModule, anchor: nullable MClassType): MType do if not need_anchor then return self - assert not anchor.need_anchor + assert anchor != null and not anchor.need_anchor # Just resolve to the anchor and clear all the virtual types var res = self.resolve_for(anchor, null, mmodule, true) assert not res.need_anchor @@ -1058,8 +1062,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. @@ -1127,6 +1140,7 @@ abstract class MType # * H[G[A], B] -> 3 # # Formal types have a depth of 1. + # Only `MClassType` and `MFormalType` nodes are counted. fun depth: Int do return 1 @@ -1140,6 +1154,7 @@ abstract class MType # * H[G[A], B] -> 4 # # Formal types have a length of 1. + # Only `MClassType` and `MFormalType` nodes are counted. fun length: Int do return 1 @@ -1206,7 +1221,7 @@ class MClassType redef fun need_anchor do return false - redef fun anchor_to(mmodule: MModule, anchor: MClassType): MClassType + redef fun anchor_to(mmodule, anchor): MClassType do return super.as(MClassType) end @@ -1364,6 +1379,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 @@ -1407,8 +1434,10 @@ class MVirtualType redef fun model do return self.mproperty.intro_mclassdef.mmodule.model - redef fun lookup_bound(mmodule: MModule, resolved_receiver: MType): MType + redef fun lookup_bound(mmodule, resolved_receiver) do + # There is two possible invalid cases: the vt does not exists in resolved_receiver or the bound is broken + if not resolved_receiver.has_mproperty(mmodule, mproperty) then return new MErrorType(model) return lookup_single_definition(mmodule, resolved_receiver).bound or else new MErrorType(model) end @@ -1570,7 +1599,8 @@ class MParameterType return res end end - abort + # Cannot found `self` in `resolved_receiver` + return new MErrorType(model) end # A PT is fixed when: @@ -1685,6 +1715,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) @@ -1783,7 +1815,7 @@ class MNullType redef fun c_name do return "null" redef fun as_nullable do return self - redef var as_notnull = new MBottomType(model) is lazy + redef var as_notnull: MBottomType = new MBottomType(model) is lazy redef fun need_anchor do return false redef fun resolve_for(mtype, anchor, mmodule, cleanup_virtual) do return self redef fun can_resolve_for(mtype, anchor, mmodule) do return true