mardi 4 janvier 2022

MonoCecil giving the wrong method name when reading an F# binary by reflection

I have a net 6 F# binary that contains some methods, on which some have one or many [<TestCategory(CategoryName)>] attribute defined on them. My goal is to use reflection, from a C# application, to read and gather the fully qualified names of those test methods.

In order to achieve this, I am trying to use the Mono.Cecil library in order to read the information from the F# binary. This seems to work pretty well with C# binaries, but not so much with F# ones. The problem I am encountering is that the fully qualified name (and name) properties of the method Mono.Cecil gives me is under the format "BinaryName.ModuleName.f@LineNumber", instead of giving me "BinaryName.ModuleName.ActualMethodName".

Here is how I get the information via reflection using Mono.Cecil.

    private static IEnumerable<GenericModule> ReadModulesRecursively(string assemblyPath)
    {
        var modules = new List<GenericModule>();

        var assemblyDefinition = AssemblyDefinition.ReadAssembly(assemblyPath);
        foreach (var module in assemblyDefinition.Modules)
        {
            var moduleTypes = module.Types.Select(ToGenericType); // Construct a DTO containing only what I want
            modules.Add(new GenericModule(module.Name, moduleTypes));
        }

        return modules;
    }

    private static GenericType ToGenericType(TypeDefinition typeDefinition)
    {
        return new GenericType(typeDefinition.Name, typeDefinition.CustomAttributes.Select(ToGenericAttribute), typeDefinition.Methods.Select(ToGenericMethod));
    }

    private static GenericMethod ToGenericMethod(MethodDefinition methodDefinition)
    {
        return new GenericMethod(methodDefinition.Name, $"{methodDefinition.DeclaringType.FullName}.{methodDefinition.Name}", methodDefinition.DeclaringType.FullName,
            methodDefinition.CustomAttributes.Select(ToGenericAttribute));
    }

And here is an example of a F# method declaration I am trying to get information on, in the F# binary:

module myModule

<open statements...>

[<TestClass>]
[<DeploymentItem("Deploy1")>]
[<DeploymentItem("Deploy2")>]
type Tests ()=

    [<TestMethod>]
    [<TestCategory("Cat1")>]
    [<TestCategory("Cat2")>]
    member x.``This is a test title`` () =
        ()

So the problem here seems to be that the MonoCecil MethodDefinition type doesn't contain the right Name and FullName property values.

Is this a known issue with MonoCecil and F#, or am I doing something wrong?





Aucun commentaire:

Enregistrer un commentaire