Created
February 12, 2014 05:24
-
-
Save TIHan/8950457 to your computer and use it in GitHub Desktop.
An unfinished type provider to handle fixed length types; it's broken. Do not use; but here for reference.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module FSharp.BitMatch.TypeProvider | |
open System | |
open System.IO | |
open System.Reflection | |
open System.Windows.Input | |
open Microsoft.FSharp.Core.CompilerServices | |
open Microsoft.FSharp.Reflection | |
open Microsoft.FSharp.Quotations | |
open Microsoft.FSharp.Quotations.Patterns | |
open Microsoft.FSharp.Quotations.DerivedPatterns | |
open Microsoft.FSharp.Quotations.ExprShape | |
open ProviderImplementation | |
open ProviderImplementation.ProvidedTypes | |
open System.Text.RegularExpressions | |
[<Interface>] | |
type nativestring = | |
abstract member Get : unit -> string | |
[<TypeProvider>] | |
type BitMatchTypeProvider (cfg: TypeProviderConfig) as this = | |
inherit TypeProviderForNamespaces () | |
let asm = Assembly.GetExecutingAssembly () | |
let ns = this.GetType().Namespace | |
let pn = "BitMatch" | |
let tempAsm = ProvidedAssembly (Path.ChangeExtension (Path.GetTempFileName (), ".dll")) | |
let parameters = [ | |
ProvidedStaticParameter ("bitSyntax", typeof<string>) ] | |
do | |
// THIS IS NECESSARY | |
AppDomain.CurrentDomain.add_AssemblyResolve (fun _ args -> | |
let name = System.Reflection.AssemblyName(args.Name) | |
let existingAssembly = | |
System.AppDomain.CurrentDomain.GetAssemblies() | |
|> Seq.tryFind(fun a -> System.Reflection.AssemblyName.ReferenceMatchesDefinition(name, a.GetName())) | |
match existingAssembly with | |
| Some a -> a | |
| None -> null) | |
let def = ProvidedTypeDefinition (asm, ns, pn, Some typeof<obj>, IsErased = false) | |
tempAsm.AddTypes [def] | |
def.DefineStaticParameters (parameters, this.GenerateTypes) | |
this.AddNamespace(ns, [def]) | |
let generateFieldConst (name: string) (typ: Type) = | |
let field = ProvidedField (name, typ) | |
field.SetFieldAttributes (FieldAttributes.Public) | |
field | |
let generateFieldString (main: ProvidedTypeDefinition) (asm: ProvidedAssembly) (name: string) (n: int) = | |
let def = ProvidedTypeDefinition ("_string" + n.ToString (), Some typeof<System.ValueType>, IsErased = false) | |
def.SetAttributes (TypeAttributes.SequentialLayout) | |
//for i = 0 to n - 1 do | |
def.AddMember <| ProvidedField ("s", typeof<sbyte>) | |
asm.AddTypes [def] | |
main.AddMember def | |
//main.AddMemberDelayed <| fun _ -> | |
// asm.AddTypes [def] | |
// def | |
let field = ProvidedField (name, def) | |
field.SetFieldAttributes (FieldAttributes.Public) | |
field | |
/// GenerateTypes | |
member internal this.GenerateTypes (typeName: string) (args: obj[]) = | |
let bitSyntax = args.[0] :?> string | |
let ctor = ProvidedConstructor ([], InvokeCode = fun _ -> <@@ () @@>) | |
let def = ProvidedTypeDefinition (asm, ns, typeName, Some typeof<System.ValueType>, IsErased = false) | |
def.SetAttributes (TypeAttributes.SequentialLayout) | |
tempAsm.AddTypes [def] | |
let bits = bitSyntax.Replace(" ", "").Split (',') | |
let fields = | |
bits |> Array.mapi (fun i x -> | |
match x with | |
| "byte" -> generateFieldConst (i.ToString()) typeof<byte> | |
| "sbyte" -> generateFieldConst (i.ToString()) typeof<sbyte> | |
| "int16" -> generateFieldConst (i.ToString()) typeof<int16> | |
| "uint16" -> generateFieldConst (i.ToString()) typeof<uint16> | |
| "int" -> generateFieldConst (i.ToString()) typeof<int> | |
| "uint32" -> generateFieldConst (i.ToString()) typeof<uint32> | |
| "int64" -> generateFieldConst (i.ToString()) typeof<int64> | |
| "uint64" -> generateFieldConst (i.ToString()) typeof<uint64> | |
| _ -> | |
let matc = Regex.Match (x, "string\[(.*?)\]") | |
match matc.Success with | |
| true -> | |
match Int32.TryParse (matc.Groups.[1].Value) with | |
| (true, n) -> generateFieldString def tempAsm (i.ToString()) (n) | |
| _ -> failwithf "Unable to parse %s." matc.Groups.[1].Value | |
| _ -> | |
failwithf "Bad type, %s." x) | |
|> List.ofArray | |
def.AddMemberDelayed <| fun () -> ctor | |
def.AddMembersDelayed <| fun () -> fields | |
// let types = | |
// Assembly.types masm | |
// |> List.filter (fun x -> FSharpType.IsRecord x) | |
// |> List.map (fun x -> | |
// let state = ProvidedField ("state", x) | |
// state.SetFieldAttributes (FieldAttributes.Private ||| FieldAttributes.InitOnly) | |
// { ModelType = x; ModuleType = moduleType x masm; State = state }) | |
// | |
// def.AddMembersDelayed <| fun () -> | |
// let defs = List.map generateViewModel types | |
// tempAsm.AddTypes defs | |
// defs | |
def | |
[<assembly:TypeProviderAssembly>] | |
do () |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment