Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions src/Fable.Transforms/Fable2Babel.fs
Original file line number Diff line number Diff line change
Expand Up @@ -4666,6 +4666,34 @@ but thanks to the optimisation done below we get
transformAttachedMethod com ctx ent info memb
)

let tryKeyName =
function
| Expression.Identifier(Identifier(name, _)) -> Some name
| _ -> None

classMembers
|> Array.choose (
function
| ClassMethod(ClassFunction(key, _), _, _, _, _, _, _, _, _) ->
tryKeyName key |> Option.map (fun n -> n, false, false)
| ClassMethod(ClassGetter(key, _), _, _, _, _, _, _, _, _) ->
tryKeyName key |> Option.map (fun n -> n, true, false)
| ClassMethod(ClassSetter(key, _), _, _, _, _, _, _, _, _) ->
tryKeyName key |> Option.map (fun n -> n, false, true)
| _ -> None
)
|> Array.groupBy (fun (name, _, _) -> name)
|> Array.iter (fun (name, entries) ->
let isValidGetterSetterPair =
entries.Length = 2
&& entries |> Array.exists (fun (_, isGetter, _) -> isGetter)
&& entries |> Array.exists (fun (_, _, isSetter) -> isSetter)

if entries.Length > 1 && not isValidGetterSetterPair then
$"Overloads are not supported when using [<AttachMembers>]: '{name}' in {decl.Name} is defined more than once. Rename one of the members."
|> addWarning com [] None
)

match decl.Constructor with
| Some cons ->
withCurrentScope ctx cons.UsedNames
Expand Down
29 changes: 29 additions & 0 deletions src/Fable.Transforms/Python/Fable2Python.Transforms.fs
Original file line number Diff line number Diff line change
Expand Up @@ -4983,6 +4983,35 @@ let rec transformDeclaration (com: IPythonCompiler) ctx (decl: Fable.Declaration
else
ctx

decl.AttachedMembers
|> List.choose (fun memb ->
if memb.IsMangled then
None
else
let info =
memb.ImplementedSignatureRef
|> Option.map com.GetMember
|> Option.defaultWith (fun () -> com.GetMember(memb.MemberRef))

Some
{|
name = memb.Name
isGetter = info.IsGetter
isSetter = info.IsSetter
|}
)
|> List.groupBy (fun m -> m.name)
|> List.iter (fun (name, entries) ->
let isValidGetterSetterPair =
entries.Length = 2
&& entries |> List.exists _.isGetter
&& entries |> List.exists _.isSetter

if entries.Length > 1 && not isValidGetterSetterPair then
$"Overloads are not supported when using [<AttachMembers>]: '{name}' in {decl.Name} is defined more than once. Rename one of the members."
|> addWarning com [] None
)

let classMembers =
decl.AttachedMembers
|> List.collect (fun memb ->
Expand Down
28 changes: 28 additions & 0 deletions tests/Integration/Compiler/CompilerMessagesTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,34 @@ let z = y ()
let x = 1
let inline y () = x
let z = y ()
"""
compile source
|> Assert.Is.success
|> ignore

testCase "Duplicate attached member names emit a warning" <| fun _ ->
let source =
"""
open Fable.Core

[<AttachMembers>]
type MyClass() =
member _.Foo(x: int) = x
member _.Foo(x: string) = x.Length
"""
compile source
|> Assert.Exists.warningWith "Overloads are not supported when using [<AttachMembers>]"
|> ignore

testCase "Getter and setter pair with same name does not emit a warning" <| fun _ ->
let source =
"""
open Fable.Core

[<AttachMembers>]
type MyClass() =
let mutable _x = 0
member _.Value with get() = _x and set(v) = _x <- v
"""
compile source
|> Assert.Is.success
Expand Down
Loading