Skip to content

Commit 4d47df8

Browse files
authored
[generator] Add missing nullable annotation (#1118)
When building API-33 `Mono.Android.dll`, there are 227 instances of the warning: warning CS8618: Non-nullable field 'sender' must contain a non-null value when exiting constructor. Consider declaring the field as nullable. This is caused by `*Implementor` constructors such as: internal sealed partial class IAnimatorUpdateListenerImplementor : global::Java.Lang.Object, IAnimatorUpdateListener { object sender; public unsafe IAnimatorUpdateListenerImplementor (object sender) : base (IntPtr.Zero, JniHandleOwnership.DoNotTransfer) { const string __id = "()V"; if (((global::Java.Lang.Object) this).Handle != IntPtr.Zero) return; var h = JniPeerMembers.InstanceMethods.StartCreateInstance (__id, ((object) this).GetType (), null); SetHandle (h.Handle, JniHandleOwnership.TransferLocalRef); JniPeerMembers.InstanceMethods.FinishCreateInstance (__id, this, null); this.sender = sender; } } We need to mark `sender` as nullable to fix the warning partial class IAnimatorUpdateListenerImplementor { object? sender; }
1 parent 46232f1 commit 4d47df8

File tree

4 files changed

+215
-4
lines changed

4 files changed

+215
-4
lines changed

tests/generator-Tests/Unit-Tests/CodeGeneratorExpectedResults/JavaInterop1/WriteDuplicateInterfaceEventArgs.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ public partial class AnimationEndEventArgs : global::System.EventArgs {
4949

5050
internal sealed partial class AnimatorListenerImplementor : global::Java.Lang.Object, AnimatorListener {
5151

52-
object sender;
52+
object? sender;
5353

5454
public unsafe AnimatorListenerImplementor (object sender) : base (IntPtr.Zero, JniHandleOwnership.DoNotTransfer)
5555
{
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,208 @@
1+
// Metadata.xml XPath interface reference: path="/api/package[@name='java.code']/interface[@name='AnimatorListener']"
2+
[Register ("java/code/AnimatorListener", "", "java.code.AnimatorListenerInvoker")]
3+
public partial interface AnimatorListener : IJavaObject, IJavaPeerable {
4+
// Metadata.xml XPath method reference: path="/api/package[@name='java.code']/interface[@name='AnimatorListener']/method[@name='OnAnimationEnd' and count(parameter)=1 and parameter[1][@type='int']]"
5+
[Register ("OnAnimationEnd", "(I)Z", "GetOnAnimationEnd_IHandler:java.code.AnimatorListenerInvoker, ")]
6+
bool OnAnimationEnd (int param1);
7+
8+
// Metadata.xml XPath method reference: path="/api/package[@name='java.code']/interface[@name='AnimatorListener']/method[@name='OnAnimationEnd' and count(parameter)=2 and parameter[1][@type='int'] and parameter[2][@type='int']]"
9+
[Register ("OnAnimationEnd", "(II)Z", "GetOnAnimationEnd_IIHandler:java.code.AnimatorListenerInvoker, ")]
10+
bool OnAnimationEnd (int param1, int param2);
11+
12+
}
13+
14+
[global::Android.Runtime.Register ("java/code/AnimatorListener", DoNotGenerateAcw=true)]
15+
internal partial class AnimatorListenerInvoker : global::Java.Lang.Object, AnimatorListener {
16+
static readonly JniPeerMembers _members = new XAPeerMembers ("java/code/AnimatorListener", typeof (AnimatorListenerInvoker));
17+
18+
static IntPtr java_class_ref {
19+
get { return _members.JniPeerType.PeerReference.Handle; }
20+
}
21+
22+
[global::System.Diagnostics.DebuggerBrowsable (global::System.Diagnostics.DebuggerBrowsableState.Never)]
23+
[global::System.ComponentModel.EditorBrowsable (global::System.ComponentModel.EditorBrowsableState.Never)]
24+
public override global::Java.Interop.JniPeerMembers JniPeerMembers {
25+
get { return _members; }
26+
}
27+
28+
[global::System.Diagnostics.DebuggerBrowsable (global::System.Diagnostics.DebuggerBrowsableState.Never)]
29+
[global::System.ComponentModel.EditorBrowsable (global::System.ComponentModel.EditorBrowsableState.Never)]
30+
protected override IntPtr ThresholdClass {
31+
get { return class_ref; }
32+
}
33+
34+
[global::System.Diagnostics.DebuggerBrowsable (global::System.Diagnostics.DebuggerBrowsableState.Never)]
35+
[global::System.ComponentModel.EditorBrowsable (global::System.ComponentModel.EditorBrowsableState.Never)]
36+
protected override global::System.Type ThresholdType {
37+
get { return _members.ManagedPeerType; }
38+
}
39+
40+
IntPtr class_ref;
41+
42+
public static AnimatorListener GetObject (IntPtr handle, JniHandleOwnership transfer)
43+
{
44+
return global::Java.Lang.Object.GetObject<AnimatorListener> (handle, transfer);
45+
}
46+
47+
static IntPtr Validate (IntPtr handle)
48+
{
49+
if (!JNIEnv.IsInstanceOf (handle, java_class_ref))
50+
throw new InvalidCastException ($"Unable to convert instance of type '{JNIEnv.GetClassNameFromInstance (handle)}' to type 'java.code.AnimatorListener'.");
51+
return handle;
52+
}
53+
54+
protected override void Dispose (bool disposing)
55+
{
56+
if (this.class_ref != IntPtr.Zero)
57+
JNIEnv.DeleteGlobalRef (this.class_ref);
58+
this.class_ref = IntPtr.Zero;
59+
base.Dispose (disposing);
60+
}
61+
62+
public AnimatorListenerInvoker (IntPtr handle, JniHandleOwnership transfer) : base (Validate (handle), transfer)
63+
{
64+
IntPtr local_ref = JNIEnv.GetObjectClass (((global::Java.Lang.Object) this).Handle);
65+
this.class_ref = JNIEnv.NewGlobalRef (local_ref);
66+
JNIEnv.DeleteLocalRef (local_ref);
67+
}
68+
69+
static Delegate cb_OnAnimationEnd_I;
70+
#pragma warning disable 0169
71+
static Delegate GetOnAnimationEnd_IHandler ()
72+
{
73+
if (cb_OnAnimationEnd_I == null)
74+
cb_OnAnimationEnd_I = JNINativeWrapper.CreateDelegate (new _JniMarshal_PPI_Z (n_OnAnimationEnd_I));
75+
return cb_OnAnimationEnd_I;
76+
}
77+
78+
static bool n_OnAnimationEnd_I (IntPtr jnienv, IntPtr native__this, int param1)
79+
{
80+
var __this = global::Java.Lang.Object.GetObject<java.code.AnimatorListener> (jnienv, native__this, JniHandleOwnership.DoNotTransfer);
81+
return __this.OnAnimationEnd (param1);
82+
}
83+
#pragma warning restore 0169
84+
85+
IntPtr id_OnAnimationEnd_I;
86+
public unsafe bool OnAnimationEnd (int param1)
87+
{
88+
if (id_OnAnimationEnd_I == IntPtr.Zero)
89+
id_OnAnimationEnd_I = JNIEnv.GetMethodID (class_ref, "OnAnimationEnd", "(I)Z");
90+
JValue* __args = stackalloc JValue [1];
91+
__args [0] = new JValue (param1);
92+
return JNIEnv.CallBooleanMethod (((global::Java.Lang.Object) this).Handle, id_OnAnimationEnd_I, __args);
93+
}
94+
95+
static Delegate cb_OnAnimationEnd_II;
96+
#pragma warning disable 0169
97+
static Delegate GetOnAnimationEnd_IIHandler ()
98+
{
99+
if (cb_OnAnimationEnd_II == null)
100+
cb_OnAnimationEnd_II = JNINativeWrapper.CreateDelegate (new _JniMarshal_PPII_Z (n_OnAnimationEnd_II));
101+
return cb_OnAnimationEnd_II;
102+
}
103+
104+
static bool n_OnAnimationEnd_II (IntPtr jnienv, IntPtr native__this, int param1, int param2)
105+
{
106+
var __this = global::Java.Lang.Object.GetObject<java.code.AnimatorListener> (jnienv, native__this, JniHandleOwnership.DoNotTransfer);
107+
return __this.OnAnimationEnd (param1, param2);
108+
}
109+
#pragma warning restore 0169
110+
111+
IntPtr id_OnAnimationEnd_II;
112+
public unsafe bool OnAnimationEnd (int param1, int param2)
113+
{
114+
if (id_OnAnimationEnd_II == IntPtr.Zero)
115+
id_OnAnimationEnd_II = JNIEnv.GetMethodID (class_ref, "OnAnimationEnd", "(II)Z");
116+
JValue* __args = stackalloc JValue [2];
117+
__args [0] = new JValue (param1);
118+
__args [1] = new JValue (param2);
119+
return JNIEnv.CallBooleanMethod (((global::Java.Lang.Object) this).Handle, id_OnAnimationEnd_II, __args);
120+
}
121+
122+
}
123+
124+
// event args for java.code.AnimatorListener.OnAnimationEnd
125+
public partial class AnimationEndEventArgs : global::System.EventArgs {
126+
bool handled;
127+
128+
public bool Handled {
129+
get { return handled; }
130+
set { handled = value; }
131+
}
132+
133+
public AnimationEndEventArgs (bool handled, int param1)
134+
{
135+
this.handled = handled;
136+
this.param1 = param1;
137+
}
138+
139+
int param1;
140+
141+
public int Param1 {
142+
get { return param1; }
143+
}
144+
145+
public AnimationEndEventArgs (bool handled, int param1, int param2)
146+
{
147+
this.handled = handled;
148+
this.param1 = param1;
149+
this.param2 = param2;
150+
}
151+
152+
int param2;
153+
154+
public int Param2 {
155+
get { return param2; }
156+
}
157+
158+
}
159+
160+
internal sealed partial class AnimatorListenerImplementor : global::Java.Lang.Object, AnimatorListener {
161+
162+
object sender;
163+
164+
public unsafe AnimatorListenerImplementor (object sender) : base (IntPtr.Zero, JniHandleOwnership.DoNotTransfer)
165+
{
166+
const string __id = "()V";
167+
if (((global::Java.Lang.Object) this).Handle != IntPtr.Zero)
168+
return;
169+
var h = JniPeerMembers.InstanceMethods.StartCreateInstance (__id, ((object) this).GetType (), null);
170+
SetHandle (h.Handle, JniHandleOwnership.TransferLocalRef);
171+
JniPeerMembers.InstanceMethods.FinishCreateInstance (__id, this, null);
172+
this.sender = sender;
173+
}
174+
175+
#pragma warning disable 0649
176+
public EventHandler<AnimationEndEventArgs> OnAnimationEndHandler;
177+
#pragma warning restore 0649
178+
179+
public bool OnAnimationEnd (int param1)
180+
{
181+
var __h = OnAnimationEndHandler;
182+
if (__h == null)
183+
return false;
184+
var __e = new AnimationEndEventArgs (true, param1);
185+
__h (sender, __e);
186+
return __e.Handled;
187+
}
188+
189+
#pragma warning disable 0649
190+
public EventHandler<AnimationEndEventArgs> OnAnimationEndHandler;
191+
#pragma warning restore 0649
192+
193+
public bool OnAnimationEnd (int param1, int param2)
194+
{
195+
var __h = OnAnimationEndHandler;
196+
if (__h == null)
197+
return false;
198+
var __e = new AnimationEndEventArgs (true, param1, param2);
199+
__h (sender, __e);
200+
return __e.Handled;
201+
}
202+
203+
internal static bool __IsEmpty (AnimatorListenerImplementor value)
204+
{
205+
return value.OnAnimationEndHandler == null && value.OnAnimationEndHandler == null;
206+
}
207+
208+
}

tests/generator-Tests/Unit-Tests/CodeGeneratorTests.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -421,7 +421,7 @@ public void WriteDuplicateInterfaceEventArgs ()
421421
generator.WriteType (iface, string.Empty, new GenerationInfo ("", "", "MyAssembly"));
422422
generator.Context.ContextTypes.Pop ();
423423

424-
AssertOriginalExpected (nameof (WriteDuplicateInterfaceEventArgs), writer.ToString ());
424+
AssertTargetedExpected (nameof (WriteDuplicateInterfaceEventArgs), writer.ToString ());
425425
}
426426

427427
[Test]

tools/generator/SourceWriters/InterfaceEventHandlerImplClass.cs

+5-2
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,11 @@ public InterfaceEventHandlerImplClass (InterfaceGen iface, CodeGenerationOptions
2222
IsSealed = true;
2323
IsPartial = true;
2424

25-
if (iface.NeedsSender)
26-
Fields.Add (new FieldWriter { Name = "sender", Type = TypeReferenceWriter.Object });
25+
if (iface.NeedsSender) {
26+
var type = TypeReferenceWriter.Object;
27+
type.Nullable = opt.SupportNullableReferenceTypes;
28+
Fields.Add (new FieldWriter { Name = "sender", Type = type });
29+
}
2730

2831
AddConstructor (iface);
2932
AddMethods (iface, opt);

0 commit comments

Comments
 (0)