[NativeAOT] Fix transforming [Preserve] into [DynamicDependency] for generic types and generic methods (#18854)

I noticed that we're generating invalid DynamicDependency attributes for generic types and methods. For example for the `void Activated(T sender)` method of `UIKit.UIGestureRecognizer.Callback<T>`:

```c#
// before:
[DynamicDependency("Activated(T)", typeof(UIKit.UIGestureRecognizer.Callback<>))]

// after:
[DynamicDependency("Activated(`0)", "UIKit.UIGestureRecognizer.Callback`1", "Microsoft.MacCatalyst")]
```

---------

Co-authored-by: Simon Rozsival <simon@rozsival.com>
This commit is contained in:
Šimon Rozsíval 2023-08-29 08:02:29 +02:00 коммит произвёл GitHub
Родитель 894c7e5220
Коммит 108967ab7e
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
2 изменённых файлов: 45 добавлений и 1 удалений

Просмотреть файл

@ -498,6 +498,19 @@ namespace Xamarin.Linker {
}
}
public MethodReference DynamicDependencyAttribute_ctor__String_String_String {
get {
return GetMethodReference (CorlibAssembly,
System_Diagnostics_CodeAnalysis_DynamicDependencyAttribute,
".ctor",
".ctor(String,String,String)",
isStatic: false,
System_String,
System_String,
System_String);
}
}
public MethodReference RuntimeTypeHandle_Equals {
get {
if (configuration.Application.XamarinRuntime == XamarinRuntime.MonoVM) {
@ -1246,12 +1259,27 @@ namespace Xamarin.Linker {
public CustomAttribute CreateDynamicDependencyAttribute (string memberSignature, TypeDefinition type)
{
if (type.HasGenericParameters) {
var typeName = Xamarin.Utils.DocumentationComments.GetSignature (type);
var assemblyName = type.Module.Assembly.Name.Name;
return CreateDynamicDependencyAttribute (memberSignature, typeName, assemblyName);
}
var attribute = new CustomAttribute (DynamicDependencyAttribute_ctor__String_Type);
attribute.ConstructorArguments.Add (new CustomAttributeArgument (System_String, memberSignature));
attribute.ConstructorArguments.Add (new CustomAttributeArgument (System_Type, type));
return attribute;
}
public CustomAttribute CreateDynamicDependencyAttribute (string memberSignature, string typeName, string assemblyName)
{
var attribute = new CustomAttribute (DynamicDependencyAttribute_ctor__String_String_String);
attribute.ConstructorArguments.Add (new CustomAttributeArgument (System_String, memberSignature));
attribute.ConstructorArguments.Add (new CustomAttributeArgument (System_String, typeName));
attribute.ConstructorArguments.Add (new CustomAttributeArgument (System_String, assemblyName));
return attribute;
}
public CustomAttribute CreateDynamicDependencyAttribute (DynamicallyAccessedMemberTypes memberTypes, TypeDefinition type)
{
var attribute = new CustomAttribute (DynamicDependencyAttribute_ctor__DynamicallyAccessedMemberTypes_Type);

Просмотреть файл

@ -28,7 +28,7 @@ namespace Xamarin.Utils {
public static string GetSignature (TypeDefinition type)
{
if (type.IsNested)
return type.Name;
return type.FullName.Replace ('/', '.');
return type.FullName;
}
@ -41,6 +41,11 @@ namespace Xamarin.Utils {
{
var sb = new StringBuilder ();
sb.Append (method.Name.Replace ('.', '#'));
if (method.HasGenericParameters) {
sb.Append ($"``{method.GenericParameters.Count}");
}
sb.Append ('(');
for (var i = 0; i < method.Parameters.Count; i++) {
if (i > 0)
@ -74,6 +79,17 @@ namespace Xamarin.Utils {
return;
}
if (type is GenericParameter gp) {
if (gp.Type == GenericParameterType.Type) {
sb.Append ('`');
} else {
sb.Append ("``");
}
sb.Append (gp.Position.ToString ());
return;
}
sb.Append (type.FullName.Replace ('/', '.'));
}
}