From e628acd3cb6dd1e52eda59c54ba4ebf28106ca5f Mon Sep 17 00:00:00 2001 From: Jonathan Peppers Date: Fri, 23 Jul 2021 09:17:21 -0500 Subject: [PATCH] [One .NET] support latest C #10 language features Fixes: https://github.com/xamarin/xamarin-android/issues/6075 Fixes: https://github.com/xamarin/xamarin-android/issues/6076 Context: https://github.com/xamarin/xamarin-macios/pull/12173 We need to make two sets of changes for C# 10: 1. Support "global usings". Our .NET 6 templates should have no `using` statements at the top of `.cs` files. 2. Use `$(Nullable)` `enable` by default in project templates. To test this, our .NET 6 MSBuild tests use `Nullable=enable` by default and do no include `using` statements. I've made a new `MainActivity.cs` for our .NET 6 MSBuild tests. The "legacy" Xamarin.Android tests will use the original file. --- .../android-activity/Activity1.cs | 7 +- .../android-bindinglib/AndroidBinding1.csproj | 1 + .../android/AndroidApp1.csproj | 1 + .../android/MainActivity.cs | 7 +- .../androidlib/AndroidLib1.csproj | 1 + .../androidlib/Class1.cs | 2 - ...droid.Sdk.ImplicitNamespaceImports.targets | 22 ++++++ .../targets/Microsoft.Android.Sdk.targets | 1 + .../Xamarin.Android.Build.Tests/XASdkTests.cs | 1 + .../Android/KnownProperties.cs | 1 + .../Android/XASdkProject.cs | 3 +- .../XamarinAndroidApplicationProject.cs | 3 +- .../Resources/DotNet/MainActivity.cs | 24 +++++++ .../Xamarin.ProjectTools.csproj | 69 +------------------ 14 files changed, 60 insertions(+), 83 deletions(-) create mode 100644 src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.ImplicitNamespaceImports.targets create mode 100644 src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/DotNet/MainActivity.cs diff --git a/src/Microsoft.Android.Templates/android-activity/Activity1.cs b/src/Microsoft.Android.Templates/android-activity/Activity1.cs index f974a451ba3..e6d6f33c9a5 100644 --- a/src/Microsoft.Android.Templates/android-activity/Activity1.cs +++ b/src/Microsoft.Android.Templates/android-activity/Activity1.cs @@ -1,14 +1,9 @@ -using Android.App; -using Android.OS; -using Android.Runtime; -using Android.Widget; - namespace AndroidApp1 { [Activity(Label = "@string/app_name", MainLauncher = true)] public class Activity1 : Activity { - protected override void OnCreate(Bundle savedInstanceState) + protected override void OnCreate(Bundle? savedInstanceState) { base.OnCreate(savedInstanceState); diff --git a/src/Microsoft.Android.Templates/android-bindinglib/AndroidBinding1.csproj b/src/Microsoft.Android.Templates/android-bindinglib/AndroidBinding1.csproj index 7cf29802739..4c01028d946 100644 --- a/src/Microsoft.Android.Templates/android-bindinglib/AndroidBinding1.csproj +++ b/src/Microsoft.Android.Templates/android-bindinglib/AndroidBinding1.csproj @@ -2,5 +2,6 @@ net6.0-android AndroidBinding1 + enable \ No newline at end of file diff --git a/src/Microsoft.Android.Templates/android/AndroidApp1.csproj b/src/Microsoft.Android.Templates/android/AndroidApp1.csproj index a46e175509f..1aa1a5f6ba2 100644 --- a/src/Microsoft.Android.Templates/android/AndroidApp1.csproj +++ b/src/Microsoft.Android.Templates/android/AndroidApp1.csproj @@ -3,5 +3,6 @@ net6.0-android AndroidApp1 Exe + enable \ No newline at end of file diff --git a/src/Microsoft.Android.Templates/android/MainActivity.cs b/src/Microsoft.Android.Templates/android/MainActivity.cs index 7e49926946e..b48279dbee4 100644 --- a/src/Microsoft.Android.Templates/android/MainActivity.cs +++ b/src/Microsoft.Android.Templates/android/MainActivity.cs @@ -1,14 +1,9 @@ -using Android.App; -using Android.OS; -using Android.Runtime; -using Android.Widget; - namespace AndroidApp1 { [Activity(Label = "@string/app_name", MainLauncher = true)] public class MainActivity : Activity { - protected override void OnCreate(Bundle savedInstanceState) + protected override void OnCreate(Bundle? savedInstanceState) { base.OnCreate(savedInstanceState); diff --git a/src/Microsoft.Android.Templates/androidlib/AndroidLib1.csproj b/src/Microsoft.Android.Templates/androidlib/AndroidLib1.csproj index 687d1512882..413be76eb70 100644 --- a/src/Microsoft.Android.Templates/androidlib/AndroidLib1.csproj +++ b/src/Microsoft.Android.Templates/androidlib/AndroidLib1.csproj @@ -2,5 +2,6 @@ net6.0-android AndroidLib1 + enable \ No newline at end of file diff --git a/src/Microsoft.Android.Templates/androidlib/Class1.cs b/src/Microsoft.Android.Templates/androidlib/Class1.cs index 1004d5770c0..5eebfbb4e60 100644 --- a/src/Microsoft.Android.Templates/androidlib/Class1.cs +++ b/src/Microsoft.Android.Templates/androidlib/Class1.cs @@ -1,5 +1,3 @@ -using System; - namespace AndroidLib1 { public class Class1 diff --git a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.ImplicitNamespaceImports.targets b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.ImplicitNamespaceImports.targets new file mode 100644 index 00000000000..d33cf85d75d --- /dev/null +++ b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.ImplicitNamespaceImports.targets @@ -0,0 +1,22 @@ + + + + + + + + + + diff --git a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.targets b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.targets index d0e154d6c20..1fe27c0461d 100644 --- a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.targets +++ b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.targets @@ -25,6 +25,7 @@ + diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/XASdkTests.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/XASdkTests.cs index 3212f882e2a..5af47bfeeb3 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/XASdkTests.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/XASdkTests.cs @@ -204,6 +204,7 @@ public void DotNetNew ([Values ("android", "androidlib", "android-bindinglib")] Assert.IsTrue (dotnet.New ("android-activity"), "`dotnet new android-activity` should succeed"); Assert.IsTrue (dotnet.New ("android-layout", Path.Combine (dotnet.ProjectDirectory, "Resources", "layout")), "`dotnet new android-layout` should succeed"); Assert.IsTrue (dotnet.Build (), "`dotnet build` should succeed"); + dotnet.AssertHasNoWarnings (); } [Test] diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Android/KnownProperties.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Android/KnownProperties.cs index 3ac6af77f8a..f31b044682e 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Android/KnownProperties.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Android/KnownProperties.cs @@ -35,6 +35,7 @@ public static class KnownProperties public const string AndroidFastDeploymentType = "AndroidFastDeploymentType"; public const string AndroidClassParser = "AndroidClassParser"; public const string _AndroidAllowDeltaInstall = "_AndroidAllowDeltaInstall"; + public const string Nullable = "Nullable"; } } diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Android/XASdkProject.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Android/XASdkProject.cs index 38c5b73357a..2fb5a9da07a 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Android/XASdkProject.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Android/XASdkProject.cs @@ -28,7 +28,7 @@ static XASdkProject () var assembly = typeof (XASdkProject).Assembly; using (var sr = new StreamReader (assembly.GetManifestResourceStream ("Xamarin.ProjectTools.Resources.Base.AndroidManifest.xml"))) default_android_manifest = sr.ReadToEnd (); - using (var sr = new StreamReader (assembly.GetManifestResourceStream ("Xamarin.ProjectTools.Resources.Base.MainActivity.cs"))) + using (var sr = new StreamReader (assembly.GetManifestResourceStream ("Xamarin.ProjectTools.Resources.DotNet.MainActivity.cs"))) default_main_activity_cs = sr.ReadToEnd (); using (var sr = new StreamReader (assembly.GetManifestResourceStream ("Xamarin.ProjectTools.Resources.Base.LayoutMain.axml"))) default_layout_main = sr.ReadToEnd (); @@ -62,6 +62,7 @@ public XASdkProject (string outputType = "Exe", [CallerMemberName] string packag JavaPackageName = JavaPackageName ?? PackageName.ToLowerInvariant (); GlobalPackagesFolder = FileSystemUtils.FindNugetGlobalPackageFolder (); SetProperty (KnownProperties.OutputType, outputType); + SetProperty (KnownProperties.Nullable, "enable"); // Add relevant Android content to our project without writing it to the .csproj file if (outputType == "Exe") { diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Android/XamarinAndroidApplicationProject.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Android/XamarinAndroidApplicationProject.cs index a02e24fdd1b..3ba243cf3f7 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Android/XamarinAndroidApplicationProject.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Android/XamarinAndroidApplicationProject.cs @@ -24,7 +24,8 @@ public class XamarinAndroidApplicationProject : XamarinAndroidCommonProject static XamarinAndroidApplicationProject () { - using (var sr = new StreamReader (typeof(XamarinAndroidApplicationProject).Assembly.GetManifestResourceStream ("Xamarin.ProjectTools.Resources.Base.MainActivity.cs"))) + var folder = Builder.UseDotNet ? "DotNet" : "Base"; + using (var sr = new StreamReader (typeof(XamarinAndroidApplicationProject).Assembly.GetManifestResourceStream ($"Xamarin.ProjectTools.Resources.{folder}.MainActivity.cs"))) default_main_activity_cs = sr.ReadToEnd (); using (var sr = new StreamReader (typeof(XamarinAndroidApplicationProject).Assembly.GetManifestResourceStream ("Xamarin.ProjectTools.Resources.Base.MainActivity.fs"))) default_main_activity_fs = sr.ReadToEnd (); diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/DotNet/MainActivity.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/DotNet/MainActivity.cs new file mode 100644 index 00000000000..8e6513c7ebf --- /dev/null +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/DotNet/MainActivity.cs @@ -0,0 +1,24 @@ +namespace ${ROOT_NAMESPACE} +{ + [Register ("${JAVA_PACKAGENAME}.MainActivity"), Activity (Label = "${PROJECT_NAME}", MainLauncher = true, Icon = "@drawable/icon")] + public class MainActivity : Activity + { + int count = 1; + + protected override void OnCreate (Bundle? bundle) + { + base.OnCreate (bundle); + + // Set our view from the "main" layout resource + SetContentView (Resource.Layout.Main); + + var button = FindViewById