Skip to content

Commit

Permalink
Properly transform indexer tuple in setter. (#2974)
Browse files Browse the repository at this point in the history
* Properly transform indexer tuple in setter.

* Update src/Fantomas.Core/ASTTransformer.fs

Co-authored-by: dawe <dawedawe@posteo.de>

---------

Co-authored-by: dawe <dawedawe@posteo.de>
  • Loading branch information
nojaf and dawedawe committed Nov 2, 2023
1 parent 3f293e7 commit 5a8458e
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 18 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Changelog

## 6.2.3 - 2023-11-2

### Fixed
* Crash when trying to format indexed property with three arguments. [#2971](https://github.com/fsprojects/fantomas/issues/2971)

## 6.2.2 - 2023-10-18

### Fixed
Expand Down
23 changes: 23 additions & 0 deletions src/Fantomas.Core.Tests/TypeDeclarationTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -3642,3 +3642,26 @@ type Meh
class
end
"""

[<Test>]
let ``multi tuple setter with indexer, 2971`` () =
formatSourceString
false
"""
type MyArray3 () =
member _.Item
with get (x: int, y: int, z: int) =
()
and set (x: int, y: int, z: int) v =
()
"""
config
|> prepend newline
|> should
equal
"""
type MyArray3() =
member _.Item
with get (x: int, y: int, z: int) = ()
and set (x: int, y: int, z: int) v = ()
"""
39 changes: 21 additions & 18 deletions src/Fantomas.Core/ASTTransformer.fs
Original file line number Diff line number Diff line change
Expand Up @@ -2661,24 +2661,27 @@ let mkPropertyGetSetBinding

let pats =
match ps with
| [ SynPat.Tuple(false, [ p1; p2; p3 ], [ comma ], _) ] ->
let mTuple = unionRanges p1.Range p2.Range

[ PatParenNode(
stn "(" Range.Zero,
Pattern.Tuple(
PatTupleNode(
[ Choice1Of2(mkPat creationAide p1)
Choice2Of2(stn "," comma)
Choice1Of2(mkPat creationAide p2) ],
mTuple
)
),
stn ")" Range.Zero,
mTuple
)
|> Pattern.Paren
mkPat creationAide p3 ]
| [ SynPat.Tuple(false, ps, commas, _) ] when
// This is the case for an indexer setter.
// The AST is weird in this case and doesn't properly reflect what the user wrote.
// It will represent `set (x: int, y: int, z: int) v` as a single tuple with 4 patterns and 2 commas.
ps.Length - 2 = commas.Length
->

let tuplePat =
let tuplePs = List.take (ps.Length - 1) ps
let mTuple = tuplePs |> List.map (fun p -> p.Range) |> List.reduce unionRanges

match tuplePs with
// If there is only a single element, it does not need any additional parentheses.
| [ singlePat ] -> singlePat
| _ -> SynPat.Paren(SynPat.Tuple(false, tuplePs, commas, mTuple), mTuple)
|> mkPat creationAide

[ tuplePat
match List.tryLast ps with
| None -> failwith ""
| Some indexerPat -> mkPat creationAide indexerPat ]
| [ SynPat.Tuple(false, [ p1; p2 ], _, _) ] -> [ mkPat creationAide p1; mkPat creationAide p2 ]
| ps -> List.map (mkPat creationAide) ps

Expand Down

0 comments on commit 5a8458e

Please sign in to comment.