0 people like it.

Assembly signature generation for MSBuild

  1: 
  2: 
  3: 
  4: 
  5: 
  6: 
  7: 
  8: 
  9: 
 10: 
 11: 
 12: 
 13: 
 14: 
 15: 
 16: 
 17: 
 18: 
 19: 
 20: 
 21: 
 22: 
 23: 
 24: 
 25: 
 26: 
 27: 
 28: 
 29: 
 30: 
 31: 
 32: 
 33: 
 34: 
 35: 
 36: 
 37: 
 38: 
 39: 
 40: 
 41: 
 42: 
 43: 
 44: 
 45: 
 46: 
 47: 
 48: 
 49: 
 50: 
 51: 
 52: 
 53: 
 54: 
 55: 
 56: 
 57: 
 58: 
 59: 
 60: 
 61: 
 62: 
 63: 
 64: 
 65: 
 66: 
 67: 
 68: 
 69: 
 70: 
 71: 
 72: 
 73: 
 74: 
 75: 
 76: 
 77: 
 78: 
 79: 
 80: 
 81: 
 82: 
 83: 
 84: 
 85: 
 86: 
 87: 
 88: 
 89: 
 90: 
 91: 
 92: 
 93: 
 94: 
 95: 
 96: 
 97: 
 98: 
 99: 
100: 
101: 
102: 
103: 
104: 
105: 
106: 
107: 
108: 
module GASig

open System
open System.Collections.Generic
open System.IO
open System.Reflection

open Microsoft.Build.Framework
open Microsoft.Build.Utilities

let loadAssembly references (qname: string) =
    let name = qname.Split([|','|]).[0].ToLower()

    match references |> Array.tryFind (fun r -> Path.GetFileNameWithoutExtension(r).ToLower() = name) with
    | Some path -> Assembly.ReflectionOnlyLoadFrom(path)
    | None -> Assembly.ReflectionOnlyLoad(qname)

let outsort fd prefix data =
    data |> Seq.map (sprintf "%O") |> Seq.sort |> Seq.iter (fprintfn fd "%s%s" prefix)

let outasm fd (asm: Assembly) =
    asm.GetCustomAttributesData() |> outsort fd ""
    fprintfn fd "assembly %s\n" asm.FullName

    for t in asm.GetExportedTypes() |> Array.sortBy (fun t -> t.FullName) do
        t.GetCustomAttributesData() |> outsort fd ""
        if t.IsEnum then
            fprintfn fd "enum %O: %O = %s" t (t.GetEnumUnderlyingType()) (t.GetEnumNames() |> String.concat ", ")
        else
            fprintfn fd "%s %O [%O]" (if t.IsValueType then "struct" else "class") t t.Attributes
            if t.BaseType <> null then fprintfn fd "\tinherit %O" t.BaseType
            t.GetInterfaces() |> outsort fd "\tinterface "

            t.GetMembers()
            |> Seq.map (fun m ->
                m,
                match m with
                | :? EventInfo as e -> sprintf "e %O" e
                | :? FieldInfo as f -> sprintf "f %O" f
                | :? ConstructorInfo as c -> sprintf "c %s(%s)" c.Name (c.GetParameters() |> Array.map string |> String.concat ", ")
                | :? MethodInfo as m -> sprintf "m %O %s(%s)" m.ReturnType m.Name (m.GetParameters() |> Array.map string |> String.concat ", ")
                | :? PropertyInfo as p -> sprintf "p %O" p
                | :? Type as t -> sprintf "t %O" t
                | x -> failwithf "Unknown member %O" x)
            |> Seq.sortBy snd
            |> Seq.iter (fun (m, s) ->
                m.GetCustomAttributesData() |> outsort fd "\t"
                fprintfn fd "\t%s" s)
        fprintfn fd ""

let writeFileIfDiffers path contents =
    try
        let current = File.ReadAllText(path)
        if current <> contents then File.WriteAllText(path, contents)
    with e -> 
        File.WriteAllText(path, contents)

