Resolve ILLink warnings in System.Text.RegularExpressions (#46687)
authorEric Erhardt <eric.erhardt@microsoft.com>
Fri, 8 Jan 2021 00:16:51 +0000 (18:16 -0600)
committerGitHub <noreply@github.com>
Fri, 8 Jan 2021 00:16:51 +0000 (18:16 -0600)
* Add DynamicallyAccessedMembers All to TypeBuilder and EnumBuilder CreateType methods.

Contributes to #45623

src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/EnumBuilder.cs
src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilder.cs
src/libraries/System.Reflection.Emit/ref/System.Reflection.Emit.cs
src/libraries/System.Text.RegularExpressions/src/ILLink/ILLink.Suppressions.Debug.xml [deleted file]
src/libraries/System.Text.RegularExpressions/src/ILLink/ILLink.Suppressions.xml [deleted file]
src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexAssemblyCompiler.cs
src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexCompiler.cs
src/mono/netcore/System.Private.CoreLib/src/System/Reflection/Emit/EnumBuilder.Mono.cs
src/mono/netcore/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilder.Mono.cs

index fd0807c..2d1c72d 100644 (file)
@@ -38,12 +38,14 @@ namespace System.Reflection.Emit
             return fieldBuilder;
         }
 
+        [return: DynamicallyAccessedMembersAttribute(DynamicallyAccessedMemberTypes.All)]
         public TypeInfo? CreateTypeInfo()
         {
             return m_typeBuilder.CreateTypeInfo();
         }
 
         // CreateType cause EnumBuilder to be baked.
+        [return: DynamicallyAccessedMembersAttribute(DynamicallyAccessedMemberTypes.All)]
         public Type? CreateType()
         {
             return m_typeBuilder.CreateType();
index 7c1f93c..3a2a774 100644 (file)
@@ -1881,6 +1881,7 @@ namespace System.Reflection.Emit
 
         #region Create Type
 
+        [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]
         public TypeInfo? CreateTypeInfo()
         {
             lock (SyncRoot)
@@ -1889,6 +1890,7 @@ namespace System.Reflection.Emit
             }
         }
 
+        [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]
         public Type? CreateType()
         {
             lock (SyncRoot)
@@ -1897,6 +1899,9 @@ namespace System.Reflection.Emit
             }
         }
 
+        [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2083:UnrecognizedReflectionPattern",
+            Justification = "Reflection.Emit is not subject to trimming")]
+        [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]
         private TypeInfo? CreateTypeNoLock()
         {
             if (IsCreated())
index 278f491..4692f04 100644 (file)
@@ -106,6 +106,7 @@ namespace System.Reflection.Emit
         public override System.RuntimeTypeHandle TypeHandle { get { throw null; } }
         public System.Reflection.Emit.FieldBuilder UnderlyingField { get { throw null; } }
         public override System.Type UnderlyingSystemType { get { throw null; } }
+        [return: System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All)]
         public System.Reflection.TypeInfo? CreateTypeInfo() { throw null; }
         public System.Reflection.Emit.FieldBuilder DefineLiteral(string literalName, object? literalValue) { throw null; }
         protected override System.Reflection.TypeAttributes GetAttributeFlagsImpl() { throw null; }
@@ -460,7 +461,9 @@ namespace System.Reflection.Emit
         public override System.RuntimeTypeHandle TypeHandle { get { throw null; } }
         public override System.Type UnderlyingSystemType { get { throw null; } }
         public void AddInterfaceImplementation([System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All)] System.Type interfaceType) { }
+        [return: System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All)]
         public System.Type? CreateType() { throw null; }
+        [return: System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All)]
         public System.Reflection.TypeInfo? CreateTypeInfo() { throw null; }
         public System.Reflection.Emit.ConstructorBuilder DefineConstructor(System.Reflection.MethodAttributes attributes, System.Reflection.CallingConventions callingConvention, System.Type[]? parameterTypes) { throw null; }
         public System.Reflection.Emit.ConstructorBuilder DefineConstructor(System.Reflection.MethodAttributes attributes, System.Reflection.CallingConventions callingConvention, System.Type[]? parameterTypes, System.Type[][]? requiredCustomModifiers, System.Type[][]? optionalCustomModifiers) { throw null; }
diff --git a/src/libraries/System.Text.RegularExpressions/src/ILLink/ILLink.Suppressions.Debug.xml b/src/libraries/System.Text.RegularExpressions/src/ILLink/ILLink.Suppressions.Debug.xml
deleted file mode 100644 (file)
index dd49320..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<linker>
-  <assembly fullname="System.Text.RegularExpressions, PublicKeyToken=b03f5f7f11d50a3a">
-    <attribute fullname="System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute">
-      <argument>ILLink</argument>
-      <argument>IL2067</argument>
-      <property name="Scope">member</property>
-      <property name="Target">M:System.Text.RegularExpressions.RegexAssemblyCompiler.DefineType(System.Reflection.Emit.ModuleBuilder,System.String,System.Boolean,System.Boolean,System.Type)</property>
-    </attribute>
-    <attribute fullname="System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute">
-      <argument>ILLink</argument>
-      <argument>IL2070</argument>
-      <property name="Scope">member</property>
-      <property name="Target">M:System.Text.RegularExpressions.RegexAssemblyCompiler.GenerateCreateInstance(System.Type)</property>
-    </attribute>
-    <attribute fullname="System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute">
-      <argument>ILLink</argument>
-      <argument>IL2070</argument>
-      <property name="Scope">member</property>
-      <property name="Target">M:System.Text.RegularExpressions.RegexAssemblyCompiler.GenerateRegexDefaultCtor(System.String,System.Text.RegularExpressions.RegexOptions,System.Type,System.Text.RegularExpressions.RegexCode,System.TimeSpan)</property>
-    </attribute>
-  </assembly>
-</linker>
\ No newline at end of file
diff --git a/src/libraries/System.Text.RegularExpressions/src/ILLink/ILLink.Suppressions.xml b/src/libraries/System.Text.RegularExpressions/src/ILLink/ILLink.Suppressions.xml
deleted file mode 100644 (file)
index e2645a3..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<linker>
-  <assembly fullname="System.Text.RegularExpressions, PublicKeyToken=b03f5f7f11d50a3a">
-    <attribute fullname="System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute">
-      <argument>ILLink</argument>
-      <argument>IL2060</argument>
-      <property name="Scope">member</property>
-      <property name="Target">M:System.Text.RegularExpressions.RegexCompiler.#cctor</property>
-    </attribute>
-  </assembly>
-</linker>
\ No newline at end of file
index ce7a8ce..8b35c6e 100644 (file)
@@ -2,9 +2,10 @@
 // The .NET Foundation licenses this file to you under the MIT license.
 
 using System.Collections;
-using System.Threading;
+using System.Diagnostics.CodeAnalysis;
 using System.Reflection;
 using System.Reflection.Emit;
+using System.Threading;
 
 #if DEBUG // until it can be fully implemented
 namespace System.Text.RegularExpressions
@@ -97,14 +98,19 @@ namespace System.Text.RegularExpressions
         }
 
         /// <summary>Generates a very simple factory method.</summary>
-        internal void GenerateCreateInstance(Type type)
+        private void GenerateCreateInstance([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] Type type)
         {
             // return new Type();
             Newobj(type.GetConstructor(Type.EmptyTypes)!);
             Ret();
         }
 
-        private void GenerateRegexDefaultCtor(string pattern, RegexOptions options, Type regexRunnerFactoryType, RegexCode code, TimeSpan matchTimeout)
+        private void GenerateRegexDefaultCtor(
+            string pattern,
+            RegexOptions options,
+            [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] Type regexRunnerFactoryType,
+            RegexCode code,
+            TimeSpan matchTimeout)
         {
             // Call the base ctor and store pattern, options, and factory.
             // base.ctor();
@@ -241,7 +247,12 @@ namespace System.Text.RegularExpressions
         }
 
         /// <summary>Begins the definition of a new type with a specified base class</summary>
-        private static TypeBuilder DefineType(ModuleBuilder moduleBuilder, string typeName, bool isPublic, bool isSealed, Type inheritFromClass)
+        private static TypeBuilder DefineType(
+            ModuleBuilder moduleBuilder,
+            string typeName,
+            bool isPublic,
+            bool isSealed,
+            [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type inheritFromClass)
         {
             TypeAttributes attrs = TypeAttributes.Class | TypeAttributes.BeforeFieldInit | (isPublic ? TypeAttributes.Public : TypeAttributes.NotPublic);
             if (isSealed)
index 7316eb8..4315c93 100644 (file)
@@ -15,6 +15,9 @@ namespace System.Text.RegularExpressions
     /// RegexCompiler translates a block of RegexCode to MSIL, and creates a
     /// subclass of the RegexRunner type.
     /// </summary>
+    [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2060:MakeGenericMethod",
+        Target = "M:System.Text.RegularExpressions.RegexCompiler.#cctor",
+        Justification = "The referenced methods don't have any DynamicallyAccessedMembers annotations. See https://github.com/mono/linker/issues/1727")]
     internal abstract class RegexCompiler
     {
         private static readonly FieldInfo s_runtextbegField = RegexRunnerField("runtextbeg");
index 38f9a9e..b9060a7 100644 (file)
@@ -192,11 +192,13 @@ namespace System.Reflection.Emit
             }
         }
 
+        [return: DynamicallyAccessedMembersAttribute(DynamicallyAccessedMemberTypes.All)]
         public Type? CreateType()
         {
             return _tb.CreateType();
         }
 
+        [return: DynamicallyAccessedMembersAttribute(DynamicallyAccessedMemberTypes.All)]
         public TypeInfo? CreateTypeInfo()
         {
             return _tb.CreateTypeInfo();
index 3febd60..a5b807d 100644 (file)
@@ -796,10 +796,9 @@ namespace System.Reflection.Emit
         // We require emitted types to have all members on their bases to be accessible.
         // This is basically an identity function for `this`.
         [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2083:UnrecognizedReflectionPattern",
-            Justification = "Reflection emitted types have all of their members")]
+            Justification = "Reflection.Emit is not subject to trimming")]
         [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]
-        public
-        TypeInfo? CreateTypeInfo()
+        public TypeInfo? CreateTypeInfo()
         {
             /* handle nesting_type */
             if (createTypeCalled)