diff --git a/src/linker/Linker.Steps/MarkStep.cs b/src/linker/Linker.Steps/MarkStep.cs index cd930e5ade19..8c6565b2087c 100644 --- a/src/linker/Linker.Steps/MarkStep.cs +++ b/src/linker/Linker.Steps/MarkStep.cs @@ -824,7 +824,6 @@ void MarkCustomAttributes (ICustomAttributeProvider provider, in DependencyInfo continue; MarkCustomAttribute (ca, reason); - MarkSpecialCustomAttributeDependencies (ca, provider); } } @@ -1563,7 +1562,6 @@ bool ProcessLateMarkedAttributes () markOccurred = true; using (ScopeStack.PushScope (scope)) { MarkCustomAttribute (customAttribute, reason); - MarkSpecialCustomAttributeDependencies (customAttribute, provider); } } @@ -2044,30 +2042,10 @@ void MarkTypeSpecialCustomAttributes (TypeDefinition type) if (MarkMethodsIf (type.Methods, MethodDefinitionExtensions.IsPublicInstancePropertyMethod, new DependencyInfo (DependencyKind.ReferencedBySpecialAttribute, type))) Tracer.AddDirectDependency (attribute, new DependencyInfo (DependencyKind.CustomAttribute, type), marked: false); break; - case "TypeDescriptionProviderAttribute" when attrType.Namespace == "System.ComponentModel": - MarkTypeConverterLikeDependency (attribute, l => l.IsDefaultConstructor (), type); - break; } } } - // - // Used for known framework attributes which can be applied to any element - // - bool MarkSpecialCustomAttributeDependencies (CustomAttribute ca, ICustomAttributeProvider provider) - { - var dt = ca.Constructor.DeclaringType; - if (dt.Name == "TypeConverterAttribute" && dt.Namespace == "System.ComponentModel") { - MarkTypeConverterLikeDependency (ca, l => - l.IsDefaultConstructor () || - l.Parameters.Count == 1 && l.Parameters[0].ParameterType.IsTypeOf ("System", "Type"), - provider); - return true; - } - - return false; - } - void MarkMethodSpecialCustomAttributes (MethodDefinition method) { if (!method.HasCustomAttributes) @@ -2090,34 +2068,6 @@ void MarkXmlSchemaProvider (TypeDefinition type, CustomAttribute attribute) } } - protected virtual void MarkTypeConverterLikeDependency (CustomAttribute attribute, Func predicate, ICustomAttributeProvider provider) - { - var args = attribute.ConstructorArguments; - if (args.Count < 1) - return; - - TypeDefinition? typeDefinition = null; - switch (attribute.ConstructorArguments[0].Value) { - case string s: - if (!Context.TypeNameResolver.TryResolveTypeName (s, ScopeStack.CurrentScope.Origin.Provider, out TypeReference? typeRef, out AssemblyDefinition? assemblyDefinition)) - break; - typeDefinition = Context.TryResolve (typeRef); - if (typeDefinition != null) - MarkingHelpers.MarkMatchingExportedType (typeDefinition, assemblyDefinition, new DependencyInfo (DependencyKind.CustomAttribute, provider), ScopeStack.CurrentScope.Origin); - - break; - case TypeReference type: - typeDefinition = Context.Resolve (type); - break; - } - - if (typeDefinition == null) - return; - - Tracer.AddDirectDependency (attribute, new DependencyInfo (DependencyKind.CustomAttribute, provider), marked: false); - MarkMethodsIf (typeDefinition.Methods, predicate, new DependencyInfo (DependencyKind.ReferencedBySpecialAttribute, attribute)); - } - static readonly Regex DebuggerDisplayAttributeValueRegex = new Regex ("{[^{}]+}", RegexOptions.Compiled); void MarkTypeWithDebuggerDisplayAttribute (TypeDefinition type, CustomAttribute attribute) diff --git a/test/Mono.Linker.Tests.Cases/ComponentModel/TypeDescriptionProviderAttributeOnType.cs b/test/Mono.Linker.Tests.Cases/ComponentModel/TypeDescriptionProviderAttributeOnType.cs index 07de3e5f82d0..ca6099f9c72b 100644 --- a/test/Mono.Linker.Tests.Cases/ComponentModel/TypeDescriptionProviderAttributeOnType.cs +++ b/test/Mono.Linker.Tests.Cases/ComponentModel/TypeDescriptionProviderAttributeOnType.cs @@ -1,37 +1,69 @@ +using System; using System.ComponentModel; +using System.Diagnostics.CodeAnalysis; using Mono.Linker.Tests.Cases.Expectations.Assertions; using Mono.Linker.Tests.Cases.Expectations.Metadata; + namespace Mono.Linker.Tests.Cases.ComponentModel { - [TypeDescriptionProvider (typeof (CustomTDP))] - - [Kept] - [KeptAttributeAttribute (typeof (TypeDescriptionProviderAttribute))] - class CustomTypeDescriptionProvider_1 + [Reference ("System.dll")] + [ExpectedNoWarnings] + public class TypeDescriptionProviderAttributeOnType { - [Kept] - public CustomTypeDescriptionProvider_1 () + public static void Main () { + var r1 = new CustomTypeDescriptionProvider_1 (); + IInterface v = InterfaceTypeConverter.CreateVisual (typeof (System.String)); } + [TypeDescriptionProvider (typeof (CustomTDP))] [Kept] - [KeptBaseType (typeof (TypeDescriptionProvider))] - class CustomTDP : TypeDescriptionProvider + [KeptAttributeAttribute (typeof (TypeDescriptionProviderAttribute))] + class CustomTypeDescriptionProvider_1 { [Kept] - public CustomTDP () + public CustomTypeDescriptionProvider_1 () { } + + [Kept] + [KeptBaseType (typeof (TypeDescriptionProvider))] + class CustomTDP : TypeDescriptionProvider + { + [Kept] + public CustomTDP () + { + } + } } - } - [Reference ("System.dll")] - public class TypeDescriptionProviderAttributeOnType - { - public static void Main () + [Kept] + [KeptAttributeAttribute (typeof (TypeConverterAttribute))] + [TypeConverter (typeof (InterfaceTypeConverter))] + public interface IInterface + { } + + [Kept] + [KeptBaseType (typeof (TypeConverter))] + public class InterfaceTypeConverter : TypeConverter { - var r1 = new CustomTypeDescriptionProvider_1 (); + [Kept] + public static IInterface CreateVisual ( + [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] + Type visualType) + { + try { + return (IInterface) Activator.CreateInstance (visualType); + } catch { + } + + return null; + } + + [Kept] + public InterfaceTypeConverter () { } } } }