Uh oh!
There was an error while loading. Please reload this page.
[Mono.Android] Fix build warnings in hand-written code - #12003
Conversation
Match the nullability of overridden base-class parameters (TypeConverter, SynchronizationContext, Java stream adapters, Color/AndroidBitmapInfo equality, AdapterView.RawAdapter) so overrides no longer widen non-nullable base parameters, guarding newly-nullable arguments where the body dereferences them.
JavaObject.ToString() overrides Java.Lang.Object.ToString() (non-null), so return a non-null string instead of string?.
Match the parameter nullability of the implemented interface members (IComparer, ISpliterator, ISetCookie, IX509TrustManager/ISSLSession, IXmlPullParser). Guard TrustManager callbacks with ArgumentNullException.ThrowIfNull and return null early from GetNamespace for a null prefix.
Add the 'new' keyword to members that intentionally hide an inherited virtual member (SparseArray<E>.Get/ValueAt, ArrayAdapter<T>.GetItem/Sort, JavaList.Equals(Java.Lang.Object)).
Add the 'new' keyword to members that intentionally hide an inherited member: generic collection specializations (JavaCollection/JavaList/JavaSet/JavaDictionary/ArrayAdapter/BaseAdapter), static helpers (FromJniHandle/ToLocalJniHandle/CreateFromResource), IXmlResourceParser members disambiguating IAttributeSet/IXmlPullParser, StringBuffer/StringBuilder.Append, AsyncTask.class_ref, and JavaProxyThrowable.InnerException.
The API-37 public API baseline was missing ~4570 members (generated bindings plus a few hand-written types), and the nullability fixes in earlier commits changed the annotations of several public members. Populate PublicAPI.Unshipped.txt via the RS0016 code fix and add *REMOVED* markers for the stale signatures (RS0017) so the PublicApiAnalyzer passes with RS0016/RS0017 enforced.
Guard CheckClientTrusted params (consistency with CheckServerTrusted); keep the clr_typemap_managed_to_java P/Invoke param non-nullable and guard the call site when Type.FullName is null; drop the redundant null-forgiving operator in AdapterView.RawAdapter getter; replace null-forgiving operators in ValueAnimator/AnimatorSet marshaling with explicit null checks that throw a clear exception.
main removed JavaPeerProxy's invokerType constructor parameter and InvokerType property and added Java.Interop.BaseExportAttribute; the rebased constructor-visibility change also exposes the JavaPeerProxy constructors as protected. Update PublicAPI.Unshipped.txt (API 37) accordingly so RS0016/RS0017 stay clean.
There was a problem hiding this comment.
Pull request overview
This PR reduces build warnings in src/Mono.Android by aligning nullability annotations in hand-written code with base members/interfaces, tightening up a few marshaling paths, and updating the API-37 public API baselines so the public API analyzer passes.
Changes:
- Updated a number of overrides/interface implementations to match expected nullable signatures and added targeted null checks where appropriate.
- Adjusted dynamic-code vs AOT code paths (notably typemap/collection conversion) and replaced/added specific suppressions so
IL3050can be removed from project-wideNoWarn. - Regenerated/cleaned PublicAPI baseline files (API-36.1/API-37) to keep RS0016/RS0017 enforced.
Show a summary per file
| File | Description |
|---|---|
| src/Mono.Android/Xamarin.Android.Net/ServerCertificateCustomValidator.cs | Align trust manager / SSL session method nullability with interfaces and add argument validation. |
| src/Mono.Android/Xamarin.Android.Net/AndroidMessageHandler.cs | Align helper method parameter nullability with HttpRequestException/WebException usage. |
| src/Mono.Android/System.Drawing/SizeFConverter.cs | Align TypeConverter override nullability and handle null CultureInfo. |
| src/Mono.Android/System.Drawing/SizeConverter.cs | Align TypeConverter override nullability and handle null CultureInfo. |
| src/Mono.Android/System.Drawing/RectangleConverter.cs | Align TypeConverter override nullability and handle null CultureInfo. |
| src/Mono.Android/System.Drawing/PointConverter.cs | Align TypeConverter override nullability. |
| src/Mono.Android/PublicAPI/API-37/PublicAPI.Shipped.txt | Remove duplicate baseline entries. |
| src/Mono.Android/PublicAPI/API-36.1/PublicAPI.Shipped.txt | Remove duplicate baseline entries. |
| src/Mono.Android/Org.Apache.Http.Impl.Cookie/BasicClientCookie.cs | Align cookie setter nullability with interface expectations. |
| src/Mono.Android/Mono.Android.csproj | Remove IL3050 from NoWarn now that code is suppressed/guarded more precisely. |
| src/Mono.Android/Microsoft.Android.Runtime/TrimmableTypeMapTypeManager.cs | Route array-type generation based on dynamic-code support vs pre-generated typemap proxies; add RequiresDynamicCode. |
| src/Mono.Android/Microsoft.Android.Runtime/ManagedTypeManager.cs | Add IL3050 suppression for reflection-based type manager base. |
| src/Mono.Android/Microsoft.Android.Runtime/JniRemappingLookup.cs | Suppress CS0649 for struct fields used as interop shapes. |
| src/Mono.Android/Microsoft.Android.Runtime/JavaMarshalRegisteredPeers.cs | Suppress CS0649 for interop struct fields. |
| src/Mono.Android/Java.Util/Spliterators.cs | Align ISpliterator-related nullability in TryAdvance. |
| src/Mono.Android/Java.Lang/StringBuilder.cs | Mark intentional member hiding with new. |
| src/Mono.Android/Java.Lang/StringBuffer.cs | Mark intentional member hiding with new. |
| src/Mono.Android/Java.Interop/TypeManager.cs | Improve nullability handling in typemap paths (e.g., pointer-to-string conversion, class-name lookup). |
| src/Mono.Android/Java.Interop/JavaPeerProxy.cs | Adjust proxy attribute ctor accessibility and validate ctor arguments. |
| src/Mono.Android/Java.Interop/JavaConvert.cs | Guard reflection-based generic collection conversion behind dynamic-code support and add RequiresDynamicCode. |
| src/Mono.Android/Android.Widget/BaseAdapter.cs | Mark intentional member hiding with new. |
| src/Mono.Android/Android.Widget/ArrayAdapter.cs | Mark intentional member hiding with new for members that shadow base APIs. |
| src/Mono.Android/Android.Widget/AdapterView.cs | Update RawAdapter nullability and remove null-forgiving in getter. |
| src/Mono.Android/Android.Util/SparseArray.cs | Mark intentional member hiding with new. |
| src/Mono.Android/Android.Runtime/XmlReaderPullParser.cs | Align nullability to IXmlPullParser expectations; add defensive null handling. |
| src/Mono.Android/Android.Runtime/XmlPullParserReader.cs | Mark intentional member hiding with new. |
| src/Mono.Android/Android.Runtime/OutputStreamAdapter.cs | Align override nullability and add argument validation. |
| src/Mono.Android/Android.Runtime/JNIEnv.cs | Refine dynamic-code/AOT array creation behavior and use targeted IL3050 suppression only when required. |
| src/Mono.Android/Android.Runtime/JavaSet.cs | Mark intentional member hiding with new. |
| src/Mono.Android/Android.Runtime/JavaProxyThrowable.cs | Mark intentional member hiding with new. |
| src/Mono.Android/Android.Runtime/JavaObject.cs | Ensure ToString() returns non-null to match Java expectations. |
| src/Mono.Android/Android.Runtime/JavaList.cs | Mark intentional member hiding with new. |
| src/Mono.Android/Android.Runtime/JavaDictionary.cs | Mark intentional member hiding with new. |
| src/Mono.Android/Android.Runtime/JavaCollection.cs | Mark intentional member hiding with new. |
| src/Mono.Android/Android.Runtime/InputStreamAdapter.cs | Align override nullability and add argument validation. |
| src/Mono.Android/Android.OS/AsyncTask.cs | Mark intentional member hiding with new. |
| src/Mono.Android/Android.Graphics/Color.cs | Align override nullability for marshaler APIs. |
| src/Mono.Android/Android.Graphics/AndroidBitmapInfo.cs | Align Equals(object) nullability. |
| src/Mono.Android/Android.Content.Res/IXmlResourceParser.cs | Disambiguate interface conflicts with new members. |
| src/Mono.Android/Android.Bluetooth/BluetoothDevice.cs | Add OS-platform obsoletion metadata for API-37. |
| src/Mono.Android/Android.App/SyncContext.cs | Align SynchronizationContext override nullability. |
| src/Mono.Android/Android.App/AlertDialog.cs | Switch to EventHelper helper to align event wiring nullability. |
| src/Mono.Android/Android.Animation/ValueAnimator.cs | Make delegate field nullable and add null checks for marshaling results. |
| src/Mono.Android/Android.Animation/AnimatorSet.cs | Make delegate field nullable and add null checks for marshaling results. |
Copilot's findings
Comments suppressed due to low confidence (1)
src/Mono.Android/Android.Graphics/Color.cs:451
- Avoid the null-forgiving operator when reflecting for the
Color(int)constructor. Even if it "should" exist, trimming/linking (or future refactors) can make this return null; an explicit check keeps the failure mode clear and avoids!.
public override Expression CreateParameterToManagedExpression (JniValueMarshalerContext context, ParameterExpression sourceValue, ParameterAttributes synchronize, Type? targetType)
{
var c = typeof (Color).GetConstructor (new[]{typeof (int)})!;
var v = Expression.Variable (typeof (Color), sourceValue.Name + "_val");
context.LocalVariables.Add (v);
context.CreationStatements.Add (Expression.Assign (v, Expression.New (c, sourceValue)));
- Files reviewed: 44/45 changed files
- Comments generated: 4
| protected override Java.Lang.Object? RawAdapter { | ||
| get { return JavaObjectExtensions.JavaCast<Java.Lang.Object>(JavaConvert.ToJavaObject (Adapter)); } | ||
| set { Adapter = JavaConvert.FromJavaObject<T>(value)!; } | ||
| } |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
simonrozsival
commented
Jul 7, 2026
@copilot fix this warning: |
…ore expected ILC warnings Co-authored-by: simonrozsival <374616+simonrozsival@users.noreply.github.com>
... Fixed in the latest commit. The class-level |
simonrozsival
commented
Jul 7, 2026
@copilot what's still left to do? |
One open reviewer thread remains: the
|
Use the AOT warning category for the ManagedTypeManager IL3050 suppression so NativeAOT analysis recognizes it. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Keep the ManagedTypeManager AOT IL3050 suppression needed for the NativeAOT build. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
simonrozsival
commented
Jul 7, 2026
/review |
✅ Android PR Reviewer completed successfully! |
There was a problem hiding this comment.
🤖 Automated review — PR #12003
Verdict: ✅ Clean, well-scoped change. This is a mechanical build-warnings cleanup by a maintainer; I found no bugs — only 3 minor 💡 suggestions posted inline (non-blocking).
What this PR does (independent read)
It removes IL3050 from <NoWarn> in Mono.Android.csproj and instead eliminates or precisely suppresses the underlying warnings in hand-written code:
- Replaces the old
IsCoreClrRuntime/IsNativeAotRuntimebranch logic inJNIEnv.ArrayCreateInstance,JavaConvert.GetJniHandleConverter, andTrimmableTypeMapTypeManager.GetArrayTypeswithRuntimeFeature.IsDynamicCodeSupportedas the primary guard (a BCL[FeatureGuard(typeof(RequiresDynamicCodeAttribute))], so[RequiresDynamicCode]calls inside those blocks no longer trip IL3050). - Adds targeted
[UnconditionalSuppressMessage]/[RequiresDynamicCode]where a suppression is genuinely required (e.g. theManagedTypeMappath). - Silences a batch of nullability (CS8764/CS8765/CS8767) and member-hiding (CS0108/CS0114) warnings via signature alignment and the
newkeyword. - Correspondingly removes the NativeAOT "expect 2 IL3050 warnings" special-case in
BuildTest2.BuildHasNoWarnings, which now asserts zero warnings for every runtime — a strengthened regression guard.
Verification notes
- Behavior-preserving restructures: I traced the three rewritten methods across CoreCLR-JIT (
IsDynamicCodeSupported == true), Mono (true), and NativeAOT (false→TrimmableTypeMapproxy path). Each new fail-fastthrow NotSupportedExceptionis only reachable in genuinely-unsupported configurations. ✔️ EventHelperrename inAlertDialog.csis correct —AndroidEventHelperis[Obsolete("Use EventHelper")], and this matches the established pattern (MediaController,ViewTreeObserver,AccountManager, and the generator'sInterfaceListenerEvent). ✔️GetClassNameFromInstance→string?(public API): every product caller uses it in string interpolation/concatenation (null-safe); the 3 test callers inJnienvArrayMarshaling.csassign tostring, but that file has no#nullable enableand the test csproj only setsWarningsAsErrors=IL2037, so no CS8600 is produced. No downstream break. ✔️- Stream adapters / converters /
new-hidden members: all mechanical alignments to base/interface signatures;ArgumentNullException.ThrowIfNullon the stream adapters matches Java NPE semantics. ✔️
CI
At review time the full Azure DevOps (dnceng-public) build — which actually validates the zero-warnings claim behind removing IL3050 from <NoWarn> — was still in progress with no failures observed (Java.Interop Tests on Windows/Mac already green; license/CLA green). Mergeability depends on those build stages completing green.
Inline suggestions (all 💡, non-blocking)
JavaConvert.csL109 —NotSupportedExceptionmessage says "array element type" for a generic-collection branch.JavaProxyThrowable.csL14 — awareness note on the now-explicitInnerExceptionshadow (behavior unchanged).PointConverter.csL67 — continuation-line indentation drifted out of alignment (recurs across theSystem.Drawingconverters).
Nice, tidy cleanup overall. 👍
Generated by Android PR Reviewer for #12003 · 367.8 AIC · ⌖ 23.2 AIC · ⊞ 6.8K
Comment /review to run again
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
The ManagedTypeManager AOT warning is now suppressed, so NativeAOT builds should be warning-free in these tests. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Uh oh!
There was an error while loading. Please reload this page.
Supersedes #11999 (that PR was from a fork; this one is rebased on latest
mainand pushed to an origin branch so it runs the full CI). #11999 will be closed.Summary
Reduces the C# build warnings in
src/Mono.Androidby fixing the warnings that originate in hand-written source, and completes the API-37 public API baseline so the public API analyzer passes.It intentionally does not remove every
NoWarnsuppression, nor theMono.Android.csprojentry in_AllowProjectWarnings(inDirectory.Build.props). The warnings that remain all originate in generated code and require changes to the code generators — see "Why suppressions remain" below.What is fixed (hand-written code)
System.DrawingTypeConvertersubclasses,SyncContext, Java stream adapters,Color/AndroidBitmapInfoequality,AdapterView.RawAdapter).JavaObject.ToString()returns non-null to matchJava.Lang.Object.ToString().IComparer,ISpliterator,ISetCookie,IX509TrustManager/ISSLSession,IXmlPullParser).newadded to members that intentionally hide an inherited member (generic collection specializations, static helpers,IXmlResourceParserdisambiguation,StringBuffer/StringBuilder.Append,AsyncTask.class_ref,JavaProxyThrowable.InnerException,SparseArray<E>,ArrayAdapter<T>,JavaList.Equals).Public API baseline (RS0016 / RS0017)
Some of the nullability fixes change the annotations of public members, and the API-37 baseline was missing a large number of generated binding members.
PublicAPI/API-37/PublicAPI.Unshipped.txtis regenerated (via theRS0016code fix, plus*REMOVED*markers for stale signatures) soRS0016/RS0017are satisfied and remain enforced (they are not inNoWarn).Why suppressions remain
The remaining warnings are all in generated code and cannot be fixed here without changing the generators:
mcw/*.cs(binding generator):CS0108,CS0114,CS0618,CS0809,CS8613,CS8764,CS8765,CS8766,CS8767.JNIEnv.g.cs(jnienv-gen,// Generated file; DO NOT EDIT!):RS0041(public members using oblivious reference types).These files are regenerated on every build, so the fix must happen in the generator. Until those follow-ups land, we keep the corresponding codes in
<NoWarn>and keep<_AllowProjectWarnings Condition=" '$(MSBuildProjectFile)' == 'Mono.Android.csproj' ">true</_AllowProjectWarnings>. Removing either now would turn hundreds of generated-code warnings into build errors underTreatWarningsAsErrors.Follow-ups
mcw/*.cs, then dropCS0108;CS0114;CS0618;CS0809;CS8613;CS8764;CS8765;CS8766;CS8767fromNoWarn.jnienv-gen- annotateJNIEnv.g.csoutput, then dropRS0041fromNoWarn.Once those land, the remaining
NoWarncodes and the_AllowProjectWarningsopt-in forMono.Android.csprojcan be removed.