Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 0 additions & 50 deletions src/linker/Linker.Steps/MarkStep.cs
Original file line number Diff line number Diff line change
Expand Up @@ -824,7 +824,6 @@ void MarkCustomAttributes (ICustomAttributeProvider provider, in DependencyInfo
continue;

MarkCustomAttribute (ca, reason);
MarkSpecialCustomAttributeDependencies (ca, provider);
}
}

Expand Down Expand Up @@ -1563,7 +1562,6 @@ bool ProcessLateMarkedAttributes ()
markOccurred = true;
using (ScopeStack.PushScope (scope)) {
MarkCustomAttribute (customAttribute, reason);
MarkSpecialCustomAttributeDependencies (customAttribute, provider);
}
}

Expand Down Expand Up @@ -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)
Expand All @@ -2090,34 +2068,6 @@ void MarkXmlSchemaProvider (TypeDefinition type, CustomAttribute attribute)
}
}

protected virtual void MarkTypeConverterLikeDependency (CustomAttribute attribute, Func<MethodDefinition, bool> 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)
Expand Down
Original file line number Diff line number Diff line change
@@ -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 () { }
}
}
}