Generate a Nit "is" for two runtime_variables

Property definitions

nitc $ JavaCompilerVisitor :: equal_test
	#  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