Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 30 additions & 30 deletions src/Java.Interop/Java.Interop/JniRuntime.JniValueManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -336,31 +336,21 @@ static Type GetPeerType ([DynamicallyAccessedMembers (Constructors)] Type type)

JniObjectReference.Dispose (ref targetClass);

var ctor = GetPeerConstructor (ref refClass, targetType);
if (ctor == null) {
var peer = CreatePeerInstance (ref refClass, targetType, ref reference, transfer);
if (peer == null) {
throw new NotSupportedException (string.Format ("Could not find an appropriate constructable wrapper type for Java type '{0}', targetType='{1}'.",
JniEnvironment.Types.GetJniTypeNameFromInstance (reference), targetType));
}

var acts = new object[] {
reference,
transfer,
};
try {
var peer = (IJavaPeerable) ctor.Invoke (acts);
peer.SetJniManagedPeerState (peer.JniManagedPeerState | JniManagedPeerStates.Replaceable);
return peer;
} finally {
reference = (JniObjectReference) acts [0];
}
peer.SetJniManagedPeerState (peer.JniManagedPeerState | JniManagedPeerStates.Replaceable);
return peer;
}

static readonly Type ByRefJniObjectReference = typeof (JniObjectReference).MakeByRefType ();

ConstructorInfo? GetPeerConstructor (
IJavaPeerable? CreatePeerInstance (
ref JniObjectReference klass,
[DynamicallyAccessedMembers (Constructors)]
Type fallbackType)
Type fallbackType,
ref JniObjectReference reference,
JniObjectReferenceOptions transfer)
{
var jniTypeName = JniEnvironment.Types.GetJniTypeNameFromClass (klass);

Expand All @@ -373,11 +363,12 @@ static Type GetPeerType ([DynamicallyAccessedMembers (Constructors)] Type type)
type = Runtime.TypeManager.GetType (sig);

if (type != null) {
var ctor = GetActivationConstructor (type);
type = GetInvokerType (type) ?? type;
var peer = TryCreatePeer (ref reference, transfer, type);

if (ctor != null) {
if (peer != null) {
JniObjectReference.Dispose (ref klass);
return ctor;
return peer;
}
}

Expand All @@ -391,20 +382,29 @@ static Type GetPeerType ([DynamicallyAccessedMembers (Constructors)] Type type)
}
JniObjectReference.Dispose (ref klass, JniObjectReferenceOptions.CopyAndDispose);

return GetActivationConstructor (fallbackType);
return TryCreatePeer (ref reference, transfer, fallbackType);
}

static ConstructorInfo? GetActivationConstructor (
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 IJavaPeerable? TryCreatePeer (
ref JniObjectReference reference,
JniObjectReferenceOptions options,
[DynamicallyAccessedMembers (Constructors)]
Type type)
{
if (type.IsAbstract || type.IsInterface) {
type = GetInvokerType (type) ?? type;
}
foreach (var c in type.GetConstructors (BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)) {
var p = c.GetParameters ();
if (p.Length == 2 && p [0].ParameterType == ByRefJniObjectReference && p [1].ParameterType == typeof (JniObjectReferenceOptions))
return c;
var c = type.GetConstructor (ActivationConstructorBindingFlags, null, JIConstructorSignature, null);
if (c != null) {
var args = new object[] {
reference,
options,
};
var p = (IJavaPeerable) c.Invoke (args);
reference = (JniObjectReference) args [0];
return p;
}
return null;
}
Expand Down
1 change: 1 addition & 0 deletions src/Java.Interop/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ static Java.Interop.JniEnvironment.BeginMarshalMethod(nint jnienv, out Java.Inte
static Java.Interop.JniEnvironment.EndMarshalMethod(ref Java.Interop.JniTransition transition) -> void
virtual Java.Interop.JniRuntime.OnEnterMarshalMethod() -> void
virtual Java.Interop.JniRuntime.OnUserUnhandledException(ref Java.Interop.JniTransition transition, System.Exception! e) -> void
virtual Java.Interop.JniRuntime.JniValueManager.TryCreatePeer(ref Java.Interop.JniObjectReference reference, Java.Interop.JniObjectReferenceOptions options, System.Type! type) -> Java.Interop.IJavaPeerable?
Java.Interop.JavaException.JavaException(ref Java.Interop.JniObjectReference reference, Java.Interop.JniObjectReferenceOptions transfer, Java.Interop.JniObjectReference throwableOverride) -> void
Java.Interop.JavaException.SetJavaStackTrace(Java.Interop.JniObjectReference peerReferenceOverride = default(Java.Interop.JniObjectReference)) -> void
Java.Interop.JniRuntime.JniValueManager.GetPeer(Java.Interop.JniObjectReference reference, System.Type? targetType = null) -> Java.Interop.IJavaPeerable?
Expand Down
Loading