2011-01-05 16 views
5

Nadal pracuję na drukarce dla wyrażeń cytowanych w F #, nie musi być idealnie, ale chciałbym zobaczyć, co jest możliwe. Aktywne wzorce w Microsoft.FSharp.Quotations.Patterns i Microsoft.FSharp.Quotations.DerivedPatterns używane do dekomponowania cytowanych wyrażeń zwykle dostarczają instancji MemberInfo, gdy jest to właściwe, mogą one służyć do uzyskania nazwy właściwości, funkcji itp. Oraz ich typu "deklarującego", takiego jak moduł lub klasa statyczna . Problem polega na tym, że wiem tylko, jak uzyskać CompiledName z tych przypadków, ale chciałbym nazwę F #. Na przykład:Jak uzyskać F # Nazwa modułu, funkcji itp. Z cytowanego wyrażenia Dopasuj

> <@ List.mapi (fun i j -> i+j) [1;2;3] @> |> (function Call(_,mi,_) -> mi.DeclaringType.Name, mi.Name);; 
val it : string * string = ("ListModule", "MapIndexed") 

Jak można przepisać ten mecz, aby powrócić ("List", "mapi")? Czy to możliwe?

FYI, tutaj jest moja ostateczna polerowane rozwiązanie z Stringer Bell i pomoc pblasucci za:

let moduleSourceName (declaringType:Type) = 
    FSharpEntity.FromType(declaringType).DisplayName 

let methodSourceName (mi:MemberInfo) = 
    mi.GetCustomAttributes(true) 
    |> Array.tryPick 
      (function 
       | :? CompilationSourceNameAttribute as csna -> Some(csna) 
       | _ -> None) 
    |> (function | Some(csna) -> csna.SourceName | None -> mi.Name) 

//usage: 
let sourceNames = 
    <@ List.mapi (fun i j -> i+j) [1;2;3] @> 
    |> (function Call(_,mi,_) -> mi.DeclaringType |> moduleSourceName, mi |> methodSourceName); 
+2

Jestem całkiem pewien, że można sprawdzić za zwyczaj metoda atrybuty 'CompilationSourceNameAttribute'; jego właściwość 'SourceName' powinna być tym, czego potrzebujesz. Postawiłbym odpowiedź z odpowiednią próbką, ale w tej chwili nie jestem w pobliżu komputera programisty. – pblasucci

+0

Dzięki za udostępnienie! Możesz również opublikować go na http://subx.com: D – Stringer

+0

@Stringer Bell - pomyślałem, że może Cię to zainteresować, rozpocząłem Unquote projektu open source (http://code.google.com/p/unquote /), który zawiera drukarkę ofertową, o której mówię tutaj bardziej szczegółowo: http://stackoverflow.com/questions/1448961/is-there-any-built-in-function- for-human-readable-f-quotations/ 4948660 # 4948660 –

Odpowiedz

4

Można użyć F # PowerPack do tego celu:

open Microsoft.FSharp.Metadata 
... 
| Call(_, mi, _) -> 
    let ty = Microsoft.FSharp.Metadata.FSharpEntity.FromType(mi.DeclaringType) 
    let name = ty.DisplayName // name is List 

Jednakże, nie wiem pomyśl, czy możliwe jest pobranie nazwy funkcji za pomocą powerpacka.

Edit:

Jak zasugerował przez pblasucci, można użyć atrybutu CompilationSourceName do pobierania nazwy źródło:

let infos = mi.DeclaringType.GetMember(mi.Name) 
let att = infos.[0].GetCustomAttributes(true) 
let fName = 
    (att.[1] :?> CompilationSourceNameAttribute).SourceName // fName is mapi 
+0

Miło, dzięki! _ –