type ResolveHandlerScope(references) =
    let handler = ResolveEventHandler(fun _ args -> loadAssembly references args.Name)

    do AppDomain.CurrentDomain.add_ReflectionOnlyAssemblyResolve(handler)

    interface IDisposable with
        member this.Dispose() =
            AppDomain.CurrentDomain.remove_ReflectionOnlyAssemblyResolve(handler)

type AssemblySignatureGenerator() =
    inherit MarshalByRefObject()

    member this.Generate(input, output: string, references) =
        printfn "Generate %s" output
        use scope = new ResolveHandlerScope(references)
        let asm = Assembly.ReflectionOnlyLoadFrom(input)

        let fd = new StringWriter()
        outasm fd asm

        writeFileIfDiffers output (fd.ToString())

type GenerateAssemblySignature() =
    inherit Task()

    member val Input: ITaskItem = null with get, set
    member val Output: ITaskItem = null with get, set
    member val References: ITaskItem[] = [||] with get, set

    override this.Execute() =
        let domain = AppDomain.CreateDomain("gasig")

        try
            let gen = domain.CreateInstanceFromAndUnwrap(typeof<AssemblySignatureGenerator>.Assembly.Location, typeof<AssemblySignatureGenerator>.FullName)
            (gen :?> AssemblySignatureGenerator).Generate(this.Input.ItemSpec, this.Output.ItemSpec, this.References |> Array.map (fun r -> r.ItemSpec))
            true
        finally
            AppDomain.Unload(domain)

type GetAssemblySignatureList() =
    inherit Task()

    member val Inputs: ITaskItem[] = [||] with get, set

    override this.Execute() =
        printfn "Get!"
        for i in this.Inputs do
            let sigf = i.ItemSpec + ".sig"
            i.SetMetadata("Signature", if File.Exists(sigf) then sigf else i.ItemSpec)

        true
module GASig
namespace System
namespace System.Collections
namespace System.Collections.Generic
namespace System.IO
namespace System.Reflection
namespace Microsoft
val loadAssembly : references:string [] -> qname:string -> Assembly

Full name: GASig.loadAssembly
val references : string []
val qname : string
Multiple items
val string : value:'T -> string

Full name: Microsoft.FSharp.Core.Operators.string

--------------------
type string = String

Full name: Microsoft.FSharp.Core.string
val name : string
String.Split([<ParamArray>] separator: char []) : string []
String.Split(separator: string [], options: StringSplitOptions) : string []
String.Split(separator: char [], options: StringSplitOptions) : string []
String.Split(separator: char [], count: int) : string []
String.Split(separator: string [], count: int, options: StringSplitOptions) : string []
String.Split(separator: char [], count: int, options: StringSplitOptions) : string []
type Array =
  member Clone : unit -> obj
  member CopyTo : array:Array * index:int -> unit + 1 overload
  member GetEnumerator : unit -> IEnumerator
  member GetLength : dimension:int -> int
  member GetLongLength : dimension:int -> int64
  member GetLowerBound : dimension:int -> int
  member GetUpperBound : dimension:int -> int
  member GetValue : [<ParamArray>] indices:int[] -> obj + 7 overloads
  member Initialize : unit -> unit
  member IsFixedSize : bool
  ...

