# Common method used when static cast test is seen by a phase
fun count_cast(node: ANode, sub, sup: MType, mmodule: MModule, anchor: nullable MClassType)
do
var nsup = sup
sup = sup.undecorate
sub = sub.undecorate
if sub == nsup then
cpt_cast_pattern.inc("monomorphic cast!?!")
node.debug("monomorphic cast {sup} to {sub}")
else if not sub isa MClassType then
cpt_cast_pattern.inc("cast to formal")
else if not sub isa MGenericType then
cpt_cast_pattern.inc("cast to non-generic")
else if sub == sup then
cpt_cast_pattern.inc("nonullable monomorphic cast")
else if sup.is_subtype(mmodule, anchor, sub) then
cpt_cast_pattern.inc("upcast to generic")
else if not sub.is_subtype(mmodule, anchor, sup) then
cpt_cast_pattern.inc("lateral cast to generic")
else if not sub.is_subtype_invar(mmodule, anchor, sup) then
assert sup isa MGenericType
if sup.mclass != sub.mclass then
cpt_cast_pattern.inc("covariant downcast to a generic (distinct classes)")
else
cpt_cast_pattern.inc("covariant downcast to a generic (same classes)")
end
else if not sup isa MGenericType then
cpt_cast_pattern.inc("invariant downcast from non-generic to a generic")
else
assert sup.mclass != sub.mclass
cpt_cast_pattern.inc("invariant downcast from generic to generic")
end
cpt_cast_kind.inc(sub.class_name.to_s)
if sub isa MGenericType then
cpt_cast_classes.inc(sub.mclass.to_s)
else if sub isa MClassType then
# No generic class, so no covariance at runtime
else
cpt_cast_classes.inc(sub.to_s)
end
end
src/metrics/detect_covariance.nit:253,2--296,4