Skip to content

Commit 441e773

Browse files
committed
Extract helper functions from pars.fsy to ParseHelpers.
1 parent 2d86dbd commit 441e773

File tree

3 files changed

+249
-161
lines changed

3 files changed

+249
-161
lines changed

src/Compiler/SyntaxTree/ParseHelpers.fs

Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ open FSharp.Compiler.Text
1313
open FSharp.Compiler.Text.Position
1414
open FSharp.Compiler.Text.Range
1515
open FSharp.Compiler.Xml
16+
open Internal.Utilities.Library
1617
open Internal.Utilities.Text.Lexing
1718
open Internal.Utilities.Text.Parsing
1819

@@ -857,3 +858,198 @@ let mkSynTypeTuple (elementTypes: SynTupleTypeSegment list) : SynType =
857858
||> List.fold (fun acc segment -> unionRanges acc segment.Range)
858859

859860
SynType.Tuple(false, elementTypes, range)
861+
862+
#if DEBUG
863+
let debugPrint s =
864+
if Internal.Utilities.Text.Parsing.Flags.debug then
865+
printfn "\n%s" s
866+
#else
867+
let debugPrint s = ignore s
868+
#endif
869+
870+
let exprFromParseError (e: SynExpr) = SynExpr.FromParseError(e, e.Range)
871+
872+
let patFromParseError (e: SynPat) = SynPat.FromParseError(e, e.Range)
873+
874+
// record bindings returned by the recdExprBindings rule has shape:
875+
// (binding, separator-before-this-binding)
876+
// this function converts arguments from form
877+
// binding1 (binding2*sep1, binding3*sep2...) sepN
878+
// to form
879+
// binding1*sep1, binding2*sep2
880+
let rebindRanges first fields lastSep =
881+
let rec run (name, mEquals, value) l acc =
882+
match l with
883+
| [] -> List.rev (SynExprRecordField(name, mEquals, value, lastSep) :: acc)
884+
| (f, m) :: xs -> run f xs (SynExprRecordField(name, mEquals, value, m) :: acc)
885+
886+
run first fields []
887+
888+
let mkUnderscoreRecdField m =
889+
SynLongIdent([ ident ("_", m) ], [], [ None ]), false
890+
891+
let mkRecdField (lidwd: SynLongIdent) = lidwd, true
892+
893+
// Used for 'do expr' in a class.
894+
let mkSynDoBinding (vis: SynAccess option, expr, m) =
895+
match vis with
896+
| Some vis -> errorR (Error(FSComp.SR.parsDoCannotHaveVisibilityDeclarations (vis.ToString()), m))
897+
| None -> ()
898+
899+
SynBinding(
900+
None,
901+
SynBindingKind.Do,
902+
false,
903+
false,
904+
[],
905+
PreXmlDoc.Empty,
906+
SynInfo.emptySynValData,
907+
SynPat.Const(SynConst.Unit, m),
908+
None,
909+
expr,
910+
m,
911+
DebugPointAtBinding.NoneAtDo,
912+
SynBindingTrivia.Zero
913+
)
914+
915+
let mkSynExprDecl (e: SynExpr) = SynModuleDecl.Expr(e, e.Range)
916+
917+
let addAttribs attrs p = SynPat.Attrib(p, attrs, p.Range)
918+
919+
let unionRangeWithPos (r: range) p =
920+
let r2 = mkRange r.FileName p p
921+
unionRanges r r2
922+
923+
/// Report a good error at the end of file, e.g. for non-terminated strings
924+
let checkEndOfFileError t =
925+
match t with
926+
| LexCont.IfDefSkip (_, _, _, m) -> reportParseErrorAt m (FSComp.SR.parsEofInHashIf ())
927+
928+
| LexCont.String (_, _, LexerStringStyle.SingleQuote, kind, m) ->
929+
if kind.IsInterpolated then
930+
reportParseErrorAt m (FSComp.SR.parsEofInInterpolatedString ())
931+
else
932+
reportParseErrorAt m (FSComp.SR.parsEofInString ())
933+
934+
| LexCont.String (_, _, LexerStringStyle.TripleQuote, kind, m) ->
935+
if kind.IsInterpolated then
936+
reportParseErrorAt m (FSComp.SR.parsEofInInterpolatedTripleQuoteString ())
937+
else
938+
reportParseErrorAt m (FSComp.SR.parsEofInTripleQuoteString ())
939+
940+
| LexCont.String (_, _, LexerStringStyle.Verbatim, kind, m) ->
941+
if kind.IsInterpolated then
942+
reportParseErrorAt m (FSComp.SR.parsEofInInterpolatedVerbatimString ())
943+
else
944+
reportParseErrorAt m (FSComp.SR.parsEofInVerbatimString ())
945+
946+
| LexCont.Comment (_, _, _, m) -> reportParseErrorAt m (FSComp.SR.parsEofInComment ())
947+
948+
| LexCont.SingleLineComment (_, _, _, m) -> reportParseErrorAt m (FSComp.SR.parsEofInComment ())
949+
950+
| LexCont.StringInComment (_, _, LexerStringStyle.SingleQuote, _, m) -> reportParseErrorAt m (FSComp.SR.parsEofInStringInComment ())
951+
952+
| LexCont.StringInComment (_, _, LexerStringStyle.Verbatim, _, m) ->
953+
reportParseErrorAt m (FSComp.SR.parsEofInVerbatimStringInComment ())
954+
955+
| LexCont.StringInComment (_, _, LexerStringStyle.TripleQuote, _, m) ->
956+
reportParseErrorAt m (FSComp.SR.parsEofInTripleQuoteStringInComment ())
957+
958+
| LexCont.MLOnly (_, _, m) -> reportParseErrorAt m (FSComp.SR.parsEofInIfOcaml ())
959+
960+
| LexCont.EndLine (_, _, LexerEndlineContinuation.Skip (_, m)) -> reportParseErrorAt m (FSComp.SR.parsEofInDirective ())
961+
962+
| LexCont.EndLine (endifs, nesting, LexerEndlineContinuation.Token)
963+
| LexCont.Token (endifs, nesting) ->
964+
match endifs with
965+
| [] -> ()
966+
| (_, m) :: _ -> reportParseErrorAt m (FSComp.SR.parsNoHashEndIfFound ())
967+
968+
match nesting with
969+
| [] -> ()
970+
| (_, _, m) :: _ -> reportParseErrorAt m (FSComp.SR.parsEofInInterpolatedStringFill ())
971+
972+
type BindingSet = BindingSetPreAttrs of range * bool * bool * (SynAttributes -> SynAccess option -> SynAttributes * SynBinding list) * range
973+
974+
let mkClassMemberLocalBindings
975+
(
976+
isStatic,
977+
initialRangeOpt,
978+
attrs,
979+
vis,
980+
BindingSetPreAttrs (_, isRec, isUse, declsPreAttrs, bindingSetRange)
981+
) =
982+
let ignoredFreeAttrs, decls = declsPreAttrs attrs vis
983+
984+
let mWhole =
985+
match initialRangeOpt with
986+
| None -> bindingSetRange
987+
| Some m -> unionRanges m bindingSetRange
988+
// decls could have a leading attribute
989+
|> fun m -> (m, decls) ||> unionRangeWithListBy (fun (SynBinding (range = m)) -> m)
990+
991+
if not (isNil ignoredFreeAttrs) then
992+
warning (Error(FSComp.SR.parsAttributesIgnored (), mWhole))
993+
994+
if isUse then
995+
errorR (Error(FSComp.SR.parsUseBindingsIllegalInImplicitClassConstructors (), mWhole))
996+
997+
SynMemberDefn.LetBindings(decls, isStatic, isRec, mWhole)
998+
999+
let mkLocalBindings (mWhole, BindingSetPreAttrs (_, isRec, isUse, declsPreAttrs, _), mIn, body: SynExpr) =
1000+
let ignoredFreeAttrs, decls = declsPreAttrs [] None
1001+
1002+
let mWhole =
1003+
match decls with
1004+
| SynBinding (xmlDoc = xmlDoc) :: _ -> unionRangeWithXmlDoc xmlDoc mWhole
1005+
| _ -> mWhole
1006+
1007+
if not (isNil ignoredFreeAttrs) then
1008+
warning (Error(FSComp.SR.parsAttributesIgnored (), mWhole))
1009+
1010+
let mIn =
1011+
mIn
1012+
|> Option.bind (fun (mIn: range) ->
1013+
if Position.posEq mIn.Start body.Range.Start then
1014+
None
1015+
else
1016+
Some mIn)
1017+
1018+
SynExpr.LetOrUse(isRec, isUse, decls, body, mWhole, { InKeyword = mIn })
1019+
1020+
let mkDefnBindings (mWhole, BindingSetPreAttrs (_, isRec, isUse, declsPreAttrs, _bindingSetRange), attrs, vis, attrsm) =
1021+
if isUse then
1022+
warning (Error(FSComp.SR.parsUseBindingsIllegalInModules (), mWhole))
1023+
1024+
let freeAttrs, decls = declsPreAttrs attrs vis
1025+
// decls might have an extended range due to leading attributes
1026+
let mWhole =
1027+
(mWhole, decls) ||> unionRangeWithListBy (fun (SynBinding (range = m)) -> m)
1028+
1029+
let letDecls = [ SynModuleDecl.Let(isRec, decls, mWhole) ]
1030+
1031+
let attrDecls =
1032+
if not (isNil freeAttrs) then
1033+
[ SynModuleDecl.Attributes(freeAttrs, attrsm) ]
1034+
else
1035+
[]
1036+
1037+
attrDecls @ letDecls
1038+
1039+
let idOfPat (parseState: IParseState) m p =
1040+
match p with
1041+
| SynPat.Wild r when parseState.LexBuffer.SupportsFeature LanguageFeature.WildCardInForLoop -> mkSynId r "_"
1042+
| SynPat.Named (SynIdent (id, _), false, _, _) -> id
1043+
| SynPat.LongIdent (longDotId = SynLongIdent ([ id ], _, _); typarDecls = None; argPats = SynArgPats.Pats []; accessibility = None) ->
1044+
id
1045+
| _ -> raiseParseErrorAt m (FSComp.SR.parsIntegerForLoopRequiresSimpleIdentifier ())
1046+
1047+
let checkForMultipleAugmentations m a1 a2 =
1048+
if not (isNil a1) && not (isNil a2) then
1049+
raiseParseErrorAt m (FSComp.SR.parsOnlyOneWithAugmentationAllowed ())
1050+
1051+
a1 @ a2
1052+
1053+
let rangeOfLongIdent (lid: LongIdent) =
1054+
System.Diagnostics.Debug.Assert(not lid.IsEmpty, "the parser should never produce a long-id that is the empty list")
1055+
(lid.Head.idRange, lid) ||> unionRangeWithListBy (fun id -> id.idRange)

