Skip to content

Commit e439510

Browse files
committed
Merge branch 'main' into dev/grendel/blobs-in-lib
* main: [Mono.Android] fix trimming warnings, part 2 (#8758)
2 parents 1e15b0d + 5205a5f commit e439510

13 files changed

+140
-28
lines changed

src/Mono.Android/Android.App/Activity.cs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,27 @@
11
using System;
2-
2+
using System.Diagnostics.CodeAnalysis;
33
using Android.Runtime;
44

55
namespace Android.App {
66

77
partial class Activity {
88

9-
public T? FindViewById<T> (int id)
9+
internal const DynamicallyAccessedMemberTypes Constructors = DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors;
10+
11+
public T? FindViewById<
12+
[DynamicallyAccessedMembers (Constructors)]
13+
T
14+
> (int id)
1015
where T : Android.Views.View
1116
{
1217
return this.FindViewById (id)!.JavaCast<T> ();
1318
}
1419

1520
// See: https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/android/app/Activity.java;l=3430
16-
public T RequireViewById<T> (int id)
21+
public T RequireViewById<
22+
[DynamicallyAccessedMembers (Constructors)]
23+
T
24+
> (int id)
1725
where T : Android.Views.View
1826
{
1927
var view = FindViewById<T> (id);

src/Mono.Android/Android.App/Dialog.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Diagnostics.CodeAnalysis;
23
using Android.Runtime;
34

45
namespace Android.App {
@@ -8,7 +9,10 @@ public partial class Dialog {
89
protected Dialog (Android.Content.Context context, bool cancelable, EventHandler cancelHandler)
910
: this (context, cancelable, new Android.Content.IDialogInterfaceOnCancelListenerImplementor () { Handler = cancelHandler }) {}
1011

11-
public T? FindViewById<T> (int id)
12+
public T? FindViewById<
13+
[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)]
14+
T
15+
> (int id)
1216
where T : Android.Views.View
1317
{
1418
return this.FindViewById (id).JavaCast<T> ();

src/Mono.Android/Android.App/FragmentManager.cs

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,35 @@
11
using Android.OS;
22
using Android.Runtime;
3+
using System.Diagnostics.CodeAnalysis;
34

45
#if ANDROID_11
56
namespace Android.App {
67
public partial class FragmentManager {
7-
public T? FindFragmentById<T> (int id) where T : Fragment
8+
const DynamicallyAccessedMemberTypes Constructors = DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors;
9+
10+
public T? FindFragmentById<
11+
[DynamicallyAccessedMembers (Constructors)]
12+
T
13+
> (int id)
14+
where T : Fragment
815
{
916
return FindFragmentById (id).JavaCast<T> ();
1017
}
11-
public T? FindFragmentByTag<T> (string tag) where T : Fragment
18+
19+
public T? FindFragmentByTag<
20+
[DynamicallyAccessedMembers (Constructors)]
21+
T
22+
> (string tag)
23+
where T : Fragment
1224
{
1325
return FindFragmentByTag (tag).JavaCast<T> ();
1426
}
15-
public T? GetFragment<T> (Bundle bundle, string key) where T : Fragment
27+
28+
public T? GetFragment<
29+
[DynamicallyAccessedMembers (Constructors)]
30+
T
31+
> (Bundle bundle, string key)
32+
where T : Fragment
1633
{
1734
return GetFragment (bundle, key).JavaCast<T> ();
1835
}

src/Mono.Android/Android.Runtime/AndroidRuntime.cs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,9 @@ struct JniRemappingReplacementMethod
247247

248248
bool jniAddNativeMethodRegistrationAttributePresent;
249249

250+
const DynamicallyAccessedMemberTypes Methods = DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods;
251+
const DynamicallyAccessedMemberTypes MethodsAndPrivateNested = Methods | DynamicallyAccessedMemberTypes.NonPublicNestedTypes;
252+
250253
public AndroidTypeManager (bool jniAddNativeMethodRegistrationAttributePresent)
251254
{
252255
this.jniAddNativeMethodRegistrationAttributePresent = jniAddNativeMethodRegistrationAttributePresent;
@@ -473,7 +476,7 @@ static bool CallRegisterMethodByIndex (JniNativeMethodRegistrationArguments argu
473476

474477
public override void RegisterNativeMembers (
475478
JniType nativeClass,
476-
[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)]
479+
[DynamicallyAccessedMembers (MethodsAndPrivateNested)]
477480
Type type,
478481
string? methods) =>
479482
RegisterNativeMembers (nativeClass, type, methods.AsSpan ());
@@ -483,7 +486,7 @@ public override void RegisterNativeMembers (
483486
[UnconditionalSuppressMessage ("Trimming", "IL2072", Justification = "Delegate.CreateDelegate() can never statically know the string value parsed from parameter 'methods'.")]
484487
public void RegisterNativeMembers (
485488
JniType nativeClass,
486-
[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] Type type,
489+
[DynamicallyAccessedMembers (MethodsAndPrivateNested)] Type type,
487490
ReadOnlySpan<char> methods)
488491
{
489492
try {
@@ -619,7 +622,11 @@ public override void WaitForGCBridgeProcessing ()
619622
AndroidRuntimeInternal.WaitForBridgeProcessing ();
620623
}
621624

622-
public override IJavaPeerable? CreatePeer (ref JniObjectReference reference, JniObjectReferenceOptions options, Type? targetType)
625+
public override IJavaPeerable? CreatePeer (
626+
ref JniObjectReference reference,
627+
JniObjectReferenceOptions options,
628+
[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)]
629+
Type? targetType)
623630
{
624631
if (!reference.IsValid)
625632
return null;

src/Mono.Android/Android.Runtime/Extensions.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@ namespace Android.Runtime {
77
public static class Extensions {
88

99
[return: NotNullIfNotNull ("instance")]
10-
public static TResult? JavaCast<TResult> (this IJavaObject? instance)
10+
public static TResult? JavaCast<
11+
[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)]
12+
TResult
13+
> (this IJavaObject? instance)
1114
where TResult : class, IJavaObject
1215
{
1316
return Java.Interop.JavaObjectExtensions.JavaCast<TResult>(instance);

src/Mono.Android/Android.Runtime/JNINativeWrapper.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Diagnostics;
3+
using System.Diagnostics.CodeAnalysis;
34
using System.Reflection;
45
using System.Reflection.Emit;
56
using System.Threading;
@@ -52,7 +53,11 @@ public static Delegate CreateDelegate (Delegate dlg)
5253
param_types [i] = parameters [i].ParameterType;
5354
}
5455

56+
// FIXME: https://github.com/xamarin/xamarin-android/issues/8724
57+
// IL3050 disabled in source: if someone uses NativeAOT, they will get the warning.
58+
#pragma warning disable IL3050
5559
var dynamic = new DynamicMethod (DynamicMethodNameCounter.GetUniqueName (), ret_type, param_types, typeof (DynamicMethodNameCounter), true);
60+
#pragma warning restore IL3050
5661
var ig = dynamic.GetILGenerator ();
5762

5863
LocalBuilder? retval = null;

src/Mono.Android/Android.Runtime/JavaProxyThrowable.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Diagnostics;
3+
using System.Diagnostics.CodeAnalysis;
34
using System.Reflection;
45

56
using StackTraceElement = Java.Lang.StackTraceElement;
@@ -38,6 +39,14 @@ public static JavaProxyThrowable Create (Exception innerException)
3839

3940
void TranslateStackTrace ()
4041
{
42+
// FIXME: https://github.com/xamarin/xamarin-android/issues/8724
43+
// StackFrame.GetMethod() will return null under NativeAOT;
44+
// However, you can still get useful information from StackFrame.ToString():
45+
// MainActivity.OnCreate() + 0x37 at offset 55 in file:line:column <filename unknown>:0:0
46+
[UnconditionalSuppressMessage ("Trimming", "IL2026", Justification = "StackFrame.GetMethod() is \"best attempt\", we handle null & exceptions")]
47+
static MethodBase? StackFrameGetMethod (StackFrame frame) =>
48+
frame.GetMethod ();
49+
4150
var trace = new StackTrace (InnerException, fNeedFileInfo: true);
4251
if (trace.FrameCount <= 0) {
4352
return;
@@ -59,7 +68,7 @@ void TranslateStackTrace ()
5968

6069
for (int i = 0; i < frames.Length; i++) {
6170
StackFrame managedFrame = frames[i];
62-
MethodBase? managedMethod = managedFrame.GetMethod ();
71+
MethodBase? managedMethod = StackFrameGetMethod (managedFrame);
6372

6473
var throwableFrame = new StackTraceElement (
6574
declaringClass: managedMethod?.DeclaringType?.FullName,

src/Mono.Android/Android.Runtime/ResourceDesignerAttribute.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,19 @@
11
using System;
2+
using System.Diagnostics.CodeAnalysis;
23

34
namespace Android.Runtime
45
{
56
[AttributeUsage (AttributeTargets.Assembly)]
67
public class ResourceDesignerAttribute : Attribute
78
{
8-
public ResourceDesignerAttribute (string fullName)
9+
public ResourceDesignerAttribute (
10+
[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)]
11+
string fullName)
912
{
1013
FullName = fullName;
1114
}
1215

16+
[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)]
1317
public string FullName { get; set; }
1418

1519
public bool IsApplication { get; set; }

src/Mono.Android/Android.Runtime/ResourceIdManager.cs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,19 @@ public static void UpdateIdValues ()
3131
}
3232
}
3333

34-
[UnconditionalSuppressMessage ("Trimming", "IL2026", Justification = "Types in Resource.designer.cs are preserved, because it is the root assembly passed to the linker.")]
34+
[return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)]
3535
static Type? GetResourceTypeFromAssembly (Assembly assembly)
3636
{
37+
const string rootAssembly = "Resources.UpdateIdValues() methods are trimmed away by the LinkResourceDesigner trimmer step. This codepath is not called unless $(AndroidUseDesignerAssembly) is disabled.";
38+
39+
[UnconditionalSuppressMessage ("Trimming", "IL2026", Justification = rootAssembly)]
40+
[UnconditionalSuppressMessage ("Trimming", "IL2073", Justification = rootAssembly)]
41+
[return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)]
42+
static Type AssemblyGetType (Assembly a, string name) => a.GetType (name);
43+
3744
foreach (var customAttribute in assembly.GetCustomAttributes (typeof (ResourceDesignerAttribute), true)) {
3845
if (customAttribute is ResourceDesignerAttribute resourceDesignerAttribute && resourceDesignerAttribute.IsApplication) {
39-
var type = assembly.GetType (resourceDesignerAttribute.FullName);
46+
var type = AssemblyGetType (assembly, resourceDesignerAttribute.FullName);
4047
if (type != null)
4148
return type;
4249
}

src/Mono.Android/Android.Views/View.cs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ public enum SystemUiFlags {
1414

1515
public partial class View {
1616

17+
internal const DynamicallyAccessedMemberTypes Constructors = DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors;
18+
1719
#if ANDROID_16
1820
[Obsolete ("This method uses wrong enum type. Please use PerformAccessibilityAction(Action) instead.")]
1921
public bool PerformAccessibilityAction (GlobalAction action, Bundle arguments)
@@ -22,14 +24,20 @@ public bool PerformAccessibilityAction (GlobalAction action, Bundle arguments)
2224
}
2325
#endif
2426

25-
public T? FindViewById<T> (int id)
27+
public T? FindViewById<
28+
[DynamicallyAccessedMembers (Constructors)]
29+
T
30+
> (int id)
2631
where T : Android.Views.View
2732
{
2833
return this.FindViewById (id).JavaCast<T> ();
2934
}
3035

3136
// See: https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/android/view/View.java;l=25322
32-
public T RequireViewById<T> (int id)
37+
public T RequireViewById<
38+
[DynamicallyAccessedMembers (Constructors)]
39+
T
40+
> (int id)
3341
where T : Android.Views.View
3442
{
3543
var view = FindViewById<T> (id);

src/Mono.Android/Android.Views/Window.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,10 @@ namespace Android.Views {
66

77
partial class Window {
88

9-
public T? FindViewById<T> (int id)
9+
public T? FindViewById<
10+
[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)]
11+
T
12+
> (int id)
1013
where T : Android.Views.View
1114
{
1215
return this.FindViewById (id).JavaCast<T> ();

src/Mono.Android/Java.Interop/JavaObjectExtensions.cs

Lines changed: 42 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
namespace Java.Interop {
99

1010
public static class JavaObjectExtensions {
11+
const DynamicallyAccessedMemberTypes Constructors = DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors;
1112

1213
[Obsolete ("Use Android.Runtime.JavaCollection.ToLocalJniHandle()")]
1314
public static JavaCollection ToInteroperableCollection (this ICollection instance)
@@ -46,13 +47,19 @@ public static JavaDictionary<K,V> ToInteroperableCollection<K,V> (this IDictiona
4647
}
4748

4849
[return: NotNullIfNotNull ("instance")]
49-
public static TResult? JavaCast<TResult> (this IJavaObject? instance)
50+
public static TResult? JavaCast<
51+
[DynamicallyAccessedMembers (Constructors)]
52+
TResult
53+
> (this IJavaObject? instance)
5054
where TResult : class, IJavaObject
5155
{
5256
return _JavaCast<TResult> (instance);
5357
}
5458

55-
internal static TResult? _JavaCast<TResult> (this IJavaObject? instance)
59+
internal static TResult? _JavaCast<
60+
[DynamicallyAccessedMembers (Constructors)]
61+
TResult
62+
> (this IJavaObject? instance)
5663
{
5764
if (instance == null)
5865
return default (TResult);
@@ -74,7 +81,10 @@ public static JavaDictionary<K,V> ToInteroperableCollection<K,V> (this IDictiona
7481
throw new NotSupportedException (FormattableString.Invariant ($"Unable to convert type '{instance.GetType ().FullName}' to '{resultType.FullName}'."));
7582
}
7683

77-
static IJavaObject CastClass (IJavaObject instance, Type resultType)
84+
static IJavaObject CastClass (
85+
IJavaObject instance,
86+
[DynamicallyAccessedMembers (Constructors)]
87+
Type resultType)
7888
{
7989
var klass = JNIEnv.FindClass (resultType);
8090
try {
@@ -97,7 +107,10 @@ static IJavaObject CastClass (IJavaObject instance, Type resultType)
97107
return (IJavaObject) TypeManager.CreateProxy (resultType, instance.Handle, JniHandleOwnership.DoNotTransfer);
98108
}
99109

100-
internal static IJavaObject? JavaCast (IJavaObject? instance, Type resultType)
110+
internal static IJavaObject? JavaCast (
111+
IJavaObject? instance,
112+
[DynamicallyAccessedMembers (Constructors)]
113+
Type resultType)
101114
{
102115
if (resultType == null)
103116
throw new ArgumentNullException ("resultType");
@@ -120,23 +133,43 @@ static IJavaObject CastClass (IJavaObject instance, Type resultType)
120133

121134
// typeof(Foo) -> FooInvoker
122135
// typeof(Foo<>) -> FooInvoker`1
123-
[UnconditionalSuppressMessage ("Trimming", "IL2026", Justification = "*Invoker types are preserved by the MarkJavaObjects linker step.")]
124-
[UnconditionalSuppressMessage ("Trimming", "IL2055", Justification = "*Invoker types are preserved by the MarkJavaObjects linker step.")]
136+
[return: DynamicallyAccessedMembers (Constructors)]
125137
internal static Type? GetInvokerType (Type type)
126138
{
139+
const string InvokerTypes = "*Invoker types are preserved by the MarkJavaObjects linker step.";
140+
141+
[UnconditionalSuppressMessage ("Trimming", "IL2026", Justification = InvokerTypes)]
142+
[UnconditionalSuppressMessage ("Trimming", "IL2055", Justification = InvokerTypes)]
143+
[UnconditionalSuppressMessage ("Trimming", "IL2073", Justification = InvokerTypes)]
144+
[return: DynamicallyAccessedMembers (Constructors)]
145+
static Type? AssemblyGetType (Assembly assembly, string typeName) =>
146+
assembly.GetType (typeName);
147+
148+
// FIXME: https://github.com/xamarin/xamarin-android/issues/8724
149+
// IL3050 disabled in source: if someone uses NativeAOT, they will get the warning.
150+
[UnconditionalSuppressMessage ("Trimming", "IL2055", Justification = InvokerTypes)]
151+
[UnconditionalSuppressMessage ("Trimming", "IL2068", Justification = InvokerTypes)]
152+
[return: DynamicallyAccessedMembers (Constructors)]
153+
static Type MakeGenericType (Type type, params Type [] typeArguments) =>
154+
#pragma warning disable IL3050
155+
type.MakeGenericType (typeArguments);
156+
#pragma warning restore IL3050
157+
127158
const string suffix = "Invoker";
159+
128160
Type[] arguments = type.GetGenericArguments ();
129161
if (arguments.Length == 0)
130-
return type.Assembly.GetType (type + suffix);
162+
return AssemblyGetType (type.Assembly, type + suffix);
131163
Type definition = type.GetGenericTypeDefinition ();
132164
int bt = definition.FullName!.IndexOf ("`", StringComparison.Ordinal);
133165
if (bt == -1)
134166
throw new NotSupportedException ("Generic type doesn't follow generic type naming convention! " + type.FullName);
135-
Type? suffixDefinition = definition.Assembly.GetType (
167+
Type? suffixDefinition = AssemblyGetType (
168+
definition.Assembly,
136169
definition.FullName.Substring (0, bt) + suffix + definition.FullName.Substring (bt));
137170
if (suffixDefinition == null)
138171
return null;
139-
return suffixDefinition.MakeGenericType (arguments);
172+
return MakeGenericType (suffixDefinition, arguments);
140173
}
141174
}
142175
}

0 commit comments

Comments
 (0)