Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

attempting to set a non-property member in jsOptions generates in valid js #3861

Open
joprice opened this issue Jun 29, 2024 · 2 comments
Open

Comments

@joprice
Copy link
Contributor

joprice commented Jun 29, 2024

Description

When using jsOptions with an interface, a non-property member (one missing a getter or setting) generates invalid js, a local FSharpRef that references a non-existent identifier copyOfStruct.

Repro code

open Fable.Core.JsInterop

type Response =  
  abstract fn: int -> int
  abstract fnProp: (int -> int) with get, set
  abstract prop: bool with get, set

let res = jsOptions<Response> (
  fun o -> 
           o.fn <- (fun i -> i)
           o.fnProp <- (fun i -> i)
           o.prop <- false
  )
import { jsOptions } from "fable-library-js/Util.js";
import { FSharpRef } from "fable-library-js/Types.js";

export const res = jsOptions((o) => {
    const addr = new FSharpRef(() => copyOfStruct, (v) => {
        copyOfStruct = v;
    });
    addr.contents = ((i) => i);
    o.fnProp = ((i_1) => i_1);
    o.prop = false;
});

Related information

  • Fable version: 4.18.0
  • Operating system: OSX
@MangelMaxime
Copy link
Member

I can't remember if Is abstract fn: int -> int equivalent to abstract fn: int -> int with get, set in F#?

I guess it is because the F# compiler don't complains during compilation.

For as long, as I remember we always recommended to use with get, set on interfaces used for POJO. However, I don't know if there is a reason for that or if supporting cases without with get, set has just been forgotten.

@joprice
Copy link
Contributor Author

joprice commented Jun 29, 2024

Going by the syntax tree alone, it seems to be a difference between the flags MemberKind:Member and MemberKind:PropertyGetSet:

https://sharplab.io/#v2:DYLgZgzgNALiCGEZQCYgNQB8YE8AOApgAQBKBEeA9gHYTEC8RRAsAFBPwBGSATvAMYwiYaiCIBLakIC0APglS2HbjD6Dh1AExiAFJJnz9ASiIB3cTAAWROjCVEuvAUJEAFHpTy79ROQpgm5lZEAOYEyDbhbEA===

Adding parens around the function type turns it from a plain member into a gettable property, which causes a compilation error in the example below since there's no setter defined. So it likes like a missing validation to me.

type Response =  
  abstract fn: int -> int
  abstract fn2: (int -> int)
  abstract fn3: (int -> int) with set
  abstract fnProp: (int -> int) with get, set
  abstract prop: bool with get, set

let res = jsOptions<Response> (
  fun o -> 
           o.fn <- (fun i -> i)
           // this line fails to compile
           o.fn2 <- (fun i -> i)
           o.fn3 <- (fun i -> i)
           o.fnProp <- (fun i -> i)
           o.prop <- false
  )

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants