Skip to content

Commit afbebfe

Browse files
authored
Remove DAM annotations from enum converter (#100347)
* Remove DAM annotations from enum converter * expand the debug assert for enum types * FB * FB2
1 parent 0c92024 commit afbebfe

File tree

5 files changed

+72
-16
lines changed

5 files changed

+72
-16
lines changed

src/libraries/System.ComponentModel.TypeConverter/ref/System.ComponentModel.TypeConverter.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -428,9 +428,8 @@ public DoubleConverter() { }
428428
}
429429
public partial class EnumConverter : System.ComponentModel.TypeConverter
430430
{
431-
public EnumConverter([System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicFields | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] System.Type type) { }
431+
public EnumConverter(System.Type type) { }
432432
protected virtual System.Collections.IComparer Comparer { get { throw null; } }
433-
[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicFields | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)]
434433
protected System.Type EnumType { get { throw null; } }
435434
protected System.ComponentModel.TypeConverter.StandardValuesCollection? Values { get { throw null; } set { } }
436435
public override bool CanConvertFrom(System.ComponentModel.ITypeDescriptorContext? context, System.Type sourceType) { throw null; }

src/libraries/System.ComponentModel.TypeConverter/src/Resources/Strings.resx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@
7676
<data name="EnumConverterInvalidValue" xml:space="preserve">
7777
<value>The value '{0}' is not a valid value for the enum '{1}'.</value>
7878
</data>
79+
<data name="EnumInvalidValue" xml:space="preserve">
80+
<value>Type provided must be an Enum.</value>
81+
</data>
7982
<data name="ErrorInvalidEventHandler" xml:space="preserve">
8083
<value>Invalid event handler for the {0} event.</value>
8184
</data>

src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/EnumConverter.cs

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System.Collections;
55
using System.Collections.Generic;
66
using System.ComponentModel.Design.Serialization;
7+
using System.Diagnostics;
78
using System.Diagnostics.CodeAnalysis;
89
using System.Globalization;
910
using System.Reflection;
@@ -20,12 +21,16 @@ public class EnumConverter : TypeConverter
2021
/// Initializes a new instance of the <see cref='System.ComponentModel.EnumConverter'/> class for the given
2122
/// type.
2223
/// </summary>
23-
public EnumConverter([DynamicallyAccessedMembers(TypeDescriptor.ReflectTypesDynamicallyAccessedMembers)] Type type)
24+
public EnumConverter(Type type)
2425
{
26+
if (!type.IsEnum && !type.Equals(typeof(Enum)))
27+
{
28+
throw new ArgumentException(SR.EnumInvalidValue);
29+
}
30+
2531
EnumType = type;
2632
}
2733

28-
[DynamicallyAccessedMembers(TypeDescriptor.ReflectTypesDynamicallyAccessedMembers)]
2934
protected Type EnumType { get; }
3035

