2011-01-05 14 views
5

Continúo trabajando en una impresora para expresiones citadas con F #, no tiene que ser perfecto, pero me gustaría ver qué es posible. Los patrones activos en Microsoft.FSharp.Quotations.Patterns y Microsoft.FSharp.Quotations.DerivedPatterns utilizados para descomponer expresiones entrecomilladas generalmente proporcionarán MemberInfo instancias cuando corresponda, estos se pueden usar para obtener el nombre de una propiedad, función, etc. y su tipo de "declaración", como un módulo o clase estática . El problema es que solo sé cómo obtener el CompiledName de estas instancias, pero me gustaría el nombre F #. Por ejemplo,Cómo obtener el nombre F # de un módulo, función, etc. De Expresión de cita cotejada

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

¿Cómo puede ser reescrito este partido para volver ("List", "mapi")? ¿Es posible?

FYI, aquí está mi solución pulido final a partir de Stringer Bell y la ayuda de 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

Estoy bastante seguro de que puede comprobar los atributos personalizados de un método para 'CompilationSourceNameAttribute'; su propiedad 'SourceName' debe ser lo que quieras. Publicaba una respuesta con una muestra adecuada, pero no estoy cerca de una computadora de desarrollo en este momento. – pblasucci

+0

¡Gracias por compartir! También podría publicarlo en http://fssnip.net de Tomas: D – Stringer

+0

@Stringer Bell: pensó que podría interesarle, comencé un proyecto de código abierto Unquote (http://code.google.com/p/unquote /) que incorpora una impresora de presupuestos, de la que hablo más específicamente aquí: http://stackoverflow.com/questions/1448961/is-there-any-built-in-function-for-human-readable-f-quotations/ 4948660 # 4948660 –

Respuesta

4

Usted puede utilizar F # unidad motriz para tal fin:

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

Sin embargo, no lo creo pensar si es posible recuperar el nombre de la función con powerpack.

Editar:

Como dio a entender por pblasucci, puede utilizar CompilationSourceName atributo para recuperar nombre de la fuente:

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

¡Agradable, gracias! _ –

Cuestiones relacionadas