From a11bef715b283b99adb535dfa857e039573bce1f Mon Sep 17 00:00:00 2001 From: Max Katz Date: Sat, 29 Apr 2023 23:44:21 -0400 Subject: [PATCH] Add Message parameter to the Unstable attribute --- nukebuild/RefAssemblyGenerator.cs | 24 ++++++++++++------- .../Metadata/UnstableAttribute.cs | 22 ++++++++++++++++- 2 files changed, 36 insertions(+), 10 deletions(-) diff --git a/nukebuild/RefAssemblyGenerator.cs b/nukebuild/RefAssemblyGenerator.cs index cbe5236bca..f0d5c81a37 100644 --- a/nukebuild/RefAssemblyGenerator.cs +++ b/nukebuild/RefAssemblyGenerator.cs @@ -96,7 +96,7 @@ public class RefAssemblyGenerator | MethodAttributes.HideBySig, type.Module.TypeSystem.Void)); } - var forceUnstable = type.CustomAttributes.Any(a => + var forceUnstable = type.CustomAttributes.FirstOrDefault(a => a.AttributeType.FullName == "Avalonia.Metadata.UnstableAttribute"); foreach (var m in type.Methods) @@ -109,22 +109,28 @@ public class RefAssemblyGenerator } } - static void MarkAsUnstable(IMemberDefinition def, MethodReference obsoleteCtor, bool force) + static void MarkAsUnstable(IMemberDefinition def, MethodReference obsoleteCtor, ICustomAttribute unstableAttribute) { - if (!force && ( - def.HasCustomAttributes == false - || def.CustomAttributes.All(a => a.AttributeType.FullName != "Avalonia.Metadata.UnstableAttribute"))) + if (def.CustomAttributes.Any(a => a.AttributeType.FullName == "System.ObsoleteAttribute")) return; - if (def.CustomAttributes.Any(a => a.AttributeType.FullName == "System.ObsoleteAttribute")) + unstableAttribute = def.CustomAttributes.FirstOrDefault(a => + a.AttributeType.FullName == "Avalonia.Metadata.UnstableAttribute") ?? unstableAttribute; + + if (unstableAttribute is null) return; + var message = unstableAttribute.ConstructorArguments.FirstOrDefault().Value?.ToString(); + if (string.IsNullOrEmpty(message)) + { + message = "This is a part of unstable API and can be changed in minor releases. Consider replacing it with alternatives or reach out developers on GitHub."; + } + def.CustomAttributes.Add(new CustomAttribute(obsoleteCtor) { ConstructorArguments = { - new CustomAttributeArgument(obsoleteCtor.Module.TypeSystem.String, - "This is a part of unstable API and can be changed in minor releases. You have been warned") + new CustomAttributeArgument(obsoleteCtor.Module.TypeSystem.String, message) } }); } @@ -168,4 +174,4 @@ public class RefAssemblyGenerator } } } -} \ No newline at end of file +} diff --git a/src/Avalonia.Base/Metadata/UnstableAttribute.cs b/src/Avalonia.Base/Metadata/UnstableAttribute.cs index 361f6d30fd..bbb298f7a6 100644 --- a/src/Avalonia.Base/Metadata/UnstableAttribute.cs +++ b/src/Avalonia.Base/Metadata/UnstableAttribute.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Avalonia.Metadata { @@ -9,5 +9,25 @@ namespace Avalonia.Metadata [AttributeUsage(AttributeTargets.All)] public sealed class UnstableAttribute : Attribute { + /// + /// Initializes a new instance of the class. + /// + public UnstableAttribute() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The text string that describes alternative workarounds. + public UnstableAttribute(string? message) + { + Message = message; + } + + /// + /// Gets a value that indicates whether the compiler will treat usage of the obsolete program element as an error. + /// + public string? Message { get; } } }