You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Context: dotnet/android#9630
Context: ec2813a
As dotnet/android#9630 required new declarations of
`DynamicallyAccessedMemberTypes.Interfaces`, we intestigated to see
*why* these were needed in Java.Interop.
There are two cases that involve `.Interfaces` within
`JniRuntime.JniValueManager.GetValueMarshaler(Type)`:
The first case is around attempts to special-case array marshaling
for builtin types:
var listIface = typeof (IList<>);
var listType =
(from iface in type.GetInterfaces ().Concat (new[]{type})
where (listIface).IsAssignableFrom (iface.IsGenericType ? iface.GetGenericTypeDefinition () : iface)
select iface)
.FirstOrDefault ();
If `IList<T>` is trimmed away (lol), then *we don't care*, as
everything else within `GetValueMarshaler(Type)` still works,
and if we can't get a value marshaler for `int[]` (which implements
`IList<T>`!), then so be it. Suppress this IL2070 message.
The second case is around looking for `[JniValueMarshaler]` on
implemented interface types, from ec2813a:
JniValueMarshalerAttribute? ifaceAttribute = null;
foreach (var iface in type.GetInterfaces ()) {
marshalerAttr = iface.GetCustomAttribute<JniValueMarshalerAttribute> ();
if (marshalerAttr != null) {
if (ifaceAttribute != null)
throw new NotSupportedException ($"There is more than one interface with custom marshaler for type {type}.");
ifaceAttribute = marshalerAttr;
}
}
if (ifaceAttribute != null)
return (JniValueMarshaler) Activator.CreateInstance (ifaceAttribute.MarshalerType)!;
It is to support the scenario
namespace Android.Runtime {
[JniValueMarshaler(typeof(IJavaObjectValueMarshaler))]
partial interface /* Android.RuntimIJavaObject {}
}
namespace Java.Lang {
partial class Object : Android.Runtime.IJavaObject {}
}
to "retrofit" `Java.Lang.Object` and `Java.Lang.Throwable` to use
`IJavaObjectValueMarshaler`.
There are three problems with this case:
1. It's not actually covered by unit tests! Removing the above
`foreach` loop doesn't break any unit tests.
2. While dotnet/android was updated for this scenario, it was only
as part of trying to use `jnimarshalmethod-gen` on
Xamarin.Android projects, which was never finished.
3. It doesn't "scale": the code throws a `NotSupportedException`
if a type implements more than one interface that has
`[JniValueMarshaler]`.
This isn't used, and *shouldn't* be relied upon. Excise it entirely.
With these changes we can remove
`DynamicallyAccessedMemberTypes.Interfaces`.
I also introduced `build-tools/trim-analyzers/trim-analyzers.props`
that will setup the appropriate trimmer MSBuild properties to make
trimmer warnings an error. This should keep us from accidentally
creating warnings. I only use this setting in projects that were
already using `$(EnableAotAnalyzer)`.
0 commit comments