From bf44afdf888f57a35a9a624842119c908924823d Mon Sep 17 00:00:00 2001 From: Dean Ellis Date: Fri, 24 Nov 2023 15:14:23 +0000 Subject: [PATCH 1/7] [LayoutBindings] LayoutBindings: 'PreserveAttribute' is obsolete warnings Fixes #7480 * Remove the use of `PreserveAttribute` as we no longer support Xamarin Classic in main. * Add #pragma and code comments to fix certain CS* warnings which are emitted by the C# compiler. * Ignore a bunch of other warnings in the unit test. --- ...GenerateLayoutBindings.BindingGenerator.cs | 17 +++---- ...teLayoutBindings.CSharpBindingGenerator.cs | 46 +++++++++++++------ ...nerateResourceDesignerIntermediateClass.cs | 4 ++ .../CodeBehindTests.cs | 4 +- .../CodeBehindBuildTests.NET.csproj | 2 +- .../BuildTests/Properties/AndroidManifest.xml | 1 - 6 files changed, 48 insertions(+), 26 deletions(-) diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/GenerateLayoutBindings.BindingGenerator.cs b/src/Xamarin.Android.Build.Tasks/Tasks/GenerateLayoutBindings.BindingGenerator.cs index b404d91156e..a31cecb1c08 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/GenerateLayoutBindings.BindingGenerator.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/GenerateLayoutBindings.BindingGenerator.cs @@ -30,8 +30,6 @@ public sealed class State // generating code for the partial Activity class public string BindingClassName { get; } - public bool LinkerPreserveConstructors { get; set; } - public List ExtraImportNamespaces { get; } = new List (); public string AndroidFragmentType { get; } @@ -155,20 +153,18 @@ protected virtual void WriteOnSetContentViewPartials (State state) WritePartialClassOnSetContentViewPartial_Int (state); } - public State BeginBindingFile (StreamWriter writer, string layoutResourceId, string classNamespace, string className, string androidFragmentType, bool linkerPreserveConstructors = true) + public State BeginBindingFile (StreamWriter writer, string layoutResourceId, string classNamespace, string className, string androidFragmentType) { - var state = new State (writer, className, !String.IsNullOrWhiteSpace (classNamespace), androidFragmentType) { - LinkerPreserveConstructors = linkerPreserveConstructors - }; + var state = new State (writer, className, !String.IsNullOrWhiteSpace (classNamespace), androidFragmentType); BeginBindingFile (state, layoutResourceId, classNamespace, className); - WriteBindingConstructors (state, className, state.LinkerPreserveConstructors); + WriteBindingConstructors (state, className); return state; } protected abstract void BeginBindingFile (State state, string layoutResourceId, string classNamespace, string className); public abstract void EndBindingFile (State state); - protected abstract void WriteBindingConstructors (State state, string className, bool linkerPreserve); + protected abstract void WriteBindingConstructors (State state, string className); protected abstract void WriteBindingViewProperty (State state, LayoutWidget widget, string resourceNamespace); protected abstract void WriteBindingFragmentProperty (State state, LayoutWidget widget, string resourceNamespace); protected abstract void WriteBindingMixedProperty (State state, LayoutWidget widget, string resourceNamespace); @@ -287,10 +283,11 @@ protected void WriteBindingPropertyBackingField (State state, LayoutWidget widge WriteResetLocation (state); } - public void WriteComment (State state, string text) + public void WriteComment (State state, params string [] text) { EnsureArgument (state, nameof (state)); - WriteLineIndent (state, $"{LineCommentString}{text}"); + foreach (string line in text) + WriteLineIndent (state, $"{LineCommentString}{line}"); } public void WriteComment (State state, ICollection lines) diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/GenerateLayoutBindings.CSharpBindingGenerator.cs b/src/Xamarin.Android.Build.Tasks/Tasks/GenerateLayoutBindings.CSharpBindingGenerator.cs index bc2b9ff6db4..a8d492852bd 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/GenerateLayoutBindings.CSharpBindingGenerator.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/GenerateLayoutBindings.CSharpBindingGenerator.cs @@ -157,8 +157,35 @@ void WriteClassClose (State state) WriteLineIndent (state, "}"); } + void WriteDisableWarnings (State state) + { + state.WriteLine ("#pragma warning disable CS0618"); + state.WriteLine ("#pragma warning disable CS8981"); + state.WriteLine ("#pragma warning disable CS1591"); + } + + void WriteEnableWarnings (State state) + { + state.WriteLine ("#pragma warning restore CS1591"); + state.WriteLine ("#pragma warning restore CS8981"); + state.WriteLine ("#pragma warning restore CS0618"); + } + + void WriteAutoGeneratedComment (State state) + { + state.WriteLine (@"//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------"); + } + void WriteFilePreamble (State state, string classNamespace) { + WriteAutoGeneratedComment (state); WriteUsings (state); state.WriteLine (); WriteNamespaceOpen (state, classNamespace); @@ -172,6 +199,7 @@ void WriteNamespaceOpen (State state, string classNamespace) state.WriteLine ($"namespace {classNamespace}"); state.WriteLine ("{"); state.IncreaseIndent (); + WriteDisableWarnings (state); } void WriteNamespaceClose (State state) @@ -179,6 +207,7 @@ void WriteNamespaceClose (State state) if (!state.IsInNamespace) return; + WriteEnableWarnings (state); state.DecreaseIndent (); state.WriteLine ("}"); } @@ -200,15 +229,14 @@ void WriteUsing (State state, string ns) state.WriteLine ($"using global::{ns};"); } - protected override void WriteBindingConstructors (State state, string className, bool linkerPreserve) + protected override void WriteBindingConstructors (State state, string className) { - WriteConstructor (state, className, "Android.App.Activity", linkerPreserve); - WriteConstructor (state, className, "Android.Views.View", linkerPreserve); + WriteConstructor (state, className, "Android.App.Activity"); + WriteConstructor (state, className, "Android.Views.View"); } - void WriteConstructor (State state, string className, string clientType, bool linkerPreserve) + void WriteConstructor (State state, string className, string clientType) { - WritePreserveAtribute (state, linkerPreserve); WriteLineIndent (state, $"public {className} ("); state.IncreaseIndent (); WriteLineIndent (state, $"global::{clientType} client,"); @@ -221,14 +249,6 @@ void WriteConstructor (State state, string className, string clientType, bool li state.WriteLine (); } - void WritePreserveAtribute (State state, bool linkerPreserve) - { - if (!linkerPreserve) - return; - - WriteLineIndent (state, $"[global::Android.Runtime.PreserveAttribute (Conditional=true)]"); - } - public override void EndBindingFile (State state) { EnsureArgument (state, nameof (state)); diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/GenerateResourceDesignerIntermediateClass.cs b/src/Xamarin.Android.Build.Tasks/Tasks/GenerateResourceDesignerIntermediateClass.cs index b6d89a6aaf6..22f9d4cf338 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/GenerateResourceDesignerIntermediateClass.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/GenerateResourceDesignerIntermediateClass.cs @@ -24,6 +24,10 @@ public class GenerateResourceDesignerIntermediateClass : AndroidTask namespace %NAMESPACE% { #pragma warning disable IDE0002 + /// + /// Android Resource Designer class. + /// Exposes the Android Resource designer assembly into the project Namespace. + /// public partial class Resource : %BASECLASS% { } #pragma warning restore IDE0002 diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/CodeBehindTests.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/CodeBehindTests.cs index b79a61409d8..72961260d27 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/CodeBehindTests.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/CodeBehindTests.cs @@ -339,6 +339,7 @@ void SuccessfulBuild_AndroidX (TestProjectInfo testInfo, bool many, bool dtb, Lo CopyLogs (testInfo, true); Assert.That (success, Is.True, "Build should have succeeded"); + Assert.IsTrue (StringAssertEx.ContainsText (builder.LastBuildOutput, " 0 Warning(s)"), $"{builder.BuildLogFile} should have no MSBuild warnings."); CopyGeneratedFiles (testInfo); @@ -508,7 +509,8 @@ string GetBuildTarget (bool isDTB) string[] GetBuildProperties (LocalBuilder builder, bool manyBuild, bool dtbBuild, bool referenceAndroidX, params string[] extraConstants) { var ret = new List { - "AndroidGenerateLayoutBindings=true" + "AndroidGenerateLayoutBindings=true", + "\"NoWarn=CS0414;CA1416;CA1422;CS1591;XA1005;XA4225\"" }; if (manyBuild) ret.Add ("ForceParallelBuild=true"); diff --git a/tests/CodeBehind/BuildTests/CodeBehindBuildTests.NET.csproj b/tests/CodeBehind/BuildTests/CodeBehindBuildTests.NET.csproj index 841b92a40eb..2175ae82a5d 100644 --- a/tests/CodeBehind/BuildTests/CodeBehindBuildTests.NET.csproj +++ b/tests/CodeBehind/BuildTests/CodeBehindBuildTests.NET.csproj @@ -64,6 +64,6 @@ - + diff --git a/tests/CodeBehind/BuildTests/Properties/AndroidManifest.xml b/tests/CodeBehind/BuildTests/Properties/AndroidManifest.xml index a0230c27bfe..72a51695329 100644 --- a/tests/CodeBehind/BuildTests/Properties/AndroidManifest.xml +++ b/tests/CodeBehind/BuildTests/Properties/AndroidManifest.xml @@ -1,6 +1,5 @@  - From 3dc5ca76e0f1e6fe8ad355a9c48f7cecc7264503 Mon Sep 17 00:00:00 2001 From: Dean Ellis Date: Thu, 30 Nov 2023 18:03:15 +0000 Subject: [PATCH 2/7] Remove the disabling of CS0618 --- .../Tasks/GenerateLayoutBindings.CSharpBindingGenerator.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/GenerateLayoutBindings.CSharpBindingGenerator.cs b/src/Xamarin.Android.Build.Tasks/Tasks/GenerateLayoutBindings.CSharpBindingGenerator.cs index a8d492852bd..92372d223e7 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/GenerateLayoutBindings.CSharpBindingGenerator.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/GenerateLayoutBindings.CSharpBindingGenerator.cs @@ -159,7 +159,6 @@ void WriteClassClose (State state) void WriteDisableWarnings (State state) { - state.WriteLine ("#pragma warning disable CS0618"); state.WriteLine ("#pragma warning disable CS8981"); state.WriteLine ("#pragma warning disable CS1591"); } @@ -168,7 +167,6 @@ void WriteEnableWarnings (State state) { state.WriteLine ("#pragma warning restore CS1591"); state.WriteLine ("#pragma warning restore CS8981"); - state.WriteLine ("#pragma warning restore CS0618"); } void WriteAutoGeneratedComment (State state) From 04103bcd6e9b4278865b63fb37650a349a8b21e3 Mon Sep 17 00:00:00 2001 From: Dean Ellis Date: Mon, 4 Mar 2024 12:48:11 +0000 Subject: [PATCH 3/7] Fix some tests --- .../Resources/LayoutBinding.cs | 2 +- .../Xamarin.Android.Build.Tests/CodeBehindTests.cs | 6 +++--- tests/CodeBehind/BuildTests/MainMergeActivity.cs | 2 ++ .../CommonSampleLibrary.NET.csproj | 6 ++++++ .../CommonSampleLibrary/Logger/LogFragment.cs | 12 ++++++++++-- 5 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/Xamarin.Android.Build.Tasks/Resources/LayoutBinding.cs b/src/Xamarin.Android.Build.Tasks/Resources/LayoutBinding.cs index 86a260258f2..985a5cba74f 100644 --- a/src/Xamarin.Android.Build.Tasks/Resources/LayoutBinding.cs +++ b/src/Xamarin.Android.Build.Tasks/Resources/LayoutBinding.cs @@ -73,7 +73,7 @@ T __FindFragment (int resourceId, Func finder, ref T cachedField cachedField = ret; return ret; } -#if __ANDROID_11__ +#if __ANDROID_11__ && !__ANDROID_28__ protected T FindFragment (int resourceId, global::Android.App.Fragment __ignoreMe, ref T cachedField) where T: global::Android.App.Fragment { return __FindFragment (resourceId, (activity) => activity.FragmentManager.FindFragmentById (resourceId), ref cachedField); diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/CodeBehindTests.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/CodeBehindTests.cs index 72961260d27..84cb508fd06 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/CodeBehindTests.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/CodeBehindTests.cs @@ -270,8 +270,8 @@ static CodeBehindTests () $"{ProjectName}.dll", "CommonSampleLibrary.dll", $"{PackageName}-Signed.apk", - $"{PackageName}.aab", - $"{PackageName}-Signed.aab", + //$"{PackageName}.aab", + //$"{PackageName}-Signed.aab", }; } @@ -510,7 +510,7 @@ string[] GetBuildProperties (LocalBuilder builder, bool manyBuild, bool dtbBuild { var ret = new List { "AndroidGenerateLayoutBindings=true", - "\"NoWarn=CS0414;CA1416;CA1422;CS1591;XA1005;XA4225\"" + "\"NoWarn=CS0414;CA1416;CS1591;XA1005;XA4225\"" //CA1422 }; if (manyBuild) ret.Add ("ForceParallelBuild=true"); diff --git a/tests/CodeBehind/BuildTests/MainMergeActivity.cs b/tests/CodeBehind/BuildTests/MainMergeActivity.cs index ec57f9540c8..d5b8600ed75 100644 --- a/tests/CodeBehind/BuildTests/MainMergeActivity.cs +++ b/tests/CodeBehind/BuildTests/MainMergeActivity.cs @@ -24,6 +24,8 @@ protected override void OnCreate (Bundle savedInstanceState) #if NOT_CONFLICTING_FRAGMENT CommonSampleLibrary.LogFragment log2 = secondary_log_fragment; +#elif __HAVE_ANDROIDX__ + global::AndroidX.Fragment.App.Fragment log2 = secondary_log_fragment; #else global::Android.App.Fragment log2 = secondary_log_fragment; #endif diff --git a/tests/CodeBehind/CommonSampleLibrary/CommonSampleLibrary.NET.csproj b/tests/CodeBehind/CommonSampleLibrary/CommonSampleLibrary.NET.csproj index 6b1daa622d0..3765f0d1a57 100644 --- a/tests/CodeBehind/CommonSampleLibrary/CommonSampleLibrary.NET.csproj +++ b/tests/CodeBehind/CommonSampleLibrary/CommonSampleLibrary.NET.csproj @@ -5,4 +5,10 @@ CommonSampleLibrary false + + $(DefineConstants);$(ExtraConstants) + + + + diff --git a/tests/CodeBehind/CommonSampleLibrary/Logger/LogFragment.cs b/tests/CodeBehind/CommonSampleLibrary/Logger/LogFragment.cs index eec0fe59ae9..b6b29ff06fb 100644 --- a/tests/CodeBehind/CommonSampleLibrary/Logger/LogFragment.cs +++ b/tests/CodeBehind/CommonSampleLibrary/Logger/LogFragment.cs @@ -19,14 +19,21 @@ using Android.Views; using Android.Widget; using Android.Graphics; +using Android.Util; namespace CommonSampleLibrary { + #pragma warning disable CA1422 /** * Simple fraggment which contains a LogView and uses is to output log data it receives * through the LogNode interface. */ - public class LogFragment : Fragment + public class LogFragment : +#if __HAVE_ANDROIDX__ + AndroidX.Fragment.App.Fragment +#else + Fragment +#endif { LogView mLogView; ScrollView mScrollView; @@ -60,7 +67,7 @@ public View InflateViews () mLogView.Gravity = GravityFlags.Bottom; mLogView.SetTextAppearance (Activity, Android.Resource.Style.TextAppearanceMedium); - + mScrollView.AddView (mLogView); return mScrollView; } @@ -77,5 +84,6 @@ public LogView LogView { get { return mLogView; } } } + #pragma warning restore CA1422 } From f216115d2612a494b33892072fbbd02ca3b35459 Mon Sep 17 00:00:00 2001 From: Dean Ellis Date: Mon, 4 Mar 2024 13:22:57 +0000 Subject: [PATCH 4/7] Fix up some more --- src/Xamarin.Android.Build.Tasks/Resources/LayoutBinding.cs | 4 +++- .../Tests/Xamarin.Android.Build.Tests/CodeBehindTests.cs | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Xamarin.Android.Build.Tasks/Resources/LayoutBinding.cs b/src/Xamarin.Android.Build.Tasks/Resources/LayoutBinding.cs index 985a5cba74f..22db3443783 100644 --- a/src/Xamarin.Android.Build.Tasks/Resources/LayoutBinding.cs +++ b/src/Xamarin.Android.Build.Tasks/Resources/LayoutBinding.cs @@ -73,11 +73,13 @@ T __FindFragment (int resourceId, Func finder, ref T cachedField cachedField = ret; return ret; } -#if __ANDROID_11__ && !__ANDROID_28__ +#if __ANDROID_11__ +#pragma warning disable CA1422 protected T FindFragment (int resourceId, global::Android.App.Fragment __ignoreMe, ref T cachedField) where T: global::Android.App.Fragment { return __FindFragment (resourceId, (activity) => activity.FragmentManager.FindFragmentById (resourceId), ref cachedField); } +#pragma warning restore CA1422 #endif // __ANDROID_11__ #if __HAVE_SUPPORT__ diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/CodeBehindTests.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/CodeBehindTests.cs index 84cb508fd06..8a7a215d51a 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/CodeBehindTests.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/CodeBehindTests.cs @@ -510,7 +510,7 @@ string[] GetBuildProperties (LocalBuilder builder, bool manyBuild, bool dtbBuild { var ret = new List { "AndroidGenerateLayoutBindings=true", - "\"NoWarn=CS0414;CA1416;CS1591;XA1005;XA4225\"" //CA1422 + "\"NoWarn=CS0414;CA1416;CS1591;XA1005;XA4225\"" }; if (manyBuild) ret.Add ("ForceParallelBuild=true"); From 84cd076dfa1a4587051bf1cbcf5a396d6aee0256 Mon Sep 17 00:00:00 2001 From: Dean Ellis Date: Mon, 4 Mar 2024 14:32:50 +0000 Subject: [PATCH 5/7] Revert this change --- .../Tests/Xamarin.Android.Build.Tests/CodeBehindTests.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/CodeBehindTests.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/CodeBehindTests.cs index 8a7a215d51a..59a6d1742ed 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/CodeBehindTests.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/CodeBehindTests.cs @@ -270,8 +270,8 @@ static CodeBehindTests () $"{ProjectName}.dll", "CommonSampleLibrary.dll", $"{PackageName}-Signed.apk", - //$"{PackageName}.aab", - //$"{PackageName}-Signed.aab", + $"{PackageName}.aab", + $"{PackageName}-Signed.aab", }; } From c6b506d36562cd974993793f1346f41edea78026 Mon Sep 17 00:00:00 2001 From: Jonathan Pryor Date: Tue, 19 Mar 2024 14:31:40 -0400 Subject: [PATCH 6/7] Add nullability info to `LayoutBinding.cs` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Context: https://github.com/xamarin/xamarin-android/pull/8529#issuecomment-1967736970 When building a project that uses layout bindings, multiple nullability warnings are emitted from `LayoutBinding.cs`: …/LayoutBinding.cs(16,98): warning CS8625: Cannot convert null literal to non-nullable reference type. …/LayoutBinding.cs(22,90): warning CS8625: Cannot convert null literal to non-nullable reference type. …/LayoutBinding.cs(16,13): warning CS8618: Non-nullable field 'boundView' must contain a non-null value when exiting constructor. Consider declaring the field as nullable. …/LayoutBinding.cs(22,13): warning CS8618: Non-nullable field 'boundActivity' must contain a non-null value when exiting constructor. Consider declaring the field as nullable. …/LayoutBinding.cs(35,11): warning CS8600: Converting null literal or possible null value to non-nullable type. …/LayoutBinding.cs(37,11): warning CS8600: Converting null literal or possible null value to non-nullable type. …/LayoutBinding.cs(79,56): warning CS8602: Dereference of a possibly null reference. …/LayoutBinding.cs(79,56): warning CS8603: Possible null reference return. …/LayoutBinding.cs(79,56): warning CA1422: This call site is reachable on: 'Android' 21.0 and later. 'Activity.FragmentManager' is obsoleted on: 'Android' 28.0 and later. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1422) …/LayoutBinding.cs(79,56): warning CA1422: This call site is reachable on: 'Android' 21.0 and later. 'FragmentManager.FindFragmentById(int)' is obsoleted on: 'Android' 28.0 and later (This class is obsoleted in this android platform). (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1422) Update `LayoutBinding.cs` to include nullability annotations. Now, no warnings are emitted when `$(AndroidGenerateLayoutBindings)`=true. --- .../Resources/LayoutBinding.cs | 32 ++++++++----------- 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/src/Xamarin.Android.Build.Tasks/Resources/LayoutBinding.cs b/src/Xamarin.Android.Build.Tasks/Resources/LayoutBinding.cs index 22db3443783..db6ddd0943d 100644 --- a/src/Xamarin.Android.Build.Tasks/Resources/LayoutBinding.cs +++ b/src/Xamarin.Android.Build.Tasks/Resources/LayoutBinding.cs @@ -9,17 +9,17 @@ namespace Xamarin.Android.Design abstract class LayoutBinding { - Activity boundActivity; - View boundView; - OnLayoutItemNotFoundHandler onLayoutItemNotFound; + Activity? boundActivity; + View? boundView; + OnLayoutItemNotFoundHandler? onLayoutItemNotFound; - protected LayoutBinding (Activity activity, OnLayoutItemNotFoundHandler onLayoutItemNotFound = null) + protected LayoutBinding (Activity activity, OnLayoutItemNotFoundHandler? onLayoutItemNotFound = null) { boundActivity = activity ?? throw new ArgumentNullException (nameof (activity)); this.onLayoutItemNotFound = onLayoutItemNotFound; } - protected LayoutBinding (View view, OnLayoutItemNotFoundHandler onLayoutItemNotFound = null) + protected LayoutBinding (View view, OnLayoutItemNotFoundHandler? onLayoutItemNotFound = null) { boundView = view ?? throw new ArgumentNullException (nameof (view)); this.onLayoutItemNotFound = onLayoutItemNotFound; @@ -30,10 +30,10 @@ protected LayoutBinding (View view, OnLayoutItemNotFoundHandler onLayoutItemNotF if (cachedField != null) return cachedField; - T ret; + T? ret = null; if (boundActivity != null) ret = boundActivity.FindViewById (resourceId); - else + else if (boundView != null) ret = boundView.FindViewById (resourceId); if (ret == null && onLayoutItemNotFound != null) @@ -58,7 +58,8 @@ Activity EnsureActivity () throw new InvalidOperationException ("Finding fragments is supported only for Activity instances"); } - T __FindFragment (int resourceId, Func finder, ref T cachedField) where T: Java.Lang.Object + T __FindFragment (int resourceId, Func finder, ref T? cachedField) + where T : Java.Lang.Object { if (cachedField != null) return cachedField; @@ -75,22 +76,17 @@ T __FindFragment (int resourceId, Func finder, ref T cachedField } #if __ANDROID_11__ #pragma warning disable CA1422 - protected T FindFragment (int resourceId, global::Android.App.Fragment __ignoreMe, ref T cachedField) where T: global::Android.App.Fragment + protected T FindFragment (int resourceId, global::Android.App.Fragment? __ignoreMe, ref T? cachedField) + where T : global::Android.App.Fragment { - return __FindFragment (resourceId, (activity) => activity.FragmentManager.FindFragmentById (resourceId), ref cachedField); + return __FindFragment (resourceId, (activity) => activity.FragmentManager?.FindFragmentById (resourceId), ref cachedField); } #pragma warning restore CA1422 #endif // __ANDROID_11__ -#if __HAVE_SUPPORT__ - protected T FindFragment (int resourceId, global::Android.Support.V4.App.Fragment __ignoreMe, ref T cachedField) where T: global::Android.Support.V4.App.Fragment - { - return __FindFragment (resourceId, (activity) => activity.FragmentManager.FindFragmentById (resourceId), ref cachedField); - } -#endif // __HAVE_SUPPORT__ - #if __HAVE_ANDROIDX__ - protected T FindFragment (int resourceId, global::AndroidX.Fragment.App.Fragment __ignoreMe, ref T cachedField) where T: global::AndroidX.Fragment.App.Fragment + protected T FindFragment (int resourceId, global::AndroidX.Fragment.App.Fragment? __ignoreMe, ref T? cachedField) + where T : global::AndroidX.Fragment.App.Fragment { return __FindFragment(resourceId, (activity) => { if (activity is AndroidX.Fragment.App.FragmentActivity activity_) { From 6d0f448ae232a208fa7dfed88ecd6feb31b6ba17 Mon Sep 17 00:00:00 2001 From: Jonathan Pryor Date: Wed, 20 Mar 2024 14:24:28 -0400 Subject: [PATCH 7/7] `#nullable enable` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The `SuccessfulAndroidXApp` test was failing, as it asserted no warnings, yet it had warnings: …\LayoutBinding.cs(61,56): warning CS8632: The annotation for nullable reference types should only be used in code within a '#nullable' annotations context. …\LayoutBinding.cs(61,72): warning CS8632: The annotation for nullable reference types should only be used in code within a '#nullable' annotations context. …\LayoutBinding.cs(79,76): warning CS8632: The annotation for nullable reference types should only be used in code within a '#nullable' annotations context. …\LayoutBinding.cs(79,95): warning CS8632: The annotation for nullable reference types should only be used in code within a '#nullable' annotations context. …\LayoutBinding.cs(88,86): warning CS8632: The annotation for nullable reference types should only be used in code within a '#nullable' annotations context. …\LayoutBinding.cs(88,105): warning CS8632: The annotation for nullable reference types should only be used in code within a '#nullable' annotations context. …\LayoutBinding.cs(16,74): warning CS8632: The annotation for nullable reference types should only be used in code within a '#nullable' annotations context. …\LayoutBinding.cs(22,66): warning CS8632: The annotation for nullable reference types should only be used in code within a '#nullable' annotations context. …\LayoutBinding.cs(12,11): warning CS8632: The annotation for nullable reference types should only be used in code within a '#nullable' annotations context. …\LayoutBinding.cs(13,7): warning CS8632: The annotation for nullable reference types should only be used in code within a '#nullable' annotations context. …\LayoutBinding.cs(14,30): warning CS8632: The annotation for nullable reference types should only be used in code within a '#nullable' annotations context. …\LayoutBinding.cs(33,5): warning CS8632: The annotation for nullable reference types should only be used in code within a '#nullable' annotations context. Slap on a `#nullable enable` so that we can reliably use nullable reference types within `LayoutBinding.cs`. --- .../Resources/LayoutBinding.cs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/Xamarin.Android.Build.Tasks/Resources/LayoutBinding.cs b/src/Xamarin.Android.Build.Tasks/Resources/LayoutBinding.cs index e140fa1bc78..3f18da73069 100644 --- a/src/Xamarin.Android.Build.Tasks/Resources/LayoutBinding.cs +++ b/src/Xamarin.Android.Build.Tasks/Resources/LayoutBinding.cs @@ -1,11 +1,13 @@ -using System; +#nullable enable + +using System; using System.Diagnostics.CodeAnalysis; using Android.App; using Android.Views; namespace Xamarin.Android.Design { - public delegate Java.Lang.Object OnLayoutItemNotFoundHandler (int resourceId, Type expectedViewType); + public delegate Java.Lang.Object? OnLayoutItemNotFoundHandler (int resourceId, Type expectedViewType); abstract class LayoutBinding { @@ -45,7 +47,7 @@ protected T FindView < ret = boundView.FindViewById (resourceId); if (ret == null && onLayoutItemNotFound != null) - ret = (T)onLayoutItemNotFound (resourceId, typeof (T)); + ret = (T?)onLayoutItemNotFound (resourceId, typeof (T)); if (ret == null) throw new global::System.InvalidOperationException ($"View not found (Resource ID: {resourceId})"); @@ -80,7 +82,7 @@ T __FindFragment< var ret = finder (EnsureActivity ()); if (ret == null && onLayoutItemNotFound != null) - ret = (T)onLayoutItemNotFound (resourceId, typeof (T)); + ret = (T?)onLayoutItemNotFound (resourceId, typeof (T)); if (ret == null) throw new InvalidOperationException ($"Fragment not found (ID: {resourceId}; Type: {typeof (T)})");