2011-01-05 16 views
5

Continuo a lavorare su una stampante per le espressioni citate F #, non deve essere perfetto, ma mi piacerebbe vedere cosa è possibile. I pattern attivi in ​​Microsoft.FSharp.Quotations.Patterns e Microsoft.FSharp.Quotations.DerivedPatterns utilizzati per la decomposizione di espressioni citate forniranno in genere le istanze MemberInfo quando appropriato, questi possono essere utilizzati per ottenere il nome di una proprietà, funzione, ecc. E il loro tipo "dichiarante", come un modulo o una classe statica . Il problema è, so solo come ottenere il CompiledName da queste istanze, ma mi piacerebbe il nome F #. Ad esempio,Come ottenere il nome F # di un modulo, funzione, ecc. Da corrispondenza espressione quotata

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

Come può essere riscritta questa corrispondenza per restituire ("List", "mapi")? È possibile?

Cordiali saluti, ecco la mia soluzione lucido finale Stringer Bell e l'aiuto di pblasucci:

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

Sono abbastanza sicuro che è possibile controllare gli attributi personalizzati di un metodo per la 'CompilationSourceNameAttribute'; la sua proprietà 'SourceName' dovrebbe essere quello che vuoi. Pubblicheremo una risposta con un campione appropriato, ma al momento non sono vicino a un computer di sviluppo. – pblasucci

+0

Grazie per aver condiviso! Puoi anche postarlo su Tomas's http://fssnip.net: D – Stringer

+0

@Stringer Bell - pensavo che tu possa essere interessato, ho avviato un progetto open source Unquote (http://code.google.com/p/unquote /) che incorpora una stampante di quotazioni, di cui parlo più specificamente qui: http://stackoverflow.com/questions/1448961/is-there-any-built-in-function-for-human-readable-f-quotations/ 4948660 # 4948660 –

risposta

4

È possibile utilizzare F # PowerPack a tal fine:

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

Tuttavia, non lo faccio pensa se è possibile recuperare il nome della funzione con powerpack.

Edit:

Come accennato da pblasucci, è possibile utilizzare l'attributo CompilationSourceName per il recupero nome di origine:

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

Bello, grazie! _ –