Monday, June 16, 2014

F# - getting function name

Getting F# function name and method info object is tricky but possible:

let getFunctionName f =
let type' = f.GetType()
let method' = type'.GetMethods() |> Array.find (fun m -> m.Name="Invoke")
let il = method'.GetMethodBody().GetILAsByteArray()
let methodCodes = [byte OpCodes.Call.Value;byte OpCodes.Callvirt.Value]
let position = il |> Array.findIndex(fun x -> methodCodes |> List.exists ((=)x))
let metadataToken = BitConverter.ToInt32(il, position+1)
let actualMethod = type'.Module.ResolveMethod metadataToken
sprintf "%s.%s" actualMethod.DeclaringType.FullName actualMethod.Name

Unfortunately, this code only works when F# compiler does not inline function body into calling method.