Full name: System.Array
val tryFind : predicate:('T -> bool) -> array:'T [] -> 'T option

Full name: Microsoft.FSharp.Collections.Array.tryFind
val r : string
type Path =
  static val DirectorySeparatorChar : char
  static val AltDirectorySeparatorChar : char
  static val VolumeSeparatorChar : char
  static val InvalidPathChars : char[]
  static val PathSeparator : char
  static member ChangeExtension : path:string * extension:string -> string
  static member Combine : [<ParamArray>] paths:string[] -> string + 3 overloads
  static member GetDirectoryName : path:string -> string
  static member GetExtension : path:string -> string
  static member GetFileName : path:string -> string
  ...

Full name: System.IO.Path
Path.GetFileNameWithoutExtension(path: string) : string
union case Option.Some: Value: 'T -> Option<'T>
val path : string
type Assembly =
  member CodeBase : string
  member CreateInstance : typeName:string -> obj + 2 overloads
  member EntryPoint : MethodInfo
  member Equals : o:obj -> bool
  member EscapedCodeBase : string
  member Evidence : Evidence
  member FullName : string
  member GetCustomAttributes : inherit:bool -> obj[] + 1 overload
  member GetCustomAttributesData : unit -> IList<CustomAttributeData>
  member GetExportedTypes : unit -> Type[]
  ...

Full name: System.Reflection.Assembly
Assembly.ReflectionOnlyLoadFrom(assemblyFile: string) : Assembly
union case Option.None: Option<'T>
Assembly.ReflectionOnlyLoad(rawAssembly: byte []) : Assembly
Assembly.ReflectionOnlyLoad(assemblyString: string) : Assembly
val outsort : fd:TextWriter -> prefix:string -> data:seq<'a> -> unit

Full name: GASig.outsort
val fd : TextWriter
val prefix : string
val data : seq<'a>
module Seq

from Microsoft.FSharp.Collections
val map : mapping:('T -> 'U) -> source:seq<'T> -> seq<'U>

Full name: Microsoft.FSharp.Collections.Seq.map
val sprintf : format:Printf.StringFormat<'T> -> 'T

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.sprintf
val sort : source:seq<'T> -> seq<'T> (requires comparison)

Full name: Microsoft.FSharp.Collections.Seq.sort
val iter : action:('T -> unit) -> source:seq<'T> -> unit

Full name: Microsoft.FSharp.Collections.Seq.iter
val fprintfn : textWriter:TextWriter -> format:Printf.TextWriterFormat<'T> -> 'T

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.fprintfn
val outasm : fd:TextWriter -> asm:Assembly -> unit

Full name: GASig.outasm
val asm : Assembly
Assembly.GetCustomAttributesData() : IList<CustomAttributeData>
property Assembly.FullName: string
val t : Type
Assembly.GetExportedTypes() : Type []
val sortBy : projection:('T -> 'Key) -> array:'T [] -> 'T [] (requires comparison)

Full name: Microsoft.FSharp.Collections.Array.sortBy
property Type.FullName: string
MemberInfo.GetCustomAttributesData() : IList<CustomAttributeData>
property Type.IsEnum: bool
Type.GetEnumUnderlyingType() : Type
Type.GetEnumNames() : string []
Multiple items
type String =
  new : value:char -> string + 7 overloads
  member Chars : int -> char
  member Clone : unit -> obj
  member CompareTo : value:obj -> int + 1 overload
  member Contains : value:string -> bool
  member CopyTo : sourceIndex:int * destination:char[] * destinationIndex:int * count:int -> unit
  member EndsWith : value:string -> bool + 2 overloads
  member Equals : obj:obj -> bool + 2 overloads
  member GetEnumerator : unit -> CharEnumerator
  member GetHashCode : unit -> int
  ...

Full name: System.String

--------------------
String(value: nativeptr<char>) : unit
String(value: nativeptr<sbyte>) : unit
String(value: char []) : unit
String(c: char, count: int) : unit
String(value: nativeptr<char>, startIndex: int, length: int) : unit
String(value: nativeptr<sbyte>, startIndex: int, length: int) : unit
String(value: char [], startIndex: int, length: int) : unit
String(value: nativeptr<sbyte>, startIndex: int, length: int, enc: Text.Encoding) : unit
val concat : sep:string -> strings:seq<string> -> string

Full name: Microsoft.FSharp.Core.String.concat
property Type.IsValueType: bool
property Type.Attributes: TypeAttributes
property Type.BaseType: Type
Type.GetInterfaces() : Type []
Type.GetMembers() : MemberInfo []
Type.GetMembers(bindingAttr: BindingFlags) : MemberInfo []
val m : MemberInfo
type EventInfo =
  inherit MemberInfo
  member AddEventHandler : target:obj * handler:Delegate -> unit
  member Attributes : EventAttributes
  member Equals : obj:obj -> bool
  member EventHandlerType : Type
  member GetAddMethod : unit -> MethodInfo + 1 overload
  member GetHashCode : unit -> int
  member GetOtherMethods : unit -> MethodInfo[] + 1 overload
  member GetRaiseMethod : unit -> MethodInfo + 1 overload
  member GetRemoveMethod : unit -> MethodInfo + 1 overload
  member IsMulticast : bool
  ...

Full name: System.Reflection.EventInfo
val e : EventInfo
type FieldInfo =
  inherit MemberInfo
  member Attributes : FieldAttributes
  member Equals : obj:obj -> bool
  member FieldHandle : RuntimeFieldHandle
  member FieldType : Type
  member GetHashCode : unit -> int
  member GetOptionalCustomModifiers : unit -> Type[]
  member GetRawConstantValue : unit -> obj
  member GetRequiredCustomModifiers : unit -> Type[]
  member GetValue : obj:obj -> obj
  member GetValueDirect : obj:TypedReference -> obj
  ...

Full name: System.Reflection.FieldInfo
val f : FieldInfo
type ConstructorInfo =
  inherit MethodBase
  member Equals : obj:obj -> bool
  member GetHashCode : unit -> int
  member Invoke : parameters:obj[] -> obj + 1 overload
  member MemberType : MemberTypes
  static val ConstructorName : string
  static val TypeConstructorName : string

Full name: System.Reflection.ConstructorInfo
val c : ConstructorInfo
property MemberInfo.Name: string
MethodBase.GetParameters() : ParameterInfo []
val map : mapping:('T -> 'U) -> array:'T [] -> 'U []

Full name: Microsoft.FSharp.Collections.Array.map
type MethodInfo =
  inherit MethodBase
  member Equals : obj:obj -> bool
  member GetBaseDefinition : unit -> MethodInfo
  member GetGenericArguments : unit -> Type[]
  member GetGenericMethodDefinition : unit -> MethodInfo
  member GetHashCode : unit -> int
  member MakeGenericMethod : [<ParamArray>] typeArguments:Type[] -> MethodInfo
  member MemberType : MemberTypes
  member ReturnParameter : ParameterInfo
  member ReturnType : Type
  member ReturnTypeCustomAttributes : ICustomAttributeProvider

Full name: System.Reflection.MethodInfo
val m : MethodInfo
property MethodInfo.ReturnType: Type
type PropertyInfo =
  inherit MemberInfo
  member Attributes : PropertyAttributes
  member CanRead : bool
  member CanWrite : bool
  member Equals : obj:obj -> bool
  member GetAccessors : unit -> MethodInfo[] + 1 overload
  member GetConstantValue : unit -> obj
  member GetGetMethod : unit -> MethodInfo + 1 overload
  member GetHashCode : unit -> int
  member GetIndexParameters : unit -> ParameterInfo[]
  member GetOptionalCustomModifiers : unit -> Type[]
  ...

Full name: System.Reflection.PropertyInfo
val p : PropertyInfo
type Type =
  inherit MemberInfo
  member Assembly : Assembly
  member AssemblyQualifiedName : string
  member Attributes : TypeAttributes
  member BaseType : Type
  member ContainsGenericParameters : bool
  member DeclaringMethod : MethodBase
  member DeclaringType : Type
  member Equals : o:obj -> bool + 1 overload
  member FindInterfaces : filter:TypeFilter * filterCriteria:obj -> Type[]
  member FindMembers : memberType:MemberTypes * bindingAttr:BindingFlags * filter:MemberFilter * filterCriteria:obj -> MemberInfo[]
  ...

Full name: System.Type
val x : MemberInfo
val failwithf : format:Printf.StringFormat<'T,'Result> -> 'T

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.failwithf
val sortBy : projection:('T -> 'Key) -> source:seq<'T> -> seq<'T> (requires comparison)

Full name: Microsoft.FSharp.Collections.Seq.sortBy
val snd : tuple:('T1 * 'T2) -> 'T2

Full name: Microsoft.FSharp.Core.Operators.snd
val s : string
val writeFileIfDiffers : path:string -> contents:string -> unit

Full name: GASig.writeFileIfDiffers
val contents : string
val current : string
type File =
  static member AppendAllLines : path:string * contents:IEnumerable<string> -> unit + 1 overload
  static member AppendAllText : path:string * contents:string -> unit + 1 overload
  static member AppendText : path:string -> StreamWriter
  static member Copy : sourceFileName:string * destFileName:string -> unit + 1 overload
  static member Create : path:string -> FileStream + 3 overloads
  static member CreateText : path:string -> StreamWriter
  static member Decrypt : path:string -> unit
  static member Delete : path:string -> unit
  static member Encrypt : path:string -> unit
  static member Exists : path:string -> bool
  ...

Full name: System.IO.File
File.ReadAllText(path: string) : string
File.ReadAllText(path: string, encoding: Text.Encoding) : string
File.WriteAllText(path: string, contents: string) : unit
File.WriteAllText(path: string, contents: string, encoding: Text.Encoding) : unit
val e : exn
Multiple items
type ResolveHandlerScope =
  interface IDisposable
  new : references:string [] -> ResolveHandlerScope

Full name: GASig.ResolveHandlerScope

--------------------
new : references:string [] -> ResolveHandlerScope
val handler : ResolveEventHandler
type ResolveEventHandler =
  delegate of obj * ResolveEventArgs -> Assembly

Full name: System.ResolveEventHandler
val args : ResolveEventArgs
property ResolveEventArgs.Name: string
type AppDomain =
  inherit MarshalByRefObject
  member ActivationContext : ActivationContext
  member AppendPrivatePath : path:string -> unit
  member ApplicationIdentity : ApplicationIdentity
  member ApplicationTrust : ApplicationTrust
  member ApplyPolicy : assemblyName:string -> string
  member BaseDirectory : string
  member ClearPrivatePath : unit -> unit
  member ClearShadowCopyPath : unit -> unit
  member CreateComInstanceFrom : assemblyName:string * typeName:string -> ObjectHandle + 1 overload
  member CreateInstance : assemblyName:string * typeName:string -> ObjectHandle + 3 overloads
  ...

Full name: System.AppDomain
property AppDomain.CurrentDomain: AppDomain
AppDomain.add_ReflectionOnlyAssemblyResolve(value: ResolveEventHandler) : unit
type IDisposable =
  member Dispose : unit -> unit

Full name: System.IDisposable
val this : ResolveHandlerScope
override ResolveHandlerScope.Dispose : unit -> unit

Full name: GASig.ResolveHandlerScope.Dispose
AppDomain.remove_ReflectionOnlyAssemblyResolve(value: ResolveEventHandler) : unit
Multiple items
type AssemblySignatureGenerator =
  inherit MarshalByRefObject
  new : unit -> AssemblySignatureGenerator
  member Generate : input:string * output:string * references:string [] -> unit

Full name: GASig.AssemblySignatureGenerator

--------------------
new : unit -> AssemblySignatureGenerator
Multiple items
type MarshalByRefObject =
  member CreateObjRef : requestedType:Type -> ObjRef
  member GetLifetimeService : unit -> obj
  member InitializeLifetimeService : unit -> obj

Full name: System.MarshalByRefObject

--------------------
MarshalByRefObject() : unit
val this : AssemblySignatureGenerator
member AssemblySignatureGenerator.Generate : input:string * output:string * references:string [] -> unit

Full name: GASig.AssemblySignatureGenerator.Generate
val input : string
val output : string
val printfn : format:Printf.TextWriterFormat<'T> -> 'T

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.printfn
val scope : ResolveHandlerScope
val fd : StringWriter
Multiple items
type StringWriter =
  inherit TextWriter
  new : unit -> StringWriter + 3 overloads
  member Close : unit -> unit
  member Encoding : Encoding
  member GetStringBuilder : unit -> StringBuilder
  member ToString : unit -> string
  member Write : value:char -> unit + 2 overloads

Full name: System.IO.StringWriter

--------------------
StringWriter() : unit
StringWriter(formatProvider: IFormatProvider) : unit
StringWriter(sb: Text.StringBuilder) : unit
StringWriter(sb: Text.StringBuilder, formatProvider: IFormatProvider) : unit
StringWriter.ToString() : string
Multiple items
type GenerateAssemblySignature =
  inherit obj
  new : unit -> GenerateAssemblySignature
  override Execute : unit -> 'a
  member Input : 'a
  member Output : 'a
  member References : 'a []
  member Input : 'a with set
  member Output : 'a with set
  member References : 'a with set

Full name: GASig.GenerateAssemblySignature

--------------------
new : unit -> GenerateAssemblySignature
member GenerateAssemblySignature.Input : 'a with set

Full name: GASig.GenerateAssemblySignature.Input
val set : elements:seq<'T> -> Set<'T> (requires comparison)

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.set
member GenerateAssemblySignature.Output : 'a with set

Full name: GASig.GenerateAssemblySignature.Output
member GenerateAssemblySignature.References : 'a with set

Full name: GASig.GenerateAssemblySignature.References
override GenerateAssemblySignature.Execute : unit -> 'a

Full name: GASig.GenerateAssemblySignature.Execute
AppDomain.CreateDomain(friendlyName: string) : AppDomain
AppDomain.CreateDomain(friendlyName: string, securityInfo: Security.Policy.Evidence) : AppDomain
AppDomain.CreateDomain(friendlyName: string, securityInfo: Security.Policy.Evidence, info: AppDomainSetup) : AppDomain
AppDomain.CreateDomain(friendlyName: string, securityInfo: Security.Policy.Evidence, info: AppDomainSetup, grantSet: Security.PermissionSet, [<ParamArray>] fullTrustAssemblies: Security.Policy.StrongName []) : AppDomain
AppDomain.CreateDomain(friendlyName: string, securityInfo: Security.Policy.Evidence, appBasePath: string, appRelativeSearchPath: string, shadowCopyFiles: bool) : AppDomain
AppDomain.CreateDomain(friendlyName: string, securityInfo: Security.Policy.Evidence, appBasePath: string, appRelativeSearchPath: string, shadowCopyFiles: bool, adInit: AppDomainInitializer, adInitArgs: string []) : AppDomain
val typeof<'T> : Type

Full name: Microsoft.FSharp.Core.Operators.typeof
AppDomain.Unload(domain: AppDomain) : unit
Multiple items
type GetAssemblySignatureList =
  inherit obj
  new : unit -> GetAssemblySignatureList
  override Execute : unit -> 'a
  member Inputs : 'a []
  member Inputs : 'a with set

Full name: GASig.GetAssemblySignatureList

--------------------
new : unit -> GetAssemblySignatureList
member GetAssemblySignatureList.Inputs : 'a with set

Full name: GASig.GetAssemblySignatureList.Inputs
override GetAssemblySignatureList.Execute : unit -> 'a

Full name: GASig.GetAssemblySignatureList.Execute
File.Exists(path: string) : bool
Raw view Test code New version

More information

Link:http://fssnip.net/8t
Posted:13 years ago
Author:
Tags: