From 120d8a71d9b1f3a84b366b5fe6f48a60ca5d0825 Mon Sep 17 00:00:00 2001 From: Jonathan Pobst Date: Thu, 26 Jan 2023 10:18:37 -1000 Subject: [PATCH] [generator] Add more [ObsoleteOSPlatform] to prevent CA1422 (#1078) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Context: https://github.com/xamarin/xamarin-android/issues/7590 Context: https://github.com/xamarin/xamarin-android/commit/700446703a262f32e379a853aac2ab19628c4a79 While building `Mono.Android.dll`, we had 1462 `CA1422` warnings of the following caused by an interface being marked as `[ObsoleteOSPlatform]` but the interface invoker class is not similarly annotated: …\xamarin-android\src\Mono.Android\obj\Debug\net8.0\android-33\mcw\Org.Apache.Commons.Logging.ILog.cs(128,11): warning CA1422: This call site is reachable on: 'Android' 21.0 and later. 'ILog' is obsoleted on: 'Android' 22.0 and later (This class is obsoleted in this android platform). There were also 42 `CA1422` warnings caused by interface async extension classes not having `[ObsoleteOSPlatform]` attributes: …\xamarin-android\src\Mono.Android\obj\Debug\net8.0\android-33\mcw\Org.Apache.Http.IO.ISessionOutputBuffer.cs(52,58): warning CA1422: This call site is reachable on: 'Android' 21.0 and later. 'ISessionOutputBuffer.Write(byte[]?, int, int)' is obsoleted on: 'Android' 22.0 and later (This class is obsoleted in this android platform). These warnings were disabled in xamarin/xamarin-android@70044670. Fix these warnings by adding the `[ObsoleteOSPlatform]` attribute to these types if the source interface is deprecated. --- .../Unit-Tests/CodeGeneratorTests.cs | 30 +++++++++++++++++++ .../SourceWriters/InterfaceExtensionsClass.cs | 2 ++ .../SourceWriters/InterfaceInvokerClass.cs | 2 ++ 3 files changed, 34 insertions(+) diff --git a/tests/generator-Tests/Unit-Tests/CodeGeneratorTests.cs b/tests/generator-Tests/Unit-Tests/CodeGeneratorTests.cs index 69d1b6455..df1359fff 100644 --- a/tests/generator-Tests/Unit-Tests/CodeGeneratorTests.cs +++ b/tests/generator-Tests/Unit-Tests/CodeGeneratorTests.cs @@ -611,6 +611,36 @@ public void ObsoletedOSPlatformAttributeUnneededSupport () Assert.True (writer.ToString ().Contains ("[global::System.Obsolete (@\"This method has an invalid deprecated-since!\")]"), writer.ToString ()); } + [Test] + public void ObsoletedOSPlatformAttributeInterfaceInfrastructureSupport () + { + var xml = @" + + + + "; + + options.UseObsoletedOSPlatformAttributes = true; + + var gens = ParseApiDefinition (xml); + var iface = gens.OfType ().Single (g => g.Name == "IMyType"); + + generator.Context.ContextTypes.Push (iface); + var invoker = new InterfaceInvokerClass (iface, options, generator.Context); + var extensions = new InterfaceExtensionsClass (iface, iface.Name, options); + generator.Context.ContextTypes.Pop (); + + // Ensure attribute was added to invoker class + var invoker_attribute = invoker.Attributes.OfType ().Single (); + Assert.AreEqual ("This interface was deprecated in API-25", invoker_attribute.Message); + Assert.AreEqual (25, invoker_attribute.Version); + + // Ensure attribute was added to extensions class + var extensions_attribute = invoker.Attributes.OfType ().Single (); + Assert.AreEqual ("This interface was deprecated in API-25", extensions_attribute.Message); + Assert.AreEqual (25, extensions_attribute.Version); + } + [Test] public void ObsoleteGetterOnlyProperty () { diff --git a/tools/generator/SourceWriters/InterfaceExtensionsClass.cs b/tools/generator/SourceWriters/InterfaceExtensionsClass.cs index edf5ac0d4..378c7323a 100644 --- a/tools/generator/SourceWriters/InterfaceExtensionsClass.cs +++ b/tools/generator/SourceWriters/InterfaceExtensionsClass.cs @@ -18,6 +18,8 @@ public InterfaceExtensionsClass (InterfaceGen iface, string declaringTypeName, C IsStatic = true; IsPartial = true; + SourceWriterExtensions.AddObsolete (Attributes, iface.DeprecatedComment, opt, iface.IsDeprecated, deprecatedSince: iface.DeprecatedSince); + foreach (var method in iface.Methods.Where (m => !m.IsStatic)) { if (method.CanHaveStringOverload) { // TODO: Don't allow obsolete here to match old generator. diff --git a/tools/generator/SourceWriters/InterfaceInvokerClass.cs b/tools/generator/SourceWriters/InterfaceInvokerClass.cs index 3bde0695a..c0e39419e 100644 --- a/tools/generator/SourceWriters/InterfaceInvokerClass.cs +++ b/tools/generator/SourceWriters/InterfaceInvokerClass.cs @@ -32,6 +32,8 @@ public InterfaceInvokerClass (InterfaceGen iface, CodeGenerationOptions opt, Cod MemberType = (!ji) ? null : (MemberTypes?) MemberTypes.TypeInfo, }); + SourceWriterExtensions.AddObsolete (Attributes, iface.DeprecatedComment, opt, iface.IsDeprecated, deprecatedSince: iface.DeprecatedSince); + Fields.Add (new PeerMembersField (opt, iface.RawJniName, $"{iface.Name}Invoker", false)); if (!ji) {