From 8752e638c23b5ff2e760d35554b9e7aa5f0ae76d Mon Sep 17 00:00:00 2001 From: Jonathan Pryor Date: Tue, 19 Nov 2019 10:05:20 -0500 Subject: [PATCH 01/33] Add #nullable for IJavaPeerable, JniEnvironment --- src/Java.Interop/Java.Interop.csproj | 19 +++++++++++++++---- .../Java.Interop/IJavaPeerable.cs | 2 ++ .../Java.Interop/JniEnvironment.Errors.cs | 4 +++- .../Java.Interop/JniEnvironment.Monitors.cs | 4 +++- .../Java.Interop/JniEnvironment.Object.cs | 4 +++- .../Java.Interop/JniEnvironment.References.cs | 2 ++ .../Java.Interop/JniEnvironment.Strings.cs | 10 ++++++---- .../Java.Interop/JniEnvironment.Types.cs | 19 +++++++++++++++---- .../Java.Interop/JniEnvironment.cs | 18 ++++++++++++------ 9 files changed, 61 insertions(+), 21 deletions(-) diff --git a/src/Java.Interop/Java.Interop.csproj b/src/Java.Interop/Java.Interop.csproj index 79f62ff99..cc2b4a66e 100644 --- a/src/Java.Interop/Java.Interop.csproj +++ b/src/Java.Interop/Java.Interop.csproj @@ -2,7 +2,6 @@ netstandard2.0 - {94BD81F7-B06F-4295-9636-F8A3B6BDC762} 1591 true ..\..\product.snk @@ -14,18 +13,21 @@ ..\..\bin\Debug ..\..\bin\Debug\Java.Interop.xml ..\..\bin\BuildDebug - DEBUG;$(DefineConstants) + INTEROP;FEATURE_JNIENVIRONMENT_JI_PINVOKES;FEATURE_JNIOBJECTREFERENCE_INTPTRS;DEBUG;NETSTANDARD;NETSTANDARD2_0 + 8.0 ..\..\bin\GendarmeDebug DEBUG;$(DefineConstants) ..\..\bin\Debug\Java.Interop.xml ..\..\bin\BuildDebug + 8.0 ..\..\bin\Release ..\..\bin\Release\Java.Interop.xml ..\..\bin\BuildRelease + 8.0 @@ -64,9 +66,18 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - {6410DA0F-5E14-4FC0-9AEE-F4C542C96C7A} - jnienv-gen False + + + + + + + + + + + \ No newline at end of file diff --git a/src/Java.Interop/Java.Interop/IJavaPeerable.cs b/src/Java.Interop/Java.Interop/IJavaPeerable.cs index f98a74721..612744b10 100644 --- a/src/Java.Interop/Java.Interop/IJavaPeerable.cs +++ b/src/Java.Interop/Java.Interop/IJavaPeerable.cs @@ -1,3 +1,5 @@ +#nullable enable + using System; namespace Java.Interop diff --git a/src/Java.Interop/Java.Interop/JniEnvironment.Errors.cs b/src/Java.Interop/Java.Interop/JniEnvironment.Errors.cs index acf281aa3..f88cd8d58 100644 --- a/src/Java.Interop/Java.Interop/JniEnvironment.Errors.cs +++ b/src/Java.Interop/Java.Interop/JniEnvironment.Errors.cs @@ -1,4 +1,6 @@ -using System; +#nullable enable + +using System; namespace Java.Interop { partial class JniEnvironment { diff --git a/src/Java.Interop/Java.Interop/JniEnvironment.Monitors.cs b/src/Java.Interop/Java.Interop/JniEnvironment.Monitors.cs index b8902845b..eaa458238 100644 --- a/src/Java.Interop/Java.Interop/JniEnvironment.Monitors.cs +++ b/src/Java.Interop/Java.Interop/JniEnvironment.Monitors.cs @@ -1,4 +1,6 @@ -using System; +#nullable enable + +using System; using System.Runtime.ExceptionServices; namespace Java.Interop { diff --git a/src/Java.Interop/Java.Interop/JniEnvironment.Object.cs b/src/Java.Interop/Java.Interop/JniEnvironment.Object.cs index 54081b377..894988bf0 100644 --- a/src/Java.Interop/Java.Interop/JniEnvironment.Object.cs +++ b/src/Java.Interop/Java.Interop/JniEnvironment.Object.cs @@ -1,4 +1,6 @@ -using System; +#nullable enable + +using System; namespace Java.Interop { diff --git a/src/Java.Interop/Java.Interop/JniEnvironment.References.cs b/src/Java.Interop/Java.Interop/JniEnvironment.References.cs index cda6442df..f1b6e8fdb 100644 --- a/src/Java.Interop/Java.Interop/JniEnvironment.References.cs +++ b/src/Java.Interop/Java.Interop/JniEnvironment.References.cs @@ -1,3 +1,5 @@ +#nullable enable + using System; using System.Runtime.ExceptionServices; diff --git a/src/Java.Interop/Java.Interop/JniEnvironment.Strings.cs b/src/Java.Interop/Java.Interop/JniEnvironment.Strings.cs index c2f179b32..9695ab030 100644 --- a/src/Java.Interop/Java.Interop/JniEnvironment.Strings.cs +++ b/src/Java.Interop/Java.Interop/JniEnvironment.Strings.cs @@ -1,3 +1,5 @@ +#nullable enable + using System; using System.Diagnostics; @@ -16,24 +18,24 @@ public static unsafe JniObjectReference NewString (string value) } #if !XA_INTEGRATION - public static string ToString (IntPtr reference) + public static string? ToString (IntPtr reference) { return ToString (new JniObjectReference (reference)); } - internal static unsafe string ToString (ref JniObjectReference reference, JniObjectReferenceOptions transfer, Type targetType) + internal static unsafe string? ToString (ref JniObjectReference reference, JniObjectReferenceOptions transfer, Type targetType) { Debug.Assert (targetType == typeof (string), "Expected targetType==typeof(string); was: " + targetType); return ToString (ref reference, transfer); } #endif // !XA_INTEGRATION - public static unsafe string ToString (JniObjectReference value) + public static unsafe string? ToString (JniObjectReference value) { return ToString (ref value, JniObjectReferenceOptions.Copy); } - public static unsafe string ToString (ref JniObjectReference value, JniObjectReferenceOptions transfer) + public static unsafe string? ToString (ref JniObjectReference value, JniObjectReferenceOptions transfer) { if (!value.IsValid) return null; diff --git a/src/Java.Interop/Java.Interop/JniEnvironment.Types.cs b/src/Java.Interop/Java.Interop/JniEnvironment.Types.cs index 292079054..ccf041a7b 100644 --- a/src/Java.Interop/Java.Interop/JniEnvironment.Types.cs +++ b/src/Java.Interop/Java.Interop/JniEnvironment.Types.cs @@ -1,3 +1,5 @@ +#nullable enable + using System; using System.Collections.Generic; using System.Text; @@ -95,16 +97,22 @@ public static unsafe JniObjectReference FindClass (string classname) #endif // !FEATURE_JNIOBJECTREFERENCE_SAFEHANDLES } - public static JniType GetTypeFromInstance (JniObjectReference instance) + public static JniType? GetTypeFromInstance (JniObjectReference instance) { + if (!instance.IsValid) + return null; + var lref = JniEnvironment.Types.GetObjectClass (instance); if (lref.IsValid) return new JniType (ref lref, JniObjectReferenceOptions.CopyAndDispose); return null; } - public static string GetJniTypeNameFromInstance (JniObjectReference instance) + public static string? GetJniTypeNameFromInstance (JniObjectReference instance) { + if (!instance.IsValid) + return null; + var lref = GetObjectClass (instance); try { return GetJniTypeNameFromClass (lref); @@ -114,10 +122,13 @@ public static string GetJniTypeNameFromInstance (JniObjectReference instance) } } - public static string GetJniTypeNameFromClass (JniObjectReference type) + public static string? GetJniTypeNameFromClass (JniObjectReference type) { + if (!type.IsValid) + return null; + var s = JniEnvironment.InstanceMethods.CallObjectMethod (type, Class_getName); - return JavaClassToJniType (Strings.ToString (ref s, JniObjectReferenceOptions.CopyAndDispose)); + return JavaClassToJniType (Strings.ToString (ref s, JniObjectReferenceOptions.CopyAndDispose)!); } static string JavaClassToJniType (string value) diff --git a/src/Java.Interop/Java.Interop/JniEnvironment.cs b/src/Java.Interop/Java.Interop/JniEnvironment.cs index 88b9c6b18..f8dfd6b74 100644 --- a/src/Java.Interop/Java.Interop/JniEnvironment.cs +++ b/src/Java.Interop/Java.Interop/JniEnvironment.cs @@ -1,3 +1,5 @@ +#nullable enable + using System; using System.Collections.Generic; using System.Diagnostics; @@ -67,7 +69,7 @@ internal static void SetEnvironmentInfo (JniEnvironmentInfo info) Info.Value = info; } - internal static Exception GetExceptionForLastThrowable () + internal static Exception? GetExceptionForLastThrowable () { var e = JniEnvironment.Exceptions.ExceptionOccurred (); if (!e.IsValid) @@ -78,7 +80,7 @@ internal static Exception GetExceptionForLastThrowable () return Runtime.GetExceptionForThrowable (ref e, JniObjectReferenceOptions.CopyAndDispose); } - internal static Exception GetExceptionForLastThrowable (IntPtr thrown) + internal static Exception? GetExceptionForLastThrowable (IntPtr thrown) { if (thrown == IntPtr.Zero) return null; @@ -183,14 +185,18 @@ sealed class JniEnvironmentInfo : IDisposable { const int NameBufferLength = 512; IntPtr environmentPointer; - char[] nameBuffer; + char[]? nameBuffer; bool disposed; + JniRuntime? runtime; - public JniRuntime Runtime {get; private set;} public int LocalReferenceCount {get; internal set;} public bool WithinNewObjectScope {get; set;} + public JniRuntime Runtime { + get => runtime ?? throw new ObjectDisposedException (nameof (JniEnvironmentInfo)); + private set => runtime = value; + } - public IntPtr EnvironmentPointer { + public IntPtr EnvironmentPointer { get {return environmentPointer;} set { if (disposed) @@ -266,7 +272,7 @@ public void Dispose () { if (disposed) return; - Runtime = null; + runtime = null; environmentPointer = IntPtr.Zero; nameBuffer = null; LocalReferenceCount = 0; From 9d0994ebc112835725cbd22b3120169bdb3eadbc Mon Sep 17 00:00:00 2001 From: Jonathan Pryor Date: Tue, 19 Nov 2019 11:30:55 -0500 Subject: [PATCH 02/33] Add #nullable for more types Add `#nullable enable` for: * `JavaArray` * `JavaException` * `JavaObject` * `JavaObjectArray` * `JavaPeerableExtensions` * `JavaPrimitiveArrays` * `JniFieldInfo` * `JniMarshal` --- src/Java.Interop/Java.Interop.csproj | 5 ++ src/Java.Interop/Java.Interop/JavaArray.cs | 6 +- .../Java.Interop/JavaException.cs | 10 +-- src/Java.Interop/Java.Interop/JavaObject.cs | 4 +- .../Java.Interop/JavaObjectArray.cs | 6 +- .../Java.Interop/JavaPeerableExtensions.cs | 4 +- .../Java.Interop/JavaPrimitiveArrays.cs | 67 ++++++++++++++----- .../Java.Interop/JavaPrimitiveArrays.tt | 9 ++- src/Java.Interop/Java.Interop/JniFieldInfo.cs | 12 ++-- src/Java.Interop/Java.Interop/JniMarshal.cs | 6 +- 10 files changed, 95 insertions(+), 34 deletions(-) diff --git a/src/Java.Interop/Java.Interop.csproj b/src/Java.Interop/Java.Interop.csproj index cc2b4a66e..50d785da4 100644 --- a/src/Java.Interop/Java.Interop.csproj +++ b/src/Java.Interop/Java.Interop.csproj @@ -69,6 +69,11 @@ False + + + JavaPrimitiveArrays.tt + + diff --git a/src/Java.Interop/Java.Interop/JavaArray.cs b/src/Java.Interop/Java.Interop/JavaArray.cs index 9c7bc19f7..7c50ba981 100644 --- a/src/Java.Interop/Java.Interop/JavaArray.cs +++ b/src/Java.Interop/Java.Interop/JavaArray.cs @@ -1,3 +1,5 @@ +#nullable enable + using System; using System.Collections; using System.Collections.Generic; @@ -217,9 +219,11 @@ bool IList.IsFixedSize { } } - object IList.this [int index] { + object? IList.this [int index] { get {return this [index];} +#pragma warning disable 8601 set {this [index] = (T) value;} +#pragma warning restore 8601 } void ICollection.CopyTo (Array array, int index) diff --git a/src/Java.Interop/Java.Interop/JavaException.cs b/src/Java.Interop/Java.Interop/JavaException.cs index cab90b613..868fe4ddf 100644 --- a/src/Java.Interop/Java.Interop/JavaException.cs +++ b/src/Java.Interop/Java.Interop/JavaException.cs @@ -1,3 +1,5 @@ +#nullable enable + using System; namespace Java.Interop @@ -8,7 +10,7 @@ unsafe public class JavaException : Exception, IJavaPeerable internal const string JniTypeName = "java/lang/Throwable"; readonly static JniPeerMembers _members = new JniPeerMembers (JniTypeName, typeof (JavaException)); - public string JavaStackTrace { get; private set; } + public string? JavaStackTrace { get; private set; } public int JniIdentityHashCode { get; private set; } public JniManagedPeerStates JniManagedPeerState { get; private set; } @@ -177,7 +179,7 @@ public override unsafe int GetHashCode () return _members.InstanceMethods.InvokeVirtualInt32Method ("hashCode.()I", this, null); } - static string GetMessage (ref JniObjectReference reference, JniObjectReferenceOptions transfer) + static string? GetMessage (ref JniObjectReference reference, JniObjectReferenceOptions transfer) { if (transfer == JniObjectReferenceOptions.None) return null; @@ -187,7 +189,7 @@ static string GetMessage (ref JniObjectReference reference, JniObjectReferenceOp return JniEnvironment.Strings.ToString (ref s, JniObjectReferenceOptions.CopyAndDispose); } - static Exception GetCause (ref JniObjectReference reference, JniObjectReferenceOptions transfer) + static Exception? GetCause (ref JniObjectReference reference, JniObjectReferenceOptions transfer) { if (transfer == JniObjectReferenceOptions.None) return null; @@ -197,7 +199,7 @@ static Exception GetCause (ref JniObjectReference reference, JniObjectReferenceO return JniEnvironment.Runtime.GetExceptionForThrowable (ref e, JniObjectReferenceOptions.CopyAndDispose); } - unsafe string GetJavaStack (JniObjectReference handle) + unsafe string? GetJavaStack (JniObjectReference handle) { using (var StringWriter_class = new JniType ("java/io/StringWriter")) using (var PrintWriter_class = new JniType ("java/io/PrintWriter")) { diff --git a/src/Java.Interop/Java.Interop/JavaObject.cs b/src/Java.Interop/Java.Interop/JavaObject.cs index 0de3258d9..b8c5e242b 100644 --- a/src/Java.Interop/Java.Interop/JavaObject.cs +++ b/src/Java.Interop/Java.Interop/JavaObject.cs @@ -1,3 +1,5 @@ +#nullable enable + using System; namespace Java.Interop @@ -125,7 +127,7 @@ public override unsafe int GetHashCode () return _members.InstanceMethods.InvokeVirtualInt32Method ("hashCode.()I", this, null); } - public override unsafe string ToString () + public override unsafe string? ToString () { var lref = _members.InstanceMethods.InvokeVirtualObjectMethod ( "toString.()Ljava/lang/String;", diff --git a/src/Java.Interop/Java.Interop/JavaObjectArray.cs b/src/Java.Interop/Java.Interop/JavaObjectArray.cs index f2db1bc3f..0ffe9f8c7 100644 --- a/src/Java.Interop/Java.Interop/JavaObjectArray.cs +++ b/src/Java.Interop/Java.Interop/JavaObjectArray.cs @@ -1,4 +1,6 @@ -using System; +#nullable enable + +using System; using System.Collections.Generic; using System.Reflection; @@ -84,11 +86,13 @@ public override void Clear () { int len = Length; var vm = JniEnvironment.Runtime.ValueManager.GetValueMarshaler (); +#pragma warning disable 8653 var s = vm.CreateArgumentState (default (T)); for (int i = 0; i < len; i++) { JniEnvironment.Arrays.SetObjectArrayElement (PeerReference, i, s.ReferenceValue); } vm.DestroyGenericArgumentState (default (T), ref s, 0); +#pragma warning restore 8653 } public override int IndexOf (T item) diff --git a/src/Java.Interop/Java.Interop/JavaPeerableExtensions.cs b/src/Java.Interop/Java.Interop/JavaPeerableExtensions.cs index 2b428d77c..e6e7e1691 100644 --- a/src/Java.Interop/Java.Interop/JavaPeerableExtensions.cs +++ b/src/Java.Interop/Java.Interop/JavaPeerableExtensions.cs @@ -1,10 +1,12 @@ +#nullable enable + using System; namespace Java.Interop { public static class JavaPeerableExtensions { - public static string GetJniTypeName (this IJavaPeerable self) + public static string? GetJniTypeName (this IJavaPeerable self) { JniPeerMembers.AssertSelf (self); return JniEnvironment.Types.GetJniTypeNameFromInstance (self.PeerReference); diff --git a/src/Java.Interop/Java.Interop/JavaPrimitiveArrays.cs b/src/Java.Interop/Java.Interop/JavaPrimitiveArrays.cs index 48bceb332..4ccf7151d 100644 --- a/src/Java.Interop/Java.Interop/JavaPrimitiveArrays.cs +++ b/src/Java.Interop/Java.Interop/JavaPrimitiveArrays.cs @@ -1,4 +1,5 @@ - +#nullable enable + using System; using System.Collections.Generic; using System.Diagnostics; @@ -140,8 +141,12 @@ protected override JniArrayElements CreateElements () public new unsafe JniBooleanArrayElements GetElements () { + if (!PeerReference.IsValid) + throw new ObjectDisposedException (this.GetType ().FullName); var elements = JniEnvironment.Arrays.GetBooleanArrayElements (PeerReference, null); - return elements == null ? null : new JniBooleanArrayElements (PeerReference, elements, Length*sizeof (Boolean)); + if (elements == null) + throw new InvalidOperationException ("`JniEnvironment.Arrays.GetBooleanArrayElements()` returned NULL!"); + return new JniBooleanArrayElements (PeerReference, elements, Length*sizeof (Boolean)); } public override unsafe int IndexOf (Boolean item) @@ -235,7 +240,7 @@ public override void DestroyGenericArgumentState (IList value, ref JniV JavaArray.DestroyArgumentState (value, ref state, synchronize); } - public override Expression CreateParameterToManagedExpression (JniValueMarshalerContext context, ParameterExpression sourceValue, ParameterAttributes synchronize = 0, Type targetType = null) + public override Expression CreateParameterToManagedExpression (JniValueMarshalerContext context, ParameterExpression sourceValue, ParameterAttributes synchronize = 0, Type? targetType = null) { Func m = JavaBooleanArray.CreateMarshaledValue; @@ -312,8 +317,12 @@ protected override JniArrayElements CreateElements () public new unsafe JniSByteArrayElements GetElements () { + if (!PeerReference.IsValid) + throw new ObjectDisposedException (this.GetType ().FullName); var elements = JniEnvironment.Arrays.GetByteArrayElements (PeerReference, null); - return elements == null ? null : new JniSByteArrayElements (PeerReference, elements, Length*sizeof (SByte)); + if (elements == null) + throw new InvalidOperationException ("`JniEnvironment.Arrays.GetByteArrayElements()` returned NULL!"); + return new JniSByteArrayElements (PeerReference, elements, Length*sizeof (SByte)); } public override unsafe int IndexOf (SByte item) @@ -407,7 +416,7 @@ public override void DestroyGenericArgumentState (IList value, ref JniVal JavaArray.DestroyArgumentState (value, ref state, synchronize); } - public override Expression CreateParameterToManagedExpression (JniValueMarshalerContext context, ParameterExpression sourceValue, ParameterAttributes synchronize = 0, Type targetType = null) + public override Expression CreateParameterToManagedExpression (JniValueMarshalerContext context, ParameterExpression sourceValue, ParameterAttributes synchronize = 0, Type? targetType = null) { Func m = JavaSByteArray.CreateMarshaledValue; @@ -484,8 +493,12 @@ protected override JniArrayElements CreateElements () public new unsafe JniCharArrayElements GetElements () { + if (!PeerReference.IsValid) + throw new ObjectDisposedException (this.GetType ().FullName); var elements = JniEnvironment.Arrays.GetCharArrayElements (PeerReference, null); - return elements == null ? null : new JniCharArrayElements (PeerReference, elements, Length*sizeof (Char)); + if (elements == null) + throw new InvalidOperationException ("`JniEnvironment.Arrays.GetCharArrayElements()` returned NULL!"); + return new JniCharArrayElements (PeerReference, elements, Length*sizeof (Char)); } public override unsafe int IndexOf (Char item) @@ -579,7 +592,7 @@ public override void DestroyGenericArgumentState (IList value, ref JniValu JavaArray.DestroyArgumentState (value, ref state, synchronize); } - public override Expression CreateParameterToManagedExpression (JniValueMarshalerContext context, ParameterExpression sourceValue, ParameterAttributes synchronize = 0, Type targetType = null) + public override Expression CreateParameterToManagedExpression (JniValueMarshalerContext context, ParameterExpression sourceValue, ParameterAttributes synchronize = 0, Type? targetType = null) { Func m = JavaCharArray.CreateMarshaledValue; @@ -656,8 +669,12 @@ protected override JniArrayElements CreateElements () public new unsafe JniInt16ArrayElements GetElements () { + if (!PeerReference.IsValid) + throw new ObjectDisposedException (this.GetType ().FullName); var elements = JniEnvironment.Arrays.GetShortArrayElements (PeerReference, null); - return elements == null ? null : new JniInt16ArrayElements (PeerReference, elements, Length*sizeof (Int16)); + if (elements == null) + throw new InvalidOperationException ("`JniEnvironment.Arrays.GetShortArrayElements()` returned NULL!"); + return new JniInt16ArrayElements (PeerReference, elements, Length*sizeof (Int16)); } public override unsafe int IndexOf (Int16 item) @@ -751,7 +768,7 @@ public override void DestroyGenericArgumentState (IList value, ref JniVal JavaArray.DestroyArgumentState (value, ref state, synchronize); } - public override Expression CreateParameterToManagedExpression (JniValueMarshalerContext context, ParameterExpression sourceValue, ParameterAttributes synchronize = 0, Type targetType = null) + public override Expression CreateParameterToManagedExpression (JniValueMarshalerContext context, ParameterExpression sourceValue, ParameterAttributes synchronize = 0, Type? targetType = null) { Func m = JavaInt16Array.CreateMarshaledValue; @@ -828,8 +845,12 @@ protected override JniArrayElements CreateElements () public new unsafe JniInt32ArrayElements GetElements () { + if (!PeerReference.IsValid) + throw new ObjectDisposedException (this.GetType ().FullName); var elements = JniEnvironment.Arrays.GetIntArrayElements (PeerReference, null); - return elements == null ? null : new JniInt32ArrayElements (PeerReference, elements, Length*sizeof (Int32)); + if (elements == null) + throw new InvalidOperationException ("`JniEnvironment.Arrays.GetIntArrayElements()` returned NULL!"); + return new JniInt32ArrayElements (PeerReference, elements, Length*sizeof (Int32)); } public override unsafe int IndexOf (Int32 item) @@ -923,7 +944,7 @@ public override void DestroyGenericArgumentState (IList value, ref JniVal JavaArray.DestroyArgumentState (value, ref state, synchronize); } - public override Expression CreateParameterToManagedExpression (JniValueMarshalerContext context, ParameterExpression sourceValue, ParameterAttributes synchronize = 0, Type targetType = null) + public override Expression CreateParameterToManagedExpression (JniValueMarshalerContext context, ParameterExpression sourceValue, ParameterAttributes synchronize = 0, Type? targetType = null) { Func m = JavaInt32Array.CreateMarshaledValue; @@ -1000,8 +1021,12 @@ protected override JniArrayElements CreateElements () public new unsafe JniInt64ArrayElements GetElements () { + if (!PeerReference.IsValid) + throw new ObjectDisposedException (this.GetType ().FullName); var elements = JniEnvironment.Arrays.GetLongArrayElements (PeerReference, null); - return elements == null ? null : new JniInt64ArrayElements (PeerReference, elements, Length*sizeof (Int64)); + if (elements == null) + throw new InvalidOperationException ("`JniEnvironment.Arrays.GetLongArrayElements()` returned NULL!"); + return new JniInt64ArrayElements (PeerReference, elements, Length*sizeof (Int64)); } public override unsafe int IndexOf (Int64 item) @@ -1095,7 +1120,7 @@ public override void DestroyGenericArgumentState (IList value, ref JniVal JavaArray.DestroyArgumentState (value, ref state, synchronize); } - public override Expression CreateParameterToManagedExpression (JniValueMarshalerContext context, ParameterExpression sourceValue, ParameterAttributes synchronize = 0, Type targetType = null) + public override Expression CreateParameterToManagedExpression (JniValueMarshalerContext context, ParameterExpression sourceValue, ParameterAttributes synchronize = 0, Type? targetType = null) { Func m = JavaInt64Array.CreateMarshaledValue; @@ -1172,8 +1197,12 @@ protected override JniArrayElements CreateElements () public new unsafe JniSingleArrayElements GetElements () { + if (!PeerReference.IsValid) + throw new ObjectDisposedException (this.GetType ().FullName); var elements = JniEnvironment.Arrays.GetFloatArrayElements (PeerReference, null); - return elements == null ? null : new JniSingleArrayElements (PeerReference, elements, Length*sizeof (Single)); + if (elements == null) + throw new InvalidOperationException ("`JniEnvironment.Arrays.GetFloatArrayElements()` returned NULL!"); + return new JniSingleArrayElements (PeerReference, elements, Length*sizeof (Single)); } public override unsafe int IndexOf (Single item) @@ -1267,7 +1296,7 @@ public override void DestroyGenericArgumentState (IList value, ref JniVa JavaArray.DestroyArgumentState (value, ref state, synchronize); } - public override Expression CreateParameterToManagedExpression (JniValueMarshalerContext context, ParameterExpression sourceValue, ParameterAttributes synchronize = 0, Type targetType = null) + public override Expression CreateParameterToManagedExpression (JniValueMarshalerContext context, ParameterExpression sourceValue, ParameterAttributes synchronize = 0, Type? targetType = null) { Func m = JavaSingleArray.CreateMarshaledValue; @@ -1344,8 +1373,12 @@ protected override JniArrayElements CreateElements () public new unsafe JniDoubleArrayElements GetElements () { + if (!PeerReference.IsValid) + throw new ObjectDisposedException (this.GetType ().FullName); var elements = JniEnvironment.Arrays.GetDoubleArrayElements (PeerReference, null); - return elements == null ? null : new JniDoubleArrayElements (PeerReference, elements, Length*sizeof (Double)); + if (elements == null) + throw new InvalidOperationException ("`JniEnvironment.Arrays.GetDoubleArrayElements()` returned NULL!"); + return new JniDoubleArrayElements (PeerReference, elements, Length*sizeof (Double)); } public override unsafe int IndexOf (Double item) @@ -1439,7 +1472,7 @@ public override void DestroyGenericArgumentState (IList value, ref JniVa JavaArray.DestroyArgumentState (value, ref state, synchronize); } - public override Expression CreateParameterToManagedExpression (JniValueMarshalerContext context, ParameterExpression sourceValue, ParameterAttributes synchronize = 0, Type targetType = null) + public override Expression CreateParameterToManagedExpression (JniValueMarshalerContext context, ParameterExpression sourceValue, ParameterAttributes synchronize = 0, Type? targetType = null) { Func m = JavaDoubleArray.CreateMarshaledValue; diff --git a/src/Java.Interop/Java.Interop/JavaPrimitiveArrays.tt b/src/Java.Interop/Java.Interop/JavaPrimitiveArrays.tt index 81b3b0132..a345c2ae6 100644 --- a/src/Java.Interop/Java.Interop/JavaPrimitiveArrays.tt +++ b/src/Java.Interop/Java.Interop/JavaPrimitiveArrays.tt @@ -3,6 +3,7 @@ <#@ import namespace="System.Collections.Generic" #> <#@ import namespace="System.Linq" #> <#@ import namespace="System.Text" #> +#nullable enable using System; using System.Collections.Generic; @@ -130,8 +131,12 @@ namespace Java.Interop { public new unsafe Jni<#= info.TypeModifier #>ArrayElements GetElements () { + if (!PeerReference.IsValid) + throw new ObjectDisposedException (this.GetType ().FullName); var elements = JniEnvironment.Arrays.Get<#= info.JniMarshalType #>ArrayElements (PeerReference, null); - return elements == null ? null : new Jni<#= info.TypeModifier #>ArrayElements (PeerReference, elements, Length*sizeof (<#= info.ManagedType #>)); + if (elements == null) + throw new InvalidOperationException ("`JniEnvironment.Arrays.Get<#= info.JniMarshalType #>ArrayElements()` returned NULL!"); + return new Jni<#= info.TypeModifier #>ArrayElements (PeerReference, elements, Length*sizeof (<#= info.ManagedType #>)); } public override unsafe int IndexOf (<#= info.ManagedType #> item) @@ -225,7 +230,7 @@ namespace Java.Interop { JavaArray<<#= info.ManagedType #>>.DestroyArgumentStateArray> (value, ref state, synchronize); } - public override Expression CreateParameterToManagedExpression (JniValueMarshalerContext context, ParameterExpression sourceValue, ParameterAttributes synchronize = 0, Type targetType = null) + public override Expression CreateParameterToManagedExpression (JniValueMarshalerContext context, ParameterExpression sourceValue, ParameterAttributes synchronize = 0, Type? targetType = null) { Func m = Java<#= info.TypeModifier #>Array.CreateMarshaledValue; diff --git a/src/Java.Interop/Java.Interop/JniFieldInfo.cs b/src/Java.Interop/Java.Interop/JniFieldInfo.cs index c64884f53..97d2c502e 100644 --- a/src/Java.Interop/Java.Interop/JniFieldInfo.cs +++ b/src/Java.Interop/Java.Interop/JniFieldInfo.cs @@ -1,3 +1,5 @@ +#nullable enable + using System; namespace Java.Interop @@ -13,22 +15,22 @@ internal bool IsValid { } #if DEBUG - string name, signature; + string? name, signature; #endif // !DEBUG public string Name { #if DEBUG - get {return name;} + get => name ?? throw new NotSupportedException (); #else // !DEBUG - get {throw new NotSupportedException ();} + get => throw new NotSupportedException (); #endif // !DEBUG } public string Signature { #if DEBUG - get {return signature;} + get => signature ?? throw new NotSupportedException (); #else // !DEBUG - get {throw new NotSupportedException ();} + get => throw new NotSupportedException (); #endif // !DEBUG } diff --git a/src/Java.Interop/Java.Interop/JniMarshal.cs b/src/Java.Interop/Java.Interop/JniMarshal.cs index 56f5303f5..00556b233 100644 --- a/src/Java.Interop/Java.Interop/JniMarshal.cs +++ b/src/Java.Interop/Java.Interop/JniMarshal.cs @@ -1,4 +1,6 @@ -using System; +#nullable enable + +using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; @@ -10,7 +12,7 @@ namespace Java.Interop { public static class JniMarshal { - public static bool RecursiveEquals (object objA, object objB) + public static bool RecursiveEquals (object? objA, object? objB) { if (object.Equals (objA, objB)) return true; From 583ad0d0bc18961cdc83c05933e08a26c19905ee Mon Sep 17 00:00:00 2001 From: Jonathan Pryor Date: Tue, 19 Nov 2019 11:36:08 -0500 Subject: [PATCH 03/33] Add #nullable for JavaProxyObject, JavaProxyThrowable --- .../Java.Interop/JavaProxyObject.cs | 18 ++++++++++-------- .../Java.Interop/JavaProxyThrowable.cs | 4 +++- .../Java.Interop/JniEnvironment.Strings.cs | 2 +- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/Java.Interop/Java.Interop/JavaProxyObject.cs b/src/Java.Interop/Java.Interop/JavaProxyObject.cs index 68cfbe6a5..b2d0d333b 100644 --- a/src/Java.Interop/Java.Interop/JavaProxyObject.cs +++ b/src/Java.Interop/Java.Interop/JavaProxyObject.cs @@ -1,4 +1,6 @@ -using System; +#nullable enable + +using System; using System.Runtime.CompilerServices; namespace Java.Interop { @@ -53,7 +55,7 @@ public override string ToString () return Value.ToString (); } - public static JavaProxyObject GetProxy (object value) + public static JavaProxyObject? GetProxy (object value) { if (value == null) return null; @@ -73,10 +75,10 @@ static bool Equals (IntPtr jnienv, IntPtr n_self, IntPtr n_value) { var envp = new JniTransition (jnienv); try { - var self = (JavaProxyObject) JniEnvironment.Runtime.ValueManager.PeekPeer (new JniObjectReference (n_self)); + var self = (JavaProxyObject?) JniEnvironment.Runtime.ValueManager.PeekPeer (new JniObjectReference (n_self)); var r_value = new JniObjectReference (n_value); var value = JniEnvironment.Runtime.ValueManager.GetValue (ref r_value, JniObjectReferenceOptions.Copy); - return self.Equals (value); + return self?.Equals (value) ?? false; } catch (Exception e) when (JniEnvironment.Runtime.ExceptionShouldTransitionToJni (e)) { envp.SetPendingException (e); @@ -92,8 +94,8 @@ static int GetHashCode (IntPtr jnienv, IntPtr n_self) { var envp = new JniTransition (jnienv); try { - var self = (JavaProxyObject) JniEnvironment.Runtime.ValueManager.PeekPeer (new JniObjectReference (n_self)); - return self.GetHashCode (); + var self = (JavaProxyObject?) JniEnvironment.Runtime.ValueManager.PeekPeer (new JniObjectReference (n_self)); + return self?.GetHashCode () ?? 0; } catch (Exception e) when (JniEnvironment.Runtime.ExceptionShouldTransitionToJni (e)) { envp.SetPendingException (e); @@ -108,8 +110,8 @@ static IntPtr ToString (IntPtr jnienv, IntPtr n_self) { var envp = new JniTransition (jnienv); try { - var self = (JavaProxyObject) JniEnvironment.Runtime.ValueManager.PeekPeer (new JniObjectReference (n_self)); - var s = self.ToString (); + var self = (JavaProxyObject?) JniEnvironment.Runtime.ValueManager.PeekPeer (new JniObjectReference (n_self)); + var s = self?.ToString (); var r = JniEnvironment.Strings.NewString (s); try { return JniEnvironment.References.NewReturnToJniRef (r); diff --git a/src/Java.Interop/Java.Interop/JavaProxyThrowable.cs b/src/Java.Interop/Java.Interop/JavaProxyThrowable.cs index 1680adb6a..974833fa6 100644 --- a/src/Java.Interop/Java.Interop/JavaProxyThrowable.cs +++ b/src/Java.Interop/Java.Interop/JavaProxyThrowable.cs @@ -1,4 +1,6 @@ -using System; +#nullable enable + +using System; namespace Java.Interop { diff --git a/src/Java.Interop/Java.Interop/JniEnvironment.Strings.cs b/src/Java.Interop/Java.Interop/JniEnvironment.Strings.cs index 9695ab030..e4b555577 100644 --- a/src/Java.Interop/Java.Interop/JniEnvironment.Strings.cs +++ b/src/Java.Interop/Java.Interop/JniEnvironment.Strings.cs @@ -9,7 +9,7 @@ partial class JniEnvironment { partial class Strings { - public static unsafe JniObjectReference NewString (string value) + public static unsafe JniObjectReference NewString (string? value) { if (value == null) return new JniObjectReference (); From 80e490e9c2610df94eac7ee1ee21c466346e1e61 Mon Sep 17 00:00:00 2001 From: Jonathan Pryor Date: Tue, 19 Nov 2019 11:37:45 -0500 Subject: [PATCH 04/33] Add #nullable for JniArgumentValue --- .../Java.Interop/JniAddNativeMethodRegistrationAttribute.cs | 4 +++- src/Java.Interop/Java.Interop/JniArgumentValue.cs | 6 ++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/Java.Interop/Java.Interop/JniAddNativeMethodRegistrationAttribute.cs b/src/Java.Interop/Java.Interop/JniAddNativeMethodRegistrationAttribute.cs index 1e8beff16..80ac074c1 100644 --- a/src/Java.Interop/Java.Interop/JniAddNativeMethodRegistrationAttribute.cs +++ b/src/Java.Interop/Java.Interop/JniAddNativeMethodRegistrationAttribute.cs @@ -1,4 +1,6 @@ -using System; +#nullable enable + +using System; namespace Java.Interop { diff --git a/src/Java.Interop/Java.Interop/JniArgumentValue.cs b/src/Java.Interop/Java.Interop/JniArgumentValue.cs index 1e9a6dbda..3613094c2 100644 --- a/src/Java.Interop/Java.Interop/JniArgumentValue.cs +++ b/src/Java.Interop/Java.Interop/JniArgumentValue.cs @@ -1,3 +1,5 @@ +#nullable enable + using System; using System.Runtime.InteropServices; @@ -90,7 +92,7 @@ public JniArgumentValue (JniObjectReference value) l = value.Handle; } - public JniArgumentValue (IJavaPeerable value) + public JniArgumentValue (IJavaPeerable? value) { this = new JniArgumentValue (); if (value != null) @@ -104,7 +106,7 @@ public override int GetHashCode () return j.GetHashCode (); } - public override bool Equals (object obj) + public override bool Equals (object? obj) { var o = obj as JniArgumentValue?; if (!o.HasValue) From b900b262d6569e3cae863a8400e1b76c848d3711 Mon Sep 17 00:00:00 2001 From: Jonathan Pryor Date: Tue, 19 Nov 2019 11:41:34 -0500 Subject: [PATCH 05/33] Add #nullable for JniBuiltinMarshalers --- src/Java.Interop/Java.Interop.csproj | 3 + .../Java.Interop/JniBuiltinMarshalers.cs | 100 +++++++++--------- .../Java.Interop/JniBuiltinMarshalers.tt | 14 +-- 3 files changed, 62 insertions(+), 55 deletions(-) diff --git a/src/Java.Interop/Java.Interop.csproj b/src/Java.Interop/Java.Interop.csproj index 50d785da4..5da48b9f7 100644 --- a/src/Java.Interop/Java.Interop.csproj +++ b/src/Java.Interop/Java.Interop.csproj @@ -73,6 +73,9 @@ JavaPrimitiveArrays.tt + + JniBuiltinMarshalers.tt + diff --git a/src/Java.Interop/Java.Interop/JniBuiltinMarshalers.cs b/src/Java.Interop/Java.Interop/JniBuiltinMarshalers.cs index 749d18448..af5facd33 100644 --- a/src/Java.Interop/Java.Interop/JniBuiltinMarshalers.cs +++ b/src/Java.Interop/Java.Interop/JniBuiltinMarshalers.cs @@ -1,4 +1,6 @@ -using System; +#nullable enable + +using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq.Expressions; @@ -68,12 +70,12 @@ static KeyValuePair[] InitJniBuiltinMarshalers () static class JniBoolean { internal const string JniTypeName = "java/lang/Boolean"; - static JniType _TypeRef; + static JniType? _TypeRef; static JniType TypeRef { get {return JniType.GetCachedJniType (ref _TypeRef, JniTypeName);} } - static JniMethodInfo init; + static JniMethodInfo? init; internal static unsafe JniObjectReference CreateLocalRef (Boolean value) { var args = stackalloc JniArgumentValue [1]; @@ -83,8 +85,8 @@ internal static unsafe JniObjectReference CreateLocalRef (Boolean value) return TypeRef.NewObject (init, args); } - static JniMethodInfo booleanValue; - internal static Boolean GetValueFromJni (ref JniObjectReference self, JniObjectReferenceOptions transfer, Type targetType) + static JniMethodInfo? booleanValue; + internal static Boolean GetValueFromJni (ref JniObjectReference self, JniObjectReferenceOptions transfer, Type? targetType) { Debug.Assert (targetType == null || targetType == typeof (Boolean), "Expected targetType==typeof(Boolean); was: " + targetType); TypeRef.GetCachedInstanceMethod (ref booleanValue, "booleanValue", "()Z"); @@ -108,14 +110,14 @@ public override Type MarshalType { get {return typeof (Boolean);} } - public override object CreateValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type targetType) + public override object? CreateValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type? targetType) { if (!reference.IsValid) return null; return CreateGenericValue (ref reference, options, targetType); } - public override Boolean CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type targetType) + public override Boolean CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type? targetType) { if (!reference.IsValid) return default (Boolean); @@ -195,12 +197,12 @@ public override void DestroyGenericArgumentState (Boolean? value, ref JniValueMa static class JniByte { internal const string JniTypeName = "java/lang/Byte"; - static JniType _TypeRef; + static JniType? _TypeRef; static JniType TypeRef { get {return JniType.GetCachedJniType (ref _TypeRef, JniTypeName);} } - static JniMethodInfo init; + static JniMethodInfo? init; internal static unsafe JniObjectReference CreateLocalRef (SByte value) { var args = stackalloc JniArgumentValue [1]; @@ -210,8 +212,8 @@ internal static unsafe JniObjectReference CreateLocalRef (SByte value) return TypeRef.NewObject (init, args); } - static JniMethodInfo byteValue; - internal static SByte GetValueFromJni (ref JniObjectReference self, JniObjectReferenceOptions transfer, Type targetType) + static JniMethodInfo? byteValue; + internal static SByte GetValueFromJni (ref JniObjectReference self, JniObjectReferenceOptions transfer, Type? targetType) { Debug.Assert (targetType == null || targetType == typeof (SByte), "Expected targetType==typeof(SByte); was: " + targetType); TypeRef.GetCachedInstanceMethod (ref byteValue, "byteValue", "()B"); @@ -235,14 +237,14 @@ public override Type MarshalType { get {return typeof (SByte);} } - public override object CreateValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type targetType) + public override object? CreateValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type? targetType) { if (!reference.IsValid) return null; return CreateGenericValue (ref reference, options, targetType); } - public override SByte CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type targetType) + public override SByte CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type? targetType) { if (!reference.IsValid) return default (SByte); @@ -322,12 +324,12 @@ public override void DestroyGenericArgumentState (SByte? value, ref JniValueMars static class JniCharacter { internal const string JniTypeName = "java/lang/Character"; - static JniType _TypeRef; + static JniType? _TypeRef; static JniType TypeRef { get {return JniType.GetCachedJniType (ref _TypeRef, JniTypeName);} } - static JniMethodInfo init; + static JniMethodInfo? init; internal static unsafe JniObjectReference CreateLocalRef (Char value) { var args = stackalloc JniArgumentValue [1]; @@ -337,8 +339,8 @@ internal static unsafe JniObjectReference CreateLocalRef (Char value) return TypeRef.NewObject (init, args); } - static JniMethodInfo charValue; - internal static Char GetValueFromJni (ref JniObjectReference self, JniObjectReferenceOptions transfer, Type targetType) + static JniMethodInfo? charValue; + internal static Char GetValueFromJni (ref JniObjectReference self, JniObjectReferenceOptions transfer, Type? targetType) { Debug.Assert (targetType == null || targetType == typeof (Char), "Expected targetType==typeof(Char); was: " + targetType); TypeRef.GetCachedInstanceMethod (ref charValue, "charValue", "()C"); @@ -362,14 +364,14 @@ public override Type MarshalType { get {return typeof (Char);} } - public override object CreateValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type targetType) + public override object? CreateValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type? targetType) { if (!reference.IsValid) return null; return CreateGenericValue (ref reference, options, targetType); } - public override Char CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type targetType) + public override Char CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type? targetType) { if (!reference.IsValid) return default (Char); @@ -449,12 +451,12 @@ public override void DestroyGenericArgumentState (Char? value, ref JniValueMarsh static class JniShort { internal const string JniTypeName = "java/lang/Short"; - static JniType _TypeRef; + static JniType? _TypeRef; static JniType TypeRef { get {return JniType.GetCachedJniType (ref _TypeRef, JniTypeName);} } - static JniMethodInfo init; + static JniMethodInfo? init; internal static unsafe JniObjectReference CreateLocalRef (Int16 value) { var args = stackalloc JniArgumentValue [1]; @@ -464,8 +466,8 @@ internal static unsafe JniObjectReference CreateLocalRef (Int16 value) return TypeRef.NewObject (init, args); } - static JniMethodInfo shortValue; - internal static Int16 GetValueFromJni (ref JniObjectReference self, JniObjectReferenceOptions transfer, Type targetType) + static JniMethodInfo? shortValue; + internal static Int16 GetValueFromJni (ref JniObjectReference self, JniObjectReferenceOptions transfer, Type? targetType) { Debug.Assert (targetType == null || targetType == typeof (Int16), "Expected targetType==typeof(Int16); was: " + targetType); TypeRef.GetCachedInstanceMethod (ref shortValue, "shortValue", "()S"); @@ -489,14 +491,14 @@ public override Type MarshalType { get {return typeof (Int16);} } - public override object CreateValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type targetType) + public override object? CreateValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type? targetType) { if (!reference.IsValid) return null; return CreateGenericValue (ref reference, options, targetType); } - public override Int16 CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type targetType) + public override Int16 CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type? targetType) { if (!reference.IsValid) return default (Int16); @@ -576,12 +578,12 @@ public override void DestroyGenericArgumentState (Int16? value, ref JniValueMars static class JniInteger { internal const string JniTypeName = "java/lang/Integer"; - static JniType _TypeRef; + static JniType? _TypeRef; static JniType TypeRef { get {return JniType.GetCachedJniType (ref _TypeRef, JniTypeName);} } - static JniMethodInfo init; + static JniMethodInfo? init; internal static unsafe JniObjectReference CreateLocalRef (Int32 value) { var args = stackalloc JniArgumentValue [1]; @@ -591,8 +593,8 @@ internal static unsafe JniObjectReference CreateLocalRef (Int32 value) return TypeRef.NewObject (init, args); } - static JniMethodInfo intValue; - internal static Int32 GetValueFromJni (ref JniObjectReference self, JniObjectReferenceOptions transfer, Type targetType) + static JniMethodInfo? intValue; + internal static Int32 GetValueFromJni (ref JniObjectReference self, JniObjectReferenceOptions transfer, Type? targetType) { Debug.Assert (targetType == null || targetType == typeof (Int32), "Expected targetType==typeof(Int32); was: " + targetType); TypeRef.GetCachedInstanceMethod (ref intValue, "intValue", "()I"); @@ -616,14 +618,14 @@ public override Type MarshalType { get {return typeof (Int32);} } - public override object CreateValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type targetType) + public override object? CreateValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type? targetType) { if (!reference.IsValid) return null; return CreateGenericValue (ref reference, options, targetType); } - public override Int32 CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type targetType) + public override Int32 CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type? targetType) { if (!reference.IsValid) return default (Int32); @@ -703,12 +705,12 @@ public override void DestroyGenericArgumentState (Int32? value, ref JniValueMars static class JniLong { internal const string JniTypeName = "java/lang/Long"; - static JniType _TypeRef; + static JniType? _TypeRef; static JniType TypeRef { get {return JniType.GetCachedJniType (ref _TypeRef, JniTypeName);} } - static JniMethodInfo init; + static JniMethodInfo? init; internal static unsafe JniObjectReference CreateLocalRef (Int64 value) { var args = stackalloc JniArgumentValue [1]; @@ -718,8 +720,8 @@ internal static unsafe JniObjectReference CreateLocalRef (Int64 value) return TypeRef.NewObject (init, args); } - static JniMethodInfo longValue; - internal static Int64 GetValueFromJni (ref JniObjectReference self, JniObjectReferenceOptions transfer, Type targetType) + static JniMethodInfo? longValue; + internal static Int64 GetValueFromJni (ref JniObjectReference self, JniObjectReferenceOptions transfer, Type? targetType) { Debug.Assert (targetType == null || targetType == typeof (Int64), "Expected targetType==typeof(Int64); was: " + targetType); TypeRef.GetCachedInstanceMethod (ref longValue, "longValue", "()J"); @@ -743,14 +745,14 @@ public override Type MarshalType { get {return typeof (Int64);} } - public override object CreateValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type targetType) + public override object? CreateValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type? targetType) { if (!reference.IsValid) return null; return CreateGenericValue (ref reference, options, targetType); } - public override Int64 CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type targetType) + public override Int64 CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type? targetType) { if (!reference.IsValid) return default (Int64); @@ -830,12 +832,12 @@ public override void DestroyGenericArgumentState (Int64? value, ref JniValueMars static class JniFloat { internal const string JniTypeName = "java/lang/Float"; - static JniType _TypeRef; + static JniType? _TypeRef; static JniType TypeRef { get {return JniType.GetCachedJniType (ref _TypeRef, JniTypeName);} } - static JniMethodInfo init; + static JniMethodInfo? init; internal static unsafe JniObjectReference CreateLocalRef (Single value) { var args = stackalloc JniArgumentValue [1]; @@ -845,8 +847,8 @@ internal static unsafe JniObjectReference CreateLocalRef (Single value) return TypeRef.NewObject (init, args); } - static JniMethodInfo floatValue; - internal static Single GetValueFromJni (ref JniObjectReference self, JniObjectReferenceOptions transfer, Type targetType) + static JniMethodInfo? floatValue; + internal static Single GetValueFromJni (ref JniObjectReference self, JniObjectReferenceOptions transfer, Type? targetType) { Debug.Assert (targetType == null || targetType == typeof (Single), "Expected targetType==typeof(Single); was: " + targetType); TypeRef.GetCachedInstanceMethod (ref floatValue, "floatValue", "()F"); @@ -870,14 +872,14 @@ public override Type MarshalType { get {return typeof (Single);} } - public override object CreateValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type targetType) + public override object? CreateValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type? targetType) { if (!reference.IsValid) return null; return CreateGenericValue (ref reference, options, targetType); } - public override Single CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type targetType) + public override Single CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type? targetType) { if (!reference.IsValid) return default (Single); @@ -957,12 +959,12 @@ public override void DestroyGenericArgumentState (Single? value, ref JniValueMar static class JniDouble { internal const string JniTypeName = "java/lang/Double"; - static JniType _TypeRef; + static JniType? _TypeRef; static JniType TypeRef { get {return JniType.GetCachedJniType (ref _TypeRef, JniTypeName);} } - static JniMethodInfo init; + static JniMethodInfo? init; internal static unsafe JniObjectReference CreateLocalRef (Double value) { var args = stackalloc JniArgumentValue [1]; @@ -972,8 +974,8 @@ internal static unsafe JniObjectReference CreateLocalRef (Double value) return TypeRef.NewObject (init, args); } - static JniMethodInfo doubleValue; - internal static Double GetValueFromJni (ref JniObjectReference self, JniObjectReferenceOptions transfer, Type targetType) + static JniMethodInfo? doubleValue; + internal static Double GetValueFromJni (ref JniObjectReference self, JniObjectReferenceOptions transfer, Type? targetType) { Debug.Assert (targetType == null || targetType == typeof (Double), "Expected targetType==typeof(Double); was: " + targetType); TypeRef.GetCachedInstanceMethod (ref doubleValue, "doubleValue", "()D"); @@ -997,14 +999,14 @@ public override Type MarshalType { get {return typeof (Double);} } - public override object CreateValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type targetType) + public override object? CreateValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type? targetType) { if (!reference.IsValid) return null; return CreateGenericValue (ref reference, options, targetType); } - public override Double CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type targetType) + public override Double CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type? targetType) { if (!reference.IsValid) return default (Double); diff --git a/src/Java.Interop/Java.Interop/JniBuiltinMarshalers.tt b/src/Java.Interop/Java.Interop/JniBuiltinMarshalers.tt index 3ae0d258c..f958c6c97 100644 --- a/src/Java.Interop/Java.Interop/JniBuiltinMarshalers.tt +++ b/src/Java.Interop/Java.Interop/JniBuiltinMarshalers.tt @@ -3,6 +3,8 @@ <#@ import namespace="System.Collections.Generic" #> <#@ import namespace="System.Linq" #> <#@ import namespace="System.Text" #> +#nullable enable + using System; using System.Collections.Generic; using System.Diagnostics; @@ -72,12 +74,12 @@ namespace Java.Interop { static class Jni<#= type.Name #> { internal const string JniTypeName = "java/lang/<#= type.Name #>"; - static JniType _TypeRef; + static JniType? _TypeRef; static JniType TypeRef { get {return JniType.GetCachedJniType (ref _TypeRef, JniTypeName);} } - static JniMethodInfo init; + static JniMethodInfo? init; internal static unsafe JniObjectReference CreateLocalRef (<#= type.Type #> value) { var args = stackalloc JniArgumentValue [1]; @@ -87,8 +89,8 @@ namespace Java.Interop { return TypeRef.NewObject (init, args); } - static JniMethodInfo <#= type.GetValue #>; - internal static <#= type.Type #> GetValueFromJni (ref JniObjectReference self, JniObjectReferenceOptions transfer, Type targetType) + static JniMethodInfo? <#= type.GetValue #>; + internal static <#= type.Type #> GetValueFromJni (ref JniObjectReference self, JniObjectReferenceOptions transfer, Type? targetType) { Debug.Assert (targetType == null || targetType == typeof (<#= type.Type #>), "Expected targetType==typeof(<#= type.Type #>); was: " + targetType); TypeRef.GetCachedInstanceMethod (ref <#= type.GetValue #>, "<#= type.GetValue #>", "()<#= type.JniType #>"); @@ -112,14 +114,14 @@ namespace Java.Interop { get {return typeof (<#= type.Type #>);} } - public override object CreateValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type targetType) + public override object? CreateValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type? targetType) { if (!reference.IsValid) return null; return CreateGenericValue (ref reference, options, targetType); } - public override <#= type.Type #> CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type targetType) + public override <#= type.Type #> CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type? targetType) { if (!reference.IsValid) return default (<#= type.Type #>); From 56e5f64a09645f1834e915bc0ad520f4df3b795d Mon Sep 17 00:00:00 2001 From: Jonathan Pryor Date: Tue, 19 Nov 2019 11:44:00 -0500 Subject: [PATCH 06/33] Add #nullable for JniMethodInfo --- src/Java.Interop/Java.Interop/JniFieldInfo.cs | 4 ++-- src/Java.Interop/Java.Interop/JniMethodInfo.cs | 16 +++++++++------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/Java.Interop/Java.Interop/JniFieldInfo.cs b/src/Java.Interop/Java.Interop/JniFieldInfo.cs index 97d2c502e..a02ec4c8c 100644 --- a/src/Java.Interop/Java.Interop/JniFieldInfo.cs +++ b/src/Java.Interop/Java.Interop/JniFieldInfo.cs @@ -55,8 +55,8 @@ public JniFieldInfo (string name, string signature, IntPtr fieldID, bool isStati public override string ToString () { #if DEBUG - bool haveName = !string.IsNullOrEmpty (Name); - bool haveSig = !string.IsNullOrEmpty (Signature); + bool haveName = !string.IsNullOrEmpty (name); + bool haveSig = !string.IsNullOrEmpty (signature); #else // DEBUG bool haveName = false; bool haveSig = false; diff --git a/src/Java.Interop/Java.Interop/JniMethodInfo.cs b/src/Java.Interop/Java.Interop/JniMethodInfo.cs index 382785a22..b2458fae7 100644 --- a/src/Java.Interop/Java.Interop/JniMethodInfo.cs +++ b/src/Java.Interop/Java.Interop/JniMethodInfo.cs @@ -1,3 +1,5 @@ +#nullable enable + using System; namespace Java.Interop @@ -13,22 +15,22 @@ internal bool IsValid { } #if DEBUG - string name, signature; + string? name, signature; #endif // !DEBUG public string Name { #if DEBUG - get {return name;} + get => name ?? throw new NotSupportedException (); #else // !DEBUG - get {throw new NotSupportedException ();} + get => throw new NotSupportedException (); #endif // !DEBUG } public string Signature { #if DEBUG - get {return signature;} + get => signature ?? throw new NotSupportedException (); #else // !DEBUG - get {throw new NotSupportedException ();} + get => throw new NotSupportedException (); #endif // !DEBUG } @@ -53,8 +55,8 @@ public JniMethodInfo (string name, string signature, IntPtr methodID, bool isSta public override string ToString () { #if DEBUG - bool haveName = !string.IsNullOrEmpty (Name); - bool haveSig = !string.IsNullOrEmpty (Signature); + bool haveName = !string.IsNullOrEmpty (name); + bool haveSig = !string.IsNullOrEmpty (signature); #else // DEBUG bool haveName = false; bool haveSig = false; From 335ea700b7671ea0ddf61adb4c9e2eefbe1dacce Mon Sep 17 00:00:00 2001 From: Jonathan Pryor Date: Tue, 19 Nov 2019 11:44:51 -0500 Subject: [PATCH 07/33] Add #nullable for JniNativeMethodRegistration --- .../Java.Interop/JniNativeMethodRegistration.cs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/Java.Interop/Java.Interop/JniNativeMethodRegistration.cs b/src/Java.Interop/Java.Interop/JniNativeMethodRegistration.cs index 8cbf62042..309eef6f3 100644 --- a/src/Java.Interop/Java.Interop/JniNativeMethodRegistration.cs +++ b/src/Java.Interop/Java.Interop/JniNativeMethodRegistration.cs @@ -1,3 +1,5 @@ +#nullable enable + using System; using System.Threading; @@ -7,11 +9,11 @@ namespace Java.Interop { public struct JniNativeMethodRegistration { - public string Name; - public string Signature; - public Delegate Marshaler; + public string? Name; + public string? Signature; + public Delegate? Marshaler; - public JniNativeMethodRegistration (string name, string signature, Delegate marshaler) + public JniNativeMethodRegistration (string? name, string? signature, Delegate? marshaler) { Name = name; Signature = signature; From da4d2f1b46a80e79513619e1247d04d3d0990e05 Mon Sep 17 00:00:00 2001 From: Jonathan Pryor Date: Tue, 19 Nov 2019 11:48:50 -0500 Subject: [PATCH 08/33] Add #nullable for JniNativeMethodRegistrationArguments --- .../Java.Interop/JniNativeMethodRegistration.cs | 14 +++++++------- .../JniNativeMethodRegistrationArguments.cs | 8 +++++--- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/Java.Interop/Java.Interop/JniNativeMethodRegistration.cs b/src/Java.Interop/Java.Interop/JniNativeMethodRegistration.cs index 309eef6f3..20f99f947 100644 --- a/src/Java.Interop/Java.Interop/JniNativeMethodRegistration.cs +++ b/src/Java.Interop/Java.Interop/JniNativeMethodRegistration.cs @@ -9,15 +9,15 @@ namespace Java.Interop { public struct JniNativeMethodRegistration { - public string? Name; - public string? Signature; - public Delegate? Marshaler; + public string Name; + public string Signature; + public Delegate Marshaler; - public JniNativeMethodRegistration (string? name, string? signature, Delegate? marshaler) + public JniNativeMethodRegistration (string name, string signature, Delegate marshaler) { - Name = name; - Signature = signature; - Marshaler = marshaler; + Name = name ?? throw new ArgumentNullException (nameof (name)); + Signature = signature ?? throw new ArgumentNullException (nameof (signature)); + Marshaler = marshaler ?? throw new ArgumentNullException (nameof (marshaler)); } } } diff --git a/src/Java.Interop/Java.Interop/JniNativeMethodRegistrationArguments.cs b/src/Java.Interop/Java.Interop/JniNativeMethodRegistrationArguments.cs index 34e0c6a23..58f6c706d 100644 --- a/src/Java.Interop/Java.Interop/JniNativeMethodRegistrationArguments.cs +++ b/src/Java.Interop/Java.Interop/JniNativeMethodRegistrationArguments.cs @@ -1,4 +1,6 @@ -using System; +#nullable enable + +using System; using System.Collections.Generic; namespace Java.Interop @@ -10,10 +12,10 @@ public struct JniNativeMethodRegistrationArguments public ICollection Registrations { get { return _registrations ?? throw new InvalidOperationException (invalidStateMessage); } } - public string Methods { get; } + public string? Methods { get; } ICollection _registrations; - public JniNativeMethodRegistrationArguments (ICollection registrations, string methods) + public JniNativeMethodRegistrationArguments (ICollection registrations, string? methods) { _registrations = registrations ?? throw new ArgumentNullException (nameof (registrations)); Methods = methods; From 30064775e67ce0bcec0afde5ca47402d579d4877 Mon Sep 17 00:00:00 2001 From: Jonathan Pryor Date: Tue, 19 Nov 2019 11:49:38 -0500 Subject: [PATCH 09/33] Add #nullable for JniObjectReference* --- src/Java.Interop/Java.Interop/JniObjectReference.cs | 2 ++ src/Java.Interop/Java.Interop/JniObjectReferenceOptions.cs | 2 ++ src/Java.Interop/Java.Interop/JniObjectReferenceType.cs | 2 ++ 3 files changed, 6 insertions(+) diff --git a/src/Java.Interop/Java.Interop/JniObjectReference.cs b/src/Java.Interop/Java.Interop/JniObjectReference.cs index e72659371..9475fd83a 100644 --- a/src/Java.Interop/Java.Interop/JniObjectReference.cs +++ b/src/Java.Interop/Java.Interop/JniObjectReference.cs @@ -1,3 +1,5 @@ +#nullable enable + using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; diff --git a/src/Java.Interop/Java.Interop/JniObjectReferenceOptions.cs b/src/Java.Interop/Java.Interop/JniObjectReferenceOptions.cs index 592b93b9c..5a1169169 100644 --- a/src/Java.Interop/Java.Interop/JniObjectReferenceOptions.cs +++ b/src/Java.Interop/Java.Interop/JniObjectReferenceOptions.cs @@ -1,3 +1,5 @@ +#nullable enable + using System; namespace Java.Interop diff --git a/src/Java.Interop/Java.Interop/JniObjectReferenceType.cs b/src/Java.Interop/Java.Interop/JniObjectReferenceType.cs index 2e51f718d..3f25c58d2 100644 --- a/src/Java.Interop/Java.Interop/JniObjectReferenceType.cs +++ b/src/Java.Interop/Java.Interop/JniObjectReferenceType.cs @@ -1,3 +1,5 @@ +#nullable enable + using System; namespace Java.Interop From 607a6de3f0dfb13e29fac0a1b3c7a091c8d5e55e Mon Sep 17 00:00:00 2001 From: Jonathan Pryor Date: Tue, 19 Nov 2019 14:41:19 -0500 Subject: [PATCH 10/33] Add #nullable for JniRuntime. Notable change: move away from `ConcurrentDictionary` to `lock` + `Dictionary`, because `ConcurrentDictionary.TryUpdate()` didn't support passing `null` as a new value. To do so, we'd have to move to `ConcurrentDictionary`, which would alter the type of `Runtime.Values`, and change other things. --- .../Java.Interop/JniEnvironment.Types.cs | 31 +++++---- .../JniRuntime.JniMarshalMemberBuilder.cs | 18 +++-- src/Java.Interop/Java.Interop/JniRuntime.cs | 68 +++++++++++-------- 3 files changed, 71 insertions(+), 46 deletions(-) diff --git a/src/Java.Interop/Java.Interop/JniEnvironment.Types.cs b/src/Java.Interop/Java.Interop/JniEnvironment.Types.cs index ccf041a7b..86f9e3afb 100644 --- a/src/Java.Interop/Java.Interop/JniEnvironment.Types.cs +++ b/src/Java.Interop/Java.Interop/JniEnvironment.Types.cs @@ -46,25 +46,30 @@ public static unsafe JniObjectReference FindClass (string classname) JniEnvironment.LogCreateLocalRef (r); return r; } + NativeMethods.java_interop_jnienv_exception_clear (info.EnvironmentPointer); var e = new JniObjectReference (thrown, JniObjectReferenceType.Local); LogCreateLocalRef (e); - var java = info.ToJavaName (classname); - var __args = stackalloc JniArgumentValue [1]; - __args [0] = new JniArgumentValue (java); + if (info.Runtime.ClassLoader_LoadClass != null) { + var java = info.ToJavaName (classname); + var __args = stackalloc JniArgumentValue [1]; + __args [0] = new JniArgumentValue (java); + + IntPtr ignoreThrown; + c = NativeMethods.java_interop_jnienv_call_object_method_a (info.EnvironmentPointer, out ignoreThrown, info.Runtime.ClassLoader.Handle, info.Runtime.ClassLoader_LoadClass.ID, (IntPtr) __args); + JniObjectReference.Dispose (ref java); + if (ignoreThrown == IntPtr.Zero) { + JniObjectReference.Dispose (ref e); + var r = new JniObjectReference (c, JniObjectReferenceType.Local); + JniEnvironment.LogCreateLocalRef (r); + return r; + } + NativeMethods.java_interop_jnienv_exception_clear (info.EnvironmentPointer); + NativeMethods.java_interop_jnienv_delete_local_ref (info.EnvironmentPointer, ignoreThrown); - IntPtr ignoreThrown; - c = NativeMethods.java_interop_jnienv_call_object_method_a (info.EnvironmentPointer, out ignoreThrown, info.Runtime.ClassLoader.Handle, info.Runtime.ClassLoader_LoadClass.ID, (IntPtr) __args); - JniObjectReference.Dispose (ref java); - if (ignoreThrown == IntPtr.Zero) { - JniObjectReference.Dispose (ref e); - var r = new JniObjectReference (c, JniObjectReferenceType.Local); - JniEnvironment.LogCreateLocalRef (r); - return r; } - NativeMethods.java_interop_jnienv_exception_clear (info.EnvironmentPointer); - NativeMethods.java_interop_jnienv_delete_local_ref (info.EnvironmentPointer, ignoreThrown); + throw info.Runtime.GetExceptionForThrowable (ref e, JniObjectReferenceOptions.CopyAndDispose); #endif // !FEATURE_JNIENVIRONMENT_JI_PINVOKES #if FEATURE_JNIOBJECTREFERENCE_SAFEHANDLES diff --git a/src/Java.Interop/Java.Interop/JniRuntime.JniMarshalMemberBuilder.cs b/src/Java.Interop/Java.Interop/JniRuntime.JniMarshalMemberBuilder.cs index cbd9eb6cc..8bc232f75 100644 --- a/src/Java.Interop/Java.Interop/JniRuntime.JniMarshalMemberBuilder.cs +++ b/src/Java.Interop/Java.Interop/JniRuntime.JniMarshalMemberBuilder.cs @@ -1,4 +1,6 @@ -using System; +#nullable enable + +using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; @@ -11,10 +13,10 @@ partial class JniRuntime { partial class CreationOptions { public bool UseMarshalMemberBuilder {get; set;} = true; - public JniMarshalMemberBuilder MarshalMemberBuilder {get; set;} + public JniMarshalMemberBuilder? MarshalMemberBuilder {get; set;} } - JniMarshalMemberBuilder marshalMemberBuilder; + JniMarshalMemberBuilder? marshalMemberBuilder; public JniMarshalMemberBuilder MarshalMemberBuilder { get { if (marshalMemberBuilder == null) @@ -51,9 +53,13 @@ partial void SetMarshalMemberBuilder (CreationOptions options) public abstract class JniMarshalMemberBuilder : IDisposable, ISetRuntime { - public JniRuntime Runtime {get; private set;} + JniRuntime? runtime; bool disposed; + public JniRuntime Runtime { + get => runtime ?? throw new NotSupportedException (); + } + protected JniMarshalMemberBuilder () { } @@ -63,7 +69,7 @@ public virtual void OnSetRuntime (JniRuntime runtime) if (disposed) throw new ObjectDisposedException (GetType ().Name); - Runtime = runtime; + this.runtime = runtime; } public void Dispose () @@ -141,7 +147,7 @@ public JniValueMarshaler GetParameterMarshaler (ParameterInfo parameter) if (parameter.ParameterType == typeof (IntPtr)) return IntPtrValueMarshaler.Instance; - JniValueMarshalerAttribute attr; + JniValueMarshalerAttribute? attr; try { attr = parameter.GetCustomAttribute (); } catch (System.IndexOutOfRangeException) { diff --git a/src/Java.Interop/Java.Interop/JniRuntime.cs b/src/Java.Interop/Java.Interop/JniRuntime.cs index 29431071c..b8a4eac1c 100644 --- a/src/Java.Interop/Java.Interop/JniRuntime.cs +++ b/src/Java.Interop/Java.Interop/JniRuntime.cs @@ -1,3 +1,5 @@ +#nullable enable + using System; using System.Collections.Concurrent; using System.Collections.Generic; @@ -58,9 +60,9 @@ public partial class CreationOptions { public JniObjectReference ClassLoader {get; set;} public IntPtr ClassLoader_LoadClass_id {get; set;} - public JniObjectReferenceManager ObjectReferenceManager {get; set;} - public JniTypeManager TypeManager {get; set;} - public string JvmLibraryPath {get; set;} + public JniObjectReferenceManager? ObjectReferenceManager {get; set;} + public JniTypeManager? TypeManager {get; set;} + public string? JvmLibraryPath {get; set;} public CreationOptions () { @@ -80,7 +82,7 @@ partial class NativeMethods { const string JavaInteropLibrary = "java-interop"; [DllImport (JavaInteropLibrary, CallingConvention=CallingConvention.Cdecl)] - internal static extern int java_interop_jvm_list ([Out] IntPtr[] handles, int bufLen, out int nVMs); + internal static extern int java_interop_jvm_list ([Out] IntPtr[]? handles, int bufLen, out int nVMs); } public partial class JniRuntime : IDisposable @@ -89,22 +91,24 @@ public partial class JniRuntime : IDisposable const int JNI_EDETACHED = -2; const int JNI_EVERSION = -3; - static ConcurrentDictionary Runtimes = new ConcurrentDictionary (); + static Dictionary Runtimes = new Dictionary (); public static IEnumerable GetRegisteredRuntimes () { return Runtimes.Values; } - public static JniRuntime GetRegisteredRuntime (IntPtr invocationPointer) + public static JniRuntime? GetRegisteredRuntime (IntPtr invocationPointer) { JniRuntime vm; - return Runtimes.TryGetValue (invocationPointer, out vm) - ? vm - : null; + lock (Runtimes) { + return Runtimes.TryGetValue (invocationPointer, out vm) + ? vm + : null; + } } - internal static int GetCreatedJavaVMs (IntPtr[] handles, int bufLen, out int nVMs) + internal static int GetCreatedJavaVMs (IntPtr[]? handles, int bufLen, out int nVMs) { return NativeMethods.java_interop_jvm_list (handles, bufLen, out nVMs); } @@ -122,20 +126,22 @@ public static IEnumerable GetAvailableInvocationPointers () return handles; } - static JniRuntime current; + static JniRuntime? current; public static JniRuntime CurrentRuntime { get { var c = current; if (c != null) return c; int count = 0; - foreach (var vm in Runtimes.Values) { - if (count++ == 0) - c = vm; + lock (Runtimes) { + foreach (var vm in Runtimes.Values) { + if (count++ == 0) + c = vm; + } } if (count == 1) { Interlocked.CompareExchange (ref current, c, null); - return c; + return c!; } if (count > 1) throw new NotSupportedException (string.Format ("Found {0} Java Runtimes. Don't know which to use. Use JniRuntime.SetCurrent().", count)); @@ -155,8 +161,10 @@ public static JniRuntime CurrentRuntime { public static void SetCurrent (JniRuntime newCurrent) { if (newCurrent == null) - throw new ArgumentNullException (nameof (newCurrent)); - Runtimes.TryAdd (newCurrent.InvocationPointer, newCurrent); + throw new ArgumentNullException ("newCurrent"); + lock (Runtimes) { + Runtimes [newCurrent.InvocationPointer] = newCurrent; + } current = newCurrent; } @@ -166,7 +174,7 @@ public static void SetCurrent (JniRuntime newCurrent) bool DestroyRuntimeOnDispose; internal JniObjectReference ClassLoader; - internal JniMethodInfo ClassLoader_LoadClass; + internal JniMethodInfo? ClassLoader_LoadClass; public IntPtr InvocationPointer {get; private set;} @@ -194,14 +202,16 @@ protected JniRuntime (CreationOptions options) SetValueManager (options); SetMarshalMemberBuilder (options); - ObjectReferenceManager = SetRuntime (options.ObjectReferenceManager); + ObjectReferenceManager = SetRuntime (options.ObjectReferenceManager ?? throw new NotSupportedException ($"Please set {nameof (CreationOptions)}.{nameof (options.ObjectReferenceManager)}!")); TypeManager = SetRuntime (options.TypeManager ?? new JniTypeManager ()); if (Interlocked.CompareExchange (ref current, this, null) != null) { Debug.WriteLine ("WARNING: More than one JniRuntime instance created. This is DOOMED TO FAIL."); } - Runtimes.TryAdd (InvocationPointer, this); + lock (Runtimes) { + Runtimes [InvocationPointer] = this; + } var envp = options.EnvironmentPointer; if (envp == IntPtr.Zero && @@ -245,7 +255,7 @@ T SetRuntime (T value) where T : class, ISetRuntime { if (value == null) - return null; + throw new NotSupportedException (); value.OnSetRuntime (this); return value; @@ -265,17 +275,17 @@ static unsafe JavaVMInterface CreateInvoker (IntPtr handle) Dispose (false); } - public virtual string GetCurrentManagedThreadName () + public virtual string? GetCurrentManagedThreadName () { return null; } - public virtual string GetCurrentManagedThreadStackTrace (int skipFrames = 0, bool fNeedFileInfo = false) + public virtual string? GetCurrentManagedThreadStackTrace (int skipFrames = 0, bool fNeedFileInfo = false) { return null; } - public virtual void FailFast (string message) + public virtual void FailFast (string? message) { var m = typeof (Environment).GetMethod ("FailFast"); m.Invoke (null, new object[]{ message }); @@ -299,7 +309,11 @@ protected virtual void Dispose (bool disposing) Interlocked.CompareExchange (ref current, null, this); - Runtimes.TryUpdate (InvocationPointer, null, this); + lock (Runtimes) { + if (Runtimes.TryGetValue (InvocationPointer, out var vm) && vm == this) { + Runtimes.Remove (InvocationPointer); + } + } if (disposing) { JniObjectReference.Dispose (ref ClassLoader); @@ -328,13 +342,13 @@ protected virtual void Dispose (bool disposing) Invoker = default (JavaVMInterface); } - public void AttachCurrentThread (string name = null, JniObjectReference group = default (JniObjectReference)) + public void AttachCurrentThread (string? name = null, JniObjectReference group = default (JniObjectReference)) { var jnienv = _AttachCurrentThread (name, group); JniEnvironment.SetEnvironmentPointer (jnienv, this); } - internal IntPtr _AttachCurrentThread (string name = null, JniObjectReference group = default (JniObjectReference)) + internal IntPtr _AttachCurrentThread (string? name = null, JniObjectReference group = default (JniObjectReference)) { AssertValid (); var threadArgs = new JavaVMThreadAttachArgs () { From 82567a2b7adde7cdea8e19bbfbdc8b5896d1d94b Mon Sep 17 00:00:00 2001 From: Jonathan Pryor Date: Tue, 19 Nov 2019 15:13:31 -0500 Subject: [PATCH 11/33] Add #nullable for JniRuntime --- src/Java.Interop/Java.Interop.csproj | 4 +- src/Java.Interop/Java.Interop/JavaArray.cs | 2 + .../Java.Interop/JavaProxyObject.cs | 6 +- .../Java.Interop/JniEnvironment.Types.cs | 2 +- .../JniRuntime.JniObjectReferenceManager.cs | 11 +++- .../Java.Interop/JniRuntime.JniTypeManager.cs | 14 ++-- .../JniRuntime.JniValueManager.cs | 65 ++++++++++++------- src/Java.Interop/Java.Interop/JniRuntime.cs | 2 +- 8 files changed, 69 insertions(+), 37 deletions(-) diff --git a/src/Java.Interop/Java.Interop.csproj b/src/Java.Interop/Java.Interop.csproj index 5da48b9f7..67135361f 100644 --- a/src/Java.Interop/Java.Interop.csproj +++ b/src/Java.Interop/Java.Interop.csproj @@ -1,7 +1,7 @@ - netstandard2.0 + netstandard2.1 1591 true ..\..\product.snk @@ -82,7 +82,7 @@ - + diff --git a/src/Java.Interop/Java.Interop/JavaArray.cs b/src/Java.Interop/Java.Interop/JavaArray.cs index 7c50ba981..c456f847c 100644 --- a/src/Java.Interop/Java.Interop/JavaArray.cs +++ b/src/Java.Interop/Java.Interop/JavaArray.cs @@ -4,6 +4,7 @@ using System.Collections; using System.Collections.Generic; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Reflection; @@ -27,6 +28,7 @@ public int Length { get {return JniEnvironment.Arrays.GetArrayLength (PeerReference);} } + [MaybeNull] public abstract T this [int index] { get; set; diff --git a/src/Java.Interop/Java.Interop/JavaProxyObject.cs b/src/Java.Interop/Java.Interop/JavaProxyObject.cs index b2d0d333b..a438cc37a 100644 --- a/src/Java.Interop/Java.Interop/JavaProxyObject.cs +++ b/src/Java.Interop/Java.Interop/JavaProxyObject.cs @@ -1,6 +1,7 @@ #nullable enable using System; +using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; namespace Java.Interop { @@ -41,20 +42,21 @@ public override int GetHashCode () return Value.GetHashCode (); } - public override bool Equals (object obj) + public override bool Equals (object? obj) { if (obj is JavaProxyObject other) return object.Equals (Value, other.Value); return object.Equals (Value, obj); } - public bool Equals (JavaProxyObject other) => object.Equals (Value, other.Value); + public bool Equals (JavaProxyObject? other) => object.Equals (Value, other?.Value); public override string ToString () { return Value.ToString (); } + [return: NotNullIfNotNull ("object")] public static JavaProxyObject? GetProxy (object value) { if (value == null) diff --git a/src/Java.Interop/Java.Interop/JniEnvironment.Types.cs b/src/Java.Interop/Java.Interop/JniEnvironment.Types.cs index 86f9e3afb..387aa9856 100644 --- a/src/Java.Interop/Java.Interop/JniEnvironment.Types.cs +++ b/src/Java.Interop/Java.Interop/JniEnvironment.Types.cs @@ -70,7 +70,7 @@ public static unsafe JniObjectReference FindClass (string classname) } - throw info.Runtime.GetExceptionForThrowable (ref e, JniObjectReferenceOptions.CopyAndDispose); + throw info.Runtime.GetExceptionForThrowable (ref e, JniObjectReferenceOptions.CopyAndDispose)!; #endif // !FEATURE_JNIENVIRONMENT_JI_PINVOKES #if FEATURE_JNIOBJECTREFERENCE_SAFEHANDLES var c = info.Invoker.FindClass (info.EnvironmentPointer, classname); diff --git a/src/Java.Interop/Java.Interop/JniRuntime.JniObjectReferenceManager.cs b/src/Java.Interop/Java.Interop/JniRuntime.JniObjectReferenceManager.cs index 5679f993a..1553c452b 100644 --- a/src/Java.Interop/Java.Interop/JniRuntime.JniObjectReferenceManager.cs +++ b/src/Java.Interop/Java.Interop/JniRuntime.JniObjectReferenceManager.cs @@ -1,3 +1,5 @@ +# nullable enable + using System; using System.Collections.Concurrent; using System.Collections.Generic; @@ -18,11 +20,14 @@ public JniObjectReferenceManager () { } - public JniRuntime Runtime { get; private set; } + JniRuntime? runtime; + public JniRuntime Runtime { + get => runtime ?? throw new NotSupportedException (); + } public virtual void OnSetRuntime (JniRuntime runtime) { - Runtime = runtime; + this.runtime = runtime; } public abstract int GlobalReferenceCount { @@ -118,7 +123,7 @@ public virtual bool LogGlobalReferenceMessages { get {return false;} } - public virtual void WriteGlobalReferenceLine (string format, params object[] args) + public virtual void WriteGlobalReferenceLine (string format, params object?[] args) { } diff --git a/src/Java.Interop/Java.Interop/JniRuntime.JniTypeManager.cs b/src/Java.Interop/Java.Interop/JniRuntime.JniTypeManager.cs index de0b1b169..59a385e56 100644 --- a/src/Java.Interop/Java.Interop/JniRuntime.JniTypeManager.cs +++ b/src/Java.Interop/Java.Interop/JniRuntime.JniTypeManager.cs @@ -1,3 +1,5 @@ +#nullable enable + using System; using System.Collections.Generic; using System.Diagnostics; @@ -12,15 +14,18 @@ public partial class JniRuntime { public class JniTypeManager : IDisposable, ISetRuntime { + JniRuntime? runtime; bool disposed; - public JniRuntime Runtime { get; private set; } + public JniRuntime Runtime { + get => runtime ?? throw new NotSupportedException (); + } public virtual void OnSetRuntime (JniRuntime runtime) { AssertValid (); - Runtime = runtime; + this.runtime = runtime; } public void Dispose () @@ -250,7 +255,8 @@ protected virtual IEnumerable GetTypesForSimpleReference (string jniSimple if (jniSimpleReference != null && jniSimpleReference.StartsWith ("L", StringComparison.Ordinal) && jniSimpleReference.EndsWith (";", StringComparison.Ordinal)) throw new ArgumentException ("Only simplified type references are supported.", nameof (jniSimpleReference)); - return CreateGetTypesForSimpleReferenceEnumerator (jniSimpleReference); + // Not sure why CS8604 is reported on following line when we check against null ~9 lines above... + return CreateGetTypesForSimpleReferenceEnumerator (jniSimpleReference!); } IEnumerable CreateGetTypesForSimpleReferenceEnumerator (string jniSimpleReference) @@ -291,7 +297,7 @@ static bool TryLoadJniMarshalMethods (JniType nativeClass, Type type, string met static List sharedRegistrations = new List (); - static bool TryRegisterNativeMembers (JniType nativeClass, Type marshalType, string methods, MethodInfo registerMethod) + static bool TryRegisterNativeMembers (JniType nativeClass, Type marshalType, string methods, MethodInfo? registerMethod) { bool lockTaken = false; bool rv = false; diff --git a/src/Java.Interop/Java.Interop/JniRuntime.JniValueManager.cs b/src/Java.Interop/Java.Interop/JniRuntime.JniValueManager.cs index 38384ba7e..2eed15628 100644 --- a/src/Java.Interop/Java.Interop/JniRuntime.JniValueManager.cs +++ b/src/Java.Interop/Java.Interop/JniRuntime.JniValueManager.cs @@ -1,5 +1,8 @@ +#nullable enable + using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Linq.Expressions; using System.Reflection; @@ -26,10 +29,13 @@ public JniSurfacedPeerInfo (int jniIdentityHashCode, WeakReference valueManager ?? throw new NotSupportedException (); + } partial void SetValueManager (CreationOptions options) { @@ -38,20 +44,23 @@ partial void SetValueManager (CreationOptions options) throw new ArgumentException ( "No JniValueManager specified in JniRuntime.CreationOptions.ValueManager.", nameof (options)); - ValueManager = SetRuntime (manager); + valueManager = SetRuntime (manager); } public abstract partial class JniValueManager : ISetRuntime, IDisposable { - public JniRuntime Runtime { get; private set; } + JniRuntime? runtime; bool disposed; + public JniRuntime Runtime { + get => runtime ?? throw new NotSupportedException (); + } public virtual void OnSetRuntime (JniRuntime runtime) { if (disposed) throw new ObjectDisposedException (GetType ().Name); - Runtime = runtime; + this.runtime = runtime; } public void Dispose () @@ -192,7 +201,7 @@ public virtual void DisposePeerUnlessReferenced (IJavaPeerable value) public abstract IJavaPeerable PeekPeer (JniObjectReference reference); - public object PeekValue (JniObjectReference reference) + public object? PeekValue (JniObjectReference reference) { if (disposed) throw new ObjectDisposedException (GetType ().Name); @@ -204,13 +213,13 @@ public object PeekValue (JniObjectReference reference) if (t == null) return t; - object r; + object? r; return TryUnboxPeerObject (t, out r) ? r : t; } - protected virtual bool TryUnboxPeerObject (IJavaPeerable value, out object result) + protected virtual bool TryUnboxPeerObject (IJavaPeerable value, [NotNullWhen (true)] out object? result) { result = null; var p = value as JavaProxyObject; @@ -226,12 +235,12 @@ protected virtual bool TryUnboxPeerObject (IJavaPeerable value, out object resul return false; } - object PeekBoxedObject (JniObjectReference reference) + object? PeekBoxedObject (JniObjectReference reference) { var t = PeekPeer (reference); if (t == null) return null; - object r; + object? r; return TryUnboxPeerObject (t, out r) ? r : null; @@ -252,7 +261,7 @@ static Type GetPeerType (Type type) return type; } - public virtual IJavaPeerable CreatePeer (ref JniObjectReference reference, JniObjectReferenceOptions transfer, Type targetType) + public virtual IJavaPeerable CreatePeer (ref JniObjectReference reference, JniObjectReferenceOptions transfer, Type? targetType) { if (disposed) throw new ObjectDisposedException (GetType ().Name); @@ -283,12 +292,12 @@ public virtual IJavaPeerable CreatePeer (ref JniObjectReference reference, JniOb static readonly Type ByRefJniObjectReference = typeof (JniObjectReference).MakeByRefType (); - ConstructorInfo GetPeerConstructor (JniObjectReference instance, Type fallbackType) + ConstructorInfo? GetPeerConstructor (JniObjectReference instance, Type fallbackType) { var klass = JniEnvironment.Types.GetObjectClass (instance); var jniTypeName = JniEnvironment.Types.GetJniTypeNameFromClass (klass); - Type type = null; + Type? type = null; while (jniTypeName != null) { JniTypeSignature sig; if (!JniTypeSignature.TryParse (jniTypeName, out sig)) @@ -329,7 +338,7 @@ static ConstructorInfo GetActivationConstructor (Type type) } - public object CreateValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type targetType = null) + public object? CreateValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type? targetType = null) { if (disposed) throw new ObjectDisposedException (GetType ().Name); @@ -358,13 +367,17 @@ public object CreateValue (ref JniObjectReference reference, JniObjectReferenceO return marshaler.CreateValue (ref reference, options, targetType); } - public T CreateValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type targetType = null) + [return: MaybeNull] + public T CreateValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type? targetType = null) { if (disposed) throw new ObjectDisposedException (GetType ().Name); - if (!reference.IsValid) + if (!reference.IsValid) { +#pragma warning disable 8653 return default (T); +#pragma warning restore 8653 + } if (targetType != null && !typeof (T).IsAssignableFrom (targetType)) throw new ArgumentException ( @@ -390,7 +403,7 @@ public T CreateValue (ref JniObjectReference reference, JniObjectReferenceOpt return marshaler.CreateGenericValue (ref reference, options, targetType); } - internal Type GetRuntimeType (JniObjectReference reference) + internal Type? GetRuntimeType (JniObjectReference reference) { JniTypeSignature signature; if (!JniTypeSignature.TryParse (JniEnvironment.Types.GetJniTypeNameFromInstance (reference), out signature)) @@ -398,7 +411,7 @@ internal Type GetRuntimeType (JniObjectReference reference) return Runtime.TypeManager.GetType (signature); } - public object GetValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type targetType = null) + public object? GetValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type? targetType = null) { if (disposed) throw new ObjectDisposedException (GetType ().Name); @@ -431,10 +444,14 @@ public T GetValue (IntPtr handle) return GetValue (ref r, JniObjectReferenceOptions.Copy); } - public T GetValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type targetType = null) + [return: MaybeNull] + public T GetValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type? targetType = null) { - if (!reference.IsValid) + if (!reference.IsValid) { +#pragma warning disable 8653 return default (T); +#pragma warning restore 8653 + } if (targetType != null && !typeof (T).IsAssignableFrom (targetType)) throw new ArgumentException ( @@ -526,7 +543,7 @@ public JniValueMarshaler GetValueMarshaler (Type type) return JavaPeerableValueMarshaler.Instance; } - JniValueMarshalerAttribute ifaceAttribute = null; + JniValueMarshalerAttribute? ifaceAttribute = null; foreach (var iface in type.GetInterfaces ()) { marshalerAttr = iface.GetCustomAttribute (); if (marshalerAttr != null) { @@ -591,7 +608,7 @@ sealed class JavaPeerableValueMarshaler : JniValueMarshaler { internal static JavaPeerableValueMarshaler Instance = new JavaPeerableValueMarshaler (); - public override IJavaPeerable CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type targetType) + public override IJavaPeerable CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type? targetType) { var jvm = JniEnvironment.Runtime; var marshaler = jvm.ValueManager.GetValueMarshaler (targetType ?? typeof(IJavaPeerable)); @@ -702,7 +719,7 @@ sealed class ProxyValueMarshaler : JniValueMarshaler { internal static ProxyValueMarshaler Instance = new ProxyValueMarshaler (); - public override object CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type targetType) + public override object CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type? targetType) { var jvm = JniEnvironment.Runtime; @@ -739,7 +756,7 @@ public override JniValueMarshalerState CreateGenericObjectReferenceArgumentState } var p = JavaProxyObject.GetProxy (value); - return new JniValueMarshalerState (p.PeerReference.NewLocalRef ()); + return new JniValueMarshalerState (p!.PeerReference.NewLocalRef ()); } public override void DestroyGenericArgumentState (object value, ref JniValueMarshalerState state, ParameterAttributes synchronize) diff --git a/src/Java.Interop/Java.Interop/JniRuntime.cs b/src/Java.Interop/Java.Interop/JniRuntime.cs index b8a4eac1c..0e72da102 100644 --- a/src/Java.Interop/Java.Interop/JniRuntime.cs +++ b/src/Java.Interop/Java.Interop/JniRuntime.cs @@ -381,7 +381,7 @@ public void DestroyRuntime () Invoker.DestroyJavaVM (InvocationPointer); } - public virtual Exception GetExceptionForThrowable (ref JniObjectReference reference, JniObjectReferenceOptions options) + public virtual Exception? GetExceptionForThrowable (ref JniObjectReference reference, JniObjectReferenceOptions options) { #if XA_INTEGRATION throw new NotSupportedException ("Do not know h ow to convert a JniObjectReference to a System.Exception!"); From 70a39c92d15bb8d5fea5faee2ffd370541c2c071 Mon Sep 17 00:00:00 2001 From: Jonathan Pryor Date: Tue, 19 Nov 2019 15:14:59 -0500 Subject: [PATCH 12/33] Add #nullable for JniSystem. --- src/Java.Interop/Java.Interop/JniSystem.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Java.Interop/Java.Interop/JniSystem.cs b/src/Java.Interop/Java.Interop/JniSystem.cs index 5fad90639..c15324730 100644 --- a/src/Java.Interop/Java.Interop/JniSystem.cs +++ b/src/Java.Interop/Java.Interop/JniSystem.cs @@ -1,14 +1,16 @@ +#nullable enable + using System; namespace Java.Interop { static class JniSystem { - static JniType _typeRef; + static JniType? _typeRef; static JniType TypeRef { get {return JniType.GetCachedJniType (ref _typeRef, "java/lang/System");} } - static JniMethodInfo _identityHashCode; + static JniMethodInfo? _identityHashCode; internal static unsafe int IdentityHashCode (JniObjectReference value) { var args = stackalloc JniArgumentValue [1]; From 9d3c875d3027ab290697e2e04a38d995c0e08cbb Mon Sep 17 00:00:00 2001 From: Jonathan Pryor Date: Tue, 19 Nov 2019 15:16:02 -0500 Subject: [PATCH 13/33] Add #nullable for JniTransition --- src/Java.Interop/Java.Interop/JniTransition.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Java.Interop/Java.Interop/JniTransition.cs b/src/Java.Interop/Java.Interop/JniTransition.cs index e47cb920d..69644ce21 100644 --- a/src/Java.Interop/Java.Interop/JniTransition.cs +++ b/src/Java.Interop/Java.Interop/JniTransition.cs @@ -1,11 +1,13 @@ -using System; +#nullable enable + +using System; namespace Java.Interop { public struct JniTransition : IDisposable { bool disposed; - Exception pendingException; + Exception? pendingException; public JniTransition (IntPtr environmentPointer) { From 26d3721fb0b4d5c11048ceabb756e90acff4873a Mon Sep 17 00:00:00 2001 From: Jonathan Pryor Date: Tue, 19 Nov 2019 15:24:00 -0500 Subject: [PATCH 14/33] Add #nullable for JniType --- src/Java.Interop/Java.Interop/JniType.cs | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/Java.Interop/Java.Interop/JniType.cs b/src/Java.Interop/Java.Interop/JniType.cs index 18c8afc51..9feaacdb9 100644 --- a/src/Java.Interop/Java.Interop/JniType.cs +++ b/src/Java.Interop/Java.Interop/JniType.cs @@ -1,4 +1,7 @@ +#nullable enable + using System; +using System.Diagnostics.CodeAnalysis; using System.Collections.Generic; using System.Linq; using System.Reflection; @@ -11,7 +14,8 @@ namespace Java.Interop { public sealed class JniType : IDisposable { - public static unsafe JniType DefineClass (string name, JniObjectReference loader, byte[] classFileData) + [return: NotNullIfNotNull ("name")] + public static unsafe JniType? DefineClass (string name, JniObjectReference loader, byte[] classFileData) { if (classFileData == null) return null; @@ -54,7 +58,7 @@ public string Name { get { AssertValid (); - return JniEnvironment.Types.GetJniTypeNameFromClass (PeerReference); + return JniEnvironment.Types.GetJniTypeNameFromClass (PeerReference)!; } } @@ -86,7 +90,7 @@ void AssertValid () throw new ObjectDisposedException (GetType ().FullName); } - public static JniType GetCachedJniType (ref JniType cachedType, string classname) + public static JniType GetCachedJniType ([NotNull] ref JniType? cachedType, string classname) { if (cachedType != null && cachedType.PeerReference.IsValid) return cachedType; @@ -108,7 +112,7 @@ public void Dispose () JniObjectReference.Dispose (ref peerReference); } - public JniType GetSuperclass () + public JniType? GetSuperclass () { AssertValid (); @@ -139,7 +143,7 @@ public bool IsInstanceOfType (JniObjectReference value) #pragma warning disable 0414 // This isn't used anywhere; it's just present so that the GC won't collect the referenced delegates. - JniNativeMethodRegistration[] methods; + JniNativeMethodRegistration[]? methods; #pragma warning restore 0414 public void RegisterNativeMethods (params JniNativeMethodRegistration[] methods) @@ -169,7 +173,7 @@ public JniMethodInfo GetConstructor (string signature) return JniEnvironment.InstanceMethods.GetMethodID (PeerReference, "", signature); } - public JniMethodInfo GetCachedConstructor (ref JniMethodInfo cachedMethod, string signature) + public JniMethodInfo GetCachedConstructor ([NotNull] ref JniMethodInfo? cachedMethod, string signature) { AssertValid (); @@ -197,7 +201,7 @@ public JniFieldInfo GetInstanceField (string name, string signature) return JniEnvironment.InstanceFields.GetFieldID (PeerReference, name, signature); } - public JniFieldInfo GetCachedInstanceField (ref JniFieldInfo cachedField, string name, string signature) + public JniFieldInfo GetCachedInstanceField ([NotNull] ref JniFieldInfo? cachedField, string name, string signature) { AssertValid (); @@ -217,7 +221,7 @@ public JniFieldInfo GetStaticField (string name, string signature) return JniEnvironment.StaticFields.GetStaticFieldID (PeerReference, name, signature); } - public JniFieldInfo GetCachedStaticField (ref JniFieldInfo cachedField, string name, string signature) + public JniFieldInfo GetCachedStaticField ([NotNull] ref JniFieldInfo? cachedField, string name, string signature) { AssertValid (); @@ -237,7 +241,7 @@ public JniMethodInfo GetInstanceMethod (string name, string signature) return JniEnvironment.InstanceMethods.GetMethodID (PeerReference, name, signature); } - public JniMethodInfo GetCachedInstanceMethod (ref JniMethodInfo cachedMethod, string name, string signature) + public JniMethodInfo GetCachedInstanceMethod ([NotNull] ref JniMethodInfo? cachedMethod, string name, string signature) { AssertValid (); @@ -257,7 +261,7 @@ public JniMethodInfo GetStaticMethod (string name, string signature) return JniEnvironment.StaticMethods.GetStaticMethodID (PeerReference, name, signature); } - public JniMethodInfo GetCachedStaticMethod (ref JniMethodInfo cachedMethod, string name, string signature) + public JniMethodInfo GetCachedStaticMethod ([NotNull] ref JniMethodInfo? cachedMethod, string name, string signature) { AssertValid (); From d18d53383f9ab20106250a0f00b303d2bede346f Mon Sep 17 00:00:00 2001 From: Jonathan Pryor Date: Tue, 19 Nov 2019 15:32:58 -0500 Subject: [PATCH 15/33] Add #nullable for JniTypeSignature --- .../Java.Interop/JniRuntime.JniTypeManager.cs | 4 +++- .../Java.Interop/JniRuntime.JniValueManager.cs | 4 +++- .../Java.Interop/JniTypeSignature.cs | 17 +++++++++++------ 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/Java.Interop/Java.Interop/JniRuntime.JniTypeManager.cs b/src/Java.Interop/Java.Interop/JniRuntime.JniTypeManager.cs index 59a385e56..9983bf059 100644 --- a/src/Java.Interop/Java.Interop/JniRuntime.JniTypeManager.cs +++ b/src/Java.Interop/Java.Interop/JniRuntime.JniTypeManager.cs @@ -212,7 +212,9 @@ public virtual IEnumerable GetTypes (JniTypeSignature typeSignature) IEnumerable CreateGetTypesEnumerator (JniTypeSignature typeSignature) { - foreach (var type in GetTypesForSimpleReference (typeSignature.SimpleReference)) { + if (!typeSignature.IsValid) + yield break; + foreach (var type in GetTypesForSimpleReference (typeSignature.SimpleReference ?? throw new InvalidOperationException ("Should not be reached")) ){ if (typeSignature.ArrayRank == 0) { yield return type; continue; diff --git a/src/Java.Interop/Java.Interop/JniRuntime.JniValueManager.cs b/src/Java.Interop/Java.Interop/JniRuntime.JniValueManager.cs index 2eed15628..5b2d159a5 100644 --- a/src/Java.Interop/Java.Interop/JniRuntime.JniValueManager.cs +++ b/src/Java.Interop/Java.Interop/JniRuntime.JniValueManager.cs @@ -405,8 +405,10 @@ public T CreateValue (ref JniObjectReference reference, JniObjectReferenceOpt internal Type? GetRuntimeType (JniObjectReference reference) { + if (!reference.IsValid) + return null; JniTypeSignature signature; - if (!JniTypeSignature.TryParse (JniEnvironment.Types.GetJniTypeNameFromInstance (reference), out signature)) + if (!JniTypeSignature.TryParse (JniEnvironment.Types.GetJniTypeNameFromInstance (reference)!, out signature)) return null; return Runtime.TypeManager.GetType (signature); } diff --git a/src/Java.Interop/Java.Interop/JniTypeSignature.cs b/src/Java.Interop/Java.Interop/JniTypeSignature.cs index b74a8423b..3e42c0359 100644 --- a/src/Java.Interop/Java.Interop/JniTypeSignature.cs +++ b/src/Java.Interop/Java.Interop/JniTypeSignature.cs @@ -1,4 +1,7 @@ +#nullable enable + using System; +using System.Diagnostics.CodeAnalysis; using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; @@ -14,7 +17,7 @@ public struct JniTypeSignature : IEquatable internal bool IsKeyword {get; private set;} - public string SimpleReference {get; private set;} + public string? SimpleReference {get; private set;} public int ArrayRank {get; private set;} public bool IsValid { @@ -24,7 +27,7 @@ public bool IsValid { public string QualifiedReference { get { string typename = IsKeyword - ? SimpleReference + ? SimpleReference ?? throw new InvalidOperationException () : "L" + SimpleReference + ";"; return ArrayRank == 0 ? typename @@ -33,7 +36,7 @@ public string QualifiedReference { } public string Name { - get {return ArrayRank == 0 ? SimpleReference : QualifiedReference;} + get {return ArrayRank == 0 ? SimpleReference ?? throw new InvalidOperationException (): QualifiedReference;} } public JniTypeSignature (string simpleReference, int arrayRank = 0, bool keyword = false) @@ -54,6 +57,8 @@ public JniTypeSignature (string simpleReference, int arrayRank = 0, bool keyword public JniTypeSignature AddArrayRank (int rank) { + if (SimpleReference == null) + throw new InvalidOperationException (); return new JniTypeSignature (SimpleReference, ArrayRank + rank, IsKeyword); } @@ -85,7 +90,7 @@ public static JniTypeSignature Parse (string signature) return r; } - public static bool TryParse (string signature, out JniTypeSignature result) + public static bool TryParse (string signature, [NotNullWhen (true)] out JniTypeSignature result) { var e = TryParseWithException (signature, out result); if (e != null) @@ -93,7 +98,7 @@ public static bool TryParse (string signature, out JniTypeSignature result) return true; } - static Exception TryParseWithException (string signature, out JniTypeSignature result) + static Exception? TryParseWithException (string signature, out JniTypeSignature result) { result = default (JniTypeSignature); @@ -102,7 +107,7 @@ static Exception TryParseWithException (string signature, out JniTypeSignature r int i = 0; int r = 0; - var n = (string) null; + var n = (string?) null; var k = false; while (i < signature.Length && signature [i] == '[') { i++; From 4358bb4c095434ba90fc5d9453c039623c523722 Mon Sep 17 00:00:00 2001 From: Jonathan Pryor Date: Tue, 19 Nov 2019 15:33:32 -0500 Subject: [PATCH 16/33] Add #nullable for JniTypeSignatureAttribute --- src/Java.Interop/Java.Interop/JniTypeSignatureAttribute.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Java.Interop/Java.Interop/JniTypeSignatureAttribute.cs b/src/Java.Interop/Java.Interop/JniTypeSignatureAttribute.cs index 676476f80..7814d12d0 100644 --- a/src/Java.Interop/Java.Interop/JniTypeSignatureAttribute.cs +++ b/src/Java.Interop/Java.Interop/JniTypeSignatureAttribute.cs @@ -1,4 +1,6 @@ -using System; +#nullable enable + +using System; namespace Java.Interop { From 4a79f5f6814387cac3d2662751b09d4e5f3db925 Mon Sep 17 00:00:00 2001 From: Jonathan Pryor Date: Tue, 19 Nov 2019 15:37:44 -0500 Subject: [PATCH 17/33] Add #nullable for ManagedPeer --- .../Java.Interop/JniRuntime.JniMarshalMemberBuilder.cs | 4 ++-- .../Java.Interop/JniRuntime.JniTypeManager.cs | 8 ++++---- src/Java.Interop/Java.Interop/ManagedPeer.cs | 8 +++++--- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/Java.Interop/Java.Interop/JniRuntime.JniMarshalMemberBuilder.cs b/src/Java.Interop/Java.Interop/JniRuntime.JniMarshalMemberBuilder.cs index 8bc232f75..6d5675ad2 100644 --- a/src/Java.Interop/Java.Interop/JniRuntime.JniMarshalMemberBuilder.cs +++ b/src/Java.Interop/Java.Interop/JniRuntime.JniMarshalMemberBuilder.cs @@ -92,9 +92,9 @@ public Delegate CreateMarshalToM public abstract LambdaExpression CreateMarshalToManagedExpression (MethodInfo method); public abstract IEnumerable GetExportedMemberRegistrations (Type declaringType); - public abstract Expression> CreateConstructActivationPeerExpression (ConstructorInfo constructor); + public abstract Expression> CreateConstructActivationPeerExpression (ConstructorInfo constructor); - public Func CreateConstructActivationPeerFunc (ConstructorInfo constructor) + public Func CreateConstructActivationPeerFunc (ConstructorInfo constructor) { if (constructor == null) throw new ArgumentNullException (nameof (constructor)); diff --git a/src/Java.Interop/Java.Interop/JniRuntime.JniTypeManager.cs b/src/Java.Interop/Java.Interop/JniRuntime.JniTypeManager.cs index 9983bf059..ed2b89a58 100644 --- a/src/Java.Interop/Java.Interop/JniRuntime.JniTypeManager.cs +++ b/src/Java.Interop/Java.Interop/JniRuntime.JniTypeManager.cs @@ -272,12 +272,12 @@ IEnumerable CreateGetTypesForSimpleReferenceEnumerator (string jniSimpleRe yield break; } - public virtual void RegisterNativeMembers (JniType nativeClass, Type type, string methods) + public virtual void RegisterNativeMembers (JniType nativeClass, Type type, string? methods) { TryRegisterNativeMembers (nativeClass, type, methods); } - protected bool TryRegisterNativeMembers (JniType nativeClass, Type type, string methods) + protected bool TryRegisterNativeMembers (JniType nativeClass, Type type, string? methods) { AssertValid (); @@ -286,7 +286,7 @@ protected bool TryRegisterNativeMembers (JniType nativeClass, Type type, string static Type [] registerMethodParameters = new Type [] { typeof (JniNativeMethodRegistrationArguments) }; - static bool TryLoadJniMarshalMethods (JniType nativeClass, Type type, string methods) + static bool TryLoadJniMarshalMethods (JniType nativeClass, Type type, string? methods) { var marshalType = type?.GetNestedType ("__<$>_jni_marshal_methods", BindingFlags.NonPublic); if (marshalType == null) @@ -299,7 +299,7 @@ static bool TryLoadJniMarshalMethods (JniType nativeClass, Type type, string met static List sharedRegistrations = new List (); - static bool TryRegisterNativeMembers (JniType nativeClass, Type marshalType, string methods, MethodInfo? registerMethod) + static bool TryRegisterNativeMembers (JniType nativeClass, Type marshalType, string? methods, MethodInfo? registerMethod) { bool lockTaken = false; bool rv = false; diff --git a/src/Java.Interop/Java.Interop/ManagedPeer.cs b/src/Java.Interop/Java.Interop/ManagedPeer.cs index 2a11d0bb8..d95252d91 100644 --- a/src/Java.Interop/Java.Interop/ManagedPeer.cs +++ b/src/Java.Interop/Java.Interop/ManagedPeer.cs @@ -1,3 +1,5 @@ +#nullable enable + using System; using System.Diagnostics; using System.Linq; @@ -148,7 +150,7 @@ static Exception CreateMissingConstructorException (Type type, Type[] ptypes) return new NotSupportedException (message.ToString (), CreateJniLocationException ()); } - static Type[] GetParameterTypes (string signature) + static Type[] GetParameterTypes (string? signature) { if (string.IsNullOrEmpty (signature)) return Array.Empty (); @@ -159,7 +161,7 @@ static Type[] GetParameterTypes (string signature) return ptypes; } - static object[] GetValues (JniRuntime runtime, JniObjectReference values, Type[] types) + static object?[]? GetValues (JniRuntime runtime, JniObjectReference values, Type[] types) { if (!values.IsValid) return null; @@ -167,7 +169,7 @@ static object[] GetValues (JniRuntime runtime, JniObjectReference values, Type[] int len = JniEnvironment.Arrays.GetArrayLength (values); Debug.Assert (len == types.Length, string.Format ("Unexpected number of parameter types! Expected {0}, got {1}", types.Length, len)); - var pvalues = new object [types.Length]; + var pvalues = new object? [types.Length]; for (int i = 0; i < pvalues.Length; ++i) { var n_value = JniEnvironment.Arrays.GetObjectArrayElement (values, i); var value = runtime.ValueManager.GetValue (ref n_value, JniObjectReferenceOptions.CopyAndDispose, types [i]); From 3854bd3b5c625e3bf21376a929ce290678ba9456 Mon Sep 17 00:00:00 2001 From: Jonathan Pryor Date: Tue, 19 Nov 2019 15:38:19 -0500 Subject: [PATCH 18/33] Add #nullable for JniValueMarshalerAttribute --- src/Java.Interop/Java.Interop/JniValueMarshalerAttribute.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Java.Interop/Java.Interop/JniValueMarshalerAttribute.cs b/src/Java.Interop/Java.Interop/JniValueMarshalerAttribute.cs index cb850210c..9e94157a3 100644 --- a/src/Java.Interop/Java.Interop/JniValueMarshalerAttribute.cs +++ b/src/Java.Interop/Java.Interop/JniValueMarshalerAttribute.cs @@ -1,3 +1,5 @@ +#nullable enable + using System; using System.Reflection; From 8bcab04dbe9f2dd58df19a2dfbe1f0f2cd2dee31 Mon Sep 17 00:00:00 2001 From: Jonathan Pryor Date: Tue, 19 Nov 2019 17:24:50 -0500 Subject: [PATCH 19/33] Add #nullable for JniBuiltinMarshalers --- src/Java.Interop/Java.Interop/JavaArray.cs | 17 ++--- .../Java.Interop/JavaObjectArray.cs | 4 +- .../Java.Interop/JavaPrimitiveArrays.cs | 64 +++++++++---------- .../Java.Interop/JavaPrimitiveArrays.tt | 8 +-- .../Java.Interop/JniBuiltinMarshalers.cs | 48 +++++++------- .../Java.Interop/JniBuiltinMarshalers.tt | 6 +- .../JniRuntime.JniMarshalMemberBuilder.cs | 12 ++-- .../JniRuntime.JniValueManager.cs | 21 +++--- .../Java.Interop/JniValueMarshaler.cs | 58 +++++++++-------- 9 files changed, 123 insertions(+), 115 deletions(-) diff --git a/src/Java.Interop/Java.Interop/JavaArray.cs b/src/Java.Interop/Java.Interop/JavaArray.cs index c456f847c..6a09bdf2d 100644 --- a/src/Java.Interop/Java.Interop/JavaArray.cs +++ b/src/Java.Interop/Java.Interop/JavaArray.cs @@ -102,7 +102,7 @@ internal static IList ToList (IEnumerable value) return value.ToList (); } - internal IList ToTargetType (Type targetType, bool dispose) + internal IList ToTargetType (Type? targetType, bool dispose) { if (TargetTypeIsCurrentType (targetType)) return this; @@ -117,19 +117,20 @@ internal IList ToTargetType (Type targetType, bool dispose) throw CreateMarshalNotSupportedException (GetType (), targetType); } - internal virtual bool TargetTypeIsCurrentType (Type targetType) + internal virtual bool TargetTypeIsCurrentType (Type? targetType) { return targetType == null || targetType == typeof (JavaArray); } - internal static Exception CreateMarshalNotSupportedException (Type sourceType, Type targetType) + internal static Exception CreateMarshalNotSupportedException (Type sourceType, Type? targetType) { - throw new NotSupportedException ( - string.Format ("Do not know how to marshal a '{0}' into a '{1}'.", - sourceType.FullName, targetType.FullName)); + return new NotSupportedException ( + string.Format ("Do not know how to marshal a `{0}`{1}.", + sourceType.FullName, + targetType != null ? $" into a `{targetType.FullName}`" : "")); } - internal static IList CreateValue (ref JniObjectReference reference, JniObjectReferenceOptions transfer, Type targetType, ArrayCreator creator) + internal static IList CreateValue (ref JniObjectReference reference, JniObjectReferenceOptions transfer, Type? targetType, ArrayCreator creator) where TArray : JavaArray { return creator (ref reference, transfer) @@ -156,7 +157,7 @@ internal static JniValueMarshalerState CreateArgumentState (IList (IList value, ref JniValueMarshalerState state, ParameterAttributes synchronize) where TArray : JavaArray { - var source = (TArray) state.PeerableValue; + var source = (TArray?) state.PeerableValue; if (source == null) return; diff --git a/src/Java.Interop/Java.Interop/JavaObjectArray.cs b/src/Java.Interop/Java.Interop/JavaObjectArray.cs index 0ffe9f8c7..67086d0a5 100644 --- a/src/Java.Interop/Java.Interop/JavaObjectArray.cs +++ b/src/Java.Interop/Java.Interop/JavaObjectArray.cs @@ -134,7 +134,7 @@ internal override void CopyToList (IList list, int index) } } - internal override bool TargetTypeIsCurrentType (Type targetType) + internal override bool TargetTypeIsCurrentType (Type? targetType) { return base.TargetTypeIsCurrentType (targetType) || targetType == typeof (JavaObjectArray); @@ -142,7 +142,7 @@ internal override bool TargetTypeIsCurrentType (Type targetType) internal sealed class ValueMarshaler : JniValueMarshaler> { - public override IList CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type targetType) + public override IList CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type? targetType) { return JavaArray.CreateValue (ref reference, options, targetType, (ref JniObjectReference h, JniObjectReferenceOptions t) => new JavaObjectArray (ref h, t) { forMarshalCollection = true, diff --git a/src/Java.Interop/Java.Interop/JavaPrimitiveArrays.cs b/src/Java.Interop/Java.Interop/JavaPrimitiveArrays.cs index 4ccf7151d..54c1e2ee9 100644 --- a/src/Java.Interop/Java.Interop/JavaPrimitiveArrays.cs +++ b/src/Java.Interop/Java.Interop/JavaPrimitiveArrays.cs @@ -201,21 +201,21 @@ public override unsafe void CopyFrom (Boolean[] sourceArray, int sourceIndex, in JniEnvironment.Arrays.SetBooleanArrayRegion (PeerReference, destinationIndex, length, (b+sourceIndex)); } - internal override bool TargetTypeIsCurrentType (Type targetType) + internal override bool TargetTypeIsCurrentType (Type? targetType) { return base.TargetTypeIsCurrentType (targetType) || typeof (JavaPrimitiveArray) == targetType || typeof (JavaBooleanArray) == targetType; } - public static object CreateMarshaledValue (IntPtr handle, Type targetType) + public static object? CreateMarshaledValue (IntPtr handle, Type? targetType) { return ArrayMarshaler.CreateValue (handle, targetType); } internal sealed class ValueMarshaler : JniValueMarshaler> { - public override IList CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type targetType) + public override IList CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type? targetType) { return JavaArray.CreateValue ( ref reference, @@ -242,7 +242,7 @@ public override void DestroyGenericArgumentState (IList value, ref JniV public override Expression CreateParameterToManagedExpression (JniValueMarshalerContext context, ParameterExpression sourceValue, ParameterAttributes synchronize = 0, Type? targetType = null) { - Func m = JavaBooleanArray.CreateMarshaledValue; + Func m = JavaBooleanArray.CreateMarshaledValue; var call = Expression.Call (m.GetMethodInfo (), sourceValue, Expression.Constant (targetType, typeof (Type))); return targetType == null @@ -377,21 +377,21 @@ public override unsafe void CopyFrom (SByte[] sourceArray, int sourceIndex, int JniEnvironment.Arrays.SetByteArrayRegion (PeerReference, destinationIndex, length, (b+sourceIndex)); } - internal override bool TargetTypeIsCurrentType (Type targetType) + internal override bool TargetTypeIsCurrentType (Type? targetType) { return base.TargetTypeIsCurrentType (targetType) || typeof (JavaPrimitiveArray) == targetType || typeof (JavaSByteArray) == targetType; } - public static object CreateMarshaledValue (IntPtr handle, Type targetType) + public static object? CreateMarshaledValue (IntPtr handle, Type? targetType) { return ArrayMarshaler.CreateValue (handle, targetType); } internal sealed class ValueMarshaler : JniValueMarshaler> { - public override IList CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type targetType) + public override IList CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type? targetType) { return JavaArray.CreateValue ( ref reference, @@ -418,7 +418,7 @@ public override void DestroyGenericArgumentState (IList value, ref JniVal public override Expression CreateParameterToManagedExpression (JniValueMarshalerContext context, ParameterExpression sourceValue, ParameterAttributes synchronize = 0, Type? targetType = null) { - Func m = JavaSByteArray.CreateMarshaledValue; + Func m = JavaSByteArray.CreateMarshaledValue; var call = Expression.Call (m.GetMethodInfo (), sourceValue, Expression.Constant (targetType, typeof (Type))); return targetType == null @@ -553,21 +553,21 @@ public override unsafe void CopyFrom (Char[] sourceArray, int sourceIndex, int d JniEnvironment.Arrays.SetCharArrayRegion (PeerReference, destinationIndex, length, (b+sourceIndex)); } - internal override bool TargetTypeIsCurrentType (Type targetType) + internal override bool TargetTypeIsCurrentType (Type? targetType) { return base.TargetTypeIsCurrentType (targetType) || typeof (JavaPrimitiveArray) == targetType || typeof (JavaCharArray) == targetType; } - public static object CreateMarshaledValue (IntPtr handle, Type targetType) + public static object? CreateMarshaledValue (IntPtr handle, Type? targetType) { return ArrayMarshaler.CreateValue (handle, targetType); } internal sealed class ValueMarshaler : JniValueMarshaler> { - public override IList CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type targetType) + public override IList CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type? targetType) { return JavaArray.CreateValue ( ref reference, @@ -594,7 +594,7 @@ public override void DestroyGenericArgumentState (IList value, ref JniValu public override Expression CreateParameterToManagedExpression (JniValueMarshalerContext context, ParameterExpression sourceValue, ParameterAttributes synchronize = 0, Type? targetType = null) { - Func m = JavaCharArray.CreateMarshaledValue; + Func m = JavaCharArray.CreateMarshaledValue; var call = Expression.Call (m.GetMethodInfo (), sourceValue, Expression.Constant (targetType, typeof (Type))); return targetType == null @@ -729,21 +729,21 @@ public override unsafe void CopyFrom (Int16[] sourceArray, int sourceIndex, int JniEnvironment.Arrays.SetShortArrayRegion (PeerReference, destinationIndex, length, (b+sourceIndex)); } - internal override bool TargetTypeIsCurrentType (Type targetType) + internal override bool TargetTypeIsCurrentType (Type? targetType) { return base.TargetTypeIsCurrentType (targetType) || typeof (JavaPrimitiveArray) == targetType || typeof (JavaInt16Array) == targetType; } - public static object CreateMarshaledValue (IntPtr handle, Type targetType) + public static object? CreateMarshaledValue (IntPtr handle, Type? targetType) { return ArrayMarshaler.CreateValue (handle, targetType); } internal sealed class ValueMarshaler : JniValueMarshaler> { - public override IList CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type targetType) + public override IList CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type? targetType) { return JavaArray.CreateValue ( ref reference, @@ -770,7 +770,7 @@ public override void DestroyGenericArgumentState (IList value, ref JniVal public override Expression CreateParameterToManagedExpression (JniValueMarshalerContext context, ParameterExpression sourceValue, ParameterAttributes synchronize = 0, Type? targetType = null) { - Func m = JavaInt16Array.CreateMarshaledValue; + Func m = JavaInt16Array.CreateMarshaledValue; var call = Expression.Call (m.GetMethodInfo (), sourceValue, Expression.Constant (targetType, typeof (Type))); return targetType == null @@ -905,21 +905,21 @@ public override unsafe void CopyFrom (Int32[] sourceArray, int sourceIndex, int JniEnvironment.Arrays.SetIntArrayRegion (PeerReference, destinationIndex, length, (b+sourceIndex)); } - internal override bool TargetTypeIsCurrentType (Type targetType) + internal override bool TargetTypeIsCurrentType (Type? targetType) { return base.TargetTypeIsCurrentType (targetType) || typeof (JavaPrimitiveArray) == targetType || typeof (JavaInt32Array) == targetType; } - public static object CreateMarshaledValue (IntPtr handle, Type targetType) + public static object? CreateMarshaledValue (IntPtr handle, Type? targetType) { return ArrayMarshaler.CreateValue (handle, targetType); } internal sealed class ValueMarshaler : JniValueMarshaler> { - public override IList CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type targetType) + public override IList CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type? targetType) { return JavaArray.CreateValue ( ref reference, @@ -946,7 +946,7 @@ public override void DestroyGenericArgumentState (IList value, ref JniVal public override Expression CreateParameterToManagedExpression (JniValueMarshalerContext context, ParameterExpression sourceValue, ParameterAttributes synchronize = 0, Type? targetType = null) { - Func m = JavaInt32Array.CreateMarshaledValue; + Func m = JavaInt32Array.CreateMarshaledValue; var call = Expression.Call (m.GetMethodInfo (), sourceValue, Expression.Constant (targetType, typeof (Type))); return targetType == null @@ -1081,21 +1081,21 @@ public override unsafe void CopyFrom (Int64[] sourceArray, int sourceIndex, int JniEnvironment.Arrays.SetLongArrayRegion (PeerReference, destinationIndex, length, (b+sourceIndex)); } - internal override bool TargetTypeIsCurrentType (Type targetType) + internal override bool TargetTypeIsCurrentType (Type? targetType) { return base.TargetTypeIsCurrentType (targetType) || typeof (JavaPrimitiveArray) == targetType || typeof (JavaInt64Array) == targetType; } - public static object CreateMarshaledValue (IntPtr handle, Type targetType) + public static object? CreateMarshaledValue (IntPtr handle, Type? targetType) { return ArrayMarshaler.CreateValue (handle, targetType); } internal sealed class ValueMarshaler : JniValueMarshaler> { - public override IList CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type targetType) + public override IList CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type? targetType) { return JavaArray.CreateValue ( ref reference, @@ -1122,7 +1122,7 @@ public override void DestroyGenericArgumentState (IList value, ref JniVal public override Expression CreateParameterToManagedExpression (JniValueMarshalerContext context, ParameterExpression sourceValue, ParameterAttributes synchronize = 0, Type? targetType = null) { - Func m = JavaInt64Array.CreateMarshaledValue; + Func m = JavaInt64Array.CreateMarshaledValue; var call = Expression.Call (m.GetMethodInfo (), sourceValue, Expression.Constant (targetType, typeof (Type))); return targetType == null @@ -1257,21 +1257,21 @@ public override unsafe void CopyFrom (Single[] sourceArray, int sourceIndex, int JniEnvironment.Arrays.SetFloatArrayRegion (PeerReference, destinationIndex, length, (b+sourceIndex)); } - internal override bool TargetTypeIsCurrentType (Type targetType) + internal override bool TargetTypeIsCurrentType (Type? targetType) { return base.TargetTypeIsCurrentType (targetType) || typeof (JavaPrimitiveArray) == targetType || typeof (JavaSingleArray) == targetType; } - public static object CreateMarshaledValue (IntPtr handle, Type targetType) + public static object? CreateMarshaledValue (IntPtr handle, Type? targetType) { return ArrayMarshaler.CreateValue (handle, targetType); } internal sealed class ValueMarshaler : JniValueMarshaler> { - public override IList CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type targetType) + public override IList CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type? targetType) { return JavaArray.CreateValue ( ref reference, @@ -1298,7 +1298,7 @@ public override void DestroyGenericArgumentState (IList value, ref JniVa public override Expression CreateParameterToManagedExpression (JniValueMarshalerContext context, ParameterExpression sourceValue, ParameterAttributes synchronize = 0, Type? targetType = null) { - Func m = JavaSingleArray.CreateMarshaledValue; + Func m = JavaSingleArray.CreateMarshaledValue; var call = Expression.Call (m.GetMethodInfo (), sourceValue, Expression.Constant (targetType, typeof (Type))); return targetType == null @@ -1433,21 +1433,21 @@ public override unsafe void CopyFrom (Double[] sourceArray, int sourceIndex, int JniEnvironment.Arrays.SetDoubleArrayRegion (PeerReference, destinationIndex, length, (b+sourceIndex)); } - internal override bool TargetTypeIsCurrentType (Type targetType) + internal override bool TargetTypeIsCurrentType (Type? targetType) { return base.TargetTypeIsCurrentType (targetType) || typeof (JavaPrimitiveArray) == targetType || typeof (JavaDoubleArray) == targetType; } - public static object CreateMarshaledValue (IntPtr handle, Type targetType) + public static object? CreateMarshaledValue (IntPtr handle, Type? targetType) { return ArrayMarshaler.CreateValue (handle, targetType); } internal sealed class ValueMarshaler : JniValueMarshaler> { - public override IList CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type targetType) + public override IList CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type? targetType) { return JavaArray.CreateValue ( ref reference, @@ -1474,7 +1474,7 @@ public override void DestroyGenericArgumentState (IList value, ref JniVa public override Expression CreateParameterToManagedExpression (JniValueMarshalerContext context, ParameterExpression sourceValue, ParameterAttributes synchronize = 0, Type? targetType = null) { - Func m = JavaDoubleArray.CreateMarshaledValue; + Func m = JavaDoubleArray.CreateMarshaledValue; var call = Expression.Call (m.GetMethodInfo (), sourceValue, Expression.Constant (targetType, typeof (Type))); return targetType == null diff --git a/src/Java.Interop/Java.Interop/JavaPrimitiveArrays.tt b/src/Java.Interop/Java.Interop/JavaPrimitiveArrays.tt index a345c2ae6..5e04f52bd 100644 --- a/src/Java.Interop/Java.Interop/JavaPrimitiveArrays.tt +++ b/src/Java.Interop/Java.Interop/JavaPrimitiveArrays.tt @@ -191,21 +191,21 @@ namespace Java.Interop { JniEnvironment.Arrays.Set<#= info.JniMarshalType #>ArrayRegion (PeerReference, destinationIndex, length, (b+sourceIndex)); } - internal override bool TargetTypeIsCurrentType (Type targetType) + internal override bool TargetTypeIsCurrentType (Type? targetType) { return base.TargetTypeIsCurrentType (targetType) || typeof (JavaPrimitiveArray<<#= info.ManagedType #>>) == targetType || typeof (Java<#= info.TypeModifier #>Array) == targetType; } - public static object CreateMarshaledValue (IntPtr handle, Type targetType) + public static object? CreateMarshaledValue (IntPtr handle, Type? targetType) { return ArrayMarshaler.CreateValue (handle, targetType); } internal sealed class ValueMarshaler : JniValueMarshaler>> { - public override IList<<#= info.TypeModifier #>> CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type targetType) + public override IList<<#= info.TypeModifier #>> CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type? targetType) { return JavaArray<<#= info.TypeModifier #>>.CreateValue ( ref reference, @@ -232,7 +232,7 @@ namespace Java.Interop { public override Expression CreateParameterToManagedExpression (JniValueMarshalerContext context, ParameterExpression sourceValue, ParameterAttributes synchronize = 0, Type? targetType = null) { - Func m = Java<#= info.TypeModifier #>Array.CreateMarshaledValue; + Func m = Java<#= info.TypeModifier #>Array.CreateMarshaledValue; var call = Expression.Call (m.GetMethodInfo (), sourceValue, Expression.Constant (targetType, typeof (Type))); return targetType == null diff --git a/src/Java.Interop/Java.Interop/JniBuiltinMarshalers.cs b/src/Java.Interop/Java.Interop/JniBuiltinMarshalers.cs index af5facd33..5eed9ad19 100644 --- a/src/Java.Interop/Java.Interop/JniBuiltinMarshalers.cs +++ b/src/Java.Interop/Java.Interop/JniBuiltinMarshalers.cs @@ -136,7 +136,7 @@ public override JniValueMarshalerState CreateGenericObjectReferenceArgumentState return new JniValueMarshalerState (r); } - public override void DestroyArgumentState (object value, ref JniValueMarshalerState state, ParameterAttributes synchronize) + public override void DestroyArgumentState (object? value, ref JniValueMarshalerState state, ParameterAttributes synchronize) { var r = state.ReferenceValue; JniObjectReference.Dispose (ref r); @@ -150,7 +150,7 @@ public override void DestroyGenericArgumentState (Boolean value, ref JniValueMar state = new JniValueMarshalerState (); } - public override Expression CreateParameterToManagedExpression (JniValueMarshalerContext context, ParameterExpression sourceValue, ParameterAttributes synchronize, Type targetType) + public override Expression CreateParameterToManagedExpression (JniValueMarshalerContext context, ParameterExpression sourceValue, ParameterAttributes synchronize, Type? targetType) { return sourceValue; } @@ -170,7 +170,7 @@ sealed class JniNullableBooleanValueMarshaler : JniValueMarshaler { internal static readonly JniNullableBooleanValueMarshaler Instance = new JniNullableBooleanValueMarshaler (); - public override Boolean? CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type targetType) + public override Boolean? CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type? targetType) { if (!reference.IsValid) return null; @@ -263,7 +263,7 @@ public override JniValueMarshalerState CreateGenericObjectReferenceArgumentState return new JniValueMarshalerState (r); } - public override void DestroyArgumentState (object value, ref JniValueMarshalerState state, ParameterAttributes synchronize) + public override void DestroyArgumentState (object? value, ref JniValueMarshalerState state, ParameterAttributes synchronize) { var r = state.ReferenceValue; JniObjectReference.Dispose (ref r); @@ -277,7 +277,7 @@ public override void DestroyGenericArgumentState (SByte value, ref JniValueMarsh state = new JniValueMarshalerState (); } - public override Expression CreateParameterToManagedExpression (JniValueMarshalerContext context, ParameterExpression sourceValue, ParameterAttributes synchronize, Type targetType) + public override Expression CreateParameterToManagedExpression (JniValueMarshalerContext context, ParameterExpression sourceValue, ParameterAttributes synchronize, Type? targetType) { return sourceValue; } @@ -297,7 +297,7 @@ sealed class JniNullableSByteValueMarshaler : JniValueMarshaler { internal static readonly JniNullableSByteValueMarshaler Instance = new JniNullableSByteValueMarshaler (); - public override SByte? CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type targetType) + public override SByte? CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type? targetType) { if (!reference.IsValid) return null; @@ -390,7 +390,7 @@ public override JniValueMarshalerState CreateGenericObjectReferenceArgumentState return new JniValueMarshalerState (r); } - public override void DestroyArgumentState (object value, ref JniValueMarshalerState state, ParameterAttributes synchronize) + public override void DestroyArgumentState (object? value, ref JniValueMarshalerState state, ParameterAttributes synchronize) { var r = state.ReferenceValue; JniObjectReference.Dispose (ref r); @@ -404,7 +404,7 @@ public override void DestroyGenericArgumentState (Char value, ref JniValueMarsha state = new JniValueMarshalerState (); } - public override Expression CreateParameterToManagedExpression (JniValueMarshalerContext context, ParameterExpression sourceValue, ParameterAttributes synchronize, Type targetType) + public override Expression CreateParameterToManagedExpression (JniValueMarshalerContext context, ParameterExpression sourceValue, ParameterAttributes synchronize, Type? targetType) { return sourceValue; } @@ -424,7 +424,7 @@ sealed class JniNullableCharValueMarshaler : JniValueMarshaler { internal static readonly JniNullableCharValueMarshaler Instance = new JniNullableCharValueMarshaler (); - public override Char? CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type targetType) + public override Char? CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type? targetType) { if (!reference.IsValid) return null; @@ -517,7 +517,7 @@ public override JniValueMarshalerState CreateGenericObjectReferenceArgumentState return new JniValueMarshalerState (r); } - public override void DestroyArgumentState (object value, ref JniValueMarshalerState state, ParameterAttributes synchronize) + public override void DestroyArgumentState (object? value, ref JniValueMarshalerState state, ParameterAttributes synchronize) { var r = state.ReferenceValue; JniObjectReference.Dispose (ref r); @@ -531,7 +531,7 @@ public override void DestroyGenericArgumentState (Int16 value, ref JniValueMarsh state = new JniValueMarshalerState (); } - public override Expression CreateParameterToManagedExpression (JniValueMarshalerContext context, ParameterExpression sourceValue, ParameterAttributes synchronize, Type targetType) + public override Expression CreateParameterToManagedExpression (JniValueMarshalerContext context, ParameterExpression sourceValue, ParameterAttributes synchronize, Type? targetType) { return sourceValue; } @@ -551,7 +551,7 @@ sealed class JniNullableInt16ValueMarshaler : JniValueMarshaler { internal static readonly JniNullableInt16ValueMarshaler Instance = new JniNullableInt16ValueMarshaler (); - public override Int16? CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type targetType) + public override Int16? CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type? targetType) { if (!reference.IsValid) return null; @@ -644,7 +644,7 @@ public override JniValueMarshalerState CreateGenericObjectReferenceArgumentState return new JniValueMarshalerState (r); } - public override void DestroyArgumentState (object value, ref JniValueMarshalerState state, ParameterAttributes synchronize) + public override void DestroyArgumentState (object? value, ref JniValueMarshalerState state, ParameterAttributes synchronize) { var r = state.ReferenceValue; JniObjectReference.Dispose (ref r); @@ -658,7 +658,7 @@ public override void DestroyGenericArgumentState (Int32 value, ref JniValueMarsh state = new JniValueMarshalerState (); } - public override Expression CreateParameterToManagedExpression (JniValueMarshalerContext context, ParameterExpression sourceValue, ParameterAttributes synchronize, Type targetType) + public override Expression CreateParameterToManagedExpression (JniValueMarshalerContext context, ParameterExpression sourceValue, ParameterAttributes synchronize, Type? targetType) { return sourceValue; } @@ -678,7 +678,7 @@ sealed class JniNullableInt32ValueMarshaler : JniValueMarshaler { internal static readonly JniNullableInt32ValueMarshaler Instance = new JniNullableInt32ValueMarshaler (); - public override Int32? CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type targetType) + public override Int32? CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type? targetType) { if (!reference.IsValid) return null; @@ -771,7 +771,7 @@ public override JniValueMarshalerState CreateGenericObjectReferenceArgumentState return new JniValueMarshalerState (r); } - public override void DestroyArgumentState (object value, ref JniValueMarshalerState state, ParameterAttributes synchronize) + public override void DestroyArgumentState (object? value, ref JniValueMarshalerState state, ParameterAttributes synchronize) { var r = state.ReferenceValue; JniObjectReference.Dispose (ref r); @@ -785,7 +785,7 @@ public override void DestroyGenericArgumentState (Int64 value, ref JniValueMarsh state = new JniValueMarshalerState (); } - public override Expression CreateParameterToManagedExpression (JniValueMarshalerContext context, ParameterExpression sourceValue, ParameterAttributes synchronize, Type targetType) + public override Expression CreateParameterToManagedExpression (JniValueMarshalerContext context, ParameterExpression sourceValue, ParameterAttributes synchronize, Type? targetType) { return sourceValue; } @@ -805,7 +805,7 @@ sealed class JniNullableInt64ValueMarshaler : JniValueMarshaler { internal static readonly JniNullableInt64ValueMarshaler Instance = new JniNullableInt64ValueMarshaler (); - public override Int64? CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type targetType) + public override Int64? CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type? targetType) { if (!reference.IsValid) return null; @@ -898,7 +898,7 @@ public override JniValueMarshalerState CreateGenericObjectReferenceArgumentState return new JniValueMarshalerState (r); } - public override void DestroyArgumentState (object value, ref JniValueMarshalerState state, ParameterAttributes synchronize) + public override void DestroyArgumentState (object? value, ref JniValueMarshalerState state, ParameterAttributes synchronize) { var r = state.ReferenceValue; JniObjectReference.Dispose (ref r); @@ -912,7 +912,7 @@ public override void DestroyGenericArgumentState (Single value, ref JniValueMars state = new JniValueMarshalerState (); } - public override Expression CreateParameterToManagedExpression (JniValueMarshalerContext context, ParameterExpression sourceValue, ParameterAttributes synchronize, Type targetType) + public override Expression CreateParameterToManagedExpression (JniValueMarshalerContext context, ParameterExpression sourceValue, ParameterAttributes synchronize, Type? targetType) { return sourceValue; } @@ -932,7 +932,7 @@ sealed class JniNullableSingleValueMarshaler : JniValueMarshaler { internal static readonly JniNullableSingleValueMarshaler Instance = new JniNullableSingleValueMarshaler (); - public override Single? CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type targetType) + public override Single? CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type? targetType) { if (!reference.IsValid) return null; @@ -1025,7 +1025,7 @@ public override JniValueMarshalerState CreateGenericObjectReferenceArgumentState return new JniValueMarshalerState (r); } - public override void DestroyArgumentState (object value, ref JniValueMarshalerState state, ParameterAttributes synchronize) + public override void DestroyArgumentState (object? value, ref JniValueMarshalerState state, ParameterAttributes synchronize) { var r = state.ReferenceValue; JniObjectReference.Dispose (ref r); @@ -1039,7 +1039,7 @@ public override void DestroyGenericArgumentState (Double value, ref JniValueMars state = new JniValueMarshalerState (); } - public override Expression CreateParameterToManagedExpression (JniValueMarshalerContext context, ParameterExpression sourceValue, ParameterAttributes synchronize, Type targetType) + public override Expression CreateParameterToManagedExpression (JniValueMarshalerContext context, ParameterExpression sourceValue, ParameterAttributes synchronize, Type? targetType) { return sourceValue; } @@ -1059,7 +1059,7 @@ sealed class JniNullableDoubleValueMarshaler : JniValueMarshaler { internal static readonly JniNullableDoubleValueMarshaler Instance = new JniNullableDoubleValueMarshaler (); - public override Double? CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type targetType) + public override Double? CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type? targetType) { if (!reference.IsValid) return null; diff --git a/src/Java.Interop/Java.Interop/JniBuiltinMarshalers.tt b/src/Java.Interop/Java.Interop/JniBuiltinMarshalers.tt index f958c6c97..7078761d9 100644 --- a/src/Java.Interop/Java.Interop/JniBuiltinMarshalers.tt +++ b/src/Java.Interop/Java.Interop/JniBuiltinMarshalers.tt @@ -140,7 +140,7 @@ namespace Java.Interop { return new JniValueMarshalerState (r); } - public override void DestroyArgumentState (object value, ref JniValueMarshalerState state, ParameterAttributes synchronize) + public override void DestroyArgumentState (object? value, ref JniValueMarshalerState state, ParameterAttributes synchronize) { var r = state.ReferenceValue; JniObjectReference.Dispose (ref r); @@ -154,7 +154,7 @@ namespace Java.Interop { state = new JniValueMarshalerState (); } - public override Expression CreateParameterToManagedExpression (JniValueMarshalerContext context, ParameterExpression sourceValue, ParameterAttributes synchronize, Type targetType) + public override Expression CreateParameterToManagedExpression (JniValueMarshalerContext context, ParameterExpression sourceValue, ParameterAttributes synchronize, Type? targetType) { return sourceValue; } @@ -174,7 +174,7 @@ namespace Java.Interop { internal static readonly JniNullable<#= type.Type #>ValueMarshaler Instance = new JniNullable<#= type.Type #>ValueMarshaler (); - public override <#= type.Type #>? CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type targetType) + public override <#= type.Type #>? CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type? targetType) { if (!reference.IsValid) return null; diff --git a/src/Java.Interop/Java.Interop/JniRuntime.JniMarshalMemberBuilder.cs b/src/Java.Interop/Java.Interop/JniRuntime.JniMarshalMemberBuilder.cs index 6d5675ad2..cb167a8a9 100644 --- a/src/Java.Interop/Java.Interop/JniRuntime.JniMarshalMemberBuilder.cs +++ b/src/Java.Interop/Java.Interop/JniRuntime.JniMarshalMemberBuilder.cs @@ -177,7 +177,7 @@ public override Expression CreateParameterFromManagedExpression (Java.Interop.Ex return sourceValue; } - public override Expression CreateParameterToManagedExpression (Java.Interop.Expressions.JniValueMarshalerContext context, ParameterExpression sourceValue, ParameterAttributes synchronize, Type targetType) + public override Expression CreateParameterToManagedExpression (Java.Interop.Expressions.JniValueMarshalerContext context, ParameterExpression sourceValue, ParameterAttributes synchronize, Type? targetType) { return sourceValue; } @@ -188,17 +188,17 @@ public override Expression CreateReturnValueFromManagedExpression (Java.Interop. } - public override object CreateValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type targetType) + public override object? CreateValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type? targetType) { throw new NotSupportedException (); } - public override IntPtr CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type targetType) + public override IntPtr CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type? targetType) { throw new NotSupportedException (); } - public override JniValueMarshalerState CreateArgumentState (object value, ParameterAttributes synchronize) + public override JniValueMarshalerState CreateArgumentState (object? value, ParameterAttributes synchronize) { throw new NotSupportedException (); } @@ -208,7 +208,7 @@ public override JniValueMarshalerState CreateGenericArgumentState (IntPtr value, throw new NotSupportedException (); } - public override JniValueMarshalerState CreateObjectReferenceArgumentState (object value, ParameterAttributes synchronize) + public override JniValueMarshalerState CreateObjectReferenceArgumentState (object? value, ParameterAttributes synchronize) { throw new NotSupportedException (); } @@ -218,7 +218,7 @@ public override JniValueMarshalerState CreateGenericObjectReferenceArgumentState throw new NotSupportedException (); } - public override void DestroyArgumentState (object value, ref JniValueMarshalerState state, ParameterAttributes synchronize) + public override void DestroyArgumentState (object? value, ref JniValueMarshalerState state, ParameterAttributes synchronize) { throw new NotSupportedException (); } diff --git a/src/Java.Interop/Java.Interop/JniRuntime.JniValueManager.cs b/src/Java.Interop/Java.Interop/JniRuntime.JniValueManager.cs index 5b2d159a5..343ecd980 100644 --- a/src/Java.Interop/Java.Interop/JniRuntime.JniValueManager.cs +++ b/src/Java.Interop/Java.Interop/JniRuntime.JniValueManager.cs @@ -590,17 +590,17 @@ public override Type MarshalType { get {return typeof (void);} } - public override object CreateValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type targetType) + public override object? CreateValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type? targetType) { throw new NotSupportedException (); } - public override JniValueMarshalerState CreateObjectReferenceArgumentState (object value, ParameterAttributes synchronize) + public override JniValueMarshalerState CreateObjectReferenceArgumentState (object? value, ParameterAttributes synchronize) { throw new NotSupportedException (); } - public override void DestroyArgumentState (object value, ref JniValueMarshalerState state, ParameterAttributes synchronize) + public override void DestroyArgumentState (object? value, ref JniValueMarshalerState state, ParameterAttributes synchronize) { throw new NotSupportedException (); } @@ -610,12 +610,13 @@ sealed class JavaPeerableValueMarshaler : JniValueMarshaler { internal static JavaPeerableValueMarshaler Instance = new JavaPeerableValueMarshaler (); + [return: MaybeNull] public override IJavaPeerable CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type? targetType) { var jvm = JniEnvironment.Runtime; var marshaler = jvm.ValueManager.GetValueMarshaler (targetType ?? typeof(IJavaPeerable)); if (marshaler != Instance) - return (IJavaPeerable) marshaler.CreateValue (ref reference, options, targetType); + return (IJavaPeerable) marshaler.CreateValue (ref reference, options, targetType)!; return jvm.ValueManager.CreatePeer (ref reference, options, targetType); } @@ -662,7 +663,7 @@ public override Expression CreateReturnValueFromManagedExpression (JniValueMarsh return ReturnObjectReferenceToJni (context, sourceValue.Name, CreateIntermediaryExpressionFromManagedExpression (context, sourceValue)); } - public override Expression CreateParameterToManagedExpression (JniValueMarshalerContext context, ParameterExpression sourceValue, ParameterAttributes synchronize, Type targetType) + public override Expression CreateParameterToManagedExpression (JniValueMarshalerContext context, ParameterExpression sourceValue, ParameterAttributes synchronize, Type? targetType) { var r = Expression.Variable (targetType, sourceValue.Name + "_val"); context.LocalVariables.Add (r); @@ -686,9 +687,10 @@ public DelegatingValueMarshaler (JniValueMarshaler valueMarshaler) ValueMarshaler = valueMarshaler; } - public override T CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type targetType) + [return: MaybeNull] + public override T CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type? targetType) { - return (T) ValueMarshaler.CreateValue (ref reference, options, targetType ?? typeof (T)); + return (T) ValueMarshaler.CreateValue (ref reference, options, targetType ?? typeof (T))!; } public override JniValueMarshalerState CreateGenericObjectReferenceArgumentState (T value, ParameterAttributes synchronize) @@ -706,7 +708,7 @@ public override Expression CreateParameterFromManagedExpression (JniValueMarshal return ValueMarshaler.CreateParameterFromManagedExpression (context, sourceValue, synchronize); } - public override Expression CreateParameterToManagedExpression (JniValueMarshalerContext context, ParameterExpression sourceValue, ParameterAttributes synchronize, Type targetType) + public override Expression CreateParameterToManagedExpression (JniValueMarshalerContext context, ParameterExpression sourceValue, ParameterAttributes synchronize, Type? targetType) { return ValueMarshaler.CreateParameterToManagedExpression (context, sourceValue, synchronize, targetType); } @@ -721,6 +723,7 @@ sealed class ProxyValueMarshaler : JniValueMarshaler { internal static ProxyValueMarshaler Instance = new ProxyValueMarshaler (); + [return: MaybeNull] public override object CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type? targetType) { var jvm = JniEnvironment.Runtime; @@ -731,7 +734,7 @@ public override object CreateGenericValue (ref JniObjectReference reference, Jni if (targetType != null) { var vm = jvm.ValueManager.GetValueMarshaler (targetType); if (vm != Instance) { - return vm.CreateValue (ref reference, options, targetType); + return vm.CreateValue (ref reference, options, targetType)!; } } diff --git a/src/Java.Interop/Java.Interop/JniValueMarshaler.cs b/src/Java.Interop/Java.Interop/JniValueMarshaler.cs index 2d856dfd4..8025e563c 100644 --- a/src/Java.Interop/Java.Interop/JniValueMarshaler.cs +++ b/src/Java.Interop/Java.Interop/JniValueMarshaler.cs @@ -1,5 +1,8 @@ +#nullable enable + using System; using System.Collections.ObjectModel; +using System.Diagnostics.CodeAnalysis; using System.Reflection; using System.Linq.Expressions; using System.Runtime.CompilerServices; @@ -18,7 +21,7 @@ protected override string GetKeyForItem (ParameterExpression item) public sealed class JniValueMarshalerContext { public Expression Runtime {get;} - public Expression ValueManager {get;} + public Expression? ValueManager {get;} public KeyedCollection LocalVariables {get;} = new VariableCollection (); public Collection CreationStatements {get;} = new Collection (); @@ -29,7 +32,7 @@ public JniValueMarshalerContext (Expression runtime) { } - public JniValueMarshalerContext (Expression runtime, Expression vm) + public JniValueMarshalerContext (Expression runtime, Expression? vm) { Runtime = runtime ?? throw new ArgumentNullException (nameof (runtime)); ValueManager = vm; @@ -43,10 +46,10 @@ public struct JniValueMarshalerState : IEquatable { public JniArgumentValue JniArgumentValue {get; private set;} public JniObjectReference ReferenceValue {get; private set;} - public IJavaPeerable PeerableValue {get; private set;} - public object Extra {get; private set;} + public IJavaPeerable? PeerableValue {get; private set;} + public object? Extra {get; private set;} - public JniValueMarshalerState (JniArgumentValue jniArgumentValue, object extra = null) + public JniValueMarshalerState (JniArgumentValue jniArgumentValue, object? extra = null) { JniArgumentValue = jniArgumentValue; ReferenceValue = default (JniObjectReference); @@ -54,7 +57,7 @@ public JniValueMarshalerState (JniArgumentValue jniArgumentValue, object extra = Extra = extra; } - public JniValueMarshalerState (JniObjectReference referenceValue, object extra = null) + public JniValueMarshalerState (JniObjectReference referenceValue, object? extra = null) { JniArgumentValue = new JniArgumentValue (referenceValue); ReferenceValue = referenceValue; @@ -62,7 +65,7 @@ public JniValueMarshalerState (JniObjectReference referenceValue, object extra = Extra = extra; } - public JniValueMarshalerState (IJavaPeerable peerableValue, object extra = null) + public JniValueMarshalerState (IJavaPeerable? peerableValue, object? extra = null) { PeerableValue = peerableValue; ReferenceValue = peerableValue == null ? default (JniObjectReference) : peerableValue.PeerReference; @@ -70,7 +73,7 @@ public JniValueMarshalerState (IJavaPeerable peerableValue, object extra = null) Extra = extra; } - internal JniValueMarshalerState (JniValueMarshalerState copy, object extra = null) + internal JniValueMarshalerState (JniValueMarshalerState copy, object? extra = null) { JniArgumentValue = copy.JniArgumentValue; ReferenceValue = copy.ReferenceValue; @@ -83,7 +86,7 @@ public override int GetHashCode () return JniArgumentValue.GetHashCode (); } - public override bool Equals (object obj) + public override bool Equals (object? obj) { var o = obj as JniValueMarshalerState?; if (!o.HasValue) @@ -123,25 +126,25 @@ public virtual Type MarshalType { get {return IntPtr_type;} } - public abstract object CreateValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type targetType = null); + public abstract object? CreateValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type? targetType = null); - public virtual JniValueMarshalerState CreateArgumentState (object value, ParameterAttributes synchronize = 0) + public virtual JniValueMarshalerState CreateArgumentState (object? value, ParameterAttributes synchronize = 0) { return CreateObjectReferenceArgumentState (value, synchronize); } - public abstract JniValueMarshalerState CreateObjectReferenceArgumentState (object value, ParameterAttributes synchronize = 0); - public abstract void DestroyArgumentState (object value, ref JniValueMarshalerState state, ParameterAttributes synchronize = 0); + public abstract JniValueMarshalerState CreateObjectReferenceArgumentState (object? value, ParameterAttributes synchronize = 0); + public abstract void DestroyArgumentState (object? value, ref JniValueMarshalerState state, ParameterAttributes synchronize = 0); - internal object CreateValue (IntPtr handle, Type targetType) + internal object? CreateValue (IntPtr handle, Type? targetType) { var r = new JniObjectReference (handle); return CreateValue (ref r, JniObjectReferenceOptions.Copy, targetType); } - public virtual Expression CreateParameterToManagedExpression (JniValueMarshalerContext context, ParameterExpression sourceValue, ParameterAttributes synchronize = 0, Type targetType = null) + public virtual Expression CreateParameterToManagedExpression (JniValueMarshalerContext context, ParameterExpression sourceValue, ParameterAttributes synchronize = 0, Type? targetType = null) { - Func m = CreateValue; + Func m = CreateValue; var self = CreateSelf (context, sourceValue); @@ -212,34 +215,35 @@ protected static Expression DisposeObjectReference (Expression sourceValue) public abstract class JniValueMarshaler : JniValueMarshaler { - public abstract T CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type targetType = null); + [return: MaybeNull] + public abstract T CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type? targetType = null); - public virtual JniValueMarshalerState CreateGenericArgumentState (T value, ParameterAttributes synchronize = 0) + public virtual JniValueMarshalerState CreateGenericArgumentState ([MaybeNull] T value, ParameterAttributes synchronize = 0) { return CreateGenericObjectReferenceArgumentState (value, synchronize); } - public abstract JniValueMarshalerState CreateGenericObjectReferenceArgumentState (T value, ParameterAttributes synchronize = 0); - public abstract void DestroyGenericArgumentState (T value, ref JniValueMarshalerState state, ParameterAttributes synchronize = 0); + public abstract JniValueMarshalerState CreateGenericObjectReferenceArgumentState ([MaybeNull] T value, ParameterAttributes synchronize = 0); + public abstract void DestroyGenericArgumentState ([MaybeNull] T value, ref JniValueMarshalerState state, ParameterAttributes synchronize = 0); - public override object CreateValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type targetType = null) + public override object? CreateValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type? targetType = null) { return CreateGenericValue (ref reference, options, targetType ?? typeof (T)); } - public override JniValueMarshalerState CreateArgumentState (object value, ParameterAttributes synchronize = 0) + public override JniValueMarshalerState CreateArgumentState (object? value, ParameterAttributes synchronize = 0) { - return CreateGenericArgumentState ((T) value, synchronize); + return CreateGenericArgumentState ((T) value!, synchronize); } - public override JniValueMarshalerState CreateObjectReferenceArgumentState (object value, ParameterAttributes synchronize = 0) + public override JniValueMarshalerState CreateObjectReferenceArgumentState (object? value, ParameterAttributes synchronize = 0) { - return CreateGenericObjectReferenceArgumentState ((T) value, synchronize); + return CreateGenericObjectReferenceArgumentState ((T) value!, synchronize); } - public override void DestroyArgumentState (object value, ref JniValueMarshalerState state, ParameterAttributes synchronize = 0) + public override void DestroyArgumentState (object? value, ref JniValueMarshalerState state, ParameterAttributes synchronize = 0) { - DestroyGenericArgumentState ((T) value, ref state, synchronize); + DestroyGenericArgumentState ((T) value!, ref state, synchronize); } } } From 7841be927e1aab93b7d31703c2b5293a7160521c Mon Sep 17 00:00:00 2001 From: Jonathan Pryor Date: Tue, 19 Nov 2019 17:27:34 -0500 Subject: [PATCH 20/33] Add #nullable for JniReleaseArrayElementsMode --- src/Java.Interop/Java.Interop/JniReleaseArrayElementsMode.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Java.Interop/Java.Interop/JniReleaseArrayElementsMode.cs b/src/Java.Interop/Java.Interop/JniReleaseArrayElementsMode.cs index 227559713..cd88d02bf 100644 --- a/src/Java.Interop/Java.Interop/JniReleaseArrayElementsMode.cs +++ b/src/Java.Interop/Java.Interop/JniReleaseArrayElementsMode.cs @@ -1,3 +1,5 @@ +#nullable enable + using System; namespace Java.Interop { From df2c08fec5ced54c0480b1eec72f67014efe37c5 Mon Sep 17 00:00:00 2001 From: Jonathan Pryor Date: Wed, 20 Nov 2019 13:32:39 -0500 Subject: [PATCH 21/33] Add #nullable for JniStringValueMarshaler --- .../Java.Interop/JniStringValueMarshaler.cs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/Java.Interop/Java.Interop/JniStringValueMarshaler.cs b/src/Java.Interop/Java.Interop/JniStringValueMarshaler.cs index 32e2dc1d4..1fb3c59eb 100644 --- a/src/Java.Interop/Java.Interop/JniStringValueMarshaler.cs +++ b/src/Java.Interop/Java.Interop/JniStringValueMarshaler.cs @@ -1,3 +1,5 @@ +#nullable enable + using System; using System.Linq.Expressions; using System.Reflection; @@ -7,22 +9,22 @@ namespace Java.Interop { - sealed class JniStringValueMarshaler : JniValueMarshaler { + sealed class JniStringValueMarshaler : JniValueMarshaler { internal static readonly JniStringValueMarshaler Instance = new JniStringValueMarshaler (); - public override string CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type targetType) + public override string? CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type? targetType) { return JniEnvironment.Strings.ToString (ref reference, options, targetType ?? typeof (string)); } - public override JniValueMarshalerState CreateGenericObjectReferenceArgumentState (string value, ParameterAttributes synchronize) + public override JniValueMarshalerState CreateGenericObjectReferenceArgumentState (string? value, ParameterAttributes synchronize) { var r = JniEnvironment.Strings.NewString (value); return new JniValueMarshalerState (r); } - public override void DestroyGenericArgumentState (string value, ref JniValueMarshalerState state, ParameterAttributes synchronize) + public override void DestroyGenericArgumentState (string? value, ref JniValueMarshalerState state, ParameterAttributes synchronize) { var r = state.ReferenceValue; JniObjectReference.Dispose (ref r); @@ -54,9 +56,9 @@ public override Expression CreateReturnValueFromManagedExpression (JniValueMarsh return ReturnObjectReferenceToJni (context, sourceValue.Name, obj); } - public override Expression CreateParameterToManagedExpression (JniValueMarshalerContext context, ParameterExpression sourceValue, ParameterAttributes synchronize, Type targetType) + public override Expression CreateParameterToManagedExpression (JniValueMarshalerContext context, ParameterExpression sourceValue, ParameterAttributes synchronize, Type? targetType) { - Func m = JniEnvironment.Strings.ToString; + Func m = JniEnvironment.Strings.ToString; var value = Expression.Variable (targetType, sourceValue.Name + "_val"); context.LocalVariables.Add (value); From be62f334819d52ac92457515a1d5af828d000567 Mon Sep 17 00:00:00 2001 From: Jonathan Pryor Date: Wed, 20 Nov 2019 13:55:29 -0500 Subject: [PATCH 22/33] Add #nullable for JniPeerMembers Of note is that we no longer null out various members in `Dispose()` and instead we call `.Clear()`. This was easier than making everything nullable, and the `Dispose()` codepath really shouldn't ever be invoked anyway.... --- src/Java.Interop/Java.Interop.csproj | 6 +++++ .../Java.Interop/JniPeerMembers.JniFields.cs | 4 +++- .../Java.Interop/JniPeerMembers.JniFields.tt | 2 ++ .../JniPeerMembers.JniInstanceFields.cs | 9 ++++---- .../JniPeerMembers.JniInstanceMethods.cs | 23 +++++++++---------- ...niPeerMembers.JniInstanceMethods_Invoke.cs | 4 +++- ...niPeerMembers.JniInstanceMethods_Invoke.tt | 2 ++ .../JniPeerMembers.JniStaticFields.cs | 9 ++++---- .../JniPeerMembers.JniStaticMethods.cs | 9 ++++---- .../Java.Interop/JniPeerMembers.cs | 18 +++++---------- 10 files changed, 45 insertions(+), 41 deletions(-) diff --git a/src/Java.Interop/Java.Interop.csproj b/src/Java.Interop/Java.Interop.csproj index 67135361f..b86b16f36 100644 --- a/src/Java.Interop/Java.Interop.csproj +++ b/src/Java.Interop/Java.Interop.csproj @@ -76,6 +76,12 @@ JniBuiltinMarshalers.tt + + JniPeerMembers.JniFields.tt + + + JniPeerMembers.JniInstanceMethods_Invoke.tt + diff --git a/src/Java.Interop/Java.Interop/JniPeerMembers.JniFields.cs b/src/Java.Interop/Java.Interop/JniPeerMembers.JniFields.cs index 3353cd872..134f21a9d 100644 --- a/src/Java.Interop/Java.Interop/JniPeerMembers.JniFields.cs +++ b/src/Java.Interop/Java.Interop/JniPeerMembers.JniFields.cs @@ -1,4 +1,6 @@ -namespace Java.Interop { +#nullable enable + +namespace Java.Interop { partial class JniPeerMembers { partial class JniInstanceFields { diff --git a/src/Java.Interop/Java.Interop/JniPeerMembers.JniFields.tt b/src/Java.Interop/Java.Interop/JniPeerMembers.JniFields.tt index d44112f76..0c333b41f 100644 --- a/src/Java.Interop/Java.Interop/JniPeerMembers.JniFields.tt +++ b/src/Java.Interop/Java.Interop/JniPeerMembers.JniFields.tt @@ -17,6 +17,8 @@ }; #> +#nullable enable + namespace Java.Interop { partial class JniPeerMembers { diff --git a/src/Java.Interop/Java.Interop/JniPeerMembers.JniInstanceFields.cs b/src/Java.Interop/Java.Interop/JniPeerMembers.JniInstanceFields.cs index 9c32951f5..b5c7f610e 100644 --- a/src/Java.Interop/Java.Interop/JniPeerMembers.JniInstanceFields.cs +++ b/src/Java.Interop/Java.Interop/JniPeerMembers.JniInstanceFields.cs @@ -1,4 +1,6 @@ -using System; +#nullable enable + +using System; using System.Collections.Generic; namespace Java.Interop @@ -17,10 +19,7 @@ internal JniInstanceFields (JniPeerMembers members) internal void Dispose () { - if (InstanceFields == null) - return; - - InstanceFields = null; + InstanceFields.Clear (); } public JniFieldInfo GetFieldInfo (string encodedMember) diff --git a/src/Java.Interop/Java.Interop/JniPeerMembers.JniInstanceMethods.cs b/src/Java.Interop/Java.Interop/JniPeerMembers.JniInstanceMethods.cs index c13bb5b0b..27eeb0351 100644 --- a/src/Java.Interop/Java.Interop/JniPeerMembers.JniInstanceMethods.cs +++ b/src/Java.Interop/Java.Interop/JniPeerMembers.JniInstanceMethods.cs @@ -1,4 +1,6 @@ -using System; +#nullable enable + +using System; using System.Collections.Generic; namespace Java.Interop @@ -9,7 +11,7 @@ public sealed partial class JniInstanceMethods internal JniInstanceMethods (JniPeerMembers members) { DeclaringType = members.ManagedPeerType; - Members = members; + this.members = members; } JniInstanceMethods (Type declaringType) @@ -26,11 +28,13 @@ internal JniInstanceMethods (JniPeerMembers members) jniPeerType.RegisterWithRuntime (); } - JniPeerMembers Members; - JniType jniPeerType; + JniPeerMembers? members; + JniType? jniPeerType; + + internal JniPeerMembers Members => members ?? throw new InvalidOperationException (); internal JniType JniPeerType { - get {return jniPeerType ?? Members.JniPeerType;} + get {return jniPeerType ?? Members?.JniPeerType ?? throw new InvalidOperationException ();} } readonly Type DeclaringType; @@ -40,15 +44,10 @@ internal JniType JniPeerType { internal void Dispose () { - if (InstanceMethods == null) - return; - - // Don't dispose JniPeerType; it's shared with others. - InstanceMethods = null; - + InstanceMethods.Clear (); foreach (var p in SubclassConstructors.Values) p.Dispose (); - SubclassConstructors = null; + SubclassConstructors.Clear (); if (jniPeerType != null) jniPeerType.Dispose (); diff --git a/src/Java.Interop/Java.Interop/JniPeerMembers.JniInstanceMethods_Invoke.cs b/src/Java.Interop/Java.Interop/JniPeerMembers.JniInstanceMethods_Invoke.cs index 571379859..a2eb530f1 100644 --- a/src/Java.Interop/Java.Interop/JniPeerMembers.JniInstanceMethods_Invoke.cs +++ b/src/Java.Interop/Java.Interop/JniPeerMembers.JniInstanceMethods_Invoke.cs @@ -1,4 +1,6 @@ -using System; +#nullable enable + +using System; namespace Java.Interop { diff --git a/src/Java.Interop/Java.Interop/JniPeerMembers.JniInstanceMethods_Invoke.tt b/src/Java.Interop/Java.Interop/JniPeerMembers.JniInstanceMethods_Invoke.tt index 0cfd669b5..57babde01 100644 --- a/src/Java.Interop/Java.Interop/JniPeerMembers.JniInstanceMethods_Invoke.tt +++ b/src/Java.Interop/Java.Interop/JniPeerMembers.JniInstanceMethods_Invoke.tt @@ -18,6 +18,8 @@ }; #> +#nullable enable + using System; namespace Java.Interop { diff --git a/src/Java.Interop/Java.Interop/JniPeerMembers.JniStaticFields.cs b/src/Java.Interop/Java.Interop/JniPeerMembers.JniStaticFields.cs index 8e1a3a3be..1ef5cae34 100644 --- a/src/Java.Interop/Java.Interop/JniPeerMembers.JniStaticFields.cs +++ b/src/Java.Interop/Java.Interop/JniPeerMembers.JniStaticFields.cs @@ -1,4 +1,6 @@ -using System; +#nullable enable + +using System; using System.Collections.Generic; namespace Java.Interop @@ -31,10 +33,7 @@ public JniFieldInfo GetFieldInfo (string encodedMember) internal void Dispose () { - if (StaticFields == null) - return; - - StaticFields = null; + StaticFields.Clear (); } }} } diff --git a/src/Java.Interop/Java.Interop/JniPeerMembers.JniStaticMethods.cs b/src/Java.Interop/Java.Interop/JniPeerMembers.JniStaticMethods.cs index bfd0b7045..bddfb5a9a 100644 --- a/src/Java.Interop/Java.Interop/JniPeerMembers.JniStaticMethods.cs +++ b/src/Java.Interop/Java.Interop/JniPeerMembers.JniStaticMethods.cs @@ -1,4 +1,6 @@ -using System; +#nullable enable + +using System; using System.Collections.Generic; namespace Java.Interop @@ -17,10 +19,7 @@ internal JniStaticMethods (JniPeerMembers members) internal void Dispose () { - if (StaticMethods == null) - return; - - StaticMethods = null; + StaticMethods.Clear (); } public JniMethodInfo GetMethodInfo (string encodedMember) diff --git a/src/Java.Interop/Java.Interop/JniPeerMembers.cs b/src/Java.Interop/Java.Interop/JniPeerMembers.cs index 9b8fcc35a..fc1db691c 100644 --- a/src/Java.Interop/Java.Interop/JniPeerMembers.cs +++ b/src/Java.Interop/Java.Interop/JniPeerMembers.cs @@ -1,4 +1,6 @@ -using System; +#nullable enable + +using System; using System.Diagnostics; using System.Collections.Generic; using System.Reflection; @@ -71,8 +73,7 @@ static JniPeerMembers CreatePeerMembers (string jniPeerTypeName, Type managedPee return new JniPeerMembers (jniPeerTypeName, managedPeerType, checkManagedPeerType: false); } - JniType jniPeerType; - + JniType? jniPeerType; JniInstanceMethods instanceMethods; JniInstanceFields instanceFields; JniStaticMethods staticMethods; @@ -118,18 +119,11 @@ protected virtual void Dispose (bool disposing) return; instanceMethods.Dispose (); - instanceMethods = null; - instanceFields.Dispose (); - instanceFields = null; - staticMethods.Dispose (); - staticMethods = null; - staticFields.Dispose (); - staticFields = null; - jniPeerType.Dispose (); + jniPeerType = null; } @@ -140,7 +134,7 @@ public static void Dispose (JniPeerMembers members) members.Dispose (true); } - protected virtual bool UsesVirtualDispatch (IJavaPeerable value, Type declaringType) + protected virtual bool UsesVirtualDispatch (IJavaPeerable value, Type? declaringType) { return value.GetType () == declaringType || declaringType == null || From 28a6d3751d1b7935e8dac35a9191e332fffce2db Mon Sep 17 00:00:00 2001 From: Jonathan Pryor Date: Wed, 20 Nov 2019 14:09:10 -0500 Subject: [PATCH 23/33] Review nullability on some JavaArray methods They support `null` as an input w/o throwing an exception... --- src/Java.Interop/Java.Interop/JavaArray.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Java.Interop/Java.Interop/JavaArray.cs b/src/Java.Interop/Java.Interop/JavaArray.cs index 6a09bdf2d..92eec322f 100644 --- a/src/Java.Interop/Java.Interop/JavaArray.cs +++ b/src/Java.Interop/Java.Interop/JavaArray.cs @@ -137,7 +137,7 @@ internal static IList CreateValue (ref JniObjectReference reference, .ToTargetType (targetType, dispose: true); } - internal static JniValueMarshalerState CreateArgumentState (IList value, ParameterAttributes synchronize, Func, bool, TArray> creator) + internal static JniValueMarshalerState CreateArgumentState (IList? value, ParameterAttributes synchronize, Func, bool, TArray> creator) where TArray : JavaArray { if (value == null) @@ -154,7 +154,7 @@ internal static JniValueMarshalerState CreateArgumentState (IList (IList value, ref JniValueMarshalerState state, ParameterAttributes synchronize) + internal static void DestroyArgumentState (IList? value, ref JniValueMarshalerState state, ParameterAttributes synchronize) where TArray : JavaArray { var source = (TArray?) state.PeerableValue; From 0b8e365ab1d55db464e1df3826bc49b1cc2ece64 Mon Sep 17 00:00:00 2001 From: Jonathan Pryor Date: Wed, 20 Nov 2019 14:12:41 -0500 Subject: [PATCH 24/33] Set `$(Nullable)`=enable in Java.Interop.csproj Enable nullability for *everything*! --- src/Java.Interop/Java.Interop-MonoAndroid.csproj | 2 ++ src/Java.Interop/Java.Interop.csproj | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/Java.Interop/Java.Interop-MonoAndroid.csproj b/src/Java.Interop/Java.Interop-MonoAndroid.csproj index 1ca0e24b9..5f81f9fa4 100644 --- a/src/Java.Interop/Java.Interop-MonoAndroid.csproj +++ b/src/Java.Interop/Java.Interop-MonoAndroid.csproj @@ -27,6 +27,7 @@ 4 false true + enable ..\..\bin\Debug\Java.Interop.xml ..\..\bin\BuildDebug @@ -39,6 +40,7 @@ false INTEROP;FEATURE_JNIENVIRONMENT_JI_PINVOKES;FEATURE_JNIOBJECTREFERENCE_INTPTRS true + enable ..\..\bin\Release\Java.Interop.xml ..\..\bin\BuildRelease diff --git a/src/Java.Interop/Java.Interop.csproj b/src/Java.Interop/Java.Interop.csproj index b86b16f36..e18bdeb3d 100644 --- a/src/Java.Interop/Java.Interop.csproj +++ b/src/Java.Interop/Java.Interop.csproj @@ -15,6 +15,7 @@ ..\..\bin\BuildDebug INTEROP;FEATURE_JNIENVIRONMENT_JI_PINVOKES;FEATURE_JNIOBJECTREFERENCE_INTPTRS;DEBUG;NETSTANDARD;NETSTANDARD2_0 8.0 + enable ..\..\bin\GendarmeDebug @@ -28,6 +29,7 @@ ..\..\bin\Release\Java.Interop.xml ..\..\bin\BuildRelease 8.0 + enable From bdd75c75138519c0b6ab877ae75ecb0d85915961 Mon Sep 17 00:00:00 2001 From: Jonathan Pobst Date: Tue, 7 Jan 2020 14:35:34 -0600 Subject: [PATCH 25/33] Bump .NET Core to 3.1.x to support NRT. --- build-tools/automation/azure-pipelines.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build-tools/automation/azure-pipelines.yaml b/build-tools/automation/azure-pipelines.yaml index 6524f5cd6..fb2aea311 100644 --- a/build-tools/automation/azure-pipelines.yaml +++ b/build-tools/automation/azure-pipelines.yaml @@ -6,7 +6,7 @@ trigger: # Global variables variables: - DotNetCoreVersion: 2.1.701 + DotNetCoreVersion: 3.1.x HostedMac: Hosted Mac Internal HostedWinVS2019: Hosted Windows 2019 with VS2019 From b6346dbe56cd1dc23d8577ae021843c9468cd8f0 Mon Sep 17 00:00:00 2001 From: Jonathan Pobst Date: Tue, 7 Jan 2020 14:41:29 -0600 Subject: [PATCH 26/33] Need a newer boots to support .Net Core 3.1. --- build-tools/automation/azure-pipelines.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build-tools/automation/azure-pipelines.yaml b/build-tools/automation/azure-pipelines.yaml index fb2aea311..17f3f9c1a 100644 --- a/build-tools/automation/azure-pipelines.yaml +++ b/build-tools/automation/azure-pipelines.yaml @@ -71,7 +71,7 @@ jobs: version: $(DotNetCoreVersion) - script: | - dotnet tool install --global boots --version 1.0.0.291 + dotnet tool install --global boots boots https://download.mono-project.com/archive/6.4.0/macos-10-universal/MonoFramework-MDK-6.4.0.198.macos10.xamarin.universal.pkg displayName: Install Mono 6.4 From 2629ac14d2c29a349e3eb7158be4dbbb1d792cf2 Mon Sep 17 00:00:00 2001 From: Jonathan Pobst Date: Tue, 7 Jan 2020 14:48:28 -0600 Subject: [PATCH 27/33] Java.Interop.dll has to remain netstandard2.0 so our other assemblies can reference it. --- src/Java.Interop/Java.Interop.csproj | 4 +- src/Java.Interop/Java.Interop/ManagedPeer.cs | 2 +- src/Java.Interop/NullableAttributes.cs | 133 +++++++++++++++++++ 3 files changed, 136 insertions(+), 3 deletions(-) create mode 100644 src/Java.Interop/NullableAttributes.cs diff --git a/src/Java.Interop/Java.Interop.csproj b/src/Java.Interop/Java.Interop.csproj index e18bdeb3d..edd40db34 100644 --- a/src/Java.Interop/Java.Interop.csproj +++ b/src/Java.Interop/Java.Interop.csproj @@ -1,11 +1,11 @@ - netstandard2.1 + netstandard2.0 1591 true ..\..\product.snk - INTEROP;FEATURE_JNIENVIRONMENT_JI_PINVOKES;FEATURE_JNIOBJECTREFERENCE_INTPTRS + INTEROP;FEATURE_JNIENVIRONMENT_JI_PINVOKES;FEATURE_JNIOBJECTREFERENCE_INTPTRS;INTERNAL_NULLABLE_ATTRIBUTES true false diff --git a/src/Java.Interop/Java.Interop/ManagedPeer.cs b/src/Java.Interop/Java.Interop/ManagedPeer.cs index d95252d91..71f591754 100644 --- a/src/Java.Interop/Java.Interop/ManagedPeer.cs +++ b/src/Java.Interop/Java.Interop/ManagedPeer.cs @@ -154,7 +154,7 @@ static Type[] GetParameterTypes (string? signature) { if (string.IsNullOrEmpty (signature)) return Array.Empty (); - var typeNames = signature.Split (':'); + var typeNames = signature!.Split (':'); var ptypes = new Type [typeNames.Length]; for (int i = 0; i < typeNames.Length; i++) ptypes [i] = Type.GetType (typeNames [i], throwOnError:true); diff --git a/src/Java.Interop/NullableAttributes.cs b/src/Java.Interop/NullableAttributes.cs new file mode 100644 index 000000000..ba4e92f01 --- /dev/null +++ b/src/Java.Interop/NullableAttributes.cs @@ -0,0 +1,133 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace System.Diagnostics.CodeAnalysis +{ + /// Specifies that null is allowed as an input even if the corresponding type disallows it. + [AttributeUsage (AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property, Inherited = false)] +#if INTERNAL_NULLABLE_ATTRIBUTES + internal +#else + public +#endif + sealed class AllowNullAttribute : Attribute + { } + + /// Specifies that null is disallowed as an input even if the corresponding type allows it. + [AttributeUsage (AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property, Inherited = false)] +#if INTERNAL_NULLABLE_ATTRIBUTES + internal +#else + public +#endif + sealed class DisallowNullAttribute : Attribute + { } + + /// Specifies that an output may be null even if the corresponding type disallows it. + [AttributeUsage (AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, Inherited = false)] +#if INTERNAL_NULLABLE_ATTRIBUTES + internal +#else + public +#endif + sealed class MaybeNullAttribute : Attribute + { } + + /// Specifies that an output will not be null even if the corresponding type allows it. + [AttributeUsage (AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, Inherited = false)] +#if INTERNAL_NULLABLE_ATTRIBUTES + internal +#else + public +#endif + sealed class NotNullAttribute : Attribute + { } + + /// Specifies that when a method returns , the parameter may be null even if the corresponding type disallows it. + [AttributeUsage (AttributeTargets.Parameter, Inherited = false)] +#if INTERNAL_NULLABLE_ATTRIBUTES + internal +#else + public +#endif + sealed class MaybeNullWhenAttribute : Attribute + { + /// Initializes the attribute with the specified return value condition. + /// + /// The return value condition. If the method returns this value, the associated parameter may be null. + /// + public MaybeNullWhenAttribute (bool returnValue) => ReturnValue = returnValue; + + /// Gets the return value condition. + public bool ReturnValue { get; } + } + + /// Specifies that when a method returns , the parameter will not be null even if the corresponding type allows it. + [AttributeUsage (AttributeTargets.Parameter, Inherited = false)] +#if INTERNAL_NULLABLE_ATTRIBUTES + internal +#else + public +#endif + sealed class NotNullWhenAttribute : Attribute + { + /// Initializes the attribute with the specified return value condition. + /// + /// The return value condition. If the method returns this value, the associated parameter will not be null. + /// + public NotNullWhenAttribute (bool returnValue) => ReturnValue = returnValue; + + /// Gets the return value condition. + public bool ReturnValue { get; } + } + + /// Specifies that the output will be non-null if the named parameter is non-null. + [AttributeUsage (AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, AllowMultiple = true, Inherited = false)] +#if INTERNAL_NULLABLE_ATTRIBUTES + internal +#else + public +#endif + sealed class NotNullIfNotNullAttribute : Attribute + { + /// Initializes the attribute with the associated parameter name. + /// + /// The associated parameter name. The output will be non-null if the argument to the parameter specified is non-null. + /// + public NotNullIfNotNullAttribute (string parameterName) => ParameterName = parameterName; + + /// Gets the associated parameter name. + public string ParameterName { get; } + } + + /// Applied to a method that will never return under any circumstance. + [AttributeUsage (AttributeTargets.Method, Inherited = false)] +#if INTERNAL_NULLABLE_ATTRIBUTES + internal +#else + public +#endif + sealed class DoesNotReturnAttribute : Attribute + { } + + /// Specifies that the method will not return if the associated Boolean parameter is passed the specified value. + [AttributeUsage (AttributeTargets.Parameter, Inherited = false)] +#if INTERNAL_NULLABLE_ATTRIBUTES + internal +#else + public +#endif + sealed class DoesNotReturnIfAttribute : Attribute + { + /// Initializes the attribute with the specified parameter value. + /// + /// The condition parameter value. Code after the method will be considered unreachable by diagnostics if the argument to + /// the associated parameter matches this value. + /// + public DoesNotReturnIfAttribute (bool parameterValue) => ParameterValue = parameterValue; + + /// Gets the condition parameter value. + public bool ParameterValue { get; } + } +} From 935b33210dc17634e62e313043a811e959395c4d Mon Sep 17 00:00:00 2001 From: Jonathan Pobst Date: Tue, 7 Jan 2020 15:01:36 -0600 Subject: [PATCH 28/33] Fix or suppress analyzer issues. --- src/Java.Interop/GlobalSuppressions.cs | 4 ++++ src/Java.Interop/Java.Interop/JniRuntime.cs | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Java.Interop/GlobalSuppressions.cs b/src/Java.Interop/GlobalSuppressions.cs index d05a0ead4..caf402aec 100644 --- a/src/Java.Interop/GlobalSuppressions.cs +++ b/src/Java.Interop/GlobalSuppressions.cs @@ -72,6 +72,10 @@ [assembly: SuppressMessage ("Performance", "CA1822:Mark members as static", Justification = "", Scope = "member", Target = "~M:Java.Interop.JniRuntime.JniMarshalMemberBuilder.IsDirectMethod(System.Reflection.ParameterInfo[])~System.Boolean")] [assembly: SuppressMessage ("Performance", "CA1822:Mark members as static", Justification = "", Scope = "member", Target = "~M:Java.Interop.JniRuntime.JniValueManager.GetJniIdentityHashCode(Java.Interop.JniObjectReference)~System.Int32")] +[assembly: SuppressMessage ("Performance", "CA1822:Mark members as static", Justification = "", Scope = "member", Target = "~P:Java.Interop.JniFieldInfo.Name")] +[assembly: SuppressMessage ("Performance", "CA1822:Mark members as static", Justification = "", Scope = "member", Target = "~P:Java.Interop.JniFieldInfo.Signature")] +[assembly: SuppressMessage ("Performance", "CA1822:Mark members as static", Justification = "", Scope = "member", Target = "~P:Java.Interop.JniMethodInfo.Name")] +[assembly: SuppressMessage ("Performance", "CA1822:Mark members as static", Justification = "", Scope = "member", Target = "~P:Java.Interop.JniMethodInfo.Signature")] [assembly: SuppressMessage ("Performance", "CA1823:Avoid unused private fields", Justification = "Used for native interop", Scope = "type", Target = "~T:Java.Interop.JavaException")] [assembly: SuppressMessage ("Performance", "CA1823:Avoid unused private fields", Justification = "Used for native interop", Scope = "type", Target = "~T:Java.Interop.JavaObject")] diff --git a/src/Java.Interop/Java.Interop/JniRuntime.cs b/src/Java.Interop/Java.Interop/JniRuntime.cs index 0e72da102..dc42931f8 100644 --- a/src/Java.Interop/Java.Interop/JniRuntime.cs +++ b/src/Java.Interop/Java.Interop/JniRuntime.cs @@ -161,7 +161,7 @@ public static JniRuntime CurrentRuntime { public static void SetCurrent (JniRuntime newCurrent) { if (newCurrent == null) - throw new ArgumentNullException ("newCurrent"); + throw new ArgumentNullException (nameof (newCurrent)); lock (Runtimes) { Runtimes [newCurrent.InvocationPointer] = newCurrent; } From c9d30e445130f20dc92744099feb94f458e0a9fb Mon Sep 17 00:00:00 2001 From: Jonathan Pobst Date: Tue, 7 Jan 2020 15:13:35 -0600 Subject: [PATCH 29/33] IDisposable suppression. --- src/Java.Interop/GlobalSuppressions.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Java.Interop/GlobalSuppressions.cs b/src/Java.Interop/GlobalSuppressions.cs index caf402aec..e5cc3b533 100644 --- a/src/Java.Interop/GlobalSuppressions.cs +++ b/src/Java.Interop/GlobalSuppressions.cs @@ -89,3 +89,5 @@ [assembly: SuppressMessage ("Usage", "CA2208:Instantiate argument exceptions correctly", Justification = "", Scope = "member", Target = "~M:Java.Interop.JniEnvironment.Exceptions.Throw(Java.Interop.JniObjectReference)")] [assembly: SuppressMessage ("Usage", "CA2208:Instantiate argument exceptions correctly", Justification = "", Scope = "member", Target = "~M:Java.Interop.JniEnvironment.Exceptions.ThrowNew(Java.Interop.JniObjectReference,System.String)")] + +[assembly: SuppressMessage ("Usage", "CA2213:Disposable fields should be disposed", Justification = "", Scope = "member", Target = "~F:Java.Interop.JniRuntime.valueManager")] From 0c5a2f1e4aa1ad042ad6ab581bfc60c7f8fe89b8 Mon Sep 17 00:00:00 2001 From: Jonathan Pobst Date: Wed, 8 Jan 2020 09:20:13 -0600 Subject: [PATCH 30/33] Fix test that now throws ODE. --- tests/Java.Interop-Tests/Java.Interop/JniRuntimeTest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Java.Interop-Tests/Java.Interop/JniRuntimeTest.cs b/tests/Java.Interop-Tests/Java.Interop/JniRuntimeTest.cs index b7f81102e..ab4f12b60 100644 --- a/tests/Java.Interop-Tests/Java.Interop/JniRuntimeTest.cs +++ b/tests/Java.Interop-Tests/Java.Interop/JniRuntimeTest.cs @@ -58,7 +58,7 @@ public void Dispose_ClearsJniEnvironment () JniRuntime.SetCurrent (r); Assert.AreEqual (r, JniEnvironment.Runtime); r.Dispose (); - Assert.Throws(() => { + Assert.Throws(() => { var env = JniEnvironment.Runtime; }); }); From 228614b823fc768f93afa9698f0608167a4d571c Mon Sep 17 00:00:00 2001 From: Jonathan Pobst Date: Wed, 8 Jan 2020 13:38:29 -0600 Subject: [PATCH 31/33] Update Java.Interop-MonoAndroid.csproj --- src/Java.Interop/Java.Interop-MonoAndroid.csproj | 5 +++-- src/Java.Interop/Java.Interop.csproj | 9 +-------- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/src/Java.Interop/Java.Interop-MonoAndroid.csproj b/src/Java.Interop/Java.Interop-MonoAndroid.csproj index 5f81f9fa4..30c3126cd 100644 --- a/src/Java.Interop/Java.Interop-MonoAndroid.csproj +++ b/src/Java.Interop/Java.Interop-MonoAndroid.csproj @@ -15,6 +15,7 @@ true ..\..\product.snk obj-MonoAndroid\ + 8.0 @@ -22,7 +23,7 @@ full false ..\..\bin\Debug - DEBUG;INTEROP;FEATURE_JNIENVIRONMENT_JI_PINVOKES;FEATURE_JNIOBJECTREFERENCE_INTPTRS + DEBUG;INTEROP;FEATURE_JNIENVIRONMENT_JI_PINVOKES;FEATURE_JNIOBJECTREFERENCE_INTPTRS;INTERNAL_NULLABLE_ATTRIBUTES prompt 4 false @@ -38,7 +39,7 @@ prompt 4 false - INTEROP;FEATURE_JNIENVIRONMENT_JI_PINVOKES;FEATURE_JNIOBJECTREFERENCE_INTPTRS + INTEROP;FEATURE_JNIENVIRONMENT_JI_PINVOKES;FEATURE_JNIOBJECTREFERENCE_INTPTRS;INTERNAL_NULLABLE_ATTRIBUTES true enable ..\..\bin\Release\Java.Interop.xml diff --git a/src/Java.Interop/Java.Interop.csproj b/src/Java.Interop/Java.Interop.csproj index edd40db34..625c8a782 100644 --- a/src/Java.Interop/Java.Interop.csproj +++ b/src/Java.Interop/Java.Interop.csproj @@ -13,17 +13,10 @@ ..\..\bin\Debug ..\..\bin\Debug\Java.Interop.xml ..\..\bin\BuildDebug - INTEROP;FEATURE_JNIENVIRONMENT_JI_PINVOKES;FEATURE_JNIOBJECTREFERENCE_INTPTRS;DEBUG;NETSTANDARD;NETSTANDARD2_0 + $(DefineConstants);DEBUG;NETSTANDARD;NETSTANDARD2_0 8.0 enable - - ..\..\bin\GendarmeDebug - DEBUG;$(DefineConstants) - ..\..\bin\Debug\Java.Interop.xml - ..\..\bin\BuildDebug - 8.0 - ..\..\bin\Release ..\..\bin\Release\Java.Interop.xml From 3d472618f4150541cc9606a54477209fd06e76cb Mon Sep 17 00:00:00 2001 From: Jonathan Pobst Date: Wed, 15 Jan 2020 09:30:27 -0600 Subject: [PATCH 32/33] [JniEnvironment] Revert change that changed an NSE to an ODE. --- src/Java.Interop/Java.Interop/JniEnvironment.cs | 2 +- tests/Java.Interop-Tests/Java.Interop/JniRuntimeTest.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Java.Interop/Java.Interop/JniEnvironment.cs b/src/Java.Interop/Java.Interop/JniEnvironment.cs index f8dfd6b74..452c5702a 100644 --- a/src/Java.Interop/Java.Interop/JniEnvironment.cs +++ b/src/Java.Interop/Java.Interop/JniEnvironment.cs @@ -192,7 +192,7 @@ sealed class JniEnvironmentInfo : IDisposable { public int LocalReferenceCount {get; internal set;} public bool WithinNewObjectScope {get; set;} public JniRuntime Runtime { - get => runtime ?? throw new ObjectDisposedException (nameof (JniEnvironmentInfo)); + get => runtime ?? throw new NotSupportedException (); private set => runtime = value; } diff --git a/tests/Java.Interop-Tests/Java.Interop/JniRuntimeTest.cs b/tests/Java.Interop-Tests/Java.Interop/JniRuntimeTest.cs index ab4f12b60..b7f81102e 100644 --- a/tests/Java.Interop-Tests/Java.Interop/JniRuntimeTest.cs +++ b/tests/Java.Interop-Tests/Java.Interop/JniRuntimeTest.cs @@ -58,7 +58,7 @@ public void Dispose_ClearsJniEnvironment () JniRuntime.SetCurrent (r); Assert.AreEqual (r, JniEnvironment.Runtime); r.Dispose (); - Assert.Throws(() => { + Assert.Throws(() => { var env = JniEnvironment.Runtime; }); }); From 11e5e7202448ea758a1f543783936c194efe91f5 Mon Sep 17 00:00:00 2001 From: Jonathan Pobst Date: Mon, 3 Feb 2020 16:26:51 -0600 Subject: [PATCH 33/33] Fix a few more nullable warnings. --- src/Java.Interop/Java.Interop/JavaArray.cs | 6 +++++- src/Java.Interop/Java.Interop/JavaObjectArray.cs | 9 +++++++++ .../Java.Interop/JniRuntime.JniValueManager.cs | 1 + src/Java.Interop/Java.Interop/JniRuntime.cs | 2 +- src/Java.Interop/Java.Interop/JniValueMarshaler.cs | 2 +- 5 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/Java.Interop/Java.Interop/JavaArray.cs b/src/Java.Interop/Java.Interop/JavaArray.cs index 92eec322f..96705f182 100644 --- a/src/Java.Interop/Java.Interop/JavaArray.cs +++ b/src/Java.Interop/Java.Interop/JavaArray.cs @@ -60,7 +60,9 @@ public virtual IEnumerator GetEnumerator () { int len = Length; for (int i = 0; i < len; ++i) +#pragma warning disable CS8603 // Possible null reference return. yield return this [i]; +#pragma warning restore CS8603 // Possible null reference return. } internal static void CheckArrayCopy (int sourceIndex, int sourceLength, int destinationIndex, int destinationLength, int length) @@ -117,7 +119,7 @@ internal IList ToTargetType (Type? targetType, bool dispose) throw CreateMarshalNotSupportedException (GetType (), targetType); } - internal virtual bool TargetTypeIsCurrentType (Type? targetType) + internal virtual bool TargetTypeIsCurrentType ([NotNullWhen (false)]Type? targetType) { return targetType == null || targetType == typeof (JavaArray); } @@ -192,7 +194,9 @@ internal virtual void CopyToList (IList list, int index) { int len = Length; for (int i = 0; i < len; i++) { +#pragma warning disable CS8601 // Possible null reference assignment. list [index + i] = this [i]; +#pragma warning restore CS8601 // Possible null reference assignment. } } diff --git a/src/Java.Interop/Java.Interop/JavaObjectArray.cs b/src/Java.Interop/Java.Interop/JavaObjectArray.cs index 67086d0a5..34735e0db 100644 --- a/src/Java.Interop/Java.Interop/JavaObjectArray.cs +++ b/src/Java.Interop/Java.Interop/JavaObjectArray.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Reflection; namespace Java.Interop @@ -47,6 +48,7 @@ public JavaObjectArray (IEnumerable value) { } + [MaybeNull] public override T this [int index] { get { if (index < 0 || index >= Length) @@ -60,6 +62,7 @@ public override T this [int index] { } } + [return: MaybeNull] T GetElementAt (int index) { var lref = JniEnvironment.Arrays.GetObjectArrayElement (PeerReference, index); @@ -78,7 +81,9 @@ public override IEnumerator GetEnumerator () { int len = Length; for (int i = 0; i < len; ++i) { +#pragma warning disable CS8603 // Possible null reference return. yield return GetElementAt (i); +#pragma warning restore CS8603 // Possible null reference return. } } @@ -101,7 +106,9 @@ public override int IndexOf (T item) for (int i = 0; i < len; i++) { var at = GetElementAt (i); try { +#pragma warning disable CS8604 // Possible null reference argument. if (EqualityComparer.Default.Equals (item, at) || JniMarshal.RecursiveEquals (item, at)) +#pragma warning restore CS8604 // Possible null reference argument. return i; } finally { var j = at as IJavaPeerable; @@ -125,7 +132,9 @@ internal override void CopyToList (IList list, int index) int len = Length; for (int i = 0; i < len; i++) { var item = GetElementAt (i); +#pragma warning disable CS8601 // Possible null reference assignment. list [index + i] = item; +#pragma warning restore CS8601 // Possible null reference assignment. if (forMarshalCollection) { var d = item as IJavaPeerable; if (d != null) diff --git a/src/Java.Interop/Java.Interop/JniRuntime.JniValueManager.cs b/src/Java.Interop/Java.Interop/JniRuntime.JniValueManager.cs index 343ecd980..347e8f1e8 100644 --- a/src/Java.Interop/Java.Interop/JniRuntime.JniValueManager.cs +++ b/src/Java.Interop/Java.Interop/JniRuntime.JniValueManager.cs @@ -440,6 +440,7 @@ public T CreateValue (ref JniObjectReference reference, JniObjectReferenceOpt return marshaler.CreateValue (ref reference, options, targetType); } + [return: MaybeNull] public T GetValue (IntPtr handle) { var r = new JniObjectReference (handle); diff --git a/src/Java.Interop/Java.Interop/JniRuntime.cs b/src/Java.Interop/Java.Interop/JniRuntime.cs index dc42931f8..86e8eb9e0 100644 --- a/src/Java.Interop/Java.Interop/JniRuntime.cs +++ b/src/Java.Interop/Java.Interop/JniRuntime.cs @@ -288,7 +288,7 @@ static unsafe JavaVMInterface CreateInvoker (IntPtr handle) public virtual void FailFast (string? message) { var m = typeof (Environment).GetMethod ("FailFast"); - m.Invoke (null, new object[]{ message }); + m.Invoke (null, new object?[]{ message }); } public override string ToString () diff --git a/src/Java.Interop/Java.Interop/JniValueMarshaler.cs b/src/Java.Interop/Java.Interop/JniValueMarshaler.cs index 8025e563c..48d554c3b 100644 --- a/src/Java.Interop/Java.Interop/JniValueMarshaler.cs +++ b/src/Java.Interop/Java.Interop/JniValueMarshaler.cs @@ -224,7 +224,7 @@ public virtual JniValueMarshalerState CreateGenericArgumentState ([MaybeNu } public abstract JniValueMarshalerState CreateGenericObjectReferenceArgumentState ([MaybeNull] T value, ParameterAttributes synchronize = 0); - public abstract void DestroyGenericArgumentState ([MaybeNull] T value, ref JniValueMarshalerState state, ParameterAttributes synchronize = 0); + public abstract void DestroyGenericArgumentState ([AllowNull] T value, ref JniValueMarshalerState state, ParameterAttributes synchronize = 0); public override object? CreateValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type? targetType = null) {