3136
protected StandardValuesCollection? Values { get; set; }
@@ -156,7 +161,10 @@ private static long GetEnumValue(bool isUnderlyingTypeUInt64, object enumVal, Cu
156161
}
157162
else
158163
{
159-
FieldInfo? info = EnumType.GetField(enumName);
164+
[UnconditionalSuppressMessage("Trimming", "IL2075:", Justification = "Trimmer does not trim Enums")]
165+
FieldInfo? GetEnumField(string name) => EnumType.GetField(name);
166+
167+
FieldInfo? info = GetEnumField(enumName);
160168
if (info != null)
161169
{
162170
return new InstanceDescriptor(info, null);
@@ -227,9 +235,27 @@ public override StandardValuesCollection GetStandardValues(ITypeDescriptorContex
227235
// We need to get the enum values in this rather round-about way so we can filter
228236
// out fields marked Browsable(false). Note that if multiple fields have the same value,
229237
// the behavior is undefined, since what we return are just enum values, not names.
230-
Type reflectType = TypeDescriptor.GetReflectionType(EnumType) ?? EnumType;
238+
// Given that EnumType is constrained to be an enum, we suppress calls for reflection with Enum.
239+
240+
[UnconditionalSuppressMessage("Trimming", "IL2067:", Justification = "Trimmer does not trim Enums")]
241+
[return: DynamicallyAccessedMembers(TypeDescriptor.ReflectTypesDynamicallyAccessedMembers)]
242+
static Type GetTypeDescriptorReflectionType(Type enumType) => TypeDescriptor.GetReflectionType(enumType);
243+
244+
Type _reflectType = GetTypeDescriptorReflectionType(EnumType);
245+
FieldInfo[]? fields;
246+
247+
if (_reflectType == null)
248+
{
249+
[UnconditionalSuppressMessage("Trimming", "IL2070:", Justification = "Trimmer does not trim Enums")]
250+
static FieldInfo[]? GetPublicStaticEnumFields(Type type) => type.GetFields(BindingFlags.Public | BindingFlags.Static);
251+
252+
fields = GetPublicStaticEnumFields(EnumType);
253+
}
254+
else
255+
{
256+
fields = _reflectType.GetFields(BindingFlags.Public | BindingFlags.Static);
257+
}
231258

232-
FieldInfo[]? fields = reflectType.GetFields(BindingFlags.Public | BindingFlags.Static);
233259
ArrayList? objValues = null;
234260

235261
if (fields != null && fields.Length > 0)

src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/ReflectTypeDescriptionProvider.cs

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ private static Dictionary<object, IntrinsicTypeConverterData> IntrinsicTypeConve
193193
//
194194
[typeof(Array)] = new IntrinsicTypeConverterData((type) => new ArrayConverter()),
195195
[typeof(ICollection)] = new IntrinsicTypeConverterData((type) => new CollectionConverter()),
196-
[typeof(Enum)] = new IntrinsicTypeConverterData((type) => CreateEnumConverter(type), cacheConverterInstance: false),
196+
[typeof(Enum)] = new IntrinsicTypeConverterData((type) => new EnumConverter(type), cacheConverterInstance: false),
197197
[s_intrinsicNullableKey] = new IntrinsicTypeConverterData((type) => CreateNullableConverter(type), cacheConverterInstance: false),
198198
[s_intrinsicReferenceKey] = new IntrinsicTypeConverterData((type) => new ReferenceConverter(type), cacheConverterInstance: false),
199199
});
@@ -204,14 +204,6 @@ private static Dictionary<object, IntrinsicTypeConverterData> IntrinsicTypeConve
204204
Justification = "IntrinsicTypeConverters is marked with RequiresUnreferencedCode. It is the only place that should call this.")]
205205
private static NullableConverter CreateNullableConverter(Type type) => new NullableConverter(type);
206206

207-
[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2067:UnrecognizedReflectionPattern",
208-
Justification = "Trimmer does not trim enums")]
209-
private static EnumConverter CreateEnumConverter(Type type)
210-
{
211-
Debug.Assert(type.IsEnum || type == typeof(Enum));
212-
return new EnumConverter(type);
213-
}
214-
215207
private static Hashtable PropertyCache => LazyInitializer.EnsureInitialized(ref s_propertyCache, () => new Hashtable());
216208

217209
private static Hashtable EventCache => LazyInitializer.EnsureInitialized(ref s_eventCache, () => new Hashtable());

