Generate a polymorphic attribute read

Property definitions

nitc $ AbstractCompilerVisitor :: read_attribute
	# Generate a polymorphic attribute read
	fun read_attribute(a: MAttribute, recv: RuntimeVariable): RuntimeVariable is abstract
src/compiler/abstract_compiler.nit:1536,2--1537,86

nitc $ SeparateCompilerVisitor :: read_attribute
	redef fun read_attribute(a, recv)
	do
		self.check_recv_notnull(recv)

		# What is the declared type of the attribute?
		var ret = a.intro.static_mtype.as(not null)
		var intromclassdef = a.intro.mclassdef
		ret = ret.resolve_for(intromclassdef.bound_mtype, intromclassdef.bound_mtype, intromclassdef.mmodule, true)

		if self.compiler.modelbuilder.toolcontext.opt_isset_checks_metrics.value then
			self.compiler.attr_read_count += 1
			self.add("count_attr_reads++;")
		end

		self.require_declaration(a.const_color)
		if self.compiler.modelbuilder.toolcontext.opt_no_union_attribute.value then
			# Get the attribute or a box (ie. always a val*)
			var cret = self.object_type.as_nullable
			var res = self.new_var(cret)
			res.mcasttype = ret

			self.add("{res} = {recv}->attrs[{a.const_color}]; /* {a} on {recv.inspect} */")

			# Check for Uninitialized attribute
			if not ret isa MNullableType and not self.compiler.modelbuilder.toolcontext.opt_no_check_attr_isset.value then
				self.add("if (unlikely({res} == NULL)) \{")
				self.add_abort("Uninitialized attribute {a.name}")
				self.add("\}")

				if self.compiler.modelbuilder.toolcontext.opt_isset_checks_metrics.value then
					self.compiler.isset_checks_count += 1
					self.add("count_isset_checks++;")
				end
			end

			# Return the attribute or its unboxed version
			# Note: it is mandatory since we reuse the box on write, we do not whant that the box escapes
			return self.autobox(res, ret)
		else
			var res = self.new_var(ret)
			self.add("{res} = {recv}->attrs[{a.const_color}].{ret.ctypename}; /* {a} on {recv.inspect} */")

			# Check for Uninitialized attribute
			if not ret.is_c_primitive and not ret isa MNullableType and not self.compiler.modelbuilder.toolcontext.opt_no_check_attr_isset.value then
				self.add("if (unlikely({res} == NULL)) \{")
				self.add_abort("Uninitialized attribute {a.name}")
				self.add("\}")
				if self.compiler.modelbuilder.toolcontext.opt_isset_checks_metrics.value then
					self.compiler.isset_checks_count += 1
					self.add("count_isset_checks++;")
				end
			end

			return res
		end
	end
src/compiler/separate_compiler.nit:1720,2--1775,4