Property definitions

nitc :: compiler_ffi $ MExplicitCall :: compile_extern_callback
	private fun compile_extern_callback(v: AbstractCompilerVisitor, ccu: CCompilationUnit, compile_implementation_too: Bool)
	do
		var mproperty = mproperty
		assert mproperty isa MMethod

		# In nitni files, declare internal function as extern
		var full_friendly_csignature = mproperty.build_csignature(recv_mtype, v.compiler.mainmodule, null, long_signature, internal_call_context)
		ccu.header_decl.add("extern {full_friendly_csignature};\n")

		if not compile_implementation_too then return

		# Internally, implement internal function
		var nitni_visitor = v.compiler.new_visitor
		nitni_visitor.frame = v.frame
		var msignature = mproperty.lookup_first_definition(v.compiler.mainmodule, recv_mtype).msignature
		var csignature_blind = mproperty.build_csignature(recv_mtype, v.compiler.mainmodule, null, long_signature, internal_call_context)

		nitni_visitor.add_decl("/* nitni callback for {mproperty.full_name} */")
		nitni_visitor.add_decl("{csignature_blind} \{")

		var vars = new Array[RuntimeVariable]
		var mtype: MType = recv_mtype
		var recv_var = null
		if mproperty.is_init then
			var recv_mtype = recv_mtype
			recv_var = nitni_visitor.init_instance_or_extern(recv_mtype)
			nitni_visitor.add("{mtype.ctype} self /* var self: {mtype} */;")
			nitni_visitor.add("self = {recv_var};")
		else
			mtype = mtype.anchor_to(v.compiler.mainmodule, recv_mtype)
			recv_var = nitni_visitor.var_from_c("self", mtype)
			recv_var = nitni_visitor.box_extern(recv_var, mtype)
		end

		vars.add(recv_var)

		for p in msignature.mparameters do
			var arg_mtype = p.mtype.anchor_to(v.compiler.mainmodule, recv_mtype)
			var arg = nitni_visitor.var_from_c(p.name, arg_mtype)
			arg = nitni_visitor.box_extern(arg, arg_mtype)
			vars.add(arg)
		end

		var ret_var = nitni_visitor.send(mproperty, vars)

		var return_mtype = msignature.return_mtype
		if mproperty.is_init then
			if recv_mtype.mclass.kind != extern_kind then ret_var = recv_var
			return_mtype = recv_mtype
		end
		if return_mtype != null then
			assert ret_var != null
			return_mtype = return_mtype.anchor_to(v.compiler.mainmodule, recv_mtype)
			ret_var = nitni_visitor.autobox(ret_var, return_mtype)
			ret_var = nitni_visitor.unbox_extern(ret_var, return_mtype)
			nitni_visitor.ret_to_c(ret_var, return_mtype)
		end
		nitni_visitor.add("\}")
	end
src/compiler/compiler_ffi/compiler_ffi.nit:84,2--142,4