diff --git a/src/Fable.Transforms/FSharp2Fable.Util.fs b/src/Fable.Transforms/FSharp2Fable.Util.fs index 0ad9e12e58..f5a13e3d5f 100644 --- a/src/Fable.Transforms/FSharp2Fable.Util.fs +++ b/src/Fable.Transforms/FSharp2Fable.Util.fs @@ -199,8 +199,17 @@ type FsAbstractSignature(s: FSharpAbstractSignature) = member _.DeclaringType = TypeHelpers.makeType Map.empty s.DeclaringType type FsMemberFunctionOrValue(m: FSharpMemberOrFunctionOrValue) = + static member CompiledName(m: FSharpMemberOrFunctionOrValue) = + if FsMemberFunctionOrValue.IsGetter(m) || + FsMemberFunctionOrValue.IsSetter(m) + then Naming.removeGetSetPrefix m.CompiledName + else m.CompiledName + static member DisplayName(m: FSharpMemberOrFunctionOrValue) = - Naming.removeGetSetPrefix m.DisplayNameCore + if FsMemberFunctionOrValue.IsGetter(m) || + FsMemberFunctionOrValue.IsSetter(m) + then Naming.removeGetSetPrefix m.DisplayNameCore + else m.DisplayNameCore // We don't consider indexer properties as getters/setters so they're always compiled as methods static member IsGetter(m: FSharpMemberOrFunctionOrValue) = @@ -692,7 +701,7 @@ module Helpers = |> Option.defaultValue false v.IsModuleValueOrMember && not v.HasSignatureFile && parentHasSignatureFile () - + let isNotPrivate (memb: FSharpMemberOrFunctionOrValue) = if memb.IsCompilerGenerated then false elif topLevelBindingHiddenBySignatureFile memb then false @@ -1842,19 +1851,11 @@ module Util = let arg = callInfo.Args |> List.tryHead |> Option.defaultWith makeNull Fable.Set(callee, Fable.FieldSet(info.name), membType, arg, r) else - // If the entity is decorated with AttachMembers, we need to remove the get/set prefix - // See https://github.com/fable-compiler/Fable/issues/3494 - let membName = - if isAttachMembersEntity com entity then - Naming.removeGetSetPrefix info.name - else - info.name - let entityGenParamsCount = entity.GenericParameters.Count let callInfo = if callInfo.GenericArgs.Length < entityGenParamsCount then callInfo else { callInfo with GenericArgs = List.skip entityGenParamsCount callInfo.GenericArgs } - getField callee membName |> makeCall r typ callInfo + getField callee info.name |> makeCall r typ callInfo let failReplace (com: IFableCompiler) ctx r (info: Fable.ReplaceCallInfo) (thisArg: Fable.Expr option) = let msg = diff --git a/src/Fable.Transforms/FSharp2Fable.fs b/src/Fable.Transforms/FSharp2Fable.fs index b6a2ca3aab..703e1e93f6 100644 --- a/src/Fable.Transforms/FSharp2Fable.fs +++ b/src/Fable.Transforms/FSharp2Fable.fs @@ -1405,7 +1405,7 @@ let private transformExplicitlyAttachedMember (com: FableCompiler) (ctx: Context let name, isMangled = match Compiler.Language with | Rust -> getMemberDeclarationName com memb |> fst, true - | _ -> Naming.removeGetSetPrefix memb.CompiledName, false + | _ -> FsMemberFunctionOrValue.CompiledName(memb), false com.AddAttachedMember(entFullName, isMangled=false, memb = { Name = name Body = body diff --git a/tests/Js/Main/TypeTests.fs b/tests/Js/Main/TypeTests.fs index 9b1e2919d3..678b877285 100644 --- a/tests/Js/Main/TypeTests.fs +++ b/tests/Js/Main/TypeTests.fs @@ -72,6 +72,19 @@ type TestType7(a1, a2, a3) = let arr = [|a1; a2; a3|] member _.Value with get(i) = arr.[i] and set(i) (v) = arr.[i] <- v +[] +type TestTypeAttached(a1, a2, a3) = + let arr = [| a1; a2; a3 |] + member _.Value1 + with get () = arr.[1] + and set (v) = arr.[1] <- v + member _.Value + with get (i) = arr.[i] + and set (i) (v) = arr.[i] <- v + member _.Item + with get (i) = arr.[i] + and set (i) (v) = arr.[i] <- v + type A = { thing: int } with member x.show() = string x.thing static member show (x: A) = "Static: " + (string x.thing) @@ -633,6 +646,18 @@ let tests = t.Value(1) |> equal 5 t.Value(2) |> equal 3 + testCase "Attached Getters Setters and Indexers work" <| fun () -> + let t = TestTypeAttached(1, 2, 3) + t.Value1 |> equal 2 + t.Value1 <- 22 + t.Value1 |> equal 22 + t.Value(0) |> equal 1 + t.Value(0) <- 11 + t.Value(0) |> equal 11 + t[2] |> equal 3 + t[2] <- 33 + t[2] |> equal 33 + testCase "Statically resolved instance calls work" <| fun () -> let a = { thing = 5 } let b = { label = "five" } diff --git a/tests/Python/TestType.fs b/tests/Python/TestType.fs index 8d8984a359..f8e68a989f 100644 --- a/tests/Python/TestType.fs +++ b/tests/Python/TestType.fs @@ -83,6 +83,19 @@ type Type7Test(a1, a2, a3) = with get (i) = arr.[i] and set (i) (v) = arr.[i] <- v +[] +type TypeAttachedTest(a1, a2, a3) = + let arr = [| a1; a2; a3 |] + member _.Value1 + with get () = arr.[1] + and set (v) = arr.[1] <- v + member _.Value + with get (i) = arr.[i] + and set (i) (v) = arr.[i] <- v + member _.Item + with get (i) = arr.[i] + and set (i) (v) = arr.[i] <- v + type A = { thing: int } member x.show() = string x.thing @@ -698,6 +711,19 @@ let ``test Getter and Setter with indexer work`` () = t.Value(1) |> equal 5 t.Value(2) |> equal 3 +[] +let ``test Attached Getters Setters and Indexers work`` () = + let t = TypeAttachedTest(1, 2, 3) + t.Value1 |> equal 2 + t.Value1 <- 22 + t.Value1 |> equal 22 + t.Value(0) |> equal 1 + t.Value(0) <- 11 + t.Value(0) |> equal 11 + t.[2] |> equal 3 + t.[2] <- 33 + t.[2] |> equal 33 + [] let ``test Statically resolved instance calls work`` () = let a = { thing = 5 } diff --git a/tests/Rust/tests/src/TypeTests.fs b/tests/Rust/tests/src/TypeTests.fs index d21cb13107..43c34f4a41 100644 --- a/tests/Rust/tests/src/TypeTests.fs +++ b/tests/Rust/tests/src/TypeTests.fs @@ -71,6 +71,19 @@ type TestType7(a1, a2, a3) = let arr = [|a1; a2; a3|] member _.Value with get(i) = arr[i] and set(i) (v) = arr[i] <- v +[] +type TestTypeAttached(a1, a2, a3) = + let arr = [| a1; a2; a3 |] + member _.Value1 + with get () = arr.[1] + and set (v) = arr.[1] <- v + member _.Value + with get (i) = arr.[i] + and set (i) (v) = arr.[i] <- v + member _.Item + with get (i) = arr.[i] + and set (i) (v) = arr.[i] <- v + type A = { thing: int } with member x.show() = string x.thing static member show (x: A) = "Static: " + (string x.thing) @@ -632,6 +645,19 @@ let ``Getter and Setter with indexer work`` () = t.Value(1) |> equal 5 t.Value(2) |> equal 3 +[] +let ``Attached Getters Setters and Indexers work`` () = + let t = TestTypeAttached(1, 2, 3) + t.Value1 |> equal 2 + t.Value1 <- 22 + t.Value1 |> equal 22 + t.Value(0) |> equal 1 + t.Value(0) <- 11 + t.Value(0) |> equal 11 + t[2] |> equal 3 + t[2] <- 33 + t[2] |> equal 33 + [] let ``Statically resolved instance calls work`` () = let a = { thing = 5 }