Skip to content

Commit 7eb9e7c

Browse files
authored
Fix jni to allow jobject and jclass as 2nd parameter (#209)
Co-authored-by: Tyler Veness <[email protected]>
1 parent cff653a commit 7eb9e7c

File tree

2 files changed

+261
-4
lines changed

2 files changed

+261
-4
lines changed

wpiformat/wpiformat/jni.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,8 @@ def run_pipeline(self, config_file, name, lines):
6868
r"JNIEXPORT\s+(?P<ret>\w+)\s+JNICALL\s+" + \
6969
r"(?P<func>Java_\w+)\s*\(\s*" + \
7070
r"(?P<env_type>JNIEnv\s*\*\s*)" + \
71-
r"(?P<env_name>\w+)?,\s*jclass\s*(?P<jclass_name>\w*)?"
71+
r"(?P<env_name>\w+)?,\s*" + \
72+
r"(?P<param_type>jclass|jobject)\s*(?P<param_name>\w*)?"
7273
regex_sig = regex.compile(regex_str_sig)
7374

7475
regex_str_func = r"Java_(?P<class>\w+)_(?P<method>[^_]+)$"
@@ -95,9 +96,9 @@ def run_pipeline(self, config_file, name, lines):
9596
jni_args += match_sig.group("env_type")
9697
if match_sig.group("env_name"):
9798
jni_args += match_sig.group("env_name")
98-
jni_args += ", jclass"
99-
if match_sig.group("jclass_name"):
100-
jni_args += " " + match_sig.group("jclass_name")
99+
jni_args += ", " + match_sig.group("param_type")
100+
if match_sig.group("param_name"):
101+
jni_args += " " + match_sig.group("param_name")
101102

102103
# Write JNI function comment. Splitting at "__" removes overload
103104
# annotation from method comment

wpiformat/wpiformat/test/test_jni.py

Lines changed: 256 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,4 +263,260 @@ def test_jni():
263263
" HAL_CleanFilter(handle);" + os.linesep + \
264264
"}" + os.linesep, True, True)
265265

