Insert additional explicit calls to get the current JNIEnv

This forces declaration of callbacks to Nit. The callbacks will be available in Java but will be used mainly by the FFI itself.

The developer can also customize the JNIEnv used by the FFI by redefining Sys::jni_env.

Property definitions

nitc :: java $ AMethPropdef :: insert_artificial_callbacks
	# Insert additional explicit calls to get the current `JNIEnv`
	#
	# This forces declaration of callbacks to Nit. The callbacks will be available in Java
	# but will be used mainly by the FFI itself.
	#
	# The developer can also customize the JNIEnv used by the FFI by redefining `Sys::jni_env`.
	private fun insert_artificial_callbacks(toolcontext: ToolContext)
	do
		var fcc = foreign_callbacks

		var modelbuilder = toolcontext.modelbuilder
		var mmodule = mpropdef.mclassdef.mmodule

		# We use callbacks from the C FFI since they will be called from generated C
		var c_language_visitor = toolcontext.ffi_language_assignation_phase.as(FFILanguageAssignationPhase).c_language
		if not mmodule.ffi_callbacks.keys.has(c_language_visitor) then
			mmodule.ffi_callbacks[c_language_visitor] = new HashSet[NitniCallback]
		end

		# Pointer::sys
		var pointer_class = modelbuilder.try_get_mclass_by_name(self, mmodule, "Pointer")
		assert pointer_class != null
		var pointer_sys_meth = modelbuilder.try_get_mproperty_by_name2(self, mmodule, pointer_class.mclass_type, "sys")
		assert pointer_sys_meth != null and pointer_sys_meth isa MMethod

		var explicit_call = new MExplicitCall(pointer_class.mclass_type, pointer_sys_meth, mmodule)
		fcc.callbacks.add(explicit_call)
		mmodule.ffi_callbacks[c_language_visitor].add(explicit_call)

		# Sys::jni_env
		var sys_class = modelbuilder.try_get_mclass_by_name(self, mmodule, "Sys")
		assert sys_class != null
		var sys_jni_env_meth = modelbuilder.try_get_mproperty_by_name2(self, mmodule, sys_class.mclass_type, "jni_env")
		if sys_jni_env_meth == null or not sys_jni_env_meth isa MMethod then
			toolcontext.error(self.location, "Java FFI Error: you must import the `java` module when using the FFI with Java")
			return
		end

		explicit_call = new MExplicitCall(sys_class.mclass_type, sys_jni_env_meth, mmodule)
		fcc.callbacks.add(explicit_call)
		mmodule.ffi_callbacks[c_language_visitor].add(explicit_call)

		# Sys::load_jclass
		var sys_jni_load_jclass_meth = modelbuilder.try_get_mproperty_by_name2(self, mmodule, sys_class.mclass_type, "load_jclass")
		assert sys_jni_load_jclass_meth != null
		assert sys_jni_load_jclass_meth isa MMethod

		explicit_call = new MExplicitCall(sys_class.mclass_type, sys_jni_load_jclass_meth, mmodule)
		fcc.callbacks.add(explicit_call)
		mmodule.ffi_callbacks[c_language_visitor].add(explicit_call)
		explicit_call.fill_type_for(fcc, mmodule)
	end
src/ffi/java.nit:328,2--379,4