[jnigen] improve coverage (https://github.com/dart-lang/jnigen/issues/274)

diff --git a/pkgs/jni/lib/src/jarray.dart b/pkgs/jni/lib/src/jarray.dart
index fe92e05..b07cee0 100644
--- a/pkgs/jni/lib/src/jarray.dart
+++ b/pkgs/jni/lib/src/jarray.dart
@@ -38,8 +38,8 @@
 
   @override
   bool operator ==(Object other) {
-    return other.runtimeType == JArrayType &&
-        other is JArrayType &&
+    return other.runtimeType == (JArrayType<T>) &&
+        other is JArrayType<T> &&
         elementType == other.elementType;
   }
 }
@@ -62,7 +62,17 @@
   ///
   /// The [length] must be a non-negative integer.
   factory JArray(JType<E> type, int length) {
-    if (type.callType == JniCallType.objectType && type is JObjType) {
+    const primitiveCallTypes = {
+      'B': JniCallType.byteType,
+      'Z': JniCallType.booleanType,
+      'C': JniCallType.charType,
+      'S': JniCallType.shortType,
+      'I': JniCallType.intType,
+      'J': JniCallType.longType,
+      'F': JniCallType.floatType,
+      'D': JniCallType.doubleType,
+    };
+    if (!primitiveCallTypes.containsKey(type.signature) && type is JObjType) {
       final clazz = (type as JObjType).getClass();
       final array = JArray<E>.fromRef(
         type,
@@ -73,7 +83,9 @@
     }
     return JArray.fromRef(
       type,
-      Jni.accessors.newPrimitiveArray(length, type.callType).object,
+      Jni.accessors
+          .newPrimitiveArray(length, primitiveCallTypes[type.signature]!)
+          .object,
     );
   }
 
@@ -357,16 +369,3 @@
     });
   }
 }
-
-extension ArrayArray<T> on JArray<JArray<T>> {
-  JArray<T> operator [](int index) {
-    return JArray<T>.fromRef(
-      (elementType as JArrayType<T>).elementType,
-      elementAt(index, JniCallType.objectType).object,
-    );
-  }
-
-  void operator []=(int index, JArray<T> value) {
-    (this as JArray<JObject>)[index] = value;
-  }
-}
diff --git a/pkgs/jni/lib/src/jprimitives.dart b/pkgs/jni/lib/src/jprimitives.dart
index f7f8a9a..6722557 100644
--- a/pkgs/jni/lib/src/jprimitives.dart
+++ b/pkgs/jni/lib/src/jprimitives.dart
@@ -6,7 +6,6 @@
 // lowercase.
 // ignore_for_file: camel_case_types
 
-import 'third_party/generated_bindings.dart';
 import 'types.dart';
 
 abstract class JPrimitive {}
@@ -19,10 +18,7 @@
   const jbyteType();
 
   @override
-  int get callType => JniCallType.byteType;
-
-  @override
-  String get signature => "B";
+  final signature = 'B';
 }
 
 abstract class jboolean extends JPrimitive {
@@ -33,10 +29,7 @@
   const jbooleanType();
 
   @override
-  int get callType => JniCallType.booleanType;
-
-  @override
-  String get signature => "Z";
+  final signature = 'Z';
 }
 
 abstract class jchar extends JPrimitive {
@@ -47,10 +40,7 @@
   const jcharType();
 
   @override
-  int get callType => JniCallType.charType;
-
-  @override
-  String get signature => "C";
+  final signature = 'C';
 }
 
 abstract class jshort extends JPrimitive {
@@ -61,10 +51,7 @@
   const jshortType();
 
   @override
-  int get callType => JniCallType.shortType;
-
-  @override
-  String get signature => "S";
+  final signature = 'S';
 }
 
 abstract class jint extends JPrimitive {
@@ -75,10 +62,7 @@
   const jintType();
 
   @override
-  int get callType => JniCallType.intType;
-
-  @override
-  String get signature => "I";
+  final signature = 'I';
 }
 
 abstract class jlong extends JPrimitive {
@@ -89,10 +73,7 @@
   const jlongType();
 
   @override
-  int get callType => JniCallType.longType;
-
-  @override
-  String get signature => "J";
+  final signature = 'J';
 }
 
 abstract class jfloat extends JPrimitive {
@@ -103,10 +84,7 @@
   const jfloatType();
 
   @override
-  int get callType => JniCallType.floatType;
-
-  @override
-  String get signature => "F";
+  final signature = 'F';
 }
 
 abstract class jdouble extends JPrimitive {
@@ -117,8 +95,5 @@
   const jdoubleType();
 
   @override
-  int get callType => JniCallType.doubleType;
-
-  @override
-  String get signature => "D";
+  final signature = 'D';
 }
