# Warning: the introduction is the first `MClassDef' object associated
# to self. If self is just created without having any associated
# definition, this method will abort
- private fun intro: MClassDef
+ fun intro: MClassDef
do
assert has_a_first_definition: not mclassdefs.is_empty
return mclassdefs.first
if not sup isa MGenericType then return true
var sub2 = sub.supertype_to(mmodule, anchor, sup.mclass)
assert sub2.mclass == sup.mclass
- assert sub2 isa MGenericType
for i in [0..sup.mclass.arity[ do
var sub_arg = sub2.arguments[i]
var sup_arg = sup.arguments[i]
private var as_nullable_cache: nullable MType = null
+
+ # The deph of the type seen as a tree.
+ #
+ # A -> 1
+ # G[A] -> 2
+ # H[A, B] -> 2
+ # H[G[A], B] -> 3
+ #
+ # Formal types have a depth of 1.
+ fun depth: Int
+ do
+ return 1
+ end
+
# Compute all the classdefs inherited/imported.
# The returned set contains:
# * the class definitions from `mmodule` and its imported modules
self.mclass = mclass
end
+ # The formal arguments of the type
+ # ENSURE: return.length == self.mclass.arity
+ var arguments: Array[MType] = new Array[MType]
+
redef fun to_s do return mclass.to_s
redef fun need_anchor do return false
end
end
- # The formal arguments of the type
- # ENSURE: return.length == self.mclass.arity
- var arguments: Array[MType]
-
# Recursively print the type of the arguments within brackets.
- # Example: "Map[String,List[Int]]"
+ # Example: "Map[String, List[Int]]"
redef fun to_s
do
- return "{mclass}[{arguments.join(",")}]"
+ return "{mclass}[{arguments.join(", ")}]"
end
redef var need_anchor: Bool
end
return mclass.get_mtype(types)
end
+
+ redef fun depth
+ do
+ var dmax = 0
+ for a in self.arguments do
+ var d = a.depth
+ if d > dmax then dmax = d
+ end
+ return dmax + 1
+ end
end
# A virtual formal type.
if t.mclass == goalclass then
# Yeah! c specialize goalclass with a "super `t'". So the question is what is the argument of f
# FIXME: Here, we stop on the first goal. Should we check others and detect inconsistencies?
- assert t isa MGenericType
var res = t.arguments[self.rank]
return res
end
if resolved_receiver isa MNullableType then resolved_receiver = resolved_receiver.mtype
if resolved_receiver isa MParameterType then
assert resolved_receiver.mclass == anchor.mclass
- resolved_receiver = anchor.as(MGenericType).arguments[resolved_receiver.rank]
+ resolved_receiver = anchor.arguments[resolved_receiver.rank]
if resolved_receiver isa MNullableType then resolved_receiver = resolved_receiver.mtype
end
assert resolved_receiver isa MClassType else print "{class_name}: {self}/{mtype}/{anchor}? {resolved_receiver}"
# Eh! The parameter is in the current class.
# So we return the corresponding argument, no mater what!
if resolved_receiver.mclass == self.mclass then
- assert resolved_receiver isa MGenericType
var res = resolved_receiver.arguments[self.rank]
#print "{class_name}: {self}/{mtype}/{anchor} -> direct {res}"
return res
return res.as_nullable
end
+ redef fun depth do return self.mtype.depth
+
redef fun collect_mclassdefs(mmodule)
do
assert not self.need_anchor
# The return type (null for a procedure)
var return_mtype: nullable MType
+ redef fun depth
+ do
+ var dmax = 0
+ var t = self.return_mtype
+ if t != null then dmax = t.depth
+ for p in mparameters do
+ var d = p.mtype.depth
+ if d > dmax then dmax = d
+ end
+ for p in mclosures do
+ var d = p.mtype.depth
+ if d > dmax then dmax = d
+ end
+ return dmax + 1
+ end
+
# REQUIRE: 1 <= mparameters.count p -> p.is_vararg
init(mparameters: Array[MParameter], return_mtype: nullable MType)
do