Add RequiresUnreferencedCodeAttribute (#36674)
authorEric Erhardt <eric.erhardt@microsoft.com>
Tue, 19 May 2020 15:29:15 +0000 (10:29 -0500)
committerGitHub <noreply@github.com>
Tue, 19 May 2020 15:29:15 +0000 (10:29 -0500)
This attribute is used by the linker to know which methods are unsafe to use when an application is trimmed.

Fix #33862

src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems
src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/RequiresUnreferencedCodeAttribute.cs [new file with mode: 0644]
src/libraries/System.Runtime/ref/System.Runtime.cs
src/libraries/System.Runtime/tests/System.Runtime.Tests.csproj
src/libraries/System.Runtime/tests/System/Diagnostics/CodeAnalysis/DynamicDependencyAttributeTests.cs
src/libraries/System.Runtime/tests/System/Diagnostics/CodeAnalysis/RequiresUnreferencedCodeAttributeTests.cs [new file with mode: 0644]

index 3ee0049..8857b33 100644 (file)
     <Compile Include="$(MSBuildThisFileDirectory)System\Decimal.DecCalc.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\DefaultBinder.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\Delegate.cs" />
+    <Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\CodeAnalysis\RequiresUnreferencedCodeAttribute.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\CodeAnalysis\DynamicallyAccessedMemberTypes.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\CodeAnalysis\DynamicallyAccessedMembersAttribute.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\CodeAnalysis\DynamicDependencyAttribute.cs" />
diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/RequiresUnreferencedCodeAttribute.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/RequiresUnreferencedCodeAttribute.cs
new file mode 100644 (file)
index 0000000..5ab2903
--- /dev/null
@@ -0,0 +1,41 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+namespace System.Diagnostics.CodeAnalysis
+{
+    /// <summary>
+    /// Indicates that the specified method requires dynamic access to code that is not referenced
+    /// statically, for example through <see cref="System.Reflection"/>.
+    /// </summary>
+    /// <remarks>
+    /// This allows tools to understand which methods are unsafe to call when removing unreferenced
+    /// code from an application.
+    /// </remarks>
+    [AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor, Inherited = false)]
+    public sealed class RequiresUnreferencedCodeAttribute : Attribute
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="RequiresUnreferencedCodeAttribute"/> class
+        /// with the specified message.
+        /// </summary>
+        /// <param name="message">
+        /// A message that contains information about the usage of unreferenced code.
+        /// </param>
+        public RequiresUnreferencedCodeAttribute(string message)
+        {
+            Message = message;
+        }
+
+        /// <summary>
+        /// Gets a message that contains information about the usage of unreferenced code.
+        /// </summary>
+        public string Message { get; }
+
+        /// <summary>
+        /// Gets or sets an optional URL that contains more information about the method,
+        /// why it requries unreferenced code, and what options a consumer has to deal with it.
+        /// </summary>
+        public string? Url { get; set; }
+    }
+}
index 0ff7018..50ef98b 100644 (file)
@@ -5698,6 +5698,13 @@ namespace System.Diagnostics.CodeAnalysis
         public bool ReturnValue { get { throw null; } }
         public string[] Members { get { throw null; } }
     }
+    [System.AttributeUsageAttribute(System.AttributeTargets.Method | System.AttributeTargets.Constructor, Inherited = false)]
+    public sealed class RequiresUnreferencedCodeAttribute : System.Attribute
+    {
+        public RequiresUnreferencedCodeAttribute(string message) { }
+        public string Message { get { throw null; } }
+        public string? Url { get { throw null; } set { } }
+    }
     [System.AttributeUsageAttribute(System.AttributeTargets.All, Inherited=false, AllowMultiple=true)]
     [System.Diagnostics.ConditionalAttribute("CODE_ANALYSIS")]
     public sealed partial class SuppressMessageAttribute : System.Attribute
index e9dd22e..69f4de9 100644 (file)
     <Compile Include="System\ComponentModel\EditorBrowsableAttributeTests.cs" />
     <Compile Include="System\Diagnostics\ConditionalAttributeTests.cs" />
     <Compile Include="System\Diagnostics\CodeAnalysis\DynamicallyAccessedMembersAttributeTests.cs" />
+    <Compile Include="System\Diagnostics\CodeAnalysis\RequiresUnreferencedCodeAttributeTests.cs" />
     <Compile Include="System\Diagnostics\CodeAnalysis\UnconditionalSuppressMessageAttributeTests.cs" />
     <Compile Include="System\IO\DirectoryNotFoundExceptionTests.cs" />
     <Compile Include="System\IO\DirectoryNotFoundException.InteropTests.cs" />
index 2b47590..337af64 100644 (file)
@@ -6,7 +6,7 @@ using Xunit;
 
 namespace System.Diagnostics.CodeAnalysis.Tests
 {
-    public class DynamicDependencyAttributeTestsTests
+    public class DynamicDependencyAttributeTests
     {
         [Theory]
         [InlineData("Foo()")]
diff --git a/src/libraries/System.Runtime/tests/System/Diagnostics/CodeAnalysis/RequiresUnreferencedCodeAttributeTests.cs b/src/libraries/System.Runtime/tests/System/Diagnostics/CodeAnalysis/RequiresUnreferencedCodeAttributeTests.cs
new file mode 100644 (file)
index 0000000..044fc78
--- /dev/null
@@ -0,0 +1,35 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using Xunit;
+
+namespace System.Diagnostics.CodeAnalysis.Tests
+{
+    public class RequiresUnreferencedCodeAttributeTests
+    {
+        [Fact]
+        public void TestConstructor()
+        {
+            var attr = new RequiresUnreferencedCodeAttribute("User Message");
+
+            Assert.Equal("User Message", attr.Message);
+            Assert.Null(attr.Url);
+        }
+
+        [Theory]
+        [InlineData("https://dot.net")]
+        [InlineData("")]
+        [InlineData(null)]
+        public void TestSetUrl(string url)
+        {
+            var attr = new RequiresUnreferencedCodeAttribute("User Message")
+            {
+                Url = url
+            };
+
+            Assert.Equal("User Message", attr.Message);
+            Assert.Equal(url, attr.Url);
+        }
+    }
+}