diff --git a/pkgs/jni/lib/src/types.dart b/pkgs/jni/lib/src/types.dart
index 64df75c..c6f44b6 100644
--- a/pkgs/jni/lib/src/types.dart
+++ b/pkgs/jni/lib/src/types.dart
@@ -6,13 +6,10 @@
 
 import 'jni.dart';
 import 'jobject.dart';
-import 'third_party/generated_bindings.dart';
 
 abstract class JType<T> {
   const JType();
 
-  int get callType;
-
   String get signature;
 }
 
@@ -24,9 +21,6 @@
 
   const JObjType();
 
-  @override
-  int get callType => JniCallType.objectType;
-
   /// Creates an object from this type using the reference.
   T fromRef(Pointer<Void> ref);
 
diff --git a/pkgs/jni/test/jarray_test.dart b/pkgs/jni/test/jarray_test.dart
index d0bc8cf..18550e5 100644
--- a/pkgs/jni/test/jarray_test.dart
+++ b/pkgs/jni/test/jarray_test.dart
@@ -144,6 +144,31 @@
       }, throwsRangeError);
     });
   });
+  testRunner("Java long array", () {
+    using((arena) {
+      final array = JArray(jlong.type, 3)..deletedIn(arena);
+      expect(array.length, 3);
+      array[0] = 1;
+      array[1] = 2;
+      array[2] = 3 + 256 * 256 * 256 * 256 * 5;
+      expect(array[0], 1);
+      expect(array[1], 2);
+      expect(array[2], 3 + 256 * 256 * 256 * 256 * 5);
+      array.setRange(0, 3, [4, 5, 6, 7], 1);
+      expect(array[0], 5);
+      expect(array[1], 6);
+      expect(array[2], 7);
+      expect(() {
+        final _ = array[-1];
+      }, throwsRangeError);
+      expect(() {
+        array[-1] = 4;
+      }, throwsRangeError);
+      expect(() {
+        array[3] = 4;
+      }, throwsRangeError);
+    });
+  });
   const epsilon = 1e-6;
   testRunner("Java float array", () {
     using((arena) {
diff --git a/pkgs/jni/test/type_test.dart b/pkgs/jni/test/type_test.dart
index ffc11d6..f0f3caa 100644
--- a/pkgs/jni/test/type_test.dart
+++ b/pkgs/jni/test/type_test.dart
@@ -236,6 +236,32 @@
     expect(lowestCommonSuperType([JByte.type, JBoolean.type]), JObject.type);
   });
 
+  testRunner('array types', () {
+    using((arena) {
+      expect(
+        lowestCommonSuperType([
+          JArray.type(jint.type),
+          JArray.type(jint.type),
+        ]),
+        JArray.type(jint.type),
+      );
+      expect(
+        lowestCommonSuperType([
+          JArray.type(JObject.type),
+          JArray.type(JObject.type),
+        ]),
+        JArray.type(JObject.type),
+      );
+      expect(
+        lowestCommonSuperType([
+          JArray.type(JObject.type),
+          JArray.type(jint.type),
+        ]),
+        JObject.type,
+      );
+    });
+  });
+
   testRunner('util types', () {
     using((arena) {
       expect(
diff --git a/pkgs/jnigen/lib/src/bindings/visitor.dart b/pkgs/jnigen/lib/src/bindings/visitor.dart
index c2bf9e6..417180c 100644
--- a/pkgs/jnigen/lib/src/bindings/visitor.dart
+++ b/pkgs/jnigen/lib/src/bindings/visitor.dart
@@ -28,13 +28,6 @@
   }
 }
 
-extension MultiTypeVisitor<T extends ReferredType> on Iterable<T> {
-  /// Accepts all lazily. Remember to call `.toList()` or similar methods!
-  Iterable<R> accept<R>(TypeVisitor<R> v) {
-    return map((e) => e.accept(v));
-  }
-}
-
 extension MultiTypeUsageVisitor on Iterable<TypeUsage> {
   /// Accepts all lazily. Remember to call `.toList()` or similar methods!
   Iterable<R> accept<R>(TypeVisitor<R> v) {