@@ -867,41 +867,19 @@ let mkClassMemberLocalBindings
867867
868868 SynMemberDefn.LetBindings( decls, isStatic, isRec, mWhole)
869869
870- let mkLocalBindings ( mWhole , BindingSetPreAttrs ( _ , isRec , isUse , declsPreAttrs , _ ), mIn , body : SynExpr ) =
871- let ignoredFreeAttrs , decls = declsPreAttrs [] None
870+ /// Creates a SynExprAndBang node for and! bindings in computation expressions
871+ let mkAndBang ( mKeyword : range , pat : SynPat , rhs : SynExpr , mWhole : range , mEquals : range , mIn : range option ) =
872+ let spBind = DebugPointAtBinding.Yes( unionRanges mKeyword rhs.Range)
872873
873- let mWhole =
874- match decls with
875- | SynBinding( xmlDoc = xmlDoc) :: _ -> unionRangeWithXmlDoc xmlDoc mWhole
876- | _ -> mWhole
877-
878- if not ( isNil ignoredFreeAttrs) then
879- warning ( Error( FSComp.SR.parsAttributesIgnored (), mWhole))
880-
881- let mIn =
882- mIn
883- |> Option.bind ( fun ( mIn : range ) ->
884- if Position.posEq mIn.Start body.Range.Start then
885- None
886- else
887- Some mIn)
888-
889- let mLetOrUse =
890- match decls with
891- | SynBinding( trivia = trivia) :: _ -> trivia.LeadingKeyword.Range
892- | _ -> range0
893-
894- SynExpr.LetOrUse(
895- isRec,
896- isUse,
897- decls,
898- body,
899- mWhole,
874+ let trivia : SynExprAndBangTrivia =
900875 {
901- LetOrUseKeyword = mLetOrUse
876+ AndBangKeyword = mKeyword
877+ EqualsRange = mEquals
902878 InKeyword = mIn
903879 }
904- )
880+
881+ // For and!, isUse is always true, isFromSource is always true
882+ SynExprAndBang( spBind, false , true , pat, rhs, mWhole, trivia)
905883
906884let mkDefnBindings ( mWhole , BindingSetPreAttrs ( _ , isRec , isUse , declsPreAttrs , _bindingSetRange ), attrs , vis , attrsm ) =
907885 if isUse then
@@ -1073,3 +1051,70 @@ let leadingKeywordIsAbstract =
10731051 | SynLeadingKeyword.StaticAbstract _
10741052 | SynLeadingKeyword.StaticAbstractMember _ -> true
10751053 | _ -> false
1054+
1055+ /// Unified helper for creating let/let!/use/use! expressions
1056+ /// Creates either SynExpr.LetOrUse or SynExpr.LetOrUseBang based on isBang parameter
1057+ /// Handles all four cases: 'let', 'let!', 'use', and 'use!'
1058+ let mkLetExpression
1059+ (
1060+ isBang : bool ,
1061+ mKeyword : range ,
1062+ mIn : Option < range >,
1063+ mWhole : range ,
1064+ body : SynExpr ,
1065+ bindingInfo : ( bool * BindingSet ) option ,
1066+ bangInfo : ( SynPat * SynExpr * SynExprAndBang list * range option * bool ) option
1067+ ) =
1068+ if isBang then
1069+ match bangInfo with
1070+ | Some( pat, rhs, andBangs, mEquals, isUse) ->
1071+ // Create let! or use! expression
1072+ let spBind = DebugPointAtBinding.Yes( unionRanges mKeyword rhs.Range)
1073+
1074+ let trivia : SynExprLetOrUseBangTrivia =
1075+ {
1076+ LetOrUseBangKeyword = mKeyword
1077+ EqualsRange = mEquals
1078+ }
1079+ // isFromSource is true for user-written code
1080+ SynExpr.LetOrUseBang( spBind, isUse, true , pat, rhs, andBangs, body, mWhole, trivia)
1081+ | None -> SynExpr.FromParseError( body, mWhole)
1082+ else
1083+ match bindingInfo with
1084+ | Some( isRec, BindingSetPreAttrs(_, _, isUse, declsPreAttrs, _)) ->
1085+ // Create regular let or use expression
1086+ let ignoredFreeAttrs , decls = declsPreAttrs [] None
1087+
1088+ let mWhole ' =
1089+ match decls with
1090+ | SynBinding( xmlDoc = xmlDoc) :: _ -> unionRangeWithXmlDoc xmlDoc mWhole
1091+ | _ -> mWhole
1092+
1093+ if not ( isNil ignoredFreeAttrs) then
1094+ warning ( Error( FSComp.SR.parsAttributesIgnored (), mWhole'))
1095+
1096+ let mIn ' =
1097+ mIn
1098+ |> Option.bind ( fun ( mIn : range ) ->
1099+ if Position.posEq mIn.Start body.Range.Start then
1100+ None
1101+ else
1102+ Some mIn)
1103+
1104+ let mLetOrUse =
1105+ match decls with
1106+ | SynBinding( trivia = trivia) :: _ -> trivia.LeadingKeyword.Range
1107+ | _ -> range0
1108+
1109+ SynExpr.LetOrUse(
1110+ isRec,
1111+ isUse, // Pass through the isUse flag from binding info
1112+ decls,
1113+ body,
1114+ mWhole',
1115+ {
1116+ LetOrUseKeyword = mLetOrUse
1117+ InKeyword = mIn'
1118+ }
1119+ )
1120+ | None -> SynExpr.FromParseError( body, mWhole)
0 commit comments