Fable: Enum.GetName or similar

Created on 3 Nov 2017  路  6Comments  路  Source: fable-compiler/Fable

It would be nice to be able to print the enum name somehow.

printfn "unknown kind in ModuleDeclaration: %A %A" nd.kind (Enum.GetName(typeof<SyntaxKind>, nd.kind))

I'm not sure if there is something Fable can do on the standard APIs or a custom Fable API, but the generated code would essentially just be a match that returned the name for each enum case.

currently with Fable 1.2.4:

error FABLE: Cannot find replacement for System.Enum::GetName
revisit

Most helpful comment

Reflection for enum types is finally supported by Fable :) Please check https://github.com/fable-compiler/Fable/commit/e2c1bef8366ab4f0ff40b4a209252485fb40c0f7#diff-32f2dda6a86cff59fc9073965d7eee93

All 6 comments

Hmm, right now enums are completely erased (they're just literal ints in JS code) so this is tricky as you cannot resolve the enum case until runtime. I guess we'll need to inject the enum info somewhere for this... or we could just do it in the type declaration and trust the JS minifiers will delete that piece of code if it's not finally used.

This is proving to be a bit complicated. I'm trying to output the Enum cases in the compiled JS so you get something like this:

type Foo =
    | Ja = 5
    | HOHOHO = 8
    | Mooo = 9

let test() =
    Enum.GetName(typeof<Foo>, Foo.Mooo) |> equal "Mooo"
    let typRef = typeof<Foo>
    Enum.GetName(typRef, 8) |> equal "HOHOHO"
    Enum.GetName(typRef, 7) |> equal null
const Foo = {
    ["5"]: "Ja",
    ["8"]: "HOHOHO",
    ["9"]: "Mooo"
};
function test() {
    equal("Mooo", Foo[9]);
    const typRef = Foo;
    equal("HOHOHO", typRef[8]);
    equal(null, typRef[7]);
}

However, for some reason I'm getting Stack Overflow exceptions when testing the code. Probably because the Fable AST was designed so Enum would be erased and thus it doesn't hold much info. Changing that may have caused some issues when traversing the AST.

This solution is not ideal either because it requires the Enum info to be in the JS, which is not the case for .dll bindings. I can think of some alternatives:

  • Resolve the name at compile time: so (Enum.GetName(typeof<SyntaxKind>, nd.Foo)) just becomes "Foo" in the compiled JS. This would be the easiest option for me, but the problem is this won't work if the enum value can only be resolved in runtime (as in your sample above).
  • Inline all the enum options in the call site. This shouldn't be too difficult to implement either, but it could bloat the code too much if Enum.GetName is used multiple times or the enum has too many cases.
  • Add an additional file to compilation to inject extra code (like the enum cases), so you only need to do it once. I'm not sure how difficult this would be, though I tried something similar in the past.

What do you think?

I wouldn't prioritize this super high right now. I'd rather get help trying to figure how to deal with imports/exports and multiple files with ts2fable https://github.com/fable-compiler/ts2fable/issues/29 https://github.com/fable-compiler/ts2fable/issues/21. :-)

This is pretty easy to work-a-round manually or by code gen in ts2fable with a custom function. In this case:

type Foo with
static member GetEnumName (v: Foo) =
  match v with
  | Ja -> "Ja"
  | HOHOHO -> "HOHOHO"
  | Mooo -> "Mooo" 

Ok, I'll close the issue for now. Feel free to reopen it if you still need the method :+1:

I just encountered same issue in my project. Nothing critical, the workaround works fine, just a heads up as it's a bit annoying as I have an enum with more than 20 cases.
Would be great to have that working OOTB in fable.
Also had to modify the workaround a bit to make it work by extracting a separate function and using fully qualified case names:

let getEnumName (v: Foo) =
  match v with
  | Foo.Ja -> "Ja"
...

Reflection for enum types is finally supported by Fable :) Please check https://github.com/fable-compiler/Fable/commit/e2c1bef8366ab4f0ff40b4a209252485fb40c0f7#diff-32f2dda6a86cff59fc9073965d7eee93

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jwosty picture jwosty  路  3Comments

tomcl picture tomcl  路  4Comments

rommsen picture rommsen  路  3Comments

alfonsogarciacaro picture alfonsogarciacaro  路  3Comments

forki picture forki  路  3Comments