-
Notifications
You must be signed in to change notification settings - Fork 568
Expand file tree
/
Copy pathJavaObjectExtensions.cs
More file actions
149 lines (127 loc) · 5.63 KB
/
JavaObjectExtensions.cs
File metadata and controls
149 lines (127 loc) · 5.63 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Reflection;
using Android.Runtime;
namespace Java.Interop {
public static class JavaObjectExtensions {
const DynamicallyAccessedMemberTypes Constructors = DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors;
[Obsolete ("Use Android.Runtime.JavaCollection.ToLocalJniHandle()")]
public static JavaCollection ToInteroperableCollection (this ICollection instance)
{
return instance is JavaCollection ? (JavaCollection) instance : new JavaCollection (instance);
}
[Obsolete ("Use Android.Runtime.JavaCollection<T>.ToLocalJniHandle()")]
public static JavaCollection<T> ToInteroperableCollection<
[DynamicallyAccessedMembers (Constructors)]
T
> (this ICollection<T> instance)
{
return instance is JavaCollection<T> ? (JavaCollection<T>) instance : new JavaCollection<T> (instance);
}
[Obsolete ("Use Android.Runtime.JavaList.ToLocalJniHandle()")]
public static JavaList ToInteroperableCollection (this IList instance)
{
return instance is JavaList ? (JavaList) instance : new JavaList (instance);
}
[Obsolete ("Use Android.Runtime.JavaList<T>.ToLocalJniHandle()")]
public static JavaList<T> ToInteroperableCollection<
[DynamicallyAccessedMembers (Constructors)]
T
> (this IList<T> instance)
{
return instance is JavaList<T> ? (JavaList<T>) instance : new JavaList<T> (instance);
}
[Obsolete ("Use Android.Runtime.JavaDictionary.ToLocalJniHandle()")]
public static JavaDictionary ToInteroperableCollection (this IDictionary instance)
{
return instance is JavaDictionary ? (JavaDictionary) instance : new JavaDictionary (instance);
}
[Obsolete ("Use Android.Runtime.JavaDictionary<K, V>.ToLocalJniHandle()")]
public static JavaDictionary<K,V> ToInteroperableCollection<
[DynamicallyAccessedMembers (Constructors)]
K,
[DynamicallyAccessedMembers (Constructors)]
V
> (this IDictionary<K,V> instance)
{
return instance is JavaDictionary<K,V> ? (JavaDictionary<K,V>) instance : new JavaDictionary<K,V> (instance);
}
[return: NotNullIfNotNull ("instance")]
public static TResult? JavaCast<
[DynamicallyAccessedMembers (Constructors)]
TResult
> (this IJavaObject? instance)
where TResult : class, IJavaObject
{
return _JavaCast<TResult> (instance);
}
internal static TResult? _JavaCast<
[DynamicallyAccessedMembers (Constructors)]
TResult
> (this IJavaObject? instance)
{
if (instance == null)
return default (TResult);
if (instance is TResult)
return (TResult) instance;
if (instance.Handle == IntPtr.Zero)
throw new ObjectDisposedException (instance.GetType ().FullName);
return (TResult?) Java.Lang.Object.GetObject (instance.Handle, JniHandleOwnership.DoNotTransfer, typeof (TResult)) ??
throw new InvalidCastException (
FormattableString.Invariant ($"Unable to convert instance of type '{instance.GetType ().FullName}' to type '{typeof (TResult).FullName}'."));
}
internal static IJavaObject? JavaCast (
IJavaObject? instance,
[DynamicallyAccessedMembers (Constructors)]
Type resultType)
{
if (resultType == null)
throw new ArgumentNullException ("resultType");
if (instance == null)
return null;
if (resultType.IsAssignableFrom (instance.GetType ()))
return instance;
return (IJavaObject?) Java.Lang.Object.GetObject (instance.Handle, JniHandleOwnership.DoNotTransfer, resultType) ??
throw new InvalidCastException (
FormattableString.Invariant ($"Unable to convert instance of type '{instance.GetType ().FullName}' to type '{resultType.FullName}'."));
}
// typeof(Foo) -> FooInvoker
// typeof(Foo<>) -> FooInvoker`1
[return: DynamicallyAccessedMembers (Constructors)]
internal static Type? GetInvokerType (Type type)
{
const string InvokerTypes = "*Invoker types are preserved by the MarkJavaObjects linker step.";
[UnconditionalSuppressMessage ("Trimming", "IL2026", Justification = InvokerTypes)]
[UnconditionalSuppressMessage ("Trimming", "IL2055", Justification = InvokerTypes)]
[UnconditionalSuppressMessage ("Trimming", "IL2073", Justification = InvokerTypes)]
[return: DynamicallyAccessedMembers (Constructors)]
static Type? AssemblyGetType (Assembly assembly, string typeName) =>
assembly.GetType (typeName);
// FIXME: https://github.com/xamarin/xamarin-android/issues/8724
// IL3050 disabled in source: if someone uses NativeAOT, they will get the warning.
[UnconditionalSuppressMessage ("Trimming", "IL2055", Justification = InvokerTypes)]
[UnconditionalSuppressMessage ("Trimming", "IL2068", Justification = InvokerTypes)]
[return: DynamicallyAccessedMembers (Constructors)]
static Type MakeGenericType (Type type, params Type [] typeArguments) =>
#pragma warning disable IL3050
type.MakeGenericType (typeArguments);
#pragma warning restore IL3050
const string suffix = "Invoker";
Type[] arguments = type.GetGenericArguments ();
if (arguments.Length == 0)
return AssemblyGetType (type.Assembly, type + suffix);
Type definition = type.GetGenericTypeDefinition ();
int bt = definition.FullName!.IndexOf ("`", StringComparison.Ordinal);
if (bt == -1)
throw new NotSupportedException ("Generic type doesn't follow generic type naming convention! " + type.FullName);
Type? suffixDefinition = AssemblyGetType (
definition.Assembly,
definition.FullName.Substring (0, bt) + suffix + definition.FullName.Substring (bt));
if (suffixDefinition == null)
return null;
return MakeGenericType (suffixDefinition, arguments);
}
}
}