From 9f21312b7ba8c427513e67a8fb35ef242cf4ef7c Mon Sep 17 00:00:00 2001
From: Jackson Schuster <36744439+jtschuster@users.noreply.github.com>
Date: Wed, 10 Sep 2025 10:49:53 -0700
Subject: [PATCH 01/10] Clean build for consistency
---
Directory.Build.props | 2 +-
src/java-interop/java-interop.targets | 12 ++++++------
tests/NativeTiming/NativeTiming.targets | 2 +-
3 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/Directory.Build.props b/Directory.Build.props
index 5da999fb1..c132f796b 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -47,7 +47,7 @@
False
False
- obj\
+ $(MSBuildProjectDirectory)\obj\
diff --git a/src/java-interop/java-interop.targets b/src/java-interop/java-interop.targets
index 9d35aaa47..9b31afb14 100644
--- a/src/java-interop/java-interop.targets
+++ b/src/java-interop/java-interop.targets
@@ -35,13 +35,13 @@
- <_MonoNativePath>$(NuGetPackageRoot)microsoft.netcore.app.runtime.mono.$(NETCoreSdkRuntimeIdentifier)/$(DotNetRuntimePacksVersion)/runtimes/$(NETCoreSdkRuntimeIdentifier)/native/
+ <_MonoNativePath>$(NuGetPackageRoot)\microsoft.netcore.app.runtime.mono.$(NETCoreSdkRuntimeIdentifier)/$(DotNetRuntimePacksVersion)/runtimes/$(NETCoreSdkRuntimeIdentifier)/native/
<_MonoIncludePath>$(_MonoNativePath)include/mono-2.0
<_DEnableMono>-DENABLE_MONO_INTEGRATION=ON
<_DEnableOsxArchitectures Condition=" $([MSBuild]::IsOSPlatform ('osx')) ">"-DENABLE_OSX_ARCHITECTURES=$(_CmakeOsxArch)"
<_DMonoDirs>"-DMONO_INCLUDE_LIST=$(_MonoIncludePath)"
<_DJdkDirs>"-DJDK_INCLUDE_LIST=@(JdkIncludePath, ';')"
- <_DJni_c>"-DJNI_C_PATH=$(MSBuildThisFileDirectory)$(IntermediateOutputPath)jni.c"
+ <_DJni_c>"-DJNI_C_PATH=$(IntermediateOutputPath)jni.c"
<_MonoLinkFlags Condition=" $([MSBuild]::IsOSPlatform ('windows')) " >$(MSBuildThisFileDirectory)coreclr.lib
<_MonoLinkFlags Condition=" !$([MSBuild]::IsOSPlatform ('windows')) ">-L $(_MonoNativePath) -lcoreclr
<_DMonoLinkFlags>"-DMONO_LINK_FLAGS=$(_MonoLinkFlags)"
@@ -71,7 +71,7 @@
<_Cmake Include="CmakePath=$(CmakePath)" />
<_Cmake Include="CmakeGenerator=$(CmakeGenerator)" />
<_Cmake Include="CmakeSourceDir=$(MSBuildThisFileDirectory)" />
- <_Cmake Include="CmakeBuildDir=$(MSBuildThisFileDirectory)$(IntermediateOutputPath)" />
+ <_Cmake Include="CmakeBuildDir=$(IntermediateOutputPath)" />
<_Cmake Include="CmakeExtraArgs=$(_ExtraArgs)" />
-
+ Inputs="$(MSBuildThisFileDirectory)coreclr.def"
+ Outputs="$(MSBuildThisFileDirectory)coreclr.lib">
+
<_Cmake Include="CmakeGenerator=$(CmakeGenerator)" />
<_Cmake Include="CmakeSourceDir=$(MSBuildThisFileDirectory)" />
- <_Cmake Include="CmakeBuildDir=$(MSBuildThisFileDirectory)$(IntermediateOutputPath)%(_NativeTimingLib.Dir)" />
+ <_Cmake Include="CmakeBuildDir=$(IntermediateOutputPath)%(_NativeTimingLib.Dir)" />
<_Cmake Include="CmakeExtraArgs=$(_JdkDirs)" />
Date: Wed, 10 Sep 2025 10:50:59 -0700
Subject: [PATCH 02/10] Update JniValueManager to only look for single best
type for peer
---
.../JniRuntime.JniValueManager.cs | 324 ++++++++++++------
1 file changed, 219 insertions(+), 105 deletions(-)
diff --git a/src/Java.Interop/Java.Interop/JniRuntime.JniValueManager.cs b/src/Java.Interop/Java.Interop/JniRuntime.JniValueManager.cs
index 1ce3e6543..baff66b8b 100644
--- a/src/Java.Interop/Java.Interop/JniRuntime.JniValueManager.cs
+++ b/src/Java.Interop/Java.Interop/JniRuntime.JniValueManager.cs
@@ -14,46 +14,49 @@
namespace Java.Interop
{
- public class JniSurfacedPeerInfo {
+ public class JniSurfacedPeerInfo
+ {
- public int JniIdentityHashCode {get; private set;}
- public WeakReference SurfacedPeer {get; private set;}
+ public int JniIdentityHashCode { get; private set; }
+ public WeakReference SurfacedPeer { get; private set; }
public JniSurfacedPeerInfo (int jniIdentityHashCode, WeakReference surfacedPeer)
{
- JniIdentityHashCode = jniIdentityHashCode;
- SurfacedPeer = surfacedPeer;
+ JniIdentityHashCode = jniIdentityHashCode;
+ SurfacedPeer = surfacedPeer;
}
}
partial class JniRuntime
{
- partial class CreationOptions {
- public JniValueManager? ValueManager {get; set;}
+ partial class CreationOptions
+ {
+ public JniValueManager? ValueManager { get; set; }
}
- internal JniValueManager? valueManager;
- public JniValueManager ValueManager {
+ internal JniValueManager? valueManager;
+ public JniValueManager ValueManager {
get => valueManager ?? throw new NotSupportedException ();
}
partial void SetValueManager (CreationOptions options)
{
- var manager = options.ValueManager;
+ var manager = options.ValueManager;
if (manager == null)
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 abstract partial class JniValueManager : ISetRuntime, IDisposable
+ {
internal const DynamicallyAccessedMemberTypes Constructors = DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors;
- JniRuntime? runtime;
- bool disposed;
- public JniRuntime Runtime {
+ JniRuntime? runtime;
+ bool disposed;
+ public JniRuntime Runtime {
get => runtime ?? throw new NotSupportedException ();
}
@@ -86,7 +89,7 @@ protected virtual void Dispose (bool disposing)
public abstract void FinalizePeer (IJavaPeerable value);
- public abstract List GetSurfacedPeers ();
+ public abstract List GetSurfacedPeers ();
public abstract void ActivatePeer (IJavaPeerable? self, JniObjectReference reference, ConstructorInfo cinfo, object? []? argumentValues);
@@ -95,7 +98,7 @@ public void ConstructPeer (IJavaPeerable peer, ref JniObjectReference reference,
if (peer == null)
throw new ArgumentNullException (nameof (peer));
- var newRef = peer.PeerReference;
+ var newRef = peer.PeerReference;
if (newRef.IsValid) {
JniObjectReference.Dispose (ref reference, options);
@@ -105,17 +108,17 @@ public void ConstructPeer (IJavaPeerable peer, ref JniObjectReference reference,
return;
}
JniObjectReference.Dispose (ref reference, options);
- newRef = newRef.NewGlobalRef ();
+ newRef = newRef.NewGlobalRef ();
} else if (options == JniObjectReferenceOptions.None) {
// `reference` is likely *InvalidJniObjectReference, and can't be touched
return;
} else if (!reference.IsValid) {
throw new ArgumentException ("JNI Object Reference is invalid.", nameof (reference));
} else {
- newRef = reference;
+ newRef = reference;
if ((options & JniObjectReferenceOptions.Copy) == JniObjectReferenceOptions.Copy) {
- newRef = reference.NewGlobalRef ();
+ newRef = reference.NewGlobalRef ();
}
JniObjectReference.Dispose (ref reference, options);
@@ -222,7 +225,7 @@ public virtual void DisposePeerUnlessReferenced (IJavaPeerable value)
if (!reference.IsValid)
return null;
- var t = PeekPeer (reference);
+ var t = PeekPeer (reference);
if (t == null)
return t;
@@ -234,15 +237,15 @@ public virtual void DisposePeerUnlessReferenced (IJavaPeerable value)
protected virtual bool TryUnboxPeerObject (IJavaPeerable value, [NotNullWhen (true)] out object? result)
{
- result = null;
- var p = value as JavaProxyObject;
+ result = null;
+ var p = value as JavaProxyObject;
if (p != null) {
- result = p.Value;
+ result = p.Value;
return true;
}
- var x = value as JavaProxyThrowable;
+ var x = value as JavaProxyThrowable;
if (x != null) {
- result = x.Exception;
+ result = x.Exception;
return true;
}
return false;
@@ -250,7 +253,7 @@ protected virtual bool TryUnboxPeerObject (IJavaPeerable value, [NotNullWhen (tr
object? PeekBoxedObject (JniObjectReference reference)
{
- var t = PeekPeer (reference);
+ var t = PeekPeer (reference);
if (t == null)
return null;
object? r;
@@ -284,7 +287,7 @@ static Type GetPeerType ([DynamicallyAccessedMembers (Constructors)] Type type)
return null;
}
- var peeked = PeekPeer (reference);
+ var peeked = PeekPeer (reference);
if (peeked != null &&
(targetType == null ||
targetType.IsAssignableFrom (peeked.GetType ()))) {
@@ -292,7 +295,72 @@ static Type GetPeerType ([DynamicallyAccessedMembers (Constructors)] Type type)
}
return CreatePeer (ref reference, JniObjectReferenceOptions.Copy, targetType);
}
+#if false
+ class AndroidTypeMapUniverse { }
+ public IJavaPeerable? CreatePeer(
+ ref JniObjectReference reference,
+ JniObjectReferenceOptions options,
+ [DynamicallyAccessedMembers (Constructors)]
+ Type? targetType)
+ {
+ if (disposed)
+ throw new ObjectDisposedException (GetType ().Name);
+
+ if (!reference.IsValid) {
+ return null;
+ }
+
+ targetType = targetType ?? typeof (JavaObject);
+ targetType = GetPeerType (targetType);
+ if (!typeof (IJavaPeerable).IsAssignableFrom (targetType))
+ throw new ArgumentException ($"targetType `{targetType.AssemblyQualifiedName}` must implement IJavaPeerable!", nameof (targetType));
+ IReadOnlyDictionary typemap = System.Runtime.InteropServices.TypeMapping.GetOrCreateExternalTypeMapping();
+ string? className;
+ JniObjectReference refClass;
+ Type? mappedType = null;
+ do {
+ refClass = JniEnvironment.Types.GetObjectClass (reference);
+ className = JniEnvironment.Types.GetJniTypeNameFromClass (refClass);
+ if (className is not null && typemap.TryGetValue (className, out mappedType)) {
+ JniObjectReference.Dispose (ref refClass);
+ break;
+ }
+ var oldClass = refClass;
+ refClass = JniEnvironment.Types.GetSuperclass (refClass);
+ JniObjectReference.Dispose (ref oldClass);
+ }
+ while (refClass.IsValid);
+
+ if (mappedType is null) {
+ throw new InvalidOperationException ("Java object type does not have mapping to .NET type.");
+ }
+ if (!mappedType.IsAssignableTo(targetType)) {
+ throw new InvalidOperationException("Mapped .NET type is not assignable to target type.");
+ }
+
+ var managedObject = GetUninitializedObject (mappedType);
+ var constructed = false;
+ try {
+ constructed = TryConstructPeer (managedObject, ref reference, options, mappedType);
+ } finally {
+ if (!constructed) {
+ GC.SuppressFinalize (managedObject);
+ managedObject = null;
+ }
+ }
+ return managedObject;
+ static IJavaPeerable GetUninitializedObject (
+ [DynamicallyAccessedMembers (Constructors)]
+ Type type)
+ {
+ var v = (IJavaPeerable) System.Runtime.CompilerServices.RuntimeHelpers.GetUninitializedObject (type);
+ v.SetJniManagedPeerState (JniManagedPeerStates.Replaceable | JniManagedPeerStates.Activatable);
+ return v;
+ }
+
+ }
+#else
public virtual IJavaPeerable? CreatePeer (
ref JniObjectReference reference,
JniObjectReferenceOptions transfer,
@@ -306,18 +374,18 @@ static Type GetPeerType ([DynamicallyAccessedMembers (Constructors)] Type type)
return null;
}
- targetType = targetType ?? typeof (JavaObject);
- targetType = GetPeerType (targetType);
+ targetType = targetType ?? typeof (JavaObject);
+ targetType = GetPeerType (targetType);
if (!typeof (IJavaPeerable).IsAssignableFrom (targetType))
throw new ArgumentException ($"targetType `{targetType.AssemblyQualifiedName}` must implement IJavaPeerable!", nameof (targetType));
- var targetSig = Runtime.TypeManager.GetTypeSignature (targetType);
+ var targetSig = Runtime.TypeManager.GetTypeSignature (targetType);
if (!targetSig.IsValid || targetSig.SimpleReference == null) {
throw new ArgumentException ($"Could not determine Java type corresponding to `{targetType.AssemblyQualifiedName}`.", nameof (targetType));
}
- var refClass = JniEnvironment.Types.GetObjectClass (reference);
+ var refClass = JniEnvironment.Types.GetObjectClass (reference);
JniObjectReference targetClass;
try {
targetClass = JniEnvironment.Types.FindClass (targetSig.SimpleReference);
@@ -369,13 +437,13 @@ static Type GetPeerType ([DynamicallyAccessedMembers (Constructors)] Type type)
}
}
- var super = JniEnvironment.Types.GetSuperclass (klass);
+ var super = JniEnvironment.Types.GetSuperclass (klass);
jniTypeName = super.IsValid
? JniEnvironment.Types.GetJniTypeNameFromClass (super)
: null;
JniObjectReference.Dispose (ref klass, JniObjectReferenceOptions.CopyAndDispose);
- klass = super;
+ klass = super;
}
JniObjectReference.Dispose (ref klass, JniObjectReferenceOptions.CopyAndDispose);
@@ -385,12 +453,54 @@ static Type GetPeerType ([DynamicallyAccessedMembers (Constructors)] Type type)
[return: DynamicallyAccessedMembers (Constructors)]
Type? GetTypeAssignableTo (JniTypeSignature sig, Type targetType)
{
- foreach (var t in Runtime.TypeManager.GetTypes (sig)) {
- if (targetType.IsAssignableFrom (t)) {
- return t;
+ string[] sdkAssemblyNames = ["Mono.Android", "Java.Base", "Java.Runtime", "Java.Interop"];
+ // Find single best instance
+ Type? best = null;
+ foreach (Type type in Runtime.TypeManager.GetTypes (sig)) {
+ if (best is null) {
+ best = type;
+ continue;
+ }
+ if (type == best)
+ continue;
+ // Types in sdk assemblies should be first in the list
+ if ((uint)Array.IndexOf(sdkAssemblyNames, best.Module.Assembly.GetName ().Name) >
+ (uint)Array.IndexOf(sdkAssemblyNames, type.Module.Assembly.GetName ().Name)) {
+ best = type;
+ continue;
+ }
+ // We found the `Invoker` type *before* the declared type
+ // Fix things up so the abstract type is first, and the `Invoker` is considered a duplicate.
+ if ((type.IsAbstract || type.IsInterface) &&
+ !best.IsAbstract &&
+ !best.IsInterface &&
+ type.IsAssignableFrom (best)) {
+ best = type;
+ continue;
+ }
+
+ // If the type is a derived type of the current best, then it is better
+ if (type.IsAssignableTo(best))
+ {
+ best = type;
+ continue;
+ }
+
+ // we found a generic subclass of a non-generic type
+ if (type.IsGenericType &&
+ !best.IsGenericType &&
+ type.IsAssignableTo (best)) {
+ best = type;
+ continue;
}
}
+ if (best is not null && best.IsAssignableTo (targetType))
+ return best;
return null;
+ //throw new InvalidOperationException (
+ // $"Best type for instance of Java class '{sig.Name}' is '{best.FullName}', "
+ // + $"which is not assignable to target type '{targetType.FullName}'."
+ // + $"\nOther mapped types:\n{string.Join("\n", Runtime.TypeManager.GetTypes(sig).Select(t => t.FullName))}");
}
}
@@ -400,16 +510,16 @@ static Type GetPeerType ([DynamicallyAccessedMembers (Constructors)] Type type)
[DynamicallyAccessedMembers (Constructors)]
Type type)
{
- type = Runtime.TypeManager.GetInvokerType (type) ?? type;
+ type = Runtime.TypeManager.GetInvokerType (type) ?? type;
- var self = GetUninitializedObject (type);
+ var self = GetUninitializedObject (type);
var constructed = false;
try {
constructed = TryConstructPeer (self, ref reference, options, type);
} finally {
if (!constructed) {
GC.SuppressFinalize (self);
- self = null;
+ self = null;
}
}
return self;
@@ -418,15 +528,16 @@ static IJavaPeerable GetUninitializedObject (
[DynamicallyAccessedMembers (Constructors)]
Type type)
{
- var v = (IJavaPeerable) System.Runtime.CompilerServices.RuntimeHelpers.GetUninitializedObject (type);
+ var v = (IJavaPeerable) System.Runtime.CompilerServices.RuntimeHelpers.GetUninitializedObject (type);
v.SetJniManagedPeerState (JniManagedPeerStates.Replaceable | JniManagedPeerStates.Activatable);
return v;
}
}
+#endif
- const BindingFlags ActivationConstructorBindingFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
- static readonly Type ByRefJniObjectReference = typeof (JniObjectReference).MakeByRefType ();
- static readonly Type[] JIConstructorSignature = new Type [] { ByRefJniObjectReference, typeof (JniObjectReferenceOptions) };
+ const BindingFlags ActivationConstructorBindingFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
+ static readonly Type ByRefJniObjectReference = typeof (JniObjectReference).MakeByRefType ();
+ static readonly Type [] JIConstructorSignature = new Type [] { ByRefJniObjectReference, typeof (JniObjectReferenceOptions) };
protected virtual bool TryConstructPeer (
@@ -438,12 +549,12 @@ protected virtual bool TryConstructPeer (
{
var c = type.GetConstructor (ActivationConstructorBindingFlags, null, JIConstructorSignature, null);
if (c != null) {
- var args = new object[] {
+ var args = new object [] {
reference,
options,
};
c.Invoke (self, args);
- reference = (JniObjectReference) args [0];
+ reference = (JniObjectReference) args [0];
return true;
}
return false;
@@ -465,7 +576,7 @@ protected virtual bool TryConstructPeer (
return JavaPeerableValueMarshaler.Instance.CreateGenericValue (ref reference, options, targetType);
}
- var boxed = PeekBoxedObject (reference);
+ var boxed = PeekBoxedObject (reference);
if (boxed != null) {
JniObjectReference.Dispose (ref reference, options);
if (targetType != null)
@@ -478,14 +589,14 @@ protected virtual bool TryConstructPeer (
// Let's hope this is an IJavaPeerable!
return JavaPeerableValueMarshaler.Instance.CreateGenericValue (ref reference, options, targetType);
}
- var marshaler = GetValueMarshaler (targetType);
+ var marshaler = GetValueMarshaler (targetType);
return marshaler.CreateValue (ref reference, options, targetType);
}
[return: MaybeNull]
public T CreateValue<
[DynamicallyAccessedMembers (Constructors)]
- T
+ T
> (
ref JniObjectReference reference,
JniObjectReferenceOptions options,
@@ -509,21 +620,21 @@ public T CreateValue<
typeof (T)),
nameof (targetType));
- var boxed = PeekBoxedObject (reference);
+ var boxed = PeekBoxedObject (reference);
if (boxed != null) {
JniObjectReference.Dispose (ref reference, options);
return (T) Convert.ChangeType (boxed, targetType ?? typeof (T));
}
- targetType = targetType ?? typeof (T);
+ targetType = targetType ?? typeof (T);
if (typeof (IJavaPeerable).IsAssignableFrom (targetType)) {
-#pragma warning disable CS8600,CS8601 // Possible null reference assignment.
+#pragma warning disable CS8600, CS8601 // Possible null reference assignment.
return (T) JavaPeerableValueMarshaler.Instance.CreateGenericValue (ref reference, options, targetType);
-#pragma warning restore CS8600,CS8601 // Possible null reference assignment.
+#pragma warning restore CS8600, CS8601 // Possible null reference assignment.
}
- var marshaler = GetValueMarshaler ();
+ var marshaler = GetValueMarshaler ();
return marshaler.CreateGenericValue (ref reference, options, targetType);
}
@@ -565,25 +676,25 @@ public T CreateValue<
// Let's hope this is an IJavaPeerable!
return JavaPeerableValueMarshaler.Instance.CreateGenericValue (ref reference, options, targetType);
}
- var marshaler = GetValueMarshaler (targetType);
+ var marshaler = GetValueMarshaler (targetType);
return marshaler.CreateValue (ref reference, options, targetType);
}
[return: MaybeNull]
public T GetValue<
[DynamicallyAccessedMembers (Constructors)]
- T
+ T
> (
IntPtr handle)
{
- var r = new JniObjectReference (handle);
+ var r = new JniObjectReference (handle);
return GetValue (ref r, JniObjectReferenceOptions.Copy);
}
[return: MaybeNull]
public T GetValue<
[DynamicallyAccessedMembers (Constructors)]
- T
+ T
> (
ref JniObjectReference reference,
JniObjectReferenceOptions options,
@@ -604,7 +715,7 @@ public T GetValue<
typeof (T)),
nameof (targetType));
- targetType = targetType ?? typeof (T);
+ targetType = targetType ?? typeof (T);
var existing = PeekValue (reference);
if (existing != null && (targetType == null || targetType.IsAssignableFrom (existing.GetType ()))) {
@@ -613,12 +724,12 @@ public T GetValue<
}
if (typeof (IJavaPeerable).IsAssignableFrom (targetType)) {
-#pragma warning disable CS8600,CS8601 // Possible null reference assignment.
+#pragma warning disable CS8600, CS8601 // Possible null reference assignment.
return (T) JavaPeerableValueMarshaler.Instance.CreateGenericValue (ref reference, options, targetType);
-#pragma warning restore CS8600,CS8601 // Possible null reference assignment.
+#pragma warning restore CS8600, CS8601 // Possible null reference assignment.
}
- var marshaler = GetValueMarshaler ();
+ var marshaler = GetValueMarshaler ();
return marshaler.CreateGenericValue (ref reference, options, targetType);
}
@@ -626,14 +737,14 @@ public T GetValue<
public JniValueMarshaler GetValueMarshaler<
[DynamicallyAccessedMembers (Constructors)]
- T
+ T
> ()
{
if (disposed)
throw new ObjectDisposedException (GetType ().Name);
- var m = GetValueMarshaler (typeof (T));
- var r = m as JniValueMarshaler;
+ var m = GetValueMarshaler (typeof (T));
+ var r = m as JniValueMarshaler;
if (r != null)
return r;
lock (Marshalers) {
@@ -653,7 +764,7 @@ public JniValueMarshaler GetValueMarshaler (Type type)
if (type.ContainsGenericParameters)
throw new ArgumentException ("Generic type definitions are not supported.", nameof (type));
- var marshalerAttr = type.GetCustomAttribute ();
+ var marshalerAttr = type.GetCustomAttribute ();
if (marshalerAttr != null)
return (JniValueMarshaler) Activator.CreateInstance (marshalerAttr.MarshalerType)!;
@@ -669,7 +780,7 @@ public JniValueMarshaler GetValueMarshaler (Type type)
}
- var listType = GetListType (type);
+ var listType = GetListType (type);
if (listType != null) {
var elementType = listType.GenericTypeArguments [0];
if (elementType.IsValueType) {
@@ -689,7 +800,7 @@ public JniValueMarshaler GetValueMarshaler (Type type)
return GetValueMarshalerCore (type);
}
- static Type? GetListType(Type type)
+ static Type? GetListType (Type type)
{
foreach (var iface in GetInterfaces (type).Concat (new [] { type })) {
if (typeof (IList<>).IsAssignableFrom (iface.IsGenericType ? iface.GetGenericTypeDefinition () : iface))
@@ -721,7 +832,7 @@ static MethodInfo MakeGenericMethod (MethodInfo method, Type type) =>
static JniValueMarshaler GetObjectArrayMarshalerHelper<
[DynamicallyAccessedMembers (Constructors)]
- T
+ T
> ()
{
return JavaObjectArray.Instance;
@@ -734,12 +845,13 @@ protected virtual JniValueMarshaler GetValueMarshalerCore (Type type)
}
}
- sealed class VoidValueMarshaler : JniValueMarshaler {
+ sealed class VoidValueMarshaler : JniValueMarshaler
+ {
- internal static VoidValueMarshaler Instance = new VoidValueMarshaler ();
+ internal static VoidValueMarshaler Instance = new VoidValueMarshaler ();
public override Type MarshalType {
- get {return typeof (void);}
+ get { return typeof (void); }
}
public override object? CreateValue (
@@ -762,9 +874,10 @@ public override void DestroyArgumentState (object? value, ref JniValueMarshalerS
}
}
- sealed class JavaPeerableValueMarshaler : JniValueMarshaler {
+ sealed class JavaPeerableValueMarshaler : JniValueMarshaler
+ {
- internal static JavaPeerableValueMarshaler Instance = new JavaPeerableValueMarshaler ();
+ internal static JavaPeerableValueMarshaler Instance = new JavaPeerableValueMarshaler ();
[return: MaybeNull]
public override IJavaPeerable? CreateGenericValue (
@@ -773,26 +886,26 @@ sealed class JavaPeerableValueMarshaler : JniValueMarshaler {
[DynamicallyAccessedMembers (Constructors)]
Type? targetType)
{
- var jvm = JniEnvironment.Runtime;
- var marshaler = jvm.ValueManager.GetValueMarshaler (targetType ?? typeof(IJavaPeerable));
+ var jvm = JniEnvironment.Runtime;
+ var marshaler = jvm.ValueManager.GetValueMarshaler (targetType ?? typeof (IJavaPeerable));
if (marshaler != Instance)
return (IJavaPeerable) marshaler.CreateValue (ref reference, options, targetType)!;
return jvm.ValueManager.CreatePeer (ref reference, options, targetType);
}
- public override JniValueMarshalerState CreateGenericObjectReferenceArgumentState ([MaybeNull]IJavaPeerable? value, ParameterAttributes synchronize)
+ public override JniValueMarshalerState CreateGenericObjectReferenceArgumentState ([MaybeNull] IJavaPeerable? value, ParameterAttributes synchronize)
{
if (value == null || !value.PeerReference.IsValid)
return new JniValueMarshalerState ();
- var r = value.PeerReference.NewLocalRef ();
+ var r = value.PeerReference.NewLocalRef ();
return new JniValueMarshalerState (r);
}
- public override void DestroyGenericArgumentState ([MaybeNull]IJavaPeerable? value, ref JniValueMarshalerState state, ParameterAttributes synchronize)
+ public override void DestroyGenericArgumentState ([MaybeNull] IJavaPeerable? value, ref JniValueMarshalerState state, ParameterAttributes synchronize)
{
- var r = state.ReferenceValue;
+ var r = state.ReferenceValue;
JniObjectReference.Dispose (ref r);
- state = new JniValueMarshalerState ();
+ state = new JniValueMarshalerState ();
}
[RequiresUnreferencedCode (ExpressionRequiresUnreferencedCode)]
@@ -809,13 +922,13 @@ public override Expression CreateParameterFromManagedExpression (JniValueMarshal
[RequiresUnreferencedCode (ExpressionRequiresUnreferencedCode)]
Expression CreateIntermediaryExpressionFromManagedExpression (JniValueMarshalerContext context, ParameterExpression sourceValue)
{
- var r = Expression.Variable (typeof (JniObjectReference), sourceValue.Name + "_ref");
+ var r = Expression.Variable (typeof (JniObjectReference), sourceValue.Name + "_ref");
context.LocalVariables.Add (r);
context.CreationStatements.Add (
Expression.IfThenElse (
- test: Expression.Equal (Expression.Constant (null), sourceValue),
- ifTrue: Expression.Assign (r, Expression.New (typeof (JniObjectReference))),
- ifFalse: Expression.Assign (r, Expression.Property (Expression.Convert (sourceValue, typeof (IJavaPeerable)), "PeerReference"))));
+ test: Expression.Equal (Expression.Constant (null), sourceValue),
+ ifTrue: Expression.Assign (r, Expression.New (typeof (JniObjectReference))),
+ ifFalse: Expression.Assign (r, Expression.Property (Expression.Convert (sourceValue, typeof (IJavaPeerable)), "PeerReference"))));
return r;
}
@@ -833,14 +946,14 @@ public override Expression CreateParameterToManagedExpression (JniValueMarshaler
{
targetType ??= typeof (object);
- var r = Expression.Variable (targetType, sourceValue.Name + "_val");
+ var r = Expression.Variable (targetType, sourceValue.Name + "_val");
context.LocalVariables.Add (r);
context.CreationStatements.Add (
Expression.Assign (r,
Expression.Call (
context.ValueManager ?? Expression.Property (context.Runtime, "ValueManager"),
"GetValue",
- new[]{targetType},
+ new [] { targetType },
sourceValue)));
return r;
}
@@ -848,16 +961,16 @@ public override Expression CreateParameterToManagedExpression (JniValueMarshaler
sealed class DelegatingValueMarshaler<
[DynamicallyAccessedMembers (Constructors)]
- T
+ T
>
: JniValueMarshaler
{
- JniValueMarshaler ValueMarshaler;
+ JniValueMarshaler ValueMarshaler;
public DelegatingValueMarshaler (JniValueMarshaler valueMarshaler)
{
- ValueMarshaler = valueMarshaler;
+ ValueMarshaler = valueMarshaler;
}
[return: MaybeNull]
@@ -870,12 +983,12 @@ public override T CreateGenericValue (
return (T) ValueMarshaler.CreateValue (ref reference, options, targetType ?? typeof (T))!;
}
- public override JniValueMarshalerState CreateGenericObjectReferenceArgumentState ([MaybeNull]T value, ParameterAttributes synchronize)
+ public override JniValueMarshalerState CreateGenericObjectReferenceArgumentState ([MaybeNull] T value, ParameterAttributes synchronize)
{
return ValueMarshaler.CreateObjectReferenceArgumentState (value, synchronize);
}
- public override void DestroyGenericArgumentState ([AllowNull]T value, ref JniValueMarshalerState state, ParameterAttributes synchronize)
+ public override void DestroyGenericArgumentState ([AllowNull] T value, ref JniValueMarshalerState state, ParameterAttributes synchronize)
{
ValueMarshaler.DestroyArgumentState (value, ref state, synchronize);
}
@@ -901,9 +1014,10 @@ public override Expression CreateReturnValueFromManagedExpression (JniValueMarsh
}
}
- sealed class ProxyValueMarshaler : JniValueMarshaler