nitc :: MGenericType :: defaultinit
# A type based on a generic class.
# A generic type a just a class with additional formal generic arguments.
class MGenericType
super MClassType
redef var arguments
# TODO: private init because strongly bounded to its mclass. see `mclass.get_mtype`
init
do
assert self.mclass.arity == arguments.length
self.need_anchor = false
for t in arguments do
if t.need_anchor then
self.need_anchor = true
break
end
end
self.to_s = "{mclass}[{arguments.join(", ")}]"
end
# The short-name of the class, then the full-name of each type arguments within brackets.
# Example: `"Map[String, List[Int]]"`
redef var to_s is noinit
# The full-name of the class, then the full-name of each type arguments within brackets.
# Example: `"core::Map[core::String, core::List[core::Int]]"`
redef var full_name is lazy do
var args = new Array[String]
for t in arguments do
args.add t.full_name
end
return "{mclass.full_name}[{args.join(", ")}]"
end
redef var c_name is lazy do
var res = mclass.c_name
# Note: because the arity is known, a prefix notation is enough
for t in arguments do
res += "__"
res += t.c_name
end
return res.to_s
end
redef var need_anchor is noinit
redef fun resolve_for(mtype, anchor, mmodule, cleanup_virtual)
do
if not need_anchor then return self
assert can_resolve_for(mtype, anchor, mmodule)
var types = new Array[MType]
for t in arguments do
types.add(t.resolve_for(mtype, anchor, mmodule, cleanup_virtual))
end
return mclass.get_mtype(types)
end
redef fun can_resolve_for(mtype, anchor, mmodule)
do
if not need_anchor then return true
for t in arguments do
if not t.can_resolve_for(mtype, anchor, mmodule) then return false
end
return true
end
redef fun is_ok
do
for t in arguments do if not t.is_ok then return false
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
var dmax = 0
for a in self.arguments do
var d = a.depth
if d > dmax then dmax = d
end
return dmax + 1
end
redef fun length
do
var res = 1
for a in self.arguments do
res += a.length
end
return res
end
end
src/model/model.nit:1396,1--1503,3