Skip to content

Bump external/xamarin-android-tools and fix NRT warnings#11247

Draft
jonathanpeppers wants to merge 6 commits intomainfrom
jonathanpeppers/bump-xamarin-android-tools-nrt-fixes
Draft

Bump external/xamarin-android-tools and fix NRT warnings#11247
jonathanpeppers wants to merge 6 commits intomainfrom
jonathanpeppers/bump-xamarin-android-tools-nrt-fixes

Conversation

@jonathanpeppers
Copy link
Copy Markdown
Member

Bumps external/xamarin-android-tools from 2fd1240 to ed6aab1, which enables nullable reference types in BaseTasks.

Fixes all resulting CS8600/CS8602/CS8604 NRT warnings across 18 files without using ! (null-forgiving operator).

Key changes in xamarin-android-tools

NRT fix patterns used

  • Null-coalescing for params args: value ?? "" for nullable strings passed to params object[]
  • Null checks + throw: for GetRegisteredTaskObjectAssemblyLocal/UnregisterTaskObjectAssemblyLocal results that must exist
  • Null-conditional calls: Log?.LogDebugMessage(...) for nullable TaskLoggingHelper
  • Remove unnecessary ?.: e.g. min_sdk?.Value -> min_sdk.Value inside if (min_sdk != null) blocks
  • Nullable variable declarations: e.g. string? mono = ... for nullable return types

Supersedes #11243

Bump the submodule from 2fd1240 to ed6aab1 which enables
nullable reference types in BaseTasks. Fix all resulting
CS8600/CS8602/CS8604 warnings in callers without using the
null-forgiving operator.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings April 29, 2026 13:41
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the external/xamarin-android-tools dependency to a commit that enables nullable reference types (NRT) in BaseTasks, and then adjusts the dotnet/android codebase to address the resulting NRT warnings in build tasks/utilities.

Changes:

  • Bump external/xamarin-android-tools (enables NRT in BaseTasks) and update consumers accordingly.
  • Add null-handling patterns (null checks/throws, null-coalescing for logging args, null-conditional debug logging) across MSBuild tasks and utilities.
  • Tighten some internal build-pipeline assumptions by failing fast when required registered task objects are missing.

Reviewed changes

Copilot reviewed 19 out of 19 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
src/Xamarin.Android.Build.Tasks/Utilities/RtxtParser.cs Make debug logging tolerant of nullable logger under NRT.
src/Xamarin.Android.Build.Tasks/Utilities/FileResourceParser.cs Adjust debug logging calls for nullable Log under NRT.
src/Xamarin.Android.Build.Tasks/Tasks/RewriteMarshalMethods.cs Add null check for required registered NativeCodeGenState.
src/Xamarin.Android.Build.Tasks/Tasks/ResolveAndroidTooling.cs Coalesce nullable strings when used as message args for coded errors.
src/Xamarin.Android.Build.Tasks/Tasks/Legacy/ValidateJavaVersion.cs Coalesce nullable BuildTools version when used as message arg.
src/Xamarin.Android.Build.Tasks/Tasks/Legacy/ResolveAndroidTooling.cs Coalesce nullable version strings when used as warning args.
src/Xamarin.Android.Build.Tasks/Tasks/GetJavaPlatformJar.cs NRT-driven adjustments around manifest logging / message args.
src/Xamarin.Android.Build.Tasks/Tasks/GenerateTypeMappings.cs Add null check for required registered NativeCodeGenState.
src/Xamarin.Android.Build.Tasks/Tasks/GenerateMainAndroidManifest.cs Add null checks for required registered objects; avoid null output path on cleanup.
src/Xamarin.Android.Build.Tasks/Tasks/GenerateLayoutBindings.cs Make registered widget collection nullable and guard its use.
src/Xamarin.Android.Build.Tasks/Tasks/GenerateAdditionalProviderSources.cs Add null check for required registered NativeCodeGenStateCollection.
src/Xamarin.Android.Build.Tasks/Tasks/ConvertCustomView.cs Coalesce nullable resource directory metadata when logging coded diagnostics.
src/Xamarin.Android.Build.Tasks/Tasks/CalculateLayoutCodeBehind.cs Remove unnecessary null-conditional on non-null widgets.
src/Xamarin.Android.Build.Tasks/Tasks/BuildAppBundle.cs Change debug log formatting while addressing NRT warnings (but see review comment).
src/Xamarin.Android.Build.Tasks/Tasks/AndroidWarning.cs Coalesce nullable resource string / format args under NRT.
src/Xamarin.Android.Build.Tasks/Tasks/AndroidError.cs Coalesce nullable resource string / format args under NRT.
src/Xamarin.Android.Build.Tasks/Tasks/AndroidDotnetToolTask.cs Treat cached mono path as nullable under NRT.
src/Xamarin.Android.Build.Tasks/Tasks/Aapt2Compile.cs Ensure non-null enumerable passed to async processing under NRT.
Comments suppressed due to low confidence (2)

