From: Jean Privat Date: Thu, 13 Jun 2019 14:14:24 +0000 (-0400) Subject: Merge: Some more small improvements on gitlab-ci X-Git-Url: http://nitlanguage.org?hp=61e9c7897630bfe23a2bf6c2a02803c1fc8dd51d Merge: Some more small improvements on gitlab-ci Pull-Request: #2744 --- diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 696b258..70b91e1 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -51,7 +51,7 @@ sanity_checks: - misc/jenkins/checksignedoffby.sh | tee -a status.txt - misc/jenkins/checklicense.sh | tee -a status.txt -build_tools: +build_tools: &build_tools stage: build script: - make 2>> status.txt @@ -65,7 +65,7 @@ build_tools: - src/nitc_0 when: always -test_some: +test_some: &test_some stage: test dependencies: - build_tools @@ -120,11 +120,12 @@ basic_android: # TEST FULL ######################################################### -test_full_nitcs: +test_full_nitcs: &test_full_nitcs stage: more_test dependencies: - build_tools script: + - share/android-bdwgc/setup.sh - cd tests - ./testfull.sh | tee log.txt - grep -v '=>' log.txt > ../status.txt || true @@ -384,11 +385,21 @@ build_catalog: paths: - catalog.out -.test_macos: - script: - - uname - - pwd - - ls / - stage: build +build_tools_macos: + <<: *build_tools + tags: + - macos + +test_some_macos: + <<: *test_some tags: - macos + dependencies: + - build_tools_macos + +test_full_nitcs_macos: + <<: *test_full_nitcs + tags: + - macos + dependencies: + - build_tools_macos diff --git a/contrib/benitlux/src/client/android.nit b/contrib/benitlux/src/client/android.nit index ee51327..3495f6c 100644 --- a/contrib/benitlux/src/client/android.nit +++ b/contrib/benitlux/src/client/android.nit @@ -52,7 +52,7 @@ redef class App android.content.IntentFilter filter = new android.content.IntentFilter(); filter.addAction(android.net.wifi.WifiManager.SCAN_RESULTS_AVAILABLE_ACTION); - final int final_self = self; + final nit.app.NitObject final_self = self; App_incr_ref(final_self); context.registerReceiver( @@ -197,7 +197,7 @@ redef class BeerView final String final_title = title; final boolean final_loggedin = loggedin; - final int final_self = self; + final nit.app.NitObject final_self = self; BeerView_incr_ref(self); // Nit GC view.setOnTouchListener(new android.view.View.OnTouchListener() { diff --git a/lib/android/NitActivity.java b/lib/android/NitActivity.java index 2f712f1..ca15d38 100644 --- a/lib/android/NitActivity.java +++ b/lib/android/NitActivity.java @@ -25,7 +25,7 @@ import android.view.KeyEvent; public class NitActivity extends Activity { // Nit activity associated to `this` - protected int nitActivity = 0; + protected long nitActivity = 0; /* * Calls to Nit or to the C framework @@ -38,21 +38,21 @@ public class NitActivity extends Activity { /* * Callbacks to Nit through C */ - protected native int nitRegisterActivity(); - protected native void nitOnCreate(int activity, Bundle savedInstanceState); - protected native void nitOnStart(int activity); - protected native void nitOnRestart(int activity); - protected native void nitOnResume(int activity); - protected native void nitOnPause(int activity); - protected native void nitOnStop(int activity); - protected native void nitOnDestroy(int activity); - protected native void nitOnSaveInstanceState(int activity, Bundle savedInstanceState); - protected native void nitOnRestoreInstanceState(int activity, Bundle savedInstanceState); - protected native boolean nitOnBackPressed(int activity); - protected native boolean nitOnKeyDown(int activity, int keyCode, KeyEvent event); - protected native boolean nitOnKeyLongPress(int activity, int keyCode, KeyEvent event); - protected native boolean nitOnKeyMultiple(int activity, int keyCode, int count, KeyEvent event); - protected native boolean nitOnKeyUp(int activity, int keyCode, KeyEvent event); + protected native long nitRegisterActivity(); + protected native void nitOnCreate(long activity, Bundle savedInstanceState); + protected native void nitOnStart(long activity); + protected native void nitOnRestart(long activity); + protected native void nitOnResume(long activity); + protected native void nitOnPause(long activity); + protected native void nitOnStop(long activity); + protected native void nitOnDestroy(long activity); + protected native void nitOnSaveInstanceState(long activity, Bundle savedInstanceState); + protected native void nitOnRestoreInstanceState(long activity, Bundle savedInstanceState); + protected native boolean nitOnBackPressed(long activity); + protected native boolean nitOnKeyDown(long activity, int keyCode, KeyEvent event); + protected native boolean nitOnKeyLongPress(long activity, int keyCode, KeyEvent event); + protected native boolean nitOnKeyMultiple(long activity, int keyCode, int count, KeyEvent event); + protected native boolean nitOnKeyUp(long activity, int keyCode, KeyEvent event); /* * Implementation of OS callbacks diff --git a/lib/android/activities.nit b/lib/android/activities.nit index a457899..76e3f07 100644 --- a/lib/android/activities.nit +++ b/lib/android/activities.nit @@ -43,7 +43,7 @@ extern class NativeActivity in "Java" `{ android.app.Activity `} # Execute `task.main` on the UI thread when possible fun run_on_ui_thread(task: Task) import Task.main in "Java" `{ - final int final_task = task; + final nit.app.NitObject final_task = task; Runnable runnable = new Runnable() { @Override public void run() { diff --git a/lib/android/assets_and_resources.nit b/lib/android/assets_and_resources.nit index 930bc17..2ca56d4 100644 --- a/lib/android/assets_and_resources.nit +++ b/lib/android/assets_and_resources.nit @@ -52,7 +52,7 @@ private extern class NativeAssetManager in "Java" `{ android.content.res.AssetMa # Get the locales that this assets manager contains data for fun get_locales: Array[JavaString] import Array[JavaString], Array[JavaString].add in "Java" `{ - int arr = new_Array_of_JavaString(); + nit.app.NitObject arr = new_Array_of_JavaString(); for (String s : self.getLocales()) { Array_of_JavaString_add(arr, s); } @@ -61,7 +61,7 @@ private extern class NativeAssetManager in "Java" `{ android.content.res.AssetMa # String Array of all the assets at the given path fun list(path: JavaString): Array[JavaString] import Array[JavaString], Array[JavaString].add in "Java" `{ - int arr = new_Array_of_JavaString(); + nit.app.NitObject arr = new_Array_of_JavaString(); try { for (String s : self.list(path)) { Array_of_JavaString_add(arr, s); diff --git a/lib/android/bundle/bundle.nit b/lib/android/bundle/bundle.nit index e02702a..521355f 100644 --- a/lib/android/bundle/bundle.nit +++ b/lib/android/bundle/bundle.nit @@ -29,6 +29,7 @@ in "Java" `{ import android.app.Activity; import java.util.ArrayList; import java.util.Set; + import nit.app.NitObject; `} extern class NativeBundle in "Java" `{ android.os.Bundle `} @@ -44,10 +45,10 @@ extern class NativeBundle in "Java" `{ android.os.Bundle `} fun get(key: JavaString): JavaObject in "Java" `{ return self.get(key); `} fun remove(key: JavaString) in "Java" `{ self.remove(key); `} fun put_all(bundle: NativeBundle) in "Java" `{ self.putAll(bundle); `} - fun key_set: HashSet[JavaString] import HashSet[JavaString], - HashSet[JavaString].add in "Java" `{ + fun key_set: HashSet[JavaString] import HashSet[JavaString], + HashSet[JavaString].add in "Java" `{ Set java_set = self.keySet(); - int nit_hashset = new_HashSet_of_JavaString(); + NitObject nit_hashset = new_HashSet_of_JavaString(); for (String element: java_set) HashSet_of_JavaString_add(nit_hashset, element); @@ -257,7 +258,7 @@ extern class NativeBundle in "Java" `{ android.os.Bundle `} fun get_integer_array_list(key: JavaString): Array[Int] import Array[Int], Array[Int].add in "Java" `{ ArrayList java_array = self.getIntegerArrayList(key); - int nit_array = new_Array_of_Int(); + NitObject nit_array = new_Array_of_Int(); if (java_array == null) return nit_array; @@ -269,7 +270,7 @@ extern class NativeBundle in "Java" `{ android.os.Bundle `} fun get_string_array_list(key: JavaString): Array[String] import StringCopyArray, StringCopyArray.add, StringCopyArray.collection in "Java" `{ ArrayList java_array = self.getStringArrayList(key); - int nit_array = new_StringCopyArray(); + NitObject nit_array = new_StringCopyArray(); if (java_array == null) return nit_array; @@ -281,7 +282,7 @@ extern class NativeBundle in "Java" `{ android.os.Bundle `} fun get_char_sequence_array_list(key: JavaString): Array[String] import StringCopyArray, StringCopyArray.add, StringCopyArray.collection in "Java" `{ ArrayList java_array = self.getCharSequenceArrayList(key); - int nit_array = new_StringCopyArray(); + NitObject nit_array = new_StringCopyArray(); if (java_array == null) return nit_array; @@ -293,7 +294,7 @@ extern class NativeBundle in "Java" `{ android.os.Bundle `} fun get_boolean_array(key: JavaString): Array[Bool] import Array[Bool], Array[Bool].add in "Java" `{ boolean[] java_array = self.getBooleanArray(key); - int nit_array = new_Array_of_Bool(); + NitObject nit_array = new_Array_of_Bool(); if (java_array == null) return nit_array; @@ -305,7 +306,7 @@ extern class NativeBundle in "Java" `{ android.os.Bundle `} fun get_byte_array(key: JavaString): Array[Int] import Array[Int], Array[Int].add in "Java" `{ byte[] java_array = self.getByteArray(key); - int nit_array = new_Array_of_Int(); + NitObject nit_array = new_Array_of_Int(); if (java_array == null) return nit_array; @@ -317,7 +318,7 @@ extern class NativeBundle in "Java" `{ android.os.Bundle `} fun get_short_array(key: JavaString): Array[Int] import Array[Int], Array[Int].add in "Java" `{ short[] java_array = self.getShortArray(key); - int nit_array = new_Array_of_Int(); + NitObject nit_array = new_Array_of_Int(); if (java_array == null) return nit_array; @@ -330,7 +331,7 @@ extern class NativeBundle in "Java" `{ android.os.Bundle `} fun get_char_array(key: JavaString): Array[Char] import Array[Char], Array[Char].add in "Java" `{ char[] java_array = self.getCharArray(key); - int nit_array = new_Array_of_Char(); + NitObject nit_array = new_Array_of_Char(); if (java_array == null) return nit_array; @@ -342,7 +343,7 @@ extern class NativeBundle in "Java" `{ android.os.Bundle `} fun get_int_array(key: JavaString): Array[Int] import Array[Int], Array[Int].add in "Java" `{ int[] java_array = self.getIntArray(key); - int nit_array = new_Array_of_Int(); + NitObject nit_array = new_Array_of_Int(); if (java_array == null) return nit_array; @@ -355,7 +356,7 @@ extern class NativeBundle in "Java" `{ android.os.Bundle `} fun get_long_array(key: JavaString): Array[Int] import Array[Int], Array[Int].add in "Java" `{ long[] java_array = self.getLongArray(key); - int nit_array = new_Array_of_Int(); + NitObject nit_array = new_Array_of_Int(); if (java_array == null) return nit_array; @@ -367,7 +368,7 @@ extern class NativeBundle in "Java" `{ android.os.Bundle `} fun get_float_array(key: JavaString): Array[Float] import Array[Float], Array[Float].add in "Java" `{ float[] java_array = self.getFloatArray(key); - int nit_array = new_Array_of_Float(); + NitObject nit_array = new_Array_of_Float(); if (java_array == null) return nit_array; @@ -379,7 +380,7 @@ extern class NativeBundle in "Java" `{ android.os.Bundle `} fun get_double_array(key: JavaString): Array[Float] import Array[Float], Array[Float].add in "Java" `{ double[] java_array = self.getDoubleArray(key); - int nit_array = new_Array_of_Float(); + NitObject nit_array = new_Array_of_Float(); if (java_array == null) return nit_array; @@ -391,7 +392,7 @@ extern class NativeBundle in "Java" `{ android.os.Bundle `} fun get_string_array(key: JavaString): Array[String] import StringCopyArray, StringCopyArray.add, StringCopyArray.collection in "Java" `{ String[] java_array = self.getStringArray(key); - int nit_array = new_StringCopyArray(); + NitObject nit_array = new_StringCopyArray(); if (java_array == null) return nit_array; @@ -403,7 +404,7 @@ extern class NativeBundle in "Java" `{ android.os.Bundle `} fun get_char_sequence_array(key: JavaString): Array[String] import StringCopyArray, StringCopyArray.add, StringCopyArray.collection in "Java" `{ CharSequence[] java_array = self.getCharSequenceArray(key); - int nit_array = new_StringCopyArray(); + NitObject nit_array = new_StringCopyArray(); if (java_array == null) return nit_array; diff --git a/lib/android/intent/intent_api10.nit b/lib/android/intent/intent_api10.nit index f9e6c3b..1c05f89 100644 --- a/lib/android/intent/intent_api10.nit +++ b/lib/android/intent/intent_api10.nit @@ -29,6 +29,7 @@ in "Java" `{ import android.graphics.Rect; import java.util.Set; import java.util.ArrayList; + import nit.app.NitObject; `} extern class NativeIntent in "Java" `{ android.content.Intent `} @@ -45,7 +46,7 @@ extern class NativeIntent in "Java" `{ android.content.Intent `} fun boolean_array_extra(name: JavaString): Array[Bool] import Array[Bool], Array[Bool].push in "Java" `{ boolean[] java_array = self.getBooleanArrayExtra(name); - int nit_array = new_Array_of_Bool(); + NitObject nit_array = new_Array_of_Bool(); for(int i=0; i < java_array.length; ++i) Array_of_Bool_push(nit_array, java_array[i]); @@ -58,7 +59,7 @@ extern class NativeIntent in "Java" `{ android.content.Intent `} fun byte_array_extra(name: JavaString): Array[Int] import Array[Int], Array[Int].add in "Java" `{ byte[] java_array = self.getByteArrayExtra(name); - int nit_array = new_Array_of_Int(); + NitObject nit_array = new_Array_of_Int(); for (int i=0; i < java_array.length; ++i) Array_of_Int_add(nit_array, java_array[i]); @@ -72,7 +73,7 @@ extern class NativeIntent in "Java" `{ android.content.Intent `} fun char_array_extra(name: JavaString): Array[Char] import Array[Char], Array[Char].add in "Java" `{ char[] java_array = self.getCharArrayExtra(name); - int nit_array = new_Array_of_Char(); + NitObject nit_array = new_Array_of_Char(); for (int i = 0; i < java_array.length; ++i) Array_of_Char_add(nit_array, java_array[i]); @@ -86,7 +87,7 @@ extern class NativeIntent in "Java" `{ android.content.Intent `} fun char_sequence_array_extra(name: JavaString): Array[String] import StringCopyArray, StringCopyArray.add, StringCopyArray.collection in "Java" `{ CharSequence[] java_array = self.getCharSequenceArrayExtra(name); - int nit_array = new_StringCopyArray(); + NitObject nit_array = new_StringCopyArray(); for (int i = 0; i < java_array.length; ++i) StringCopyArray_add(nit_array, (String) java_array[i]); @@ -96,7 +97,7 @@ extern class NativeIntent in "Java" `{ android.content.Intent `} fun char_sequence_array_list_extra(name: JavaString): Array[String] import StringCopyArray, StringCopyArray.add, StringCopyArray.collection in "Java" `{ ArrayList java_array = self.getCharSequenceArrayListExtra(name); - int nit_array = new_StringCopyArray(); + NitObject nit_array = new_StringCopyArray(); if (java_array == null) return nit_array; @@ -111,7 +112,7 @@ extern class NativeIntent in "Java" `{ android.content.Intent `} fun categories: HashSet[String] import StringCopyHashSet, StringCopyHashSet.add, StringCopyHashSet.collection in "Java" `{ Set java_set = self.getCategories(); - int nit_hashset = new_StringCopyHashSet(); + NitObject nit_hashset = new_StringCopyHashSet(); if (java_set == null) return nit_hashset; @@ -125,7 +126,7 @@ extern class NativeIntent in "Java" `{ android.content.Intent `} fun double_array_extra(name: JavaString): Array[Float] import Array[Float], Array[Float].push in "Java" `{ double[] java_array = self.getDoubleArrayExtra(name); - int nit_array = new_Array_of_Float(); + NitObject nit_array = new_Array_of_Float(); for(int i=0; i < java_array.length; ++i) Array_of_Float_push(nit_array, java_array[i]); @@ -139,7 +140,7 @@ extern class NativeIntent in "Java" `{ android.content.Intent `} fun float_array_extra(name: JavaString): Array[Float] import Array[Float], Array[Float].push in "Java" `{ float[] java_array = self.getFloatArrayExtra(name); - int nit_array = new_Array_of_Float(); + NitObject nit_array = new_Array_of_Float(); for(int i=0; i < java_array.length; ++i) Array_of_Float_push(nit_array, java_array[i]); @@ -152,7 +153,7 @@ extern class NativeIntent in "Java" `{ android.content.Intent `} fun int_array_extra(name: JavaString): Array[Int] import Array[Int], Array[Int].push in "Java" `{ int[] java_array = self.getIntArrayExtra(name); - int nit_array = new_Array_of_Int(); + NitObject nit_array = new_Array_of_Int(); for(int i=0; i < java_array.length; ++i) Array_of_Int_push(nit_array, java_array[i]); @@ -165,7 +166,7 @@ extern class NativeIntent in "Java" `{ android.content.Intent `} fun long_array_extra(name: JavaString): Array[Int] import Array[Int], Array[Int].push in "Java" `{ long[] java_array = self.getLongArrayExtra(name); - int nit_array = new_Array_of_Int(); + NitObject nit_array = new_Array_of_Int(); for(int i=0; i < java_array.length; ++i) Array_of_Int_push(nit_array, (int) java_array[i]); @@ -180,7 +181,7 @@ extern class NativeIntent in "Java" `{ android.content.Intent `} fun short_array_extra(name: JavaString): Array[Int] import Array[Int], Array[Int].push in "Java" `{ short[] java_array = self.getShortArrayExtra(name); - int nit_array = new_Array_of_Int(); + NitObject nit_array = new_Array_of_Int(); for(int i=0; i < java_array.length; ++i) Array_of_Int_push(nit_array, (int) java_array[i]); @@ -193,7 +194,7 @@ extern class NativeIntent in "Java" `{ android.content.Intent `} fun string_array_extra(name: JavaString): Array[String] import StringCopyArray, StringCopyArray.add, StringCopyArray.collection in "Java" `{ String[] java_array = self.getStringArrayExtra(name); - int nit_array = new_StringCopyArray(); + NitObject nit_array = new_StringCopyArray(); for(int i=0; i < java_array.length; ++i) StringCopyArray_add(nit_array, java_array[i]); @@ -203,7 +204,7 @@ extern class NativeIntent in "Java" `{ android.content.Intent `} fun string_array_list_extra(name: JavaString): Array[String] import StringCopyArray, StringCopyArray.add, StringCopyArray.collection in "Java" `{ ArrayList java_array = self.getStringArrayListExtra(name); - int nit_array = new_StringCopyArray(); + NitObject nit_array = new_StringCopyArray(); for (String element: java_array) StringCopyArray_add(nit_array, element); diff --git a/lib/android/nit_activity.nit b/lib/android/nit_activity.nit index f084958..980270c 100644 --- a/lib/android/nit_activity.nit +++ b/lib/android/nit_activity.nit @@ -36,7 +36,7 @@ # the Java virtual machine. For this reason, the main _must_ execute quickly, # on the main UI thread at least. module nit_activity is - extra_java_files "NitActivity.java" + extra_java_files "nit.app.NitActivity" android_activity "nit.app.NitActivity" end @@ -74,94 +74,94 @@ in "C body" `{ * Implementations of NitActivity.java native methods */ - JNIEXPORT jint JNICALL Java_nit_app_NitActivity_nitRegisterActivity + JNIEXPORT jlong JNICALL Java_nit_app_NitActivity_nitRegisterActivity (JNIEnv *env, jobject java_activity) { Activity nit_activity = App_register_activity(global_app, java_activity); Activity_incr_ref(nit_activity); - return (jint)(void*)nit_activity; + return (jlong)(void*)nit_activity; } JNIEXPORT void JNICALL Java_nit_app_NitActivity_nitOnCreate - (JNIEnv *env, jobject java_activity, jint nit_activity, jobject saved_state) + (JNIEnv *env, jobject java_activity, jlong nit_activity, jobject saved_state) { Activity_on_create((Activity)nit_activity, saved_state); } JNIEXPORT void JNICALL Java_nit_app_NitActivity_nitOnStart - (JNIEnv *env, jobject java_activity, jint nit_activity) + (JNIEnv *env, jobject java_activity, jlong nit_activity) { Activity_on_start((Activity)nit_activity); } JNIEXPORT void JNICALL Java_nit_app_NitActivity_nitOnRestart - (JNIEnv *env, jobject java_activity, jint nit_activity) + (JNIEnv *env, jobject java_activity, jlong nit_activity) { Activity_on_restart((Activity)nit_activity); } JNIEXPORT void JNICALL Java_nit_app_NitActivity_nitOnResume - (JNIEnv *env, jobject java_activity, jint nit_activity) + (JNIEnv *env, jobject java_activity, jlong nit_activity) { Activity_on_resume((Activity)nit_activity); } JNIEXPORT void JNICALL Java_nit_app_NitActivity_nitOnPause - (JNIEnv *env, jobject java_activity, jint nit_activity) + (JNIEnv *env, jobject java_activity, jlong nit_activity) { Activity_on_pause((Activity)nit_activity); } JNIEXPORT void JNICALL Java_nit_app_NitActivity_nitOnStop - (JNIEnv *env, jobject java_activity, jint nit_activity) + (JNIEnv *env, jobject java_activity, jlong nit_activity) { Activity_on_stop((Activity)nit_activity); } JNIEXPORT void JNICALL Java_nit_app_NitActivity_nitOnDestroy - (JNIEnv *env, jobject java_activity, jint nit_activity) + (JNIEnv *env, jobject java_activity, jlong nit_activity) { Activity_on_destroy((Activity)nit_activity); } JNIEXPORT void JNICALL Java_nit_app_NitActivity_nitOnSaveInstanceState - (JNIEnv *env, jobject java_activity, jint nit_activity, jobject saved_state) + (JNIEnv *env, jobject java_activity, jlong nit_activity, jobject saved_state) { Activity_on_save_instance_state((Activity)nit_activity, saved_state); } JNIEXPORT void JNICALL Java_nit_app_NitActivity_nitOnRestoreInstanceState - (JNIEnv *env, jobject java_activity, jint nit_activity, jobject saved_state) + (JNIEnv *env, jobject java_activity, jlong nit_activity, jobject saved_state) { Activity_on_restore_instance_state((Activity)nit_activity, saved_state); } JNIEXPORT jboolean JNICALL Java_nit_app_NitActivity_nitOnBackPressed - (JNIEnv *env, jobject java_activity, jint nit_activity) + (JNIEnv *env, jobject java_activity, jlong nit_activity) { return (jboolean)Activity_on_back_pressed((Activity)nit_activity); } JNIEXPORT jboolean JNICALL Java_nit_app_NitActivity_nitOnKeyDown - (JNIEnv *env, jobject java_activity, jint nit_activity, jint keyCode, jobject event) + (JNIEnv *env, jobject java_activity, jlong nit_activity, jint keyCode, jobject event) { return (jboolean)Activity_on_key_down((Activity)nit_activity, keyCode, event); } JNIEXPORT jboolean JNICALL Java_nit_app_NitActivity_nitOnKeyLongPress - (JNIEnv *env, jobject java_activity, jint nit_activity, jint keyCode, jobject event) + (JNIEnv *env, jobject java_activity, jlong nit_activity, jint keyCode, jobject event) { return (jboolean)Activity_on_key_long_press((Activity)nit_activity, keyCode, event); } JNIEXPORT jboolean JNICALL Java_nit_app_NitActivity_nitOnKeyMultiple - (JNIEnv *env, jobject java_activity, jint nit_activity, jint keyCode, jint count, jobject event) + (JNIEnv *env, jobject java_activity, jlong nit_activity, jint keyCode, jint count, jobject event) { return (jboolean)Activity_on_key_multiple((Activity)nit_activity, keyCode, count, event); } JNIEXPORT jboolean JNICALL Java_nit_app_NitActivity_nitOnKeyUp - (JNIEnv *env, jobject java_activity, jint nit_activity, jint keyCode, jobject event) + (JNIEnv *env, jobject java_activity, jlong nit_activity, jint keyCode, jobject event) { return (jboolean)Activity_on_key_up((Activity)nit_activity, keyCode, event); } diff --git a/lib/android/service/NitService.java b/lib/android/service/NitService.java index b0767d6..fd7e79f 100644 --- a/lib/android/service/NitService.java +++ b/lib/android/service/NitService.java @@ -22,7 +22,7 @@ import android.os.IBinder; // Service implemented in Nit public class NitService extends Service { - protected int nitService = 0; + protected long nitService = 0; static { System.loadLibrary("nit_app"); @@ -51,8 +51,8 @@ public class NitService extends Service { return null; } - protected native int nitNewService(); - protected native int nitOnStartCommand(int nitService, Intent intent, int flags, int id); - protected native void nitOnCreate(int nitService); - protected native void nitOnDestroy(int nitService); + protected native long nitNewService(); + protected native int nitOnStartCommand(long nitService, Intent intent, int flags, int id); + protected native void nitOnCreate(long nitService); + protected native void nitOnDestroy(long nitService); } diff --git a/lib/android/service/at_boot.nit b/lib/android/service/at_boot.nit index a2c1868..9669fe7 100644 --- a/lib/android/service/at_boot.nit +++ b/lib/android/service/at_boot.nit @@ -14,7 +14,7 @@ # Import this module to launch `Service` at device boot module at_boot is - extra_java_files "NitBroadcastReceiver.java" + extra_java_files "nit.app.NitBroadcastReceiver" android_manifest """ """ diff --git a/lib/android/service/service.nit b/lib/android/service/service.nit index 901a0e2..823d16e 100644 --- a/lib/android/service/service.nit +++ b/lib/android/service/service.nit @@ -14,7 +14,7 @@ # Android service support for _app.nit_ centered around the class `Service` module service is - extra_java_files "NitService.java" + extra_java_files "nit.app.NitService" android_manifest_application """""" end @@ -24,7 +24,7 @@ in "C" `{ // Nit's App running instance, declared in `nit_activity` extern App global_app; - JNIEXPORT jint JNICALL Java_nit_app_NitService_nitNewService + JNIEXPORT jlong JNICALL Java_nit_app_NitService_nitNewService (JNIEnv *env, jobject java_service) { // Pin a ref to the Java service in the Java GC @@ -39,23 +39,23 @@ in "C" `{ Service_incr_ref(nit_service); - return (jint)(void*)nit_service; + return (jlong)(void*)nit_service; } JNIEXPORT jint JNICALL Java_nit_app_NitService_nitOnStartCommand - (JNIEnv *env, jobject java_service, jint nit_service, jobject intent, jint flags, jint id) + (JNIEnv *env, jobject java_service, jlong nit_service, jobject intent, jint flags, jint id) { return Service_on_start_command((Service)nit_service, intent, flags, id); } JNIEXPORT void JNICALL Java_nit_app_NitService_nitOnCreate - (JNIEnv *env, jobject java_service, jint nit_service) + (JNIEnv *env, jobject java_service, jlong nit_service) { Service_on_create((Service)nit_service); } JNIEXPORT void JNICALL Java_nit_app_NitService_nitOnDestroy - (JNIEnv *env, jobject java_service, jint nit_service) + (JNIEnv *env, jobject java_service, jlong nit_service) { Service_on_destroy((Service)nit_service); diff --git a/lib/android/shared_preferences/shared_preferences_api10.nit b/lib/android/shared_preferences/shared_preferences_api10.nit index 0464b67..f012ed2 100644 --- a/lib/android/shared_preferences/shared_preferences_api10.nit +++ b/lib/android/shared_preferences/shared_preferences_api10.nit @@ -38,7 +38,7 @@ extern class NativeSharedPreferences in "Java" `{ android.content.SharedPreferen fun get_all: HashMap[JavaString, JavaObject] import HashMap[JavaString, JavaObject], HashMap[JavaString, JavaObject].[]= in "Java" `{ Map java_map = null; - int nit_hashmap = new_HashMap_of_JavaString_JavaObject(); + nit.app.NitObject nit_hashmap = new_HashMap_of_JavaString_JavaObject(); try { java_map = self.getAll(); } catch (NullPointerException e) { diff --git a/lib/android/shared_preferences/shared_preferences_api11.nit b/lib/android/shared_preferences/shared_preferences_api11.nit index 85623d8..9d2dbcf 100644 --- a/lib/android/shared_preferences/shared_preferences_api11.nit +++ b/lib/android/shared_preferences/shared_preferences_api11.nit @@ -32,7 +32,7 @@ redef extern class NativeSharedPreferences HashSet[JavaString].add in "Java" `{ Set def_value = new HashSet(); Set java_set = self.getStringSet(key, def_value); - int nit_hashset = new_HashSet_of_JavaString(); + nit.app.NitObject nit_hashset = new_HashSet_of_JavaString(); for (String element: java_set) HashSet_of_JavaString_add(nit_hashset, element); @@ -47,7 +47,7 @@ redef extern class NativeSharedPreferencesEditor import HashSet[JavaString], HashSet[JavaString].iterator, Iterator[JavaString].is_ok, Iterator[JavaString].item, Iterator[JavaString].next in "Java" `{ Set java_set = new HashSet(); - int itr = HashSet_of_JavaString_iterator(value); + nit.app.NitObject itr = HashSet_of_JavaString_iterator(value); while (Iterator_of_JavaString_is_ok(itr)) { java_set.add(Iterator_of_JavaString_item(itr)); diff --git a/lib/android/ui/ui.nit b/lib/android/ui/ui.nit index 60f7909..767039b 100644 --- a/lib/android/ui/ui.nit +++ b/lib/android/ui/ui.nit @@ -207,7 +207,7 @@ end redef class Android_widget_ArrayAdapter private new (context: NativeContext, res: Int, sender: ListLayout) import ListLayout.create_view in "Java" `{ - final int final_sender_object = sender; + final nit.app.NitObject final_sender_object = sender; ListLayout_incr_ref(sender); return new android.widget.ArrayAdapter(context, (int)res) { @@ -276,7 +276,7 @@ redef class CheckBox private fun set_callback_on_toggle(view: NATIVE) import on_toggle in "Java" `{ - final int final_sender_object = self; + final nit.app.NitObject final_sender_object = self; CheckBox_incr_ref(final_sender_object); view.setOnCheckedChangeListener( @@ -328,7 +328,7 @@ end redef class NativeButton private new (context: NativeActivity, sender_object: Button) import Button.on_click in "Java" `{ - final int final_sender_object = sender_object; + final nit.app.NitObject final_sender_object = sender_object; Button_incr_ref(final_sender_object); return new android.widget.Button(context) { @@ -349,7 +349,7 @@ end redef class Android_app_Fragment private new (nit_window: Window) import Window.on_create_fragment in "Java" `{ - final int final_nit_window = nit_window; + final nit.app.NitObject final_nit_window = nit_window; Window_incr_ref(nit_window); return new android.app.Fragment(){ diff --git a/lib/core/bytes.nit b/lib/core/bytes.nit index f386c47..3013321 100644 --- a/lib/core/bytes.nit +++ b/lib/core/bytes.nit @@ -538,6 +538,12 @@ class Bytes length += cln end + redef fun has(c) + do + if not c isa Int then return false + return super(c&255) + end + # var b = new Bytes.empty # b.append([104, 101, 108, 108, 111]) # assert b.to_s == "hello" diff --git a/lib/core/collection/abstract_collection.nit b/lib/core/collection/abstract_collection.nit index b51cd22..9e2179b 100644 --- a/lib/core/collection/abstract_collection.nit +++ b/lib/core/collection/abstract_collection.nit @@ -307,6 +307,45 @@ private class StepIterator[E] redef fun next_by(step) do real.next_by(step * self.step) end +# An iterator that lazyly cache the current item. +# +# This class can be used as an helper to build simple iterator with a single and simplier `next_item` method. +# The only constraint is that `next_item` returns null on the last item, so `null` cannot be a valid element. +abstract class CachedIterator[E: Object] + super Iterator[E] + + # Get the next item if any. + # Returns null if there is no next item. + fun next_item: nullable E is abstract + + # The last item effectively read. + # `null` if on start, after a next of if no more items are available. + protected var cache: nullable E = null + + # The current item, if any. + # If not, the cache is effectively filled (with `next_item`). + # Return `null` iff there is no more elements. + protected fun current_item: nullable E + do + var cache = self.cache + if cache != null then return cache + cache = next_item + self.cache = cache + return cache + end + + redef fun item do return current_item.as(not null) + + redef fun is_ok do return current_item != null + + redef fun next do + # If needed, fill the cache (an consume the current element) + current_item + # Empty the cache (so the next element will be read) + cache = null + end +end + # A collection that contains only one item. # # Used to pass arguments by reference. diff --git a/lib/core/stream.nit b/lib/core/stream.nit index 152c294..b0486ef 100644 --- a/lib/core/stream.nit +++ b/lib/core/stream.nit @@ -484,37 +484,18 @@ end # Iterator returned by `Reader::each_line`. # See the aforementioned method for details. class LineIterator - super Iterator[String] + super CachedIterator[String] # The original stream var stream: Reader - redef fun is_ok + redef fun next_item do - var res = not stream.eof - if not res and close_on_finish then stream.close - return res - end - - redef fun item - do - var line = self.line - if line == null then - line = stream.read_line + if stream.eof then + if close_on_finish then stream.close + return null end - self.line = line - return line - end - - # The last line read (cache) - private var line: nullable String = null - - redef fun next - do - # force the read - if line == null then item - # drop the line - line = null + return stream.read_line end # Close the stream when the stream is at the EOF. diff --git a/lib/java/NitObject.java b/lib/java/NitObject.java new file mode 100644 index 0000000..a09a9aa --- /dev/null +++ b/lib/java/NitObject.java @@ -0,0 +1,27 @@ +/* This file is part of NIT ( http://www.nitlanguage.org ). + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package nit.app; + +// General class for all references to Nit objects from Java in the FFI +public class NitObject { + + // Address to the object in Nit memory + private long pointer; + + protected NitObject(long pointer) { + this.pointer = pointer; + } +} diff --git a/lib/java/ffi_support.nit b/lib/java/ffi_support.nit index 5fafd18..c6a7e2d 100644 --- a/lib/java/ffi_support.nit +++ b/lib/java/ffi_support.nit @@ -21,6 +21,7 @@ module ffi_support is cflags "-I $(JAVA_HOME)/include/ -I $(JAVA_HOME)/include/linux/" ldflags "-L $(JNI_LIB_PATH) -ljvm" new_annotation extra_java_files + extra_java_files "nit.app.NitObject" end import jvm diff --git a/lib/pthreads/concurrent_collections.nit b/lib/pthreads/concurrent_collections.nit index 3c5ae98..a8b4bbc 100644 --- a/lib/pthreads/concurrent_collections.nit +++ b/lib/pthreads/concurrent_collections.nit @@ -421,6 +421,14 @@ class ConcurrentArray[E] mutex.unlock end + redef fun has(e) + do + mutex.lock + var result = real_collection.has(e) + mutex.unlock + return result + end + # ## The following method defs are conflict resolutions # diff --git a/misc/docker/ci/Dockerfile b/misc/docker/ci/Dockerfile index 000c0c1..e4ba62b 100644 --- a/misc/docker/ci/Dockerfile +++ b/misc/docker/ci/Dockerfile @@ -108,3 +108,6 @@ RUN pip3 install junit2html # Prepare to install npm (npm is not packaged for debian:stretch) RUN npm install pug-cli -g + +# Some tools, like gradle, need an explitit UTF8 environement +ENV LANG C.UTF-8 diff --git a/misc/jenkins/check_manpages.sh b/misc/jenkins/check_manpages.sh index b03b22a..c60113e 100755 --- a/misc/jenkins/check_manpages.sh +++ b/misc/jenkins/check_manpages.sh @@ -59,7 +59,7 @@ for bin in bin/nit*; do fi # Test what is expected - if ! diff -q <(sed 's/\s*(.*)//' check_manpages-from_help.out) <(sed 's/\s*(.*)//' check_manpages-from_man.out) > /dev/null; then + if ! diff -q <(sed -E 's/\s*(.*)//' check_manpages-from_help.out) <(sed -E 's/\s*(.*)//' check_manpages-from_man.out) > /dev/null; then echo "$opt: mismatch documentation in the manpage $man. Here the word diff:" echo "" wdiff check_manpages-from_help.out check_manpages-from_man.out | colordiff diff --git a/src/astbuilder.nit b/src/astbuilder.nit index 79d0ba1..240e00b 100644 --- a/src/astbuilder.nit +++ b/src/astbuilder.nit @@ -29,6 +29,12 @@ class ASTBuilder # The anchor used for some mechanism relying on types var anchor: nullable MClassType + # Check mmodule to avoid a new instantiation of ASTBuilder + fun check_mmodule(mmodule: MModule) + do + if self.mmodule != mmodule then self.mmodule = mmodule + end + # Make a new Int literal fun make_int(value: Int): AIntegerExpr do @@ -102,6 +108,55 @@ class ASTBuilder do return new AIfExpr.make(condition, mtype) end + + # Make a new assert + fun make_assert(n_id : nullable TId , n_expr : AExpr , n_else : nullable AExpr): AAssertExpr + do + return new AAssertExpr.make(n_id , n_expr , n_else) + end + + # Make a new method + fun make_method(n_visibility: nullable APublicVisibility, + tk_redef: nullable TKwredef, + mmethoddef: MMethodDef, + n_signature: nullable ASignature, + n_annotations: nullable AAnnotations, + n_extern_calls: nullable AExternCalls, + n_extern_code_block: nullable AExternCodeBlock, + n_block: AExpr): AMethPropdef + do + return new AMethPropdef.make(n_visibility, tk_redef, mmethoddef, n_signature, n_annotations, n_extern_calls, n_extern_code_block, n_block) + end + + # Make a new or with two expr + fun make_or(right_expr: AExpr, left_expr: AExpr): AOrExpr + do + return new AOrExpr.make(right_expr,left_expr) + end + + # Make a new and with two expr + fun make_and(right_expr: AExpr, left_expr: AExpr): AAndExpr + do + return new AAndExpr.make(right_expr,left_expr) + end + + # Make a new parenthesis expr + fun make_parenthesis(expr: AExpr, annotations: nullable AAnnotations): AParExpr + do + return new AParExpr.make(expr,annotations) + end + + # Make a new message super + fun make_super_call(args: nullable Array[AExpr], n_qualified: nullable AQualified): ASuperExpr + do + return new ASuperExpr.make(args,n_qualified) + end + + # Make a new return + fun make_return(expr: nullable AExpr): AReturnExpr + do + return new AReturnExpr.make(expr) + end end redef class AExpr @@ -159,6 +214,14 @@ redef class AExpr print "add not implemented in {inspect}" abort end + + redef fun accept_ast_validation(v) + do + super + if mtype == null and not is_typed then + #debug "TYPING: untyped expression" + end + end end # A placeholder for a `AExpr` node @@ -173,6 +236,82 @@ class APlaceholderExpr private init make do end + + redef fun accept_ast_validation(v) + do + super + debug "PARENT: remaining placeholder" + end +end + +redef class AReturnExpr + private init make(expr: nullable AExpr) + do + self.init_areturnexpr(null, expr) + end +end + +redef class ASuperExpr + private init make(args: nullable Array[AExpr], n_qualified: nullable AQualified) + do + var n_args = new AListExprs + if args != null then + n_args.n_exprs.add_all(args) + end + self.init_asuperexpr(n_qualified, new TKwsuper, n_args) + end +end + +redef class AParExpr + private init make(expr: AExpr, annotations: nullable AAnnotations) + do + self.location = expr.location + self.init_aparexpr(new TOpar, expr, new TCpar, annotations) + end +end + +redef class AOrExpr + private init make(right_expr: AExpr, left_expr: AExpr) + do + self.init_aorexpr(right_expr,new TKwor,left_expr) + end +end + +redef class AAndExpr + private init make(right_expr: AExpr, left_expr: AExpr) + do + self.init_aandexpr(right_expr,new TKwand ,left_expr) + end +end + +redef class AMethPropdef + private init make(n_visibility: nullable APublicVisibility, + tk_redef: nullable TKwredef, + mmethoddef: MMethodDef, + n_signature: nullable ASignature, + n_annotations: nullable AAnnotations, + n_extern_calls: nullable AExternCalls, + n_extern_code_block: nullable AExternCodeBlock, + n_block: nullable AExpr) + do + var n_tid = new TId + n_tid.text = mmethoddef.name + var n_methid = new AIdMethid.init_aidmethid(n_tid) + if n_signature == null then n_signature = new ASignature + if n_visibility == null then n_visibility = new APublicVisibility + self.init_amethpropdef(null,tk_redef,n_visibility,new TKwmeth,null,null,null,n_methid,n_signature,n_annotations,n_extern_calls,n_extern_code_block,new TKwdo,n_block,new TKwend) + self.mpropdef = mmethoddef + end +end + +redef class AAssertExpr + private init make(n_id : nullable TId , n_expr : nullable AExpr , n_else : nullable AExpr) + do + n_kwassert = new TKwassert + n_kwelse = null + if n_else != null then n_kwelse = new TKwelse + self.init_aassertexpr(n_kwassert, n_id , n_expr , n_kwelse , n_else) + end end redef class ABlockExpr @@ -299,6 +438,7 @@ redef class ACallExpr _n_args = new AListExprs _n_qid = new AQid _n_qid.n_id = new TId + _n_qid.n_id.text = callsite.mproperty.name if args != null then self.n_args.n_exprs.add_all(args) end @@ -354,3 +494,66 @@ redef class AVarAssignExpr end end +# Check the consitency of AST +class ASTValidationVisitor + super Visitor + redef fun visit(node) + do + node.accept_ast_validation(self) + end + private var path = new CircularArray[ANode] + private var seen = new HashSet[ANode] +end + +redef class ANode + # Recursively validate a AST node. + # This ensure that location and parenting are defined and coherent. + # + # After complex low-level AST manipulation and construction, + # it is recommended to call it. + # + # Note: this just instantiate and run an `ASTValidationVisitor`. + fun validate + do + (new ASTValidationVisitor).enter_visit(self) + end + + private fun accept_ast_validation(v: ASTValidationVisitor) + do + var parent = self.parent + var path = v.path + + if path.length > 0 then + var path_parent = v.path.first + if parent == null then + self.parent = path_parent + #debug "PARENT: expected parent: {path_parent}" + v.seen.add(self) + else if parent != path_parent then + self.parent = path_parent + if v.seen.has(self) then + debug "DUPLICATE (NOTATREE): already seen node with parent {parent} now with {path_parent}." + else + v.seen.add(self) + debug "PARENT: expected parent: {path_parent}, got {parent}" + end + end + end + + if not isset _location then + #debug "LOCATION: unlocated node {v.path.join(", ")}" + _location = self.parent.location + end + + path.unshift(self) + visit_all(v) + path.shift + end +end + +redef class AAnnotation + redef fun accept_ast_validation(v) + do + # Do not enter in annotations + end +end diff --git a/src/astvalidation.nit b/src/astvalidation.nit deleted file mode 100644 index cf3da76..0000000 --- a/src/astvalidation.nit +++ /dev/null @@ -1,100 +0,0 @@ -# This file is part of NIT ( http://www.nitlanguage.org ). -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Check the consitency of AST -module astvalidation - -intrude import parser -import astbuilder - -class ASTValidationVisitor - super Visitor - redef fun visit(node) - do - node.accept_ast_validation(self) - end - private var path = new CircularArray[ANode] - private var seen = new HashSet[ANode] -end - -redef class ANode - # Recursively validate a AST node. - # This ensure that location and parenting are defined and coherent. - # - # After complex low-level AST manipulation and construction, - # it is recommended to call it. - # - # Note: this just instantiate and run an `ASTValidationVisitor`. - fun validate - do - (new ASTValidationVisitor).enter_visit(self) - end - - private fun accept_ast_validation(v: ASTValidationVisitor) - do - var parent = self.parent - var path = v.path - - if path.length > 0 then - var path_parent = v.path.first - if parent == null then - self.parent = path_parent - #debug "PARENT: expected parent: {path_parent}" - v.seen.add(self) - else if parent != path_parent then - self.parent = path_parent - if v.seen.has(self) then - debug "DUPLICATE (NOTATREE): already seen node with parent {parent} now with {path_parent}." - else - v.seen.add(self) - debug "PARENT: expected parent: {path_parent}, got {parent}" - end - end - end - - if not isset _location then - #debug "LOCATION: unlocated node {v.path.join(", ")}" - _location = self.parent.location - end - - path.unshift(self) - visit_all(v) - path.shift - end -end - -redef class AAnnotation - redef fun accept_ast_validation(v) - do - # Do not enter in annotations - end -end - -redef class AExpr - redef fun accept_ast_validation(v) - do - super - if mtype == null and not is_typed then - #debug "TYPING: untyped expression" - end - end -end - -redef class APlaceholderExpr - redef fun accept_ast_validation(v) - do - super - debug "PARENT: remaining placeholder" - end -end diff --git a/src/c_tools.nit b/src/c_tools.nit index 9a03c5a..61c1f9c 100644 --- a/src/c_tools.nit +++ b/src/c_tools.nit @@ -105,7 +105,8 @@ end # An extern file to compile class ExternFile - # The filename of the file + + # Filename relative to the nit-compile folder var filename: String # The name of the target in the Makefile @@ -118,6 +119,7 @@ class ExternFile fun compiles_to_o_file: Bool do return false + # Is `self` a Java file to include in the JAR archive? fun add_to_jar: Bool do return false # Additional libraries needed for the compilation diff --git a/src/compiler/abstract_compiler.nit b/src/compiler/abstract_compiler.nit index 32dd807..e786374 100644 --- a/src/compiler/abstract_compiler.nit +++ b/src/compiler/abstract_compiler.nit @@ -465,6 +465,13 @@ ifneq ($(findstring MINGW64,$(uname_S)),) CFLAGS += -Wno-pointer-to-int-cast -Wno-int-to-pointer-cast endif +# Add the compilation dir to the Java CLASSPATH +ifeq ($(CLASSPATH),) + CLASSPATH := . +else + CLASSPATH := $(CLASSPATH):. +endif + """ makefile.write("all: {outpath}\n") @@ -528,8 +535,7 @@ endif var java_files = new Array[ExternFile] for f in compiler.extern_bodies do var o = f.makefile_rule_name - var ff = f.filename.basename - makefile.write("{o}: {ff}\n") + makefile.write("{o}: {f.filename}\n") makefile.write("\t{f.makefile_rule_content}\n\n") dep_rules.add(f.makefile_rule_name) @@ -712,7 +718,7 @@ abstract class AbstractCompiler stream.write("const char* get_nit_name(register const char* procname, register unsigned int len);\n") stream.close - extern_bodies.add(new ExternCFile("{compile_dir}/c_functions_hash.c", "")) + extern_bodies.add(new ExternCFile("c_functions_hash.c", "")) end # Compile C headers diff --git a/src/compiler/compiler_ffi/light.nit b/src/compiler/compiler_ffi/light.nit index 1f59771..ce0f71b 100644 --- a/src/compiler/compiler_ffi/light.nit +++ b/src/compiler/compiler_ffi/light.nit @@ -29,7 +29,7 @@ redef class MModule return v.compiler.modelbuilder.mmodule2node(self) end - redef fun finalize_ffi(compiler: AbstractCompiler) + redef fun finalize_ffi(compiler) do if not uses_ffi then return @@ -53,7 +53,7 @@ extern void nitni_global_ref_decr(void*); nitni_ccu.write_as_nitni(self, v.compiler.toolchain.compile_dir) for file in nitni_ccu.files do - var f = new ExternCFile(file, cflags) + var f = new ExternCFile(file.basename, cflags) f.pkgconfigs.add_all pkgconfigs v.compiler.extern_bodies.add(f) end diff --git a/src/ffi/cpp.nit b/src/ffi/cpp.nit index 13a6e92..f660114 100644 --- a/src/ffi/cpp.nit +++ b/src/ffi/cpp.nit @@ -171,7 +171,7 @@ class CPPCompilationUnit files.add("{compdir}/{c_file}") - return new ExternCppFile("{compdir}/{c_file}", mmodule) + return new ExternCppFile(c_file, mmodule) end end @@ -180,8 +180,8 @@ class ExternCppFile var mmodule: MModule - redef fun makefile_rule_name do return "{filename.basename}.o" - redef fun makefile_rule_content do return "$(CXX) $(CFLAGS) {mmodule.cppflags[""].join(" ")} -c {filename.basename} -o {filename.basename}.o" + redef fun makefile_rule_name do return "{filename}.o" + redef fun makefile_rule_content do return "$(CXX) $(CFLAGS) {mmodule.cppflags[""].join(" ")} -c {filename} -o {filename}.o" redef fun compiles_to_o_file do return true end diff --git a/src/ffi/extra_java_files.nit b/src/ffi/extra_java_files.nit index e6dfca2..c355441 100644 --- a/src/ffi/extra_java_files.nit +++ b/src/ffi/extra_java_files.nit @@ -29,7 +29,7 @@ end redef class MModule # Extra Java files to compile with the module - private var extra_java_files: nullable Array[JavaFile] = null + private var extra_java_files: nullable Array[ExtraJavaFile] = null end private class JavaExtraFilesPhase @@ -60,18 +60,20 @@ private class JavaExtraFilesPhase var mmodule = nmodule.mmodule.as(not null) var java_files = mmodule.extra_java_files if java_files == null then - java_files = new Array[JavaFile] + java_files = new Array[ExtraJavaFile] mmodule.extra_java_files = java_files end var format_error = "Syntax Error: `{annot_name}` expects its arguments to be paths to java files." for arg in args do - var path = arg.as_string - if path == null then + var name = arg.as_string + if name == null or name.is_empty then modelbuilder.error(arg, format_error) return end + var path = name.split(".").last + ".java" + # Append specified path to directory of the Nit source file var source_file = nat.location.file if source_file != null then path = "{source_file.filename.dirname}/{path}" @@ -81,7 +83,7 @@ private class JavaExtraFilesPhase continue end - var file = new JavaFile(path) + var file = new ExtraJavaFile(name, path) mmodule.ffi_files.add file java_files.add file end @@ -93,11 +95,28 @@ redef class JavaLanguage do super - # also copy over the java files + # Also copy over the extra Java files var extra_java_files = mmodule.extra_java_files if extra_java_files != null then for file in extra_java_files do - var path = file.filename - path.file_copy_to("{compdir}/{path.basename}") + + var dir = compdir / file.filename.dirname + dir.mkdir + + file.src_path.file_copy_to(compdir/file.filename) end end end + +# User supplied Java file to include with the app for use from the FFI +class ExtraJavaFile + super JavaFile + + autoinit full_name, src_path + + redef var full_name + + # Path to the original user file + var src_path: String + + redef fun filename do return full_name.replace(".", "/") + ".java" +end diff --git a/src/ffi/java.nit b/src/ffi/java.nit index 0dd65be..fe8bc19 100644 --- a/src/ffi/java.nit +++ b/src/ffi/java.nit @@ -105,7 +105,7 @@ class JavaLanguage jni_signature_alt = mclass_type.jni_signature_alt return_type = mclass_type else - params.add "self" + params.add to_java_call_context.cast_to(mclass_type, "self") if signature.return_mtype != null then var ret_mtype = signature.return_mtype ret_mtype = ret_mtype.resolve_for(mclass_type, mclass_type, mmodule, true) @@ -165,6 +165,9 @@ class JavaLanguage redef fun compile_to_files(mmodule, compdir) do + var ffi_ccu = ffi_ccu + assert ffi_ccu != null + # Make sure we have a .java file mmodule.ensure_java_files @@ -172,7 +175,65 @@ class JavaLanguage mmodule.insert_compiler_options # Enable linking C callbacks to java native methods - mmodule.ensure_linking_callback_methods(ffi_ccu.as(not null)) + mmodule.ensure_linking_callback_methods(ffi_ccu) + + # Function to build instances to the Java class NitObject + var callbacks = mmodule.callbacks_used_from_java.callbacks + if callbacks.not_empty then + var cf = new CFunction("jobject nit_ffi_with_java_new_nit_object(JNIEnv *env, void *data)") + cf.exprs.add """ + // retrieve the current JVM + Sys sys = Pointer_sys(NULL); + + jclass java_class = Sys_load_jclass(sys, "nit/app/NitObject"); + if (java_class == NULL) { + PRINT_ERROR("Nit FFI with Java error: failed to load class NitObject.\\n"); + (*env)->ExceptionDescribe(env); + exit(1); + } + + jmethodID java_init = (*env)->GetMethodID(env, java_class, "", "(J)V"); + if (java_init == NULL) { + PRINT_ERROR("Nit FFI with Java error: NitObject constructor not found.\\n"); + (*env)->ExceptionDescribe(env); + exit(1); + } + + jobject nit_object = (*env)->NewObject(env, java_class, java_init, (jlong)data); + if (nit_object == NULL) { + PRINT_ERROR("Nit FFI with Java error: NitObject construction failed.\\n"); + (*env)->ExceptionDescribe(env); + exit(1); + } + + return nit_object; + """ + ffi_ccu.add_local_function cf + + # Function to extract the pointer held by instances of the Java class NitObject + cf = new CFunction("void *nit_ffi_with_java_nit_object_data(JNIEnv *env, jobject nit_object)") + cf.exprs.add """ + Sys sys = Pointer_sys(NULL); + jclass java_class = Sys_load_jclass(sys, "nit/app/NitObject"); + if (java_class == NULL) { + PRINT_ERROR("Nit FFI with Java error: failed to load class NitObject.\\n"); + (*env)->ExceptionDescribe(env); + exit(1); + } + + jfieldID java_field = (*env)->GetFieldID(env, java_class, "pointer", "J"); + if (java_field == NULL) { + PRINT_ERROR("Nit FFI with Java error: NitObject field not found.\\n"); + (*env)->ExceptionDescribe(env); + exit(1); + } + + jlong data = (*env)->GetLongField(env, nit_object, java_field); + + return (void*)data; + """ + ffi_ccu.add_local_function cf + end # Java implementation code var java_file = mmodule.java_file @@ -343,7 +404,7 @@ class JavaClassTemplate fun write_to_files(compdir: String): ExternFile do var filename = "{java_class_name}.java" - var filepath = "{compdir}/{filename}" + var filepath = compdir/filename write_to_file filepath @@ -364,8 +425,11 @@ end class JavaFile super ExternFile - redef fun makefile_rule_name do return "{filename.basename(".java")}.class" - redef fun makefile_rule_content do return "javac {filename.basename} -d ." + # Full Java class name: package and class + fun full_name: String do return filename.basename(".java") + + redef fun makefile_rule_name do return full_name.replace(".", "/") + ".class" + redef fun makefile_rule_content do return "javac {filename} -d ." redef fun add_to_jar do return true end @@ -380,8 +444,24 @@ end private class ToJavaCallContext super CallContext - redef fun cast_to(mtype, name) do return "({mtype.jni_type})({name})" - redef fun cast_from(mtype, name) do return "({mtype.cname})({name})" + redef fun cast_to(mtype, name) + do + if mtype.java_is_nit_object then + return "nit_ffi_with_java_new_nit_object(nit_ffi_jni_env, {name})" + else + return "({mtype.jni_type})({name})" + end + end + + redef fun cast_from(mtype, name) + do + if mtype.java_is_nit_object then + return "({mtype.cname})nit_ffi_with_java_nit_object_data(nit_ffi_jni_env, {name})" + else + return "({mtype.cname})({name})" + end + end + redef fun name_mtype(mtype) do return mtype.jni_type end @@ -389,8 +469,24 @@ end private class FromJavaCallContext super CallContext - redef fun cast_to(mtype, name) do return "({mtype.cname})({name})" - redef fun cast_from(mtype, name) do return "({mtype.jni_type})({name})" + redef fun cast_to(mtype, name) + do + if mtype.java_is_nit_object then + return "({mtype.cname})nit_ffi_with_java_nit_object_data(nit_ffi_jni_env, {name})" + else + return "({mtype.cname})({name})" + end + end + + redef fun cast_from(mtype, name) + do + if mtype.java_is_nit_object then + return "nit_ffi_with_java_new_nit_object(nit_ffi_jni_env, {name})" + else + return "({mtype.jni_type})({name})" + end + end + redef fun name_mtype(mtype) do return mtype.jni_type end @@ -452,21 +548,23 @@ redef class MType # # * Primitives common to both languages use their Java primitive type # * Nit extern Java classes are represented by their full Java type - # * Other Nit objects are represented by `int` in Java. It holds the - # pointer to the underlying C structure. - # TODO create static Java types to store and hide the pointer - private fun java_type: String do return "int" + # * Other Nit objects are represented by `NitObject` in Java, a class + # encapsulating the pointer to the underlying C structure. + private fun java_type: String do return "nit.app.NitObject" + + # Is this type opaque in Java? As so it is represented by `nit.app.NitObject`. + private fun java_is_nit_object: Bool do return true # JNI type name (in C) # # So this is a C type, usually defined in `jni.h` - private fun jni_type: String do return "long" + private fun jni_type: String do return "jobject" # JNI short type name (for signatures) # # Is used by `MMethod::build_jni_format` to pass a Java method signature # to the JNI function `GetStaticMetodId`. - private fun jni_format: String do return "I" + private fun jni_format: String do return "Lnit/app/NitObject;" # Type name appearing within JNI function names. # @@ -476,20 +574,22 @@ redef class MType redef fun compile_callback_to_java(mmodule, mainmodule, ccu) do + if self isa MClassType and mclass.ftype isa ForeignJavaType then return + var java_file = mmodule.java_file - if java_file == null then return + if java_file == null or mmodule.callbacks_used_from_java.callbacks.is_empty then return for variation in ["incr", "decr"] do var friendly_name = "{mangled_cname}_{variation}_ref" # C - var csignature = "void {mmodule.impl_java_class_name}_{friendly_name}(JNIEnv *env, jclass clazz, jint object)" + var csignature = "void {mmodule.impl_java_class_name}_{friendly_name}(JNIEnv *nit_ffi_jni_env, jclass clazz, jobject object)" var cf = new CFunction("JNIEXPORT {csignature}") - cf.exprs.add "\tnitni_global_ref_{variation}((void*)(long)object);" + cf.exprs.add "\tnitni_global_ref_{variation}(nit_ffi_with_java_nit_object_data(nit_ffi_jni_env, object));" ccu.add_non_static_local_function cf # Java - java_file.class_content.add "private native static void {friendly_name}(int object);\n" + java_file.class_content.add "private native static void {friendly_name}(nit.app.NitObject object);\n" end end @@ -498,7 +598,7 @@ redef class MType var arr = new Array[String] for variation in ["incr", "decr"] do var friendly_name = "{mangled_cname}_{variation}_ref" - var jni_format = "(I)V" + var jni_format = "(Lnit/app/NitObject;)V" var cname = "{from_mmodule.impl_java_class_name}_{friendly_name}" arr.add """{"{{{friendly_name}}}", "{{{jni_format}}}", {{{cname}}}}""" end @@ -526,6 +626,16 @@ redef class MClassType return super end + redef fun java_is_nit_object + do + var ftype = mclass.ftype + if ftype isa ForeignJavaType then return false + + var java_primitives = once new HashSet[String].from( + ["Bool", "Char", "Int", "Float", "Byte", "Int8", "Int16", "UInt16", "Int32", "UInt32"]) + return not java_primitives.has(mclass.name) + end + redef fun jni_type do var ftype = mclass.ftype @@ -625,6 +735,22 @@ redef class MClassType if mclass.name == "UInt32" then return "Int" return super end + + redef fun compile_callback_to_java(mmodule, mainmodule, ccu) + do + # Don't generate functions for reference counters on extern classes + if mclass.ftype != null then return + + super + end + + redef fun jni_methods_declaration(from_mmodule) + do + # Don't generate functions for reference counters on extern classes + if mclass.ftype != null then return new Array[String] + + return super + end end redef class MMethod @@ -690,8 +816,7 @@ redef class MMethod var cparams = new List[String] - # This is different - cparams.add "JNIEnv *env" + cparams.add "JNIEnv *nit_ffi_jni_env" cparams.add "jclass clazz" if not self.is_init then diff --git a/src/ffi/light_ffi.nit b/src/ffi/light_ffi.nit index 2245a92..b8d572b 100644 --- a/src/ffi/light_ffi.nit +++ b/src/ffi/light_ffi.nit @@ -57,7 +57,7 @@ redef class MModule ffi_ccu.write_as_impl(self, compdir) for filename in ffi_ccu.files do - var f = new ExternCFile(filename, cflags) + var f = new ExternCFile(filename.basename, cflags) f.pkgconfigs.add_all pkgconfigs ffi_files.add(f) end diff --git a/src/ffi/objc.nit b/src/ffi/objc.nit index 9c0545a..24ce15d 100644 --- a/src/ffi/objc.nit +++ b/src/ffi/objc.nit @@ -156,7 +156,7 @@ private class ObjCCompilationUnit mmodule.ldflags.add_one("", "-lobjc") - return new ExternObjCFile(compdir/c_file, mmodule) + return new ExternObjCFile(c_file, mmodule) end end @@ -169,7 +169,7 @@ class ExternObjCFile redef fun makefile_rule_name do return "{filename.basename(".m")}_m.o" redef fun makefile_rule_content do - return "clang $(CFLAGS) -c {filename.basename} -o {makefile_rule_name}" + return "clang $(CFLAGS) -c {filename} -o {makefile_rule_name}" end redef fun compiles_to_o_file do return true end diff --git a/src/frontend/explain_assert.nit b/src/frontend/explain_assert.nit index 326f588..f8b4710 100644 --- a/src/frontend/explain_assert.nit +++ b/src/frontend/explain_assert.nit @@ -35,7 +35,6 @@ module explain_assert import astbuilder intrude import literal # for value= intrude import typing # for mtype= -import astvalidation import explain_assert_api diff --git a/src/frontend/parallelization_phase.nit b/src/frontend/parallelization_phase.nit index 080efe6..b5cc9fd 100644 --- a/src/frontend/parallelization_phase.nit +++ b/src/frontend/parallelization_phase.nit @@ -22,7 +22,6 @@ private import parser_util import modelize import astbuilder private import annotation -private import astvalidation redef class ToolContext # Transforms a function annotated with "threaded" diff --git a/src/interpreter/dynamic_loading_ffi/on_demand_compiler.nit b/src/interpreter/dynamic_loading_ffi/on_demand_compiler.nit index 44f6854..acd783a 100644 --- a/src/interpreter/dynamic_loading_ffi/on_demand_compiler.nit +++ b/src/interpreter/dynamic_loading_ffi/on_demand_compiler.nit @@ -404,7 +404,7 @@ redef class ExternCFile var cflags = mmodule.cflags[""].join(" ") + " " + pkg_cflags var obj = compile_dir / filename.basename(".c") + ".o" - var cmd = "{v.c_compiler} -Wall -c -fPIC -I {compile_dir} -g -o {obj} {filename} {cflags}" + var cmd = "{v.c_compiler} -Wall -c -fPIC -I {compile_dir} -g -o {obj} {compile_dir / filename} {cflags}" if sys.system(cmd) != 0 then v.fatal "FFI Error: Failed to compile C code using `{cmd}`" return false diff --git a/src/platform/android.nit b/src/platform/android.nit index 3c85633..9bff506 100644 --- a/src/platform/android.nit +++ b/src/platform/android.nit @@ -419,8 +419,10 @@ target_link_libraries(nit_app gc-lib for mmodule in compiler.mainmodule.in_importation.greaters do var extra_java_files = mmodule.extra_java_files if extra_java_files != null then for file in extra_java_files do - var path = file.filename - path.file_copy_to(java_dir/path.basename) + var path = file.src_path + var dir = file.filename.dirname + (java_dir/dir).mkdir + path.file_copy_to(java_dir/file.filename) end end diff --git a/src/transform.nit b/src/transform.nit index 3e5865b..3499d9b 100644 --- a/src/transform.nit +++ b/src/transform.nit @@ -17,7 +17,6 @@ module transform import astbuilder -import astvalidation import semantize intrude import semantize::scope intrude import semantize::typing diff --git a/tests/gitlab_ci.skip b/tests/gitlab_ci.skip index c75645c..669601e 100644 --- a/tests/gitlab_ci.skip +++ b/tests/gitlab_ci.skip @@ -1,5 +1,4 @@ emscripten -java glsl mpi objc diff --git a/tests/sav/test_file_read3.res b/tests/sav/test_file_read3.res new file mode 100644 index 0000000..461ab2d --- /dev/null +++ b/tests/sav/test_file_read3.res @@ -0,0 +1,263 @@ +# This file is part of NIT ( http://www.nitlanguage.org ). +true +# +true +# Copyright 2004-2008 Jean Privat +true +# +true +# Licensed under the Apache License, Version 2.0 (the "License"); +true +# you may not use this file except in compliance with the License. +true +# You may obtain a copy of the License at +true +# +true +# http://www.apache.org/licenses/LICENSE-2.0 +true +# +true +# Unless required by applicable law or agreed to in writing, software +true +# distributed under the License is distributed on an "AS IS" BASIS, +true +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +true +# See the License for the specific language governing permissions and +true +# limitations under the License. +true + +true +var f = new FileReader.open("test_file_read.nit") +true +var s: String +true +while not f.eof do +true + s = f.read_line +true + printn(s) +true + printn("\n") +true +end +true +f.close +true + +true +f.reopen +true +printn(f.read(10)) +true +printn("|") +true +printn(f.read_all) +true +--- +true +# This file is part of NIT ( http://www.nitlanguage.org ). +true +# This file is part of NIT ( http://www.nitlanguage.org ). +true +true +# +true +# +true +true +# Copyright 2004-2008 Jean Privat +true +# Copyright 2004-2008 Jean Privat +true +true +# +true +# +true +true +# Licensed under the Apache License, Version 2.0 (the "License"); +true +# Licensed under the Apache License, Version 2.0 (the "License"); +true +true +# you may not use this file except in compliance with the License. +true +# you may not use this file except in compliance with the License. +true +true +# You may obtain a copy of the License at +true +# You may obtain a copy of the License at +true +true +# +true +# +true +true +# http://www.apache.org/licenses/LICENSE-2.0 +true +# http://www.apache.org/licenses/LICENSE-2.0 +true +true +# +true +# +true +true +# Unless required by applicable law or agreed to in writing, software +true +# Unless required by applicable law or agreed to in writing, software +true +true +# distributed under the License is distributed on an "AS IS" BASIS, +true +# distributed under the License is distributed on an "AS IS" BASIS, +true +true +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +true +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +true +true +# See the License for the specific language governing permissions and +true +# See the License for the specific language governing permissions and +true +true +# limitations under the License. +true +# limitations under the License. +true +true + +true + +true +true +var f = new FileReader.open("test_file_read.nit") +true +var f = new FileReader.open("test_file_read.nit") +true +true +var s: String +true +var s: String +true +true +while not f.eof do +true +while not f.eof do +true +true + s = f.read_line +true + s = f.read_line +true +true + printn(s) +true + printn(s) +true +true + printn("\n") +true + printn("\n") +true +true +end +true +end +true +true +f.close +true +f.close +true +true + +true + +true +true +f.reopen +true +f.reopen +true +true +printn(f.read(10)) +true +printn(f.read(10)) +true +true +printn("|") +true +printn("|") +true +true +printn(f.read_all) +true +printn(f.read_all) +true +--- +# This file is part of NIT ( http://www.nitlanguage.org ). +# This file is part of NIT ( http://www.nitlanguage.org ). +# +# +# Copyright 2004-2008 Jean Privat +# Copyright 2004-2008 Jean Privat +# +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# You may obtain a copy of the License at +# +# +# http://www.apache.org/licenses/LICENSE-2.0 +# http://www.apache.org/licenses/LICENSE-2.0 +# +# +# Unless required by applicable law or agreed to in writing, software +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# See the License for the specific language governing permissions and +# limitations under the License. +# limitations under the License. + + +var f = new FileReader.open("test_file_read.nit") +var f = new FileReader.open("test_file_read.nit") +var s: String +var s: String +while not f.eof do +while not f.eof do + s = f.read_line + s = f.read_line + printn(s) + printn(s) + printn("\n") + printn("\n") +end +end +f.close +f.close + + +f.reopen +f.reopen +printn(f.read(10)) +printn(f.read(10)) +printn("|") +printn("|") +printn(f.read_all) +printn(f.read_all) diff --git a/tests/test_ffi_java_annot_files.nit b/tests/test_ffi_java_annot_files.nit index c57135a..aa87613 100644 --- a/tests/test_ffi_java_annot_files.nit +++ b/tests/test_ffi_java_annot_files.nit @@ -15,7 +15,7 @@ # limitations under the License. module test_ffi_java_annot_files is - extra_java_files("test_ffi_java_annot_files_a.java") + extra_java_files("test_ffi_java_annot_files_a") end import java diff --git a/tests/test_file_read3.nit b/tests/test_file_read3.nit new file mode 100644 index 0000000..f81a854 --- /dev/null +++ b/tests/test_file_read3.nit @@ -0,0 +1,52 @@ +# This file is part of NIT ( http://www.nitlanguage.org ). +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +var f +var i +var l = 0 + +f = new FileReader.open("test_file_read.nit") +i = f.each_line +while i.is_ok do + l += 1 + print i.item + print i.is_ok + i.next +end +f.close + +print "---" + +f = new FileReader.open("test_file_read.nit") +i = f.each_line +while i.is_ok do + print i.is_ok + print i.item + print i.is_ok + print i.item + print i.is_ok + i.next +end +f.close + +print "---" + +f = new FileReader.open("test_file_read.nit") +i = f.each_line +for x in [0..l[ do + print i.item + print i.item + i.next +end +f.close diff --git a/tests/tests.sh b/tests/tests.sh index 2aff98a..c19a9a8 100755 --- a/tests/tests.sh +++ b/tests/tests.sh @@ -37,9 +37,13 @@ if ! locale -a 2>/dev/null | grep -q C.UTF-8; then fi export LC_ALL="$locale_candidate" +# Darwin / macOS if uname | grep Darwin 1>/dev/null 2>&1; then export LANG=en_US.UTF-8 export LC_ALL=en_US.UTF-8 + + # Fix for errors on some libevent/nitcorn clients + export EVENT_NOKQUEUE=1 fi export NIT_TESTING=true