src/libraries/apicompat/ApiCompatBaseline.NetCoreAppLatestStable.xml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,12 @@
8585
<Left>net8.0/netstandard.dll</Left>
8686
<Right>net9.0/netstandard.dll</Right>
8787
</Suppression>
88+
<Suppression>
89+
<DiagnosticId>CP0014</DiagnosticId>
90+
<Target>M:System.ComponentModel.EnumConverter.#ctor(System.Type)$0:[T:System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute]</Target>
91+
<Left>net8.0/netstandard.dll</Left>
92+
<Right>net9.0/netstandard.dll</Right>
93+
</Suppression>
8894
<Suppression>
8995
<DiagnosticId>CP0014</DiagnosticId>
9096
<Target>P:System.ComponentModel.DesignerAttribute.DesignerBaseTypeName:[T:System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute]</Target>
@@ -109,6 +115,12 @@
109115
<Left>net8.0/netstandard.dll</Left>
110116
<Right>net9.0/netstandard.dll</Right>
111117
</Suppression>
118+
<Suppression>
119+
<DiagnosticId>CP0014</DiagnosticId>
120+
<Target>P:System.ComponentModel.EnumConverter.EnumType:[T:System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute]</Target>
121+
<Left>net8.0/netstandard.dll</Left>
122+
<Right>net9.0/netstandard.dll</Right>
123+
</Suppression>
112124
<Suppression>
113125
<DiagnosticId>CP0014</DiagnosticId>
114126
<Target>M:System.ComponentModel.DesignerAttribute.#ctor(System.String,System.String)$0:[T:System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute]</Target>
@@ -301,6 +313,12 @@
301313
<Left>net8.0/System.ComponentModel.TypeConverter.dll</Left>
302314
<Right>net9.0/System.ComponentModel.TypeConverter.dll</Right>
303315
</Suppression>
316+
<Suppression>
317+
<DiagnosticId>CP0014</DiagnosticId>
318+
<Target>M:System.ComponentModel.EnumConverter.#ctor(System.Type)$0:[T:System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute]</Target>
319+
<Left>net8.0/System.ComponentModel.TypeConverter.dll</Left>
320+
<Right>net9.0/System.ComponentModel.TypeConverter.dll</Right>
321+
</Suppression>
304322
<Suppression>
305323
<DiagnosticId>CP0014</DiagnosticId>
306324
<Target>P:System.ComponentModel.DesignerAttribute.DesignerBaseTypeName:[T:System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute]</Target>
@@ -325,6 +343,12 @@
325343
<Left>net8.0/System.ComponentModel.TypeConverter.dll</Left>
326344
<Right>net9.0/System.ComponentModel.TypeConverter.dll</Right>
327345
</Suppression>
346+
<Suppression>
347+
<DiagnosticId>CP0014</DiagnosticId>
348+
<Target>P:System.ComponentModel.EnumConverter.EnumType:[T:System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute]</Target>
349+
<Left>net8.0/System.ComponentModel.TypeConverter.dll</Left>
350+
<Right>net9.0/System.ComponentModel.TypeConverter.dll</Right>
351+
</Suppression>
328352
<Suppression>
329353
<DiagnosticId>CP0014</DiagnosticId>
330354
<Target>M:System.ComponentModel.DesignerAttribute.#ctor(System.String,System.String)$0:[T:System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute]</Target>
@@ -409,6 +433,12 @@
409433
<Left>net8.0/System.dll</Left>
410434
<Right>net9.0/System.dll</Right>
411435
</Suppression>
436+
<Suppression>
437+
<DiagnosticId>CP0014</DiagnosticId>
438+
<Target>M:System.ComponentModel.EnumConverter.#ctor(System.Type)$0:[T:System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute]</Target>
439+
<Left>net8.0/System.dll</Left>
440+
<Right>net9.0/System.dll</Right>
441+
</Suppression>
412442
<Suppression>
413443
<DiagnosticId>CP0014</DiagnosticId>
414444
<Target>P:System.ComponentModel.DesignerAttribute.DesignerBaseTypeName:[T:System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute]</Target>
@@ -433,4 +463,10 @@
433463
<Left>net8.0/System.dll</Left>
434464
<Right>net9.0/System.dll</Right>
435465
</Suppression>
466+
<Suppression>
467+
<DiagnosticId>CP0014</DiagnosticId>
468+
<Target>P:System.ComponentModel.EnumConverter.EnumType:[T:System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute]</Target>
469+
<Left>net8.0/System.dll</Left>
470+
<Right>net9.0/System.dll</Right>
471+
</Suppression>
436472
</Suppressions>

0 commit comments

Comments
 (0)