-
-
Notifications
You must be signed in to change notification settings - Fork 142
Description
AsmResolver Version
4.11.2
.NET Version
.NET 6.0
Operating System
Windows
Describe the Bug
Class types that use a custom attribute type decorator do not update the class type's custom attribute's fixed arguments to reflect the attribute type's new name upon renaming.
This can be explained better with code. Let's suppose we have two type definitions (TypeDefinition) for classes ClassA and ClassB. ClassB has an attribute decorator of MyCustomAttribute which takes one argument, a type. ClassB is instantiated as follows:
[MyCustomAttribute(typeof(ClassA))]
public class ClassB {
....
}Let's say the TypeDefinition variable for ClassA is stored as a variable as follows:
TypeDefinition tDefForClassA = Module.GetAllTypes().Where(x => string.Equals(x.Name?.Value, "ClassA"));If I were to rename ClassA via:
tDefForAttr.tDefForClassA = "ClassC"You would see that the arguments for the CustomAttributes field on ClassB's TypeDefinition object does not update to reflect the new argument of ClassC.
How To Reproduce
Create an example project with the following file:
using System;
namespace TestProject
{
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
class MyCustomAttribute : Attribute
{
public Type Type { get; set; }
public MyCustomAttribute(Type outputType)
{
Type = outputType;
}
}
internal class ClassA
{
}
[MyCustomAttribute(typeof(ClassA))]
internal class ClassB
{
internal void HelloWorld()
{
Console.WriteLine("Hello, world!");
}
}
internal class Program
{
public static void Main(string[] args)
{
var b = new ClassB();
b.HelloWorld();
}
}
}Compile to TestProject.exe. Then, in a separate project leveraging AsmResolver, use the following code to update the ClassA type definition name:
var module = ModuleDefinition.FromFile("TestProject.exe");
TypeDefinition tDefClassA = module.GetAllTypes().First(x => x.Name == "ClassA");
tDefClassA.Name = "ClassC";
_editor.Module.Write("SecondTest.exe");If you were to inspect ClassB's type definition via:
TypeDefinition tDefClassB = module.GetAllTypes().First(x => x.Name == "ClassB");
// Inspect tDefClassB.CustomAttributes.SignatureYou would see that the signature here still references ClassA which no longer exists in the assembly.
Expected Behavior
The arguments to custom attribute decorator of classes getting updated as required. For example, ClassC should now populate the arguments of the signature in the previous code instead of ClassA.
Actual Behavior
ClassA remains referenced as an argument to the attribute constructor even though this type no longer exists.
Additional Context
No response