# Generate a Nit "is" for two runtime_variables
fun equal_test(value1, value2: RuntimeVariable): RuntimeVariable do
var res = new_var(compiler.mainmodule.bool_type)
if value2.mtype.is_java_primitive and not value1.mtype.is_java_primitive then
var tmp = value1
value1 = value2
value2 = tmp
end
if value1.mtype.is_java_primitive then
if value2.mtype == value1.mtype then
add("{res} = {value1} == {value2}; /* == with two primitives */")
else if value2.mtype.is_java_primitive then
add("{res} = true; /* incompatible types {value1.mtype} vs. {value2.mtype}*/")
# else if value1.mtype.is_tagged then
# add("{res} = ({value2} != NULL) && ({autobox(value2, value1.mtype)} == {value1});")
else
var rt_name = value1.mtype.as(MClassType).mclass.rt_name
add("{res} = ({value2} != null) && ({value2}.rtclass == {rt_name}.get{rt_name}());")
add("if ({res}) \{")
add("{res} = ({self.autobox(value2, value1.mtype)} == {value1});")
add("\}")
end
return res
end
var maybe_null = true
var test = new Array[String]
var t1 = value1.mcasttype
if t1 isa MNullableType then
test.add("{value1} != null && !{value1}.is_null()")
t1 = t1.mtype
else
maybe_null = false
end
var t2 = value2.mcasttype
if t2 isa MNullableType then
test.add("{value2} != null && !{value2}.is_null()")
t2 = t2.mtype
else
maybe_null = false
end
var incompatible = false
var primitive
if t1.is_java_primitive then
primitive = t1
if t1 == t2 then
# No need to compare class
else if t2.is_java_primitive then
incompatible = true
else if can_be_primitive(value2) then
if t1.is_java_primitive then
self.add("{res} = {value1} == {value2}; /* t1 is primitive and t2 can be */")
return res
end
# if not compiler.modelbuilder.toolcontext.opt_no_tag_primitives.value then
# test.add("(!{extract_tag(value2)})")
# end
test.add("{value1}.rtclass == {value2}.rtclass")
else
incompatible = true
end
else if t2.is_java_primitive then
primitive = t2
if can_be_primitive(value1) then
if t2.is_java_primitive then
self.add("{res} = {value1} == {value2}; /* t2 is primitive and t1 can be */")
return res
end
test.add("{value1}.rtclass == {value2}.rtclass")
else
incompatible = true
end
else
primitive = null
end
if incompatible then
if maybe_null then
self.add("{res} = {value1} == {value2}; /* incompatible types {t1} vs. {t2}; but may be NULL*/")
return res
else
self.add("{res} = false; /* incompatible types {t1} vs. {t2}; cannot be NULL */")
return res
end
end
if primitive != null then
if primitive.is_java_primitive then
self.add("{res} = {value1} == {value2};")
return res
end
test.add("({value1}.value == {value2}.value")
else if can_be_primitive(value1) and can_be_primitive(value2) then
test.add("{value1}.rtclass == {value2}.rtclass")
var s = new Array[String]
for b in compiler.box_kinds do
var rt_name = b.mclass.rt_name
s.add "({value1}.rtclass == {rt_name}.get{rt_name}()) && ({value1}.value.equals({value2}.value))"
if b.mclass.name == "Float" then
s.add "({value1}.rtclass == RTClass_kernel_Float.getRTClass_kernel_Float() && {value1}.rtclass == {value2}.rtclass && Math.abs((double)({value1}.value)) == 0.0 && Math.abs((double)({value2}.value)) == 0.0)"
end
end
if s.is_empty then
self.add("{res} = {value1} == {value2}; /* both can be primitive */")
return res
end
test.add("({s.join(" || ")})")
else
self.add("{res} = {value1} == {value2}; /* no primitives */")
return res
end
self.add("{res} = {value1} == {value2} || ({test.join(" && ")});")
return res
end
src/compiler/java_compiler.nit:965,2--1077,4