Skip to content

Commit d18cc65

Browse files
authored
Use correct visibility of get/set property and member. (#2903)
* Move the visibility of a get/set property to the member. * Add issue number * Revert changes. * Verify if the accessibility is part of the PropertyGetSetBindingNode or the parent MemberDefnPropertyGetSetNode. * Add changelog entry. * Use rangeBeforePos from FCS to determine what came before what.
1 parent 4f2f9c1 commit d18cc65

File tree

3 files changed

+144
-7
lines changed

3 files changed

+144
-7
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# Changelog
22

3+
## [6.0.6] - 2023-06-19
4+
5+
### Fixed
6+
* Setter is also private. [#2902](https://github.com/fsprojects/fantomas/issues/2902)
7+
38
## [6.0.5] - 2023-06-06
49

510
### Fixed

src/Fantomas.Core.Tests/StructTests.fs

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,3 +189,115 @@ struct // 1
189189
// 5
190190
|} // 6
191191
"""
192+
193+
[<Test>]
194+
let ``second binding does not contain accessibility, 2902`` () =
195+
formatSourceString
196+
false
197+
"""
198+
module Telplin
199+
200+
type T =
201+
struct
202+
member private this.X with get () : int = 1 and set (_:int) = ()
203+
end
204+
"""
205+
config
206+
|> prepend newline
207+
|> should
208+
equal
209+
"""
210+
module Telplin
211+
212+
type T =
213+
struct
214+
member private this.X
215+
with get (): int = 1
216+
and set (_: int) = ()
217+
end
218+
"""
219+
220+
[<Test>]
221+
let ``different accessibility on setter`` () =
222+
formatSourceString
223+
false
224+
"""
225+
module Telplin
226+
227+
type T =
228+
struct
229+
member this.X with get () : int = 1 and private set (_:int) = ()
230+
member this.Y with internal get () : int = 1 and private set (_:int) = ()
231+
member private this.Z with get () : int = 1 and set (_:int) = ()
232+
member this.S with internal set (_:int) = () and private get () : int = 1
233+
end
234+
"""
235+
config
236+
|> prepend newline
237+
|> should
238+
equal
239+
"""
240+
module Telplin
241+
242+
type T =
243+
struct
244+
member this.X
245+
with get (): int = 1
246+
and private set (_: int) = ()
247+
248+
member this.Y
249+
with internal get (): int = 1
250+
and private set (_: int) = ()
251+
252+
member private this.Z
253+
with get (): int = 1
254+
and set (_: int) = ()
255+
256+
member this.S
257+
with internal set (_: int) = ()
258+
and private get (): int = 1
259+
end
260+
"""
261+
262+
[<Test>]
263+
let ``private setter on next line`` () =
264+
formatSourceString
265+
false
266+
"""
267+
type Y =
268+
member this.X
269+
with get (): int = 1
270+
and private set (_: int) = ()
271+
"""
272+
config
273+
|> prepend newline
274+
|> should
275+
equal
276+
"""
277+
type Y =
278+
member this.X
279+
with get (): int = 1
280+
and private set (_: int) = ()
281+
"""
282+
283+
[<Test>]
284+
let ``private property with identifier on next line`` () =
285+
formatSourceString
286+
false
287+
"""
288+
type Y =
289+
member private
290+
this.X
291+
with get (): int = 1
292+
and set (_: int) = ()
293+
"""
294+
config
295+
|> prepend newline
296+
|> should
297+
equal
298+
"""
299+
type Y =
300+
member private this.X
301+
with get (): int = 1
302+
and set (_: int) = ()
303+
"""

src/Fantomas.Core/ASTTransformer.fs

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2566,14 +2566,24 @@ let mkPropertyGetSetBinding
25662566
: PropertyGetSetBindingNode =
25672567
match binding with
25682568
| SynBinding(
2569-
headPat = SynPat.LongIdent(extraId = Some extraIdent; accessibility = ao; argPats = SynArgPats.Pats ps)
2569+
headPat = SynPat.LongIdent(
2570+
longDotId = lid; extraId = Some extraIdent; accessibility = ao; argPats = SynArgPats.Pats ps)
25702571
returnInfo = returnInfo
25712572
expr = expr
25722573
trivia = { EqualsRange = Some mEq
25732574
InlineKeyword = inlineKw }) ->
25742575
let e = parseExpressionInSynBinding returnInfo expr
25752576
let returnTypeNode = mkBindingReturnInfo creationAide returnInfo
25762577

2578+
// Only use the accessibility of the property binding if the keyword came after the member identifier.
2579+
let accessibility =
2580+
ao
2581+
|> Option.bind (fun vis ->
2582+
if rangeBeforePos lid.Range vis.Range.Start then
2583+
Some vis
2584+
else
2585+
None)
2586+
25772587
let pats =
25782588
match ps with
25792589
| [ SynPat.Tuple(false, [ p1; p2; p3 ], [ comma ], _) ] ->
@@ -2601,7 +2611,7 @@ let mkPropertyGetSetBinding
26012611

26022612
PropertyGetSetBindingNode(
26032613
Option.map (stn "inline") inlineKw,
2604-
mkSynAccess ao,
2614+
mkSynAccess accessibility,
26052615
leadingKeyword,
26062616
pats,
26072617
returnTypeNode,
@@ -2763,32 +2773,42 @@ let mkMemberDefn (creationAide: CreationAide) (md: SynMemberDefn) =
27632773
)
27642774
|> MemberDefn.AbstractSlot
27652775
| SynMemberDefn.GetSetMember(Some(SynBinding(
2766-
accessibility = ao
27672776
attributes = ats
27682777
xmlDoc = px
2769-
headPat = SynPat.LongIdent(longDotId = memberName)
2778+
headPat = SynPat.LongIdent(longDotId = memberName; accessibility = visGet)
27702779
trivia = { LeadingKeyword = lk
27712780
InlineKeyword = inlineKw }) as getBinding),
2772-
Some setBinding,
2781+
Some(SynBinding(headPat = SynPat.LongIdent(accessibility = visSet)) as setBinding),
27732782
_,
27742783
{ GetKeyword = Some getKeyword
27752784
SetKeyword = Some setKeyword
27762785
WithKeyword = withKeyword
27772786
AndKeyword = andKeyword }) ->
2778-
let firstBinding, lastBinding =
2787+
let firstAccessibility, firstBinding, lastBinding =
27792788
if Position.posLt getKeyword.Start setKeyword.Start then
2789+
visGet,
27802790
mkPropertyGetSetBinding creationAide (stn "get" getKeyword) getBinding,
27812791
Some(mkPropertyGetSetBinding creationAide (stn "set" setKeyword) setBinding)
27822792
else
2793+
visSet,
27832794
mkPropertyGetSetBinding creationAide (stn "set" setKeyword) setBinding,
27842795
Some(mkPropertyGetSetBinding creationAide (stn "get" getKeyword) getBinding)
27852796

2797+
// Only use the accessibility of the first binding if the keyword came before the member identifier.
2798+
let accessibility =
2799+
firstAccessibility
2800+
|> Option.bind (fun vis ->
2801+
if rangeBeforePos vis.Range memberName.Range.Start then
2802+
Some vis
2803+
else
2804+
None)
2805+
27862806
MemberDefnPropertyGetSetNode(
27872807
mkXmlDoc px,
27882808
mkAttributes creationAide ats,
27892809
mkSynLeadingKeyword lk,
27902810
Option.map (stn "inline") inlineKw,
2791-
mkSynAccess ao,
2811+
mkSynAccess accessibility,
27922812
mkSynLongIdent memberName,
27932813
stn "with" withKeyword,
27942814
firstBinding,

0 commit comments

Comments
 (0)