Skip to content

Instantly share code, notes, and snippets.

@Kimserey
Last active December 16, 2015 03:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Kimserey/786971d87ea9895e767e to your computer and use it in GitHub Desktop.
Save Kimserey/786971d87ea9895e767e to your computer and use it in GitHub Desktop.
W# Macro to get a config object constructed before JS built. The macro can then be used to access the config from the W# JavaScript annotated code. The advantage is that we have full flexibility in getConfig as it is before JS compilation.
type private ConfigMacro () =
interface M.IMacro with
member this.Translate(q, tr) =
match q with
| Q.CallOrCallModule (_, []) ->
let rec convert (obj: obj) =
match obj.GetType() with
| ty when ty.IsGenericType && ty.GetGenericTypeDefinition() = typedefof<list<_>> ->
C.NewArray <| (obj :?> seq<_> |> List.ofSeq |> List.map convert)
| ty when ty.IsPrimitive || ty = typeof<string> -> !~ (C.String (string obj))
| ty when FSharpType.IsUnion ty ->
let unionInfo, _ = FSharpValue.GetUnionFields(obj, ty)
C.NewObject [ "$", !~ (C.String (string unionInfo.Tag)) ]
| ty when FSharpType.IsRecord ty ->
C.NewObject
<| (Array.map2
<| fun (field: PropertyInfo) value -> field.Name, convert value
<| FSharpType.GetRecordFields ty
<| FSharpValue.GetRecordFields obj
|> List.ofArray)
| ty -> failwith <| sprintf "Cannot convert type {%s} to Websharper JS expression" ty.Name
convert (getConfig ())
| _ -> failwith "Config must be Call or CallModule"
@Kimserey
Copy link
Author

Not working fully, discriminated unions with arguments aren't supported. It should be enough to work with json file with simple record type.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment