@@ -2650,17 +2650,30 @@ let mkWithGetSet (withKeyword: range option) (getSet: GetSetKeywords option) =
2650
2650
2651
2651
let mkPropertyGetSetBinding
2652
2652
( creationAide : CreationAide )
2653
+ ( withOrAndKeyword : range )
2653
2654
( accessibility : SynAccess option )
2654
2655
( leadingKeyword : SingleTextNode )
2655
2656
( binding : SynBinding )
2656
2657
: PropertyGetSetBindingNode =
2657
2658
match binding with
2658
2659
| SynBinding(
2660
+ attributes = attributes
2659
2661
headPat = SynPat.LongIdent( extraId = Some extraIdent; argPats = SynArgPats.Pats ps)
2660
2662
returnInfo = returnInfo
2661
2663
expr = expr
2662
2664
trivia = { EqualsRange = Some mEq
2663
2665
InlineKeyword = inlineKw }) ->
2666
+ // Attribute are not accurate in this case.
2667
+ // The binding could contain attributes for the entire member and the getter or setter member.
2668
+ // We use the `with` or `and` keyword to filter them.
2669
+ let attributes =
2670
+ attributes
2671
+ |> List.map ( fun al ->
2672
+ { al with
2673
+ Attributes =
2674
+ al.Attributes
2675
+ |> List.filter ( fun a -> Position.posGt a.Range.Start withOrAndKeyword.End) })
2676
+
2664
2677
let e = parseExpressionInSynBinding returnInfo expr
2665
2678
let returnTypeNode = mkBindingReturnInfo creationAide returnInfo
2666
2679
@@ -2694,6 +2707,7 @@ let mkPropertyGetSetBinding
2694
2707
2695
2708
PropertyGetSetBindingNode(
2696
2709
Option.map ( stn " inline" ) inlineKw,
2710
+ mkAttributes creationAide attributes,
2697
2711
mkSynAccess accessibility,
2698
2712
leadingKeyword,
2699
2713
pats,
@@ -2863,7 +2877,7 @@ let mkMemberDefn (creationAide: CreationAide) (md: SynMemberDefn) =
2863
2877
GetKeyword = Some getKeyword
2864
2878
SetKeyword = Some setKeyword
2865
2879
WithKeyword = withKeyword
2866
- AndKeyword = andKeyword }) ->
2880
+ AndKeyword = Some andKeyword }) ->
2867
2881
2868
2882
let firstAccessibility , firstBinding , firstKeyword , lastBinding , lastKeyword =
2869
2883
if Position.posLt getKeyword.Start setKeyword.Start then
@@ -2885,27 +2899,43 @@ let mkMemberDefn (creationAide: CreationAide) (md: SynMemberDefn) =
2885
2899
| SynBinding( headPat = SynPat.LongIdent( accessibility = Some vis)) when
2886
2900
rangeBeforePos memberName.Range vis.Range.Start
2887
2901
->
2888
- mkPropertyGetSetBinding creationAide ( Some vis) firstKeyword firstBinding
2889
- | _ -> mkPropertyGetSetBinding creationAide None firstKeyword firstBinding
2902
+ mkPropertyGetSetBinding creationAide withKeyword ( Some vis) firstKeyword firstBinding
2903
+ | _ -> mkPropertyGetSetBinding creationAide withKeyword None firstKeyword firstBinding
2890
2904
2891
2905
let lastBinding =
2892
2906
match lastBinding with
2893
2907
| SynBinding( headPat = SynPat.LongIdent( accessibility = Some vis)) when
2894
2908
rangeBeforePos memberName.Range vis.Range.Start
2895
2909
->
2896
- mkPropertyGetSetBinding creationAide ( Some vis) lastKeyword lastBinding
2897
- | _ -> mkPropertyGetSetBinding creationAide None lastKeyword lastBinding
2910
+ mkPropertyGetSetBinding creationAide andKeyword ( Some vis) lastKeyword lastBinding
2911
+ | _ -> mkPropertyGetSetBinding creationAide andKeyword None lastKeyword lastBinding
2912
+
2913
+ // Attributes placed on the member will be included in both bindings for the getter and setter.
2914
+ // We need to filter out the attributes above the leading keyword (typically `member`).
2915
+ let memberAttributes =
2916
+ ats
2917
+ |> List.choose ( fun al ->
2918
+ let filteredAttributeList =
2919
+ { al with
2920
+ Attributes =
2921
+ al.Attributes
2922
+ |> List.filter ( fun a -> Position.posLt a.Range.End lk.Range.Start) }
2923
+
2924
+ if filteredAttributeList.Attributes.IsEmpty then
2925
+ None
2926
+ else
2927
+ Some filteredAttributeList)
2898
2928
2899
2929
MemberDefnPropertyGetSetNode(
2900
2930
mkXmlDoc px,
2901
- mkAttributes creationAide ats ,
2931
+ mkAttributes creationAide memberAttributes ,
2902
2932
mkSynLeadingKeyword lk,
2903
2933
Option.map ( stn " inline" ) inlineKw,
2904
2934
mkSynAccess accessibility,
2905
2935
mkSynLongIdent memberName,
2906
2936
stn " with" withKeyword,
2907
2937
firstBinding,
2908
- Option.map ( stn " and" ) andKeyword,
2938
+ Some ( stn " and" andKeyword) ,
2909
2939
Some lastBinding,
2910
2940
memberDefinitionRange
2911
2941
)
@@ -2945,7 +2975,7 @@ let mkMemberDefn (creationAide: CreationAide) (md: SynMemberDefn) =
2945
2975
match getKeyword, setKeyword with
2946
2976
| Some getKeyword, None ->
2947
2977
let bindingNode =
2948
- mkPropertyGetSetBinding creationAide visProperty ( stn " get" getKeyword) binding
2978
+ mkPropertyGetSetBinding creationAide withKeyword visProperty ( stn " get" getKeyword) binding
2949
2979
2950
2980
MemberDefnPropertyGetSetNode(
2951
2981
mkXmlDoc px,
@@ -2963,7 +2993,7 @@ let mkMemberDefn (creationAide: CreationAide) (md: SynMemberDefn) =
2963
2993
|> MemberDefn.PropertyGetSet
2964
2994
| None, Some setKeyword ->
2965
2995
let bindingNode =
2966
- mkPropertyGetSetBinding creationAide visProperty ( stn " set" setKeyword) binding
2996
+ mkPropertyGetSetBinding creationAide withKeyword visProperty ( stn " set" setKeyword) binding
2967
2997
2968
2998
MemberDefnPropertyGetSetNode(
2969
2999
mkXmlDoc px,
0 commit comments