src/Xamarin.Android.Build.Tasks/Tasks/GenerateLayoutBindings.cs:213

  • After the widgets is null || widgets.Count == 0 guard, widgets is known to be non-null, but later the code still uses the null-forgiving operator (widgets!) when calling GenerateSource. Since this PR aims to fix NRT warnings without !, please refactor to avoid the null-forgiving operator here (e.g., by passing the non-null widgets variable directly after the guard).
			string collectionKey;
			if (!GetRequiredMetadata (item, CalculateLayoutCodeBehind.WidgetCollectionKeyMetadata, out collectionKey))
				return;

			ICollection<LayoutWidget>? widgets = BuildEngine4.GetRegisteredTaskObjectAssemblyLocal<ICollection<LayoutWidget>> (ProjectSpecificTaskObjectKey (collectionKey), RegisteredTaskObjectLifetime.Build);
			if (widgets is null || widgets.Count == 0) {
				string inputPaths = String.Join ("; ", resourceItems.Select (i => i.ItemSpec));
				LogCodedWarning ("XA4222", Properties.Resources.XA4222, inputPaths);
				return;
			}

src/Xamarin.Android.Build.Tasks/Utilities/FileResourceParser.cs:76

  • ResourceParser.Log is nullable, but this method now mixes Log?.LogDebugMessage(...) with later unconditional Log.LogDebugMessage(...) calls in the same method body. If Log is required for this parser, consider validating Log is non-null once at the start of Parse() (and then using Log. consistently) instead of sprinkling null-conditional calls (which can also leave CS8602 warnings on the remaining Log. usages).
		public IList<R> Parse (string resourceDirectory, IEnumerable<string> additionalResourceDirectories, IEnumerable<string> aarLibraries, Dictionary<string, string> resourceMap)
		{
			Log?.LogDebugMessage ($"Parsing Directory {resourceDirectory}");
			publicXml = LoadPublicXml ();
			var result = new List<R> ();
			Dictionary<string, ICollection<R>> resources = new Dictionary<string, ICollection<R>> ();
			foreach (var knownType in RtxtParser.knownTypes) {
				if (knownType == "styleable") {
					resources.Add (knownType, new List<R> ());
					continue;
				}
				resources.Add (knownType, new SortedSet<R> (new RComparer ()));
			}
			foreach (var dir in Directory.EnumerateDirectories (resourceDirectory, "*", SearchOption.TopDirectoryOnly)) {
				foreach (var file in Directory.EnumerateFiles (dir, "*.*", SearchOption.AllDirectories)) {
					ProcessResourceFile (file, resources);
				}
			}
			foreach (var dir in additionalResourceDirectories ?? []) {
				Log.LogDebugMessage ($"Processing Directory {dir}");
				if (Directory.Exists (dir)) {
					foreach (var file in Directory.EnumerateFiles (dir, "*.*", SearchOption.AllDirectories)) {
						ProcessResourceFile (file, resources);
					}
				} else {
					Log.LogDebugMessage ($"Skipping non-existent directory: {dir}");
				}

Comment thread src/Xamarin.Android.Build.Tasks/Tasks/GetJavaPlatformJar.cs
Comment thread src/Xamarin.Android.Build.Tasks/Tasks/AndroidWarning.cs
Comment thread src/Xamarin.Android.Build.Tasks/Tasks/AndroidError.cs
Comment thread src/Xamarin.Android.Build.Tasks/Tasks/BuildAppBundle.cs
@jonathanpeppers jonathanpeppers marked this pull request as draft April 29, 2026 14:11
jonathanpeppers and others added 5 commits April 29, 2026 09:18
Use `required` on ResourceParser.Log so it must be set via
object initializer, eliminating the need for Log?.

Pass log and map as parameters to RtxtParser.ProcessRtxtFile
instead of storing them in nullable fields, removing the
null-conditional calls and the runtime null check.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The `required` keyword needs CompilerFeatureRequiredAttribute
which is only available in net7.0+, not netstandard2.0. Use a
constructor parameter for ResourceParser.Log instead, and
chain it through FileResourceParser, JavaResourceParser, and
ManagedResourceParser.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Move Parser field initialization into the constructor that
takes TaskLoggingHelper, removing the old parameterless
constructor. Also remove Log! usages now that Log is
guaranteed non-null. Add missing using System in
RewriteMarshalMethods.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants