# Generate a polymorphic attribute is_set test
fun isset_attribute(a: MAttribute, recv: RuntimeVariable): RuntimeVariable is abstract
src/compiler/abstract_compiler.nit:1532,2--1533,87
redef fun isset_attribute(a, recv)
do
self.check_recv_notnull(recv)
var res = self.new_var(bool_type)
# What is the declared type of the attribute?
var mtype = a.intro.static_mtype.as(not null)
var intromclassdef = a.intro.mclassdef
mtype = mtype.resolve_for(intromclassdef.bound_mtype, intromclassdef.bound_mtype, intromclassdef.mmodule, true)
if mtype isa MNullableType then
self.add("{res} = 1; /* easy isset: {a} on {recv.inspect} */")
return res
end
self.require_declaration(a.const_color)
if self.compiler.modelbuilder.toolcontext.opt_no_union_attribute.value then
self.add("{res} = {recv}->attrs[{a.const_color}] != NULL; /* {a} on {recv.inspect}*/")
else
if not mtype.is_c_primitive and not mtype.is_tagged then
self.add("{res} = {recv}->attrs[{a.const_color}].val != NULL; /* {a} on {recv.inspect} */")
else
self.add("{res} = 1; /* NOT YET IMPLEMENTED: isset of primitives: {a} on {recv.inspect} */")
end
end
return res
end
src/compiler/separate_compiler.nit:1691,2--1718,4
redef fun isset_attribute(a, recv)
do
check_recv_notnull(recv)
var types = self.collect_types(recv)
var res = self.new_var(bool_type)
if types.is_empty then
self.add("/*BUG: no live types for {recv.inspect} . {a}*/")
self.bugtype(recv)
return res
end
self.add("/* isset {a} on {recv.inspect} */")
self.add("switch({recv}->classid) \{")
var last = types.last
for t in types do
if not self.compiler.hardening and t == last then
self.add("default: /*{self.compiler.classid(t)}*/")
else
self.add("case {self.compiler.classid(t)}:")
end
var recv2 = self.autoadapt(recv, t)
var ta = a.intro.static_mtype.as(not null)
ta = self.resolve_for(ta, recv2)
var attr = self.new_expr("((struct {t.c_name}*){recv})->{a.intro.c_name}", ta)
if not ta isa MNullableType then
if not ta.is_c_primitive then
self.add("{res} = ({attr} != NULL);")
else
self.add("{res} = 1; /*NOTYET isset on primitive attributes*/")
end
end
self.add("break;")
end
if self.compiler.hardening then
self.add("default: /* Bug */")
self.bugtype(recv)
end
self.add("\}")
return res
end
src/compiler/global_compiler.nit:735,2--776,4