src/Compiler/SyntaxTree/ParseHelpers.fsi

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,3 +180,56 @@ val mkSynMemberDefnGetSet:
180180
val adjustHatPrefixToTyparLookup: mFull: range -> rightExpr: SynExpr -> SynExpr
181181

182182
val mkSynTypeTuple: elementTypes: SynTupleTypeSegment list -> SynType
183+
184+
#if DEBUG
185+
val debugPrint: s: string -> unit
186+
#else
187+
val debugPrint: s: 'a -> unit
188+
#endif
189+
190+
val exprFromParseError: e: SynExpr -> SynExpr
191+
192+
val patFromParseError: e: SynPat -> SynPat
193+
194+
val rebindRanges:
195+
first: (RecordFieldName * range option * SynExpr option) ->
196+
fields: ((RecordFieldName * range option * SynExpr option) * BlockSeparator option) list ->
197+
lastSep: BlockSeparator option ->
198+
SynExprRecordField list
199+
200+
val mkUnderscoreRecdField: m: range -> SynLongIdent * bool
201+
202+
val mkRecdField: lidwd: SynLongIdent -> SynLongIdent * bool
203+
204+
val mkSynDoBinding: vis: SynAccess option * expr: SynExpr * m: range -> SynBinding
205+
206+
val mkSynExprDecl: e: SynExpr -> SynModuleDecl
207+
208+
val addAttribs: attrs: SynAttributes -> p: SynPat -> SynPat
209+
210+
val unionRangeWithPos: r: range -> p: pos -> range
211+
212+
val checkEndOfFileError: t: LexerContinuation -> unit
213+
214+
type BindingSet =
215+
| BindingSetPreAttrs of
216+
range *
217+
bool *
218+
bool *
219+
(SynAttributes -> SynAccess option -> SynAttributes * SynBinding list) *
220+
range
221+
222+
val mkClassMemberLocalBindings:
223+
isStatic: bool * initialRangeOpt: range option * attrs: SynAttributes * vis: SynAccess option * BindingSet ->
224+
SynMemberDefn
225+
226+
val mkLocalBindings: mWhole: range * BindingSet * mIn: range option * body: SynExpr -> SynExpr
227+
228+
val mkDefnBindings:
229+
mWhole: range * BindingSet * attrs: SynAttributes * vis: SynAccess option * attrsm: range -> SynModuleDecl list
230+
231+
val idOfPat: parseState: IParseState -> m: range -> p: SynPat -> Ident
232+
233+
val checkForMultipleAugmentations: m: range -> a1: 'a list -> a2: 'a list -> 'a list
234+
235+
val rangeOfLongIdent: lid: LongIdent -> range

0 commit comments

Comments
 (0)