diff --git a/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.LinkAttributes.Shared.xml b/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.LinkAttributes.Shared.xml index f10548a4a70dc..a66cc3b616de2 100644 --- a/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.LinkAttributes.Shared.xml +++ b/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.LinkAttributes.Shared.xml @@ -141,6 +141,9 @@ + + + diff --git a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems index c19e0f2a827d8..8befa9e63d06f 100644 --- a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems +++ b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems @@ -259,6 +259,7 @@ + diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/ExperimentalAttribute.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/ExperimentalAttribute.cs new file mode 100644 index 0000000000000..5619e669d5711 --- /dev/null +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/ExperimentalAttribute.cs @@ -0,0 +1,55 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Diagnostics.CodeAnalysis +{ + /// + /// Indicates that an API is experimental and it may change in the future. + /// + /// + /// This attribute allows call sites to be flagged with a diagnostic that indicates that an experimental + /// feature is used. Authors can use this attribute to ship preview features in their assemblies. + /// + [AttributeUsage(AttributeTargets.Assembly | + AttributeTargets.Module | + AttributeTargets.Class | + AttributeTargets.Struct | + AttributeTargets.Enum | + AttributeTargets.Constructor | + AttributeTargets.Method | + AttributeTargets.Property | + AttributeTargets.Field | + AttributeTargets.Event | + AttributeTargets.Interface | + AttributeTargets.Delegate, Inherited = false)] + public sealed class ExperimentalAttribute : Attribute + { + /// + /// Initializes a new instance of the class, specifying the ID that the compiler will use + /// when reporting a use of the API the attribute applies to. + /// + /// The ID that the compiler will use when reporting a use of the API the attribute applies to. + public ExperimentalAttribute(string diagnosticId) + { + DiagnosticId = diagnosticId; + } + + /// + /// Gets or sets the ID that the compiler will use when reporting a use of the API the attribute applies to. + /// + /// The unique diagnostic ID. + /// + /// The diagnostic ID is shown in build output for warnings and errors. + /// This property represents the unique ID that can be used to suppress the warnings or errors, if needed. + /// + public string DiagnosticId { get; } + + /// + /// Gets or sets the URL for corresponding documentation. + /// The API accepts a format string instead of an actual URL, creating a generic URL that includes the diagnostic ID. + /// + /// The format string that represents a URL to corresponding documentation. + /// An example format string is https://contoso.com/obsoletion-warnings/{0}. + public string? UrlFormat { get; set; } + } +} diff --git a/src/libraries/System.Runtime/ref/System.Runtime.cs b/src/libraries/System.Runtime/ref/System.Runtime.cs index 5362c12fcb659..8573cdb9bb021 100644 --- a/src/libraries/System.Runtime/ref/System.Runtime.cs +++ b/src/libraries/System.Runtime/ref/System.Runtime.cs @@ -8281,6 +8281,13 @@ public sealed partial class ExcludeFromCodeCoverageAttribute : System.Attribute public ExcludeFromCodeCoverageAttribute() { } public string? Justification { get { throw null; } set { } } } + [System.AttributeUsage(System.AttributeTargets.Assembly | System.AttributeTargets.Module | System.AttributeTargets.Class | System.AttributeTargets.Struct | System.AttributeTargets.Enum | System.AttributeTargets.Constructor | System.AttributeTargets.Method | System.AttributeTargets.Property | System.AttributeTargets.Field | System.AttributeTargets.Event | System.AttributeTargets.Interface | System.AttributeTargets.Delegate, Inherited = false)] + public sealed class ExperimentalAttribute : System.Attribute + { + public ExperimentalAttribute(string diagnosticId) { } + public string DiagnosticId { get { throw null; } } + public string? UrlFormat { get; set; } + } [System.AttributeUsageAttribute(System.AttributeTargets.Field | System.AttributeTargets.Parameter | System.AttributeTargets.Property | System.AttributeTargets.ReturnValue, Inherited=false)] public sealed partial class MaybeNullAttribute : System.Attribute { diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests.csproj b/src/libraries/System.Runtime/tests/System.Runtime.Tests.csproj index b4e389485006a..359d3158aeea4 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests.csproj +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests.csproj @@ -68,6 +68,7 @@ + diff --git a/src/libraries/System.Runtime/tests/System/Diagnostics/CodeAnalysis/ExperimentalAttributeTests.cs b/src/libraries/System.Runtime/tests/System/Diagnostics/CodeAnalysis/ExperimentalAttributeTests.cs new file mode 100644 index 0000000000000..91beaf2991fca --- /dev/null +++ b/src/libraries/System.Runtime/tests/System/Diagnostics/CodeAnalysis/ExperimentalAttributeTests.cs @@ -0,0 +1,40 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Xunit; + +namespace System.Diagnostics.CodeAnalysis.Tests +{ + public class ExperimentalAttributeTests + { + [Theory] + // Note: Once the compiler support is implemented these should fail + [InlineData("")] + [InlineData(" ")] + [InlineData("\t")] + // Note end + [InlineData("diagnosticId")] + public void TestConstructor(string expected) + { + var attr = new ExperimentalAttribute(expected); + + Assert.Equal(expected, attr.DiagnosticId); + Assert.Null(attr.UrlFormat); + } + + [Theory] + [InlineData(null)] + [InlineData("")] + [InlineData("https://contoso.com/obsoletion-warnings/{0}")] + public void TestSetUrlFormat(string urlFormat) + { + var attr = new ExperimentalAttribute("diagnosticId") + { + UrlFormat = urlFormat + }; + + Assert.Equal("diagnosticId", attr.DiagnosticId); + Assert.Equal(urlFormat, attr.UrlFormat); + } + } +}