266+
# Input args go to next line even if they fit on same line
267+
test.add_input("./TestJNI.cpp",
268+
"JNIEXPORT void JNICALL" + os.linesep + \
269+
"Java_TestJNI_testFunc(JNIEnv* env, jobject) {" + os.linesep)
270+
test.add_output(
271+
"/*" + os.linesep + \
272+
" * Class: TestJNI" + os.linesep + \
273+
" * Method: testFunc" + os.linesep + \
274+
" * Signature: ()V" + os.linesep + \
275+
" */" + os.linesep + \
276+
"JNIEXPORT void JNICALL" + os.linesep + \
277+
"Java_TestJNI_testFunc" + os.linesep + \
278+
" (JNIEnv* env, jobject)" + os.linesep + \
279+
"{" + os.linesep, True, True)
280+
281+
# Input aligned to "(" and args past end of line
282+
test.add_input("./TestJNI.cpp",
283+
"JNIEXPORT void JNICALL" + os.linesep + \
284+
"Java_edu_wpi_cscore_CameraServerJNI_setCameraExposureHoldCurrent(JNIEnv* env," + os.linesep + \
285+
" jobject," + os.linesep + \
286+
" jint source) {" + os.linesep)
287+
test.add_output(
288+
"/*" + os.linesep + \
289+
" * Class: edu_wpi_cscore_CameraServerJNI" + os.linesep + \
290+
" * Method: setCameraExposureHoldCurrent" + os.linesep + \
291+
" * Signature: (I)V" + os.linesep + \
292+
" */" + os.linesep + \
293+
"JNIEXPORT void JNICALL" + os.linesep + \
294+
"Java_edu_wpi_cscore_CameraServerJNI_setCameraExposureHoldCurrent" + os.linesep + \
295+
" (JNIEnv* env, jobject, jint source)" + os.linesep + \
296+
"{" + os.linesep, True, True)
297+
298+
# Args in input on line after "(" and args length > 80 characters
299+
test.add_input("./TestJNI.cpp",
300+
"JNIEXPORT void JNICALL Java_edu_wpi_cscore_CameraServerJNI_putSourceFrame(" + os.linesep + \
301+
" JNIEnv *env, jobject, jint source, jlong imageNativeObj) {" + os.linesep)
302+
test.add_output(
303+
"/*" + os.linesep + \
304+
" * Class: edu_wpi_cscore_CameraServerJNI" + os.linesep + \
305+
" * Method: putSourceFrame" + os.linesep + \
306+
" * Signature: (IJ)V" + os.linesep + \
307+
" */" + os.linesep + \
308+
"JNIEXPORT void JNICALL" + os.linesep + \
309+
"Java_edu_wpi_cscore_CameraServerJNI_putSourceFrame" + os.linesep + \
310+
" (JNIEnv *env, jobject, jint source, jlong imageNativeObj)" + os.linesep + \
311+
"{" + os.linesep, True, True)
312+
313+
# Args > 80 characters long
314+
test.add_input("./TestJNI.cpp",
315+
"JNIEXPORT jint JNICALL Java_edu_wpi_cscore_CameraServerJNI_createSourceProperty(" + os.linesep + \
316+
" JNIEnv *env, jobject, jint source, jstring name, jint kind, jint minimum," + os.linesep + \
317+
" jint maximum, jint step, jint defaultValue, jint value) {" + os.linesep)
318+
test.add_output(
319+
"/*" + os.linesep + \
320+
" * Class: edu_wpi_cscore_CameraServerJNI" + os.linesep + \
321+
" * Method: createSourceProperty" + os.linesep + \
322+
" * Signature: (ILjava/lang/String;IIIIII)I" + os.linesep + \
323+
" */" + os.linesep + \
324+
"JNIEXPORT jint JNICALL" + os.linesep + \
325+
"Java_edu_wpi_cscore_CameraServerJNI_createSourceProperty" + os.linesep + \
326+
" (JNIEnv *env, jobject, jint source, jstring name, jint kind, jint minimum," + os.linesep + \
327+
" jint maximum, jint step, jint defaultValue, jint value)" + os.linesep + \
328+
"{" + os.linesep, True, True)
329+
330+
# Ensure fixes clang-format output aligned with "("
331+
test.add_input("./TestJNI.cpp",
332+
"JNIEXPORT jint JNICALL" + os.linesep + \
333+
"Java_edu_wpi_first_networktables_NetworkTablesJNI_createInstance(JNIEnv*," + os.linesep + \
334+
" jobject) {" + os.linesep)
335+
test.add_output(
336+
"/*" + os.linesep + \
337+
" * Class: edu_wpi_first_networktables_NetworkTablesJNI" + os.linesep + \
338+
" * Method: createInstance" + os.linesep + \
339+
" * Signature: ()I" + os.linesep + \
340+
" */" + os.linesep + \
341+
"JNIEXPORT jint JNICALL" + os.linesep + \
342+
"Java_edu_wpi_first_networktables_NetworkTablesJNI_createInstance" + os.linesep + \
343+
" (JNIEnv*, jobject)" + os.linesep + \
344+
"{" + os.linesep, True, True)
345+
346+
# Idempotence for same code
347+
test.add_input("./TestJNI.cpp",
348+
"/*" + os.linesep + \
349+
" * Class: edu_wpi_first_networktables_NetworkTablesJNI" + os.linesep + \
350+
" * Method: createInstance" + os.linesep + \
351+
" * Signature: ()I" + os.linesep + \
352+
" */" + os.linesep + \
353+
"JNIEXPORT jint JNICALL" + os.linesep + \
354+
"Java_edu_wpi_first_networktables_NetworkTablesJNI_createInstance" + os.linesep + \
355+
" (JNIEnv*, jobject)" + os.linesep + \
356+
"{" + os.linesep)
357+
test.add_latest_input_as_output(True)
358+
359+
# Idempotence for same code with named jobject variable
360+
test.add_input("./TestJNI.cpp",
361+
"/*" + os.linesep + \
362+
" * Class: edu_wpi_first_networktables_NetworkTablesJNI" + os.linesep + \
363+
" * Method: createInstance" + os.linesep + \
364+
" * Signature: ()I" + os.linesep + \
365+
" */" + os.linesep + \
366+
"JNIEXPORT jint JNICALL" + os.linesep + \
367+
"Java_edu_wpi_first_networktables_NetworkTablesJNI_createInstance" + os.linesep + \
368+
" (JNIEnv*, jobject class)" + os.linesep + \
369+
"{" + os.linesep)
370+
test.add_latest_input_as_output(True)
371+
372+
# Check signature that breaks verbose regexes
373+
test.add_input("./NetworkTablesJNI.cpp",
374+
"/*" + os.linesep + \
375+
" * Class: edu_wpi_first_networktables_NetworkTablesJNI" + os.linesep + \
376+
" * Method: getEntry" + os.linesep + \
377+
" * Signature: (ILjava/lang/String;)I" + os.linesep + \
378+
" */" + os.linesep + \
379+
"JNIEXPORT jint JNICALL" + os.linesep + \
380+
"Java_edu_wpi_first_networktables_NetworkTablesJNI_getEntry(JNIEnv* env, jobject," + os.linesep + \
381+
" jint inst," + os.linesep + \
382+
" jstring key) {" + os.linesep)
383+
test.add_output("/*" + os.linesep + \
384+
" * Class: edu_wpi_first_networktables_NetworkTablesJNI" + os.linesep + \
385+
" * Method: getEntry" + os.linesep + \
386+
" * Signature: (ILjava/lang/String;)I" + os.linesep + \
387+
" */" + os.linesep + \
388+
"JNIEXPORT jint JNICALL" + os.linesep + \
389+
"Java_edu_wpi_first_networktables_NetworkTablesJNI_getEntry" + os.linesep + \
390+
" (JNIEnv* env, jobject, jint inst, jstring key)" + os.linesep + \
391+
"{" + os.linesep, True, True)
392+
393+
# Function with array type as argument
394+
test.add_input("./NetworkTablesJNI.cpp",
395+
"/*" + os.linesep + \
396+
" * Class: edu_wpi_first_networktables_NetworkTablesJNI" + os.linesep + \
397+
" * Method: getEntries" + os.linesep + \
398+
" * Signature: (ILjava/lang/String;I)[I" + os.linesep + \
399+
" */" + os.linesep + \
400+
"JNIEXPORT jintArray JNICALL" + os.linesep + \
401+
"Java_edu_wpi_first_networktables_NetworkTablesJNI_getEntries(JNIEnv* env," + os.linesep + \
402+
" jobject, jint inst," + os.linesep + \
403+
" jstring prefix," + os.linesep + \
404+
" jint types) {" + os.linesep)
405+
test.add_output("/*" + os.linesep + \
406+
" * Class: edu_wpi_first_networktables_NetworkTablesJNI" + os.linesep + \
407+
" * Method: getEntries" + os.linesep + \
408+
" * Signature: (ILjava/lang/String;I)[I" + os.linesep + \
409+
" */" + os.linesep + \
410+
"JNIEXPORT jintArray JNICALL" + os.linesep + \
411+
"Java_edu_wpi_first_networktables_NetworkTablesJNI_getEntries" + os.linesep + \
412+
" (JNIEnv* env, jobject, jint inst, jstring prefix, jint types)" + os.linesep + \
413+
"{" + os.linesep, True, True)
414+
415+
# Ensure functions with overloads are handled correctly
416+
test.add_input("./NetworkTablesJNI.cpp",
417+
"/*" + os.linesep + \
418+
" * Class: edu_wpi_first_networktables_NetworkTablesJNI" + os.linesep + \
419+
" * Method: setRaw" + os.linesep + \
420+
" * Signature: (IJ[BZ)Z" + os.linesep + \
421+
" */" + os.linesep + \
422+
"JNIEXPORT jboolean JNICALL" + os.linesep + \
423+
"Java_edu_wpi_first_networktables_NetworkTablesJNI_setRaw__IJ_3BZ" + os.linesep + \
424+
" (JNIEnv* env, jobject, jint entry, jlong time, jbyteArray value," + os.linesep + \
425+
" jboolean force)" + os.linesep + \
426+
"{" + os.linesep)
427+
test.add_latest_input_as_output(True)
428+
429+
# Ensure text before JNIEXPORT and after args and ")" is handled correctly
430+
# as well as two JNI functions in a row
431+
test.add_input("./TestJNI.cpp",
432+
"/**" + os.linesep + \
433+
" *" + os.linesep + \
434+
" */" + os.linesep + \
435+
"JNIEXPORT jint JNICALL" + os.linesep + \
436+
"Java_edu_wpi_first_networktables_NetworkTablesJNI_getDefaultInstance" + os.linesep + \
437+
" (JNIEnv *, jobject)" + os.linesep + \
438+
"{" + os.linesep + \
439+
" return nt::GetDefaultInstance();" + os.linesep + \
440+
"}" + os.linesep + \
441+
os.linesep + \
442+
"JNIEXPORT jint JNICALL" + os.linesep + \
443+
"Java_edu_wpi_first_networktables_NetworkTablesJNI_createInstance" + os.linesep + \
444+
" (JNIEnv *, jobject)" + os.linesep + \
445+
"{" + os.linesep + \
446+
" return nt::CreateInstance();" + os.linesep + \
447+
"}" + os.linesep)
448+
test.add_output(
449+
"/*" + os.linesep + \
450+
" * Class: edu_wpi_first_networktables_NetworkTablesJNI" + os.linesep + \
451+
" * Method: getDefaultInstance" + os.linesep + \
452+
" * Signature: ()I" + os.linesep + \
453+
" */" + os.linesep + \
454+
"JNIEXPORT jint JNICALL" + os.linesep + \
455+
"Java_edu_wpi_first_networktables_NetworkTablesJNI_getDefaultInstance" + os.linesep + \
456+
" (JNIEnv *, jobject)" + os.linesep + \
457+
"{" + os.linesep + \
458+
" return nt::GetDefaultInstance();" + os.linesep + \
459+
"}" + os.linesep + \
460+
os.linesep + \
461+
"/*" + os.linesep + \
462+
" * Class: edu_wpi_first_networktables_NetworkTablesJNI" + os.linesep + \
463+
" * Method: createInstance" + os.linesep + \
464+
" * Signature: ()I" + os.linesep + \
465+
" */" + os.linesep + \
466+
"JNIEXPORT jint JNICALL" + os.linesep + \
467+
"Java_edu_wpi_first_networktables_NetworkTablesJNI_createInstance" + os.linesep + \
468+
" (JNIEnv *, jobject)" + os.linesep + \
469+
"{" + os.linesep + \
470+
" return nt::CreateInstance();" + os.linesep + \
471+
"}" + os.linesep, True, True)
472+
473+
# Handle function declarations properly
474+
test.add_input("./TestJNI.cpp",
475+
"/*" + os.linesep + \
476+
" * Class: edu_wpi_first_networktables_NetworkTablesJNI" + os.linesep + \
477+
" * Method: getDefaultInstance" + os.linesep + \
478+
" * Signature: ()I" + os.linesep + \
479+
" */" + os.linesep + \
480+
"JNIEXPORT jint JNICALL" + os.linesep + \
481+
"Java_edu_wpi_first_networktables_NetworkTablesJNI_getDefaultInstance" + os.linesep + \
482+
" (JNIEnv *, jobject);" + os.linesep + \
483+
os.linesep + \
484+
"/*" + os.linesep + \
485+
" * Class: edu_wpi_first_networktables_NetworkTablesJNI" + os.linesep + \
486+
" * Method: createInstance" + os.linesep + \
487+
" * Signature: ()I" + os.linesep + \
488+
" */" + os.linesep + \
489+
"JNIEXPORT jint JNICALL" + os.linesep + \
490+
"Java_edu_wpi_first_networktables_NetworkTablesJNI_createInstance" + os.linesep + \
491+
" (JNIEnv *, jobject)" + os.linesep + \
492+
"{" + os.linesep + \
493+
" return nt::CreateInstance();" + os.linesep + \
494+
"}" + os.linesep)
495+
test.add_latest_input_as_output(True)
496+
497+
# Handle functions whose arguments don't have variable names properly
498+
test.add_input("./DigitalGlitchFilterJNI.cpp",
499+
"/*" + os.linesep + \
500+
" * Class: edu_wpi_first_wpilibj_hal_DigitalGlitchFilterJNI" + os.linesep + \
501+
" * Method: cleanFilter" + os.linesep + \
502+
" * Signature: (I)V" + os.linesep + \
503+
" */" + os.linesep + \
504+
"JNIEXPORT void JNICALL Java_edu_wpi_first_wpilibj_hal_DigitalGlitchFilterJNI_cleanFilter" + os.linesep + \
505+
" (JNIEnv *, jobject, jint)" + os.linesep + \
506+
"{" + os.linesep + \
507+
" HAL_CleanFilter(handle);" + os.linesep + \
508+
"}" + os.linesep)
509+
test.add_output(
510+
"/*" + os.linesep + \
511+
" * Class: edu_wpi_first_wpilibj_hal_DigitalGlitchFilterJNI" + os.linesep + \
512+
" * Method: cleanFilter" + os.linesep + \
513+
" * Signature: (I)V" + os.linesep + \
514+
" */" + os.linesep + \
515+
"JNIEXPORT void JNICALL" + os.linesep + \
516+
"Java_edu_wpi_first_wpilibj_hal_DigitalGlitchFilterJNI_cleanFilter" + os.linesep + \
517+
" (JNIEnv *, jobject, jint)" + os.linesep + \
518+
"{" + os.linesep + \
519+
" HAL_CleanFilter(handle);" + os.linesep + \
520+
"}" + os.linesep, True, True)
521+
266522
test.run(OutputType.FILE)

0 commit comments

Comments
 (0)