Skip to content

Commit d471b4a

Browse files
authored
[Mono.Android] Add NRT annotations. (#4227)
Context: dotnet/java-interop@01d0684 Annotates all API levels of `Mono.Android.dll` with [C#8 Nullable Reference Type][0] (NRT) annotations, pulled directly from the Java `.jar` files. Additionally, our hand written code has been audited and updated to include NRT annotations. ~~ Notes ~~ There are 8 new warnings caused by this change of the form: Android.Runtime/JavaDictionary.cs(655,24): warning CS8714: The type 'K' cannot be used as type parameter 'TKey' in the generic type or method 'IDictionary<TKey, TValue>'. Nullability of type argument 'K' doesn't match 'notnull' constraint. This is due to the BCL being improperly annotated. The change has since been reverted, but it has not made it into various distribution packs: dotnet/runtime#793 There are a considerable number of warnings (~400) caused by mismatched annotations when members are overridden, such as: CS8610: Nullability of reference types in type of parameter 'baz' doesn't match overridden member. While it may be desirable to fix these, it is a non-trivial job that will be prioritized separately. In the mean time, this set of warnings has been disabled: <NoWarn>8609;8610;8614;8617;8613;8764;8765;8766;8767</NoWarn> Finally, when `$(AndroidGenerateJniMarshalMethods)`=True and `jnimarshalmethod-gen.exe` is executed, the resulting app was crashing because `MagicRegistrationMap.CallRegisterMethodByIndex()` had a parameter change from `int` to `int?`. Fix this by calling `Nullable<int>.GetValueOrDefault()` with the `switch`. `MonoDroidMarkStep.UpdateRegistrationSwitch()` now emits IL like: .method private hidebysig static bool CallRegisterMethodByIndex([Java.Interop]Java.Interop.JniNativeMethodRegistrationArguments arguments, [mscorlib]System.Nullable`1<int32> typeIdx) cil managed { // Code size 9285 (0x2445) .maxstack 2 .locals init ([mscorlib]System.Nullable`1<int32> V_0) IL_0000: ldarg.1 IL_0001: stloc.0 IL_0002: ldloca.s V_0 IL_0004: call instance !0 [mscorlib]System.Nullable`1<int32>::GetValueOrDefault() IL_0009: switch ( … Co-authored-by: Radek Doulik <[email protected]> [0]: https://docs.microsoft.com/en-us/dotnet/csharp/nullable-references
1 parent a574834 commit d471b4a

File tree

169 files changed

+1327
-1129
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

169 files changed

+1327
-1129
lines changed
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#### Mono.Android.dll Nullable Reference Type Annotations
2+
3+
`Mono.Android.dll` assemblies of all platform levels are now annotated with
4+
C#8's nullable reference types (NRT). Users who opt their applications into
5+
this feature with `<Nullable>enable</Nullable>` will receive warnings if their
6+
code does not properly account for possible `null` values.
7+
8+
General documentation for the NRT feature is available here:
9+
https://docs.microsoft.com/en-us/dotnet/csharp/nullable-references.
10+
11+
Note:
12+
The majority of `Mono.Android.dll` is automatically generated from the Android
13+
Java source, including these new annotations. As such, we will not be manually
14+
fixing places where the Android source code is not annotated correctly.
15+
16+
If there is an error regarding nullability for any of the Mono.Android APIs
17+
that Xamarin adds to the Android source (such as `JavaList` or `InputStreamAdapter`),
18+
please file a bug so we can properly annotate our additions.

external/Java.Interop

src/Mono.Android/Android.Accounts/AccountManager.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@ namespace Android.Accounts {
1010

1111
public partial class AccountManager {
1212

13-
public static AccountManager FromContext (Context context)
13+
public static AccountManager? FromContext (Context context)
1414
{
1515
return context.GetSystemService (Context.AccountService) as AccountManager;
1616
}
1717

18-
WeakReference weak_implementor_AccountsUpdated;
18+
WeakReference? weak_implementor_AccountsUpdated;
1919
public event EventHandler<AccountsUpdateEventArgs> AccountsUpdated {
2020
add {
2121
AndroidEventHelper.AddEventHandler<IOnAccountsUpdateListener, IOnAccountsUpdateListenerImplementor>(
@@ -33,7 +33,7 @@ public event EventHandler<AccountsUpdateEventArgs> AccountsUpdated {
3333
}
3434
}
3535

36-
void SetOnAccountsUpdatedListener (IOnAccountsUpdateListener value)
36+
void SetOnAccountsUpdatedListener (IOnAccountsUpdateListener? value)
3737
{
3838
AddOnAccountsUpdatedListener (value, null, false);
3939
}

src/Mono.Android/Android.Animation/Animator.cs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,14 @@ namespace Android.Animation {
88

99
partial class Animator {
1010

11-
WeakReference dispatcher;
11+
WeakReference? dispatcher;
1212
AnimatorEventDispatcher Dispatcher {
1313
get {
1414
if (dispatcher == null || !dispatcher.IsAlive) {
1515
dispatcher = new WeakReference (new AnimatorEventDispatcher ());
16-
AddListener ((AnimatorEventDispatcher) dispatcher.Target);
16+
AddListener ((AnimatorEventDispatcher) dispatcher.Target!);
1717
}
18-
return (AnimatorEventDispatcher) dispatcher.Target;
18+
return (AnimatorEventDispatcher) dispatcher.Target!;
1919
}
2020
}
2121

@@ -67,33 +67,33 @@ public AnimatorEventDispatcher ()
6767
JNIEnv.FinishCreateInstance (Handle, "()V");
6868
}
6969

70-
public EventHandler AnimationCancel;
71-
public EventHandler AnimationEnd;
72-
public EventHandler AnimationRepeat;
73-
public EventHandler AnimationStart;
70+
public EventHandler? AnimationCancel;
71+
public EventHandler? AnimationEnd;
72+
public EventHandler? AnimationRepeat;
73+
public EventHandler? AnimationStart;
7474

75-
public void OnAnimationCancel (Animator animation)
75+
public void OnAnimationCancel (Animator? animation)
7676
{
7777
var h = AnimationCancel;
7878
if (h != null)
7979
h (animation, EventArgs.Empty);
8080
}
8181

82-
public void OnAnimationEnd (Animator animation)
82+
public void OnAnimationEnd (Animator? animation)
8383
{
8484
var h = AnimationEnd;
8585
if (h != null)
8686
h (animation, EventArgs.Empty);
8787
}
8888

89-
public void OnAnimationRepeat (Animator animation)
89+
public void OnAnimationRepeat (Animator? animation)
9090
{
9191
var h = AnimationRepeat;
9292
if (h != null)
9393
h (animation, EventArgs.Empty);
9494
}
9595

96-
public void OnAnimationStart (Animator animation)
96+
public void OnAnimationStart (Animator? animation)
9797
{
9898
var h = AnimationStart;
9999
if (h != null)

src/Mono.Android/Android.Animation/AnimatorSet.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,19 @@ public override Animator SetDuration (long duration)
1717
if (base.GetType () == this.ThresholdType) {
1818
return Java.Lang.Object.GetObject<AnimatorSet> (
1919
JNIEnv.CallObjectMethod (base.Handle, id_setDuration_J, new JValue (duration)),
20-
JniHandleOwnership.TransferLocalRef);
20+
JniHandleOwnership.TransferLocalRef)!;
2121
} else {
2222
return Java.Lang.Object.GetObject<AnimatorSet> (
2323
JNIEnv.CallNonvirtualObjectMethod (
2424
base.Handle,
2525
this.ThresholdClass,
2626
JNIEnv.GetMethodID (ThresholdClass, "setDuration", "(J)Landroid/animation/Animator;"),
2727
new JValue (duration)),
28-
JniHandleOwnership.TransferLocalRef);
28+
JniHandleOwnership.TransferLocalRef)!;
2929
}
3030
}
3131

32-
private static Delegate cb_setDuration_J;
32+
private static Delegate? cb_setDuration_J;
3333

3434
private static Delegate GetSetDuration_JHandler ()
3535
{
@@ -40,7 +40,7 @@ private static Delegate GetSetDuration_JHandler ()
4040

4141
private static IntPtr n_SetDuration_J (IntPtr jnienv, IntPtr native__this, long duration)
4242
{
43-
AnimatorSet @object = Java.Lang.Object.GetObject<AnimatorSet> (native__this, JniHandleOwnership.DoNotTransfer);
43+
AnimatorSet @object = Java.Lang.Object.GetObject<AnimatorSet> (native__this, JniHandleOwnership.DoNotTransfer)!;
4444
return JNIEnv.ToJniHandle (@object.SetDuration (duration));
4545
}
4646
}

src/Mono.Android/Android.Animation/FloatArrayEvaluator.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ namespace Android.Animation
77
{
88
public partial class FloatArrayEvaluator
99
{
10-
Object ITypeEvaluator.Evaluate (float fraction, Object startValue, Object endValue)
10+
Object ITypeEvaluator.Evaluate (float fraction, Object? startValue, Object? endValue)
1111
{
12-
return new JavaArray<float> (JNIEnv.NewArray<float> (Evaluate (fraction, (float []) (JavaArray<float>) startValue, (float []) (JavaArray<float>) endValue)), JniHandleOwnership.TransferLocalRef);
12+
return new JavaArray<float> (JNIEnv.NewArray<float> (Evaluate (fraction, (float []?) (JavaArray<float>?) startValue, (float []?) (JavaArray<float>?) endValue)), JniHandleOwnership.TransferLocalRef);
1313
}
1414
}
1515
}

src/Mono.Android/Android.Animation/FloatEvaluator.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ namespace Android.Animation
77
{
88
public partial class FloatEvaluator
99
{
10-
public virtual Object Evaluate (float fraction, Object startValue, Object endValue)
10+
public virtual Object? Evaluate (float fraction, Object? startValue, Object? endValue)
1111
{
1212
return Evaluate (fraction, startValue.JavaCast<Number> (), endValue.JavaCast<Number> ());
1313
}

src/Mono.Android/Android.Animation/IntArrayEvaluator.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ namespace Android.Animation
77
{
88
public partial class IntArrayEvaluator
99
{
10-
Object ITypeEvaluator.Evaluate (float fraction, Object startValue, Object endValue)
10+
Object ITypeEvaluator.Evaluate (float fraction, Object? startValue, Object? endValue)
1111
{
12-
return new JavaArray<int> (JNIEnv.NewArray<int> (Evaluate (fraction, (int []) (JavaArray<int>) startValue, (int []) (JavaArray<int>) endValue)), JniHandleOwnership.TransferLocalRef);
12+
return new JavaArray<int> (JNIEnv.NewArray<int> (Evaluate (fraction, (int []?) (JavaArray<int>?) startValue, (int []?) (JavaArray<int>?) endValue)), JniHandleOwnership.TransferLocalRef);
1313
}
1414
}
1515
}

src/Mono.Android/Android.Animation/IntEvaluator.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ namespace Android.Animation
77
{
88
public partial class IntEvaluator
99
{
10-
public virtual Object Evaluate (float fraction, Object startValue, Object endValue)
10+
public virtual Object? Evaluate (float fraction, Object? startValue, Object? endValue)
1111
{
1212
return Evaluate (fraction, startValue.JavaCast<Integer> (), endValue.JavaCast<Integer> ());
1313
}

src/Mono.Android/Android.Animation/PointFEvaluator.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ namespace Android.Animation
77
{
88
public partial class PointFEvaluator
99
{
10-
Object ITypeEvaluator.Evaluate (float fraction, Object startValue, Object endValue)
10+
Object? ITypeEvaluator.Evaluate (float fraction, Object? startValue, Object? endValue)
1111
{
12-
return Evaluate (fraction, (PointF) startValue, (PointF) endValue);
12+
return Evaluate (fraction, (PointF?) startValue, (PointF?) endValue);
1313
}
1414
}
1515
}

0 commit comments

Comments
 (0)