X-Git-Url: http://nitlanguage.org diff --git a/src/model/model.nit b/src/model/model.nit index 1dbedfb..4e9be82 100644 --- a/src/model/model.nit +++ b/src/model/model.nit @@ -206,6 +206,9 @@ redef class MModule # The primitive type `Int` var int_type: MClassType = self.get_primitive_class("Int").mclass_type is lazy + # The primitive type `Byte` + var byte_type: MClassType = self.get_primitive_class("Byte").mclass_type is lazy + # The primitive type `Char` var char_type: MClassType = self.get_primitive_class("Char").mclass_type is lazy @@ -380,6 +383,29 @@ class MClass # is empty if the class is not generic var mparameters = new Array[MParameterType] + # A string version of the signature a generic class. + # + # eg. `Map[K: nullable Object, V: nullable Object]` + # + # If the class in non generic the name is just given. + # + # eg. `Object` + fun signature_to_s: String + do + if arity == 0 then return name + var res = new FlatBuffer + res.append name + res.append "[" + for i in [0..arity[ do + if i > 0 then res.append ", " + res.append mparameters[i].name + res.append ": " + res.append intro.bound_mtype.arguments[i].to_s + end + res.append "]" + return res.to_s + end + # Initialize `mparameters` from their names. protected fun setup_parameter_names(parameter_names: nullable Array[String]) is autoinit @@ -708,6 +734,8 @@ abstract class MType if sup isa MNullableType then sup_accept_null = true sup = sup.mtype + else if sup isa MNotNullType then + sup = sup.mtype else if sup isa MNullType then sup_accept_null = true end @@ -715,16 +743,20 @@ abstract class MType # Can `sub` provide null or not? # Thus we can match with `sup_accept_null` # Also discard the nullable marker if it exists + var sub_reject_null = false if sub isa MNullableType then if not sup_accept_null then return false sub = sub.mtype + else if sub isa MNotNullType then + sub_reject_null = true + sub = sub.mtype else if sub isa MNullType then return sup_accept_null end # Now the case of direct null and nullable is over. # If `sub` is a formal type, then it is accepted if its bound is accepted - while sub isa MParameterType or sub isa MVirtualType do + while sub isa MFormalType do #print "3.is {sub} a {sup}?" # A unfixed formal type can only accept itself @@ -732,12 +764,16 @@ abstract class MType assert anchor != null sub = sub.lookup_bound(mmodule, anchor) + if sub_reject_null then sub = sub.as_notnull #print "3.is {sub} a {sup}?" # Manage the second layer of null/nullable if sub isa MNullableType then - if not sup_accept_null then return false + if not sup_accept_null and not sub_reject_null then return false + sub = sub.mtype + else if sub isa MNotNullType then + sub_reject_null = true sub = sub.mtype else if sub isa MNullType then return sup_accept_null @@ -745,10 +781,10 @@ abstract class MType end #print "4.is {sub} a {sup}? <- no more resolution" - assert sub isa MClassType # It is the only remaining type + assert sub isa MClassType else print "{sub} vararg_rank=1 var vararg_rank: Int is noinit - # The number or parameters + # The number of parameters fun arity: Int do return mparameters.length + # The number of non-default parameters + # + # The number of default parameters is then `arity-min_arity`. + # + # Note that there cannot be both varargs and default prameters, thus + # if `vararg_rank != -1` then `min_arity` == `arity` + fun min_arity: Int + do + if vararg_rank != -1 then return arity + var res = 0 + for p in mparameters do + if not p.is_default then res += 1 + end + return res + end + redef fun to_s do var b = new FlatBuffer @@ -1716,6 +1870,9 @@ class MParameter # Is the parameter a vararg? var is_vararg: Bool + # Is the parameter a default one? + var is_default: Bool + redef fun to_s do if is_vararg then @@ -1731,7 +1888,7 @@ class MParameter do if not self.mtype.need_anchor then return self var newtype = self.mtype.resolve_for(mtype, anchor, mmodule, cleanup_virtual) - var res = new MParameter(self.name, newtype, self.is_vararg) + var res = new MParameter(self.name, newtype, self.is_vararg, self.is_default) return res end @@ -1819,7 +1976,7 @@ abstract class MProperty fun lookup_definitions(mmodule: MModule, mtype: MType): Array[MPROPDEF] do assert not mtype.need_anchor - mtype = mtype.as_notnullable + mtype = mtype.undecorate var cache = self.lookup_definitions_cache[mmodule, mtype] if cache != null then return cache @@ -1859,7 +2016,7 @@ abstract class MProperty fun lookup_super_definitions(mmodule: MModule, mtype: MType): Array[MPROPDEF] do assert not mtype.need_anchor - mtype = mtype.as_notnullable + mtype = mtype.undecorate # First, select all candidates var candidates = new Array[MPROPDEF] @@ -1937,7 +2094,7 @@ abstract class MProperty # REQUIRE: `mtype.has_mproperty(mmodule, self)` fun lookup_all_definitions(mmodule: MModule, mtype: MType): Array[MPROPDEF] do - mtype = mtype.as_notnullable + mtype = mtype.undecorate var cache = self.lookup_all_definitions_cache[mmodule, mtype] if cache != null then return cache @@ -1999,6 +2156,10 @@ class MMethod do return self.is_init end + + # A specific method that is safe to call on null. + # Currently, only `==`, `!=` and `is_same_instance` are safe + fun is_null_safe: Bool do return name == "==" or name == "!=" or name == "is_same_instance" end # A global attribute