fable-compiler / Fable

F# to JavaScript, TypeScript, Python, Rust and Dart Compiler
http://fable.io/
MIT License
2.91k stars 298 forks source link

ReflectedDecoratorAttribute gives mangled name in MethodInfo #2723

Open chkn opened 2 years ago

chkn commented 2 years ago

Description

Following the steps in https://fable.io/blog/2021/2021-09-17-JS-decorators-Fable-3-3.html to use ReflectedDecoratorAttribute, the MethodInfo contains the mangled name of the function.

Repro code

The REPL doesn't seem to have the decorator attributes, but you can repro by following these steps.

  1. Create the following files:

Foo.fsproj

<Project Sdk="Microsoft.NET.Sdk">
    <PropertyGroup>
        <OutputType>Exe</OutputType>
        <TargetFramework>net6.0</TargetFramework>
    </PropertyGroup>
    <ItemGroup>
        <Compile Include="FableDecorator.fs" />
        <PackageReference Include="Fable.Core" Version="3.6.1" />
    </ItemGroup>
</Project>

FableDecorator.fs

open Fable.Core.JS

type FooAttribute() =
    inherit ReflectedDecoratorAttribute()
    override _.Decorate(fn, info) =
        printfn $"Decorating function {info.Name}"
        fn

[<Foo>]
let ``foo bar baz`` () = ()
  1. dotnet fable Foo.fsproj
  2. mv FableDecorator.fs.js FableDecorator.fs.mjs
  3. node FableDecorator.fs.mjs

Expected and actual results

Expected to print: "Decorating function foo bar baz" Actual output: "Decorating function foo$0020bar$0020baz"

Related information

alfonsogarciacaro commented 2 years ago

Yes, this is an unfortunate design choice from my part. Using the mangled name was intended because Fable.Lit uses it to identify the member in the JS module when doing hot reloading. I now realized I should have used the original name and provide the mangled name through a special Fable extension. I just need to find a way to do it without breaking Fable.Lit 😅

chkn commented 2 years ago

Ah makes sense. I'm using it in an experiment to see if I can bring my unit test framework to Fable. The name is just used to print the name of the test, so it's not a big deal right now. I could maybe contribute a fix if it progresses past an experiment.

The best thing would be if it were possible to decorate a whole module and get something like a System.Type with all the MethodInfos, but that's a separate thing :)