Skip to content

Commit 050271d

Browse files
nojafvzarytovskii
andauthored
Add SynExprSequentialTrivia (#16981)
* Add SynExprSequentialTrivia * Add release note * Format * Apply feedback from code review * PR is fine --------- Co-authored-by: Vlad Zarytovskii <vzaritovsky@hotmail.com>
1 parent 3d95e4e commit 050271d

30 files changed

+221
-79
lines changed

docs/release-notes/.FSharp.Compiler.Service/8.0.300.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
* Parser: more 'as' pattern recovery ([PR #16837](https://github.com/dotnet/fsharp/pull/16837))
4646
* Add extended data for `DefinitionsInSigAndImplNotCompatibleAbbreviationsDiffer` (FS0318). ([PR #16811](https://github.com/dotnet/fsharp/pull/16811)))
4747
* Checker/patterns: recover on unresolved long identifiers ([PR #16842](https://github.com/dotnet/fsharp/pull/16842))
48+
* SynExprSequentialTrivia ([Issue #16914](https://github.com/dotnet/fsharp/issues/16914), [PR #16981](https://github.com/dotnet/fsharp/pull/16981))
4849

4950
### Changed
5051

src/Compiler/Checking/CheckComputationExpressions.fs

Lines changed: 40 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ let (|SimpleSemicolonSequence|_|) cenv acceptDeprecated cexpr =
205205

206206
let rec TryGetSimpleSemicolonSequenceOfComprehension expr acc =
207207
match expr with
208-
| SynExpr.Sequential(_, true, e1, e2, _) ->
208+
| SynExpr.Sequential(isTrueSeq = true; expr1 = e1; expr2 = e2) ->
209209
if IsSimpleSemicolonSequenceElement e1 then
210210
TryGetSimpleSemicolonSequenceOfComprehension e2 (e1 :: acc)
211211
else
@@ -752,8 +752,14 @@ let TcComputationExpression (cenv: cenv) env (overallTy: OverallTy) tpenv (mWhol
752752

753753
let (|ForEachThen|_|) synExpr =
754754
match synExpr with
755-
| SynExpr.ForEach(_spFor, _spIn, SeqExprOnly false, isFromSource, pat1, expr1, SynExpr.Sequential(_, true, clause, rest, _), _) ->
756-
Some(isFromSource, pat1, expr1, clause, rest)
755+
| SynExpr.ForEach(_spFor,
756+
_spIn,
757+
SeqExprOnly false,
758+
isFromSource,
759+
pat1,
760+
expr1,
761+
SynExpr.Sequential(isTrueSeq = true; expr1 = clause; expr2 = rest),
762+
_) -> Some(isFromSource, pat1, expr1, clause, rest)
757763
| _ -> None
758764

759765
let (|CustomOpId|_|) predicate synExpr =
@@ -998,7 +1004,7 @@ let TcComputationExpression (cenv: cenv) env (overallTy: OverallTy) tpenv (mWhol
9981004

9991005
let (|OptionalSequential|) e =
10001006
match e with
1001-
| SynExpr.Sequential(_sp, true, dataComp1, dataComp2, _) -> (dataComp1, Some dataComp2)
1007+
| SynExpr.Sequential(debugPoint = _sp; isTrueSeq = true; expr1 = dataComp1; expr2 = dataComp2) -> (dataComp1, Some dataComp2)
10021008
| _ -> (e, None)
10031009

10041010
// "cexpr; cexpr" is treated as builder.Combine(cexpr1, cexpr1)
@@ -1233,7 +1239,14 @@ let TcComputationExpression (cenv: cenv) env (overallTy: OverallTy) tpenv (mWhol
12331239
// 2. incompatible types: int and string
12341240
// with SynExpr.ArbitraryAfterError we have only first one
12351241
let wrapInArbErrSequence l caption =
1236-
SynExpr.Sequential(DebugPointAtSequential.SuppressNeither, true, l, (arbExpr (caption, l.Range.EndRange)), l.Range)
1242+
SynExpr.Sequential(
1243+
DebugPointAtSequential.SuppressNeither,
1244+
true,
1245+
l,
1246+
(arbExpr (caption, l.Range.EndRange)),
1247+
l.Range,
1248+
SynExprSequentialTrivia.Zero
1249+
)
12371250

12381251
let mkOverallExprGivenVarSpaceExpr, varSpaceInner =
12391252

@@ -1529,7 +1542,14 @@ let TcComputationExpression (cenv: cenv) env (overallTy: OverallTy) tpenv (mWhol
15291542
SynExpr.While(
15301543
DebugPointAtWhile.No,
15311544
SynExpr.Ident idCond,
1532-
SynExpr.Sequential(DebugPointAtSequential.SuppressBoth, true, innerComp, bindCondExpr, mWhile),
1545+
SynExpr.Sequential(
1546+
DebugPointAtSequential.SuppressBoth,
1547+
true,
1548+
innerComp,
1549+
bindCondExpr,
1550+
mWhile,
1551+
SynExprSequentialTrivia.Zero
1552+
),
15331553
mOrig
15341554
)
15351555

@@ -1658,7 +1678,7 @@ let TcComputationExpression (cenv: cenv) env (overallTy: OverallTy) tpenv (mWhol
16581678
// Now run the consumeCustomOpClauses
16591679
Some(consumeCustomOpClauses q varSpace dataCompPriorToOp comp false mClause)
16601680

1661-
| SynExpr.Sequential(sp, true, innerComp1, innerComp2, m) ->
1681+
| SynExpr.Sequential(sp, true, innerComp1, innerComp2, m, _) ->
16621682

16631683
// Check for 'where x > y' and other mis-applications of infix operators. If detected, give a good error message, and just ignore innerComp1
16641684
if isQuery && checkForBinaryApp innerComp1 then
@@ -1761,7 +1781,7 @@ let TcComputationExpression (cenv: cenv) env (overallTy: OverallTy) tpenv (mWhol
17611781

17621782
SynExpr.SequentialOrImplicitYield(sp, innerComp1, holeFill, combineExpr, m)
17631783
else
1764-
SynExpr.Sequential(sp, true, innerComp1, holeFill, m)
1784+
SynExpr.Sequential(sp, true, innerComp1, holeFill, m, SynExprSequentialTrivia.Zero)
17651785

17661786
translatedCtxt fillExpr)
17671787
)
@@ -2643,7 +2663,14 @@ let TcComputationExpression (cenv: cenv) env (overallTy: OverallTy) tpenv (mWhol
26432663
comp.Range
26442664
)
26452665
else
2646-
SynExpr.Sequential(DebugPointAtSequential.SuppressExpr, true, comp, holeFill, comp.Range)
2666+
SynExpr.Sequential(
2667+
DebugPointAtSequential.SuppressExpr,
2668+
true,
2669+
comp,
2670+
holeFill,
2671+
comp.Range,
2672+
SynExprSequentialTrivia.Zero
2673+
)
26472674

26482675
translatedCtxt fillExpr)
26492676

@@ -2772,14 +2799,14 @@ let TcComputationExpression (cenv: cenv) env (overallTy: OverallTy) tpenv (mWhol
27722799

27732800
Some(varSpaceExpr, Some(innerComp, mClause))
27742801

2775-
| SynExpr.Sequential(sp, true, innerComp1, innerComp2, m) ->
2802+
| SynExpr.Sequential(sp, true, innerComp1, innerComp2, m, trivia) ->
27762803

27772804
// Check the first part isn't a computation expression construct
27782805
if isSimpleExpr innerComp1 then
27792806
// Check the second part is a simple return
27802807
match convertSimpleReturnToExpr varSpace innerComp2 with
27812808
| None -> None
2782-
| Some(innerExpr2, optionalCont) -> Some(SynExpr.Sequential(sp, true, innerComp1, innerExpr2, m), optionalCont)
2809+
| Some(innerExpr2, optionalCont) -> Some(SynExpr.Sequential(sp, true, innerComp1, innerExpr2, m, trivia), optionalCont)
27832810
else
27842811
None
27852812

@@ -2798,7 +2825,7 @@ let TcComputationExpression (cenv: cenv) env (overallTy: OverallTy) tpenv (mWhol
27982825
| SynExpr.ImplicitZero _ -> false
27992826
| OptionalSequential(JoinOrGroupJoinOrZipClause _, _) -> false
28002827
| OptionalSequential(CustomOperationClause _, _) -> false
2801-
| SynExpr.Sequential(_, _, innerComp1, innerComp2, _) -> isSimpleExpr innerComp1 && isSimpleExpr innerComp2
2828+
| SynExpr.Sequential(expr1 = innerComp1; expr2 = innerComp2) -> isSimpleExpr innerComp1 && isSimpleExpr innerComp2
28022829
| SynExpr.IfThenElse(thenExpr = thenComp; elseExpr = elseCompOpt) ->
28032830
isSimpleExpr thenComp
28042831
&& (match elseCompOpt with
@@ -3122,7 +3149,7 @@ let TcSequenceExpression (cenv: cenv) env tpenv comp (overallTy: OverallTy) m =
31223149

31233150
| SynExpr.DoBang(_rhsExpr, m) -> error (Error(FSComp.SR.tcDoBangIllegalInSequenceExpression (), m))
31243151

3125-
| SynExpr.Sequential(sp, true, innerComp1, innerComp2, m) ->
3152+
| SynExpr.Sequential(sp, true, innerComp1, innerComp2, m, _) ->
31263153
let env1 =
31273154
{ env with
31283155
eIsControlFlow =

src/Compiler/Checking/CheckExpressions.fs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5795,7 +5795,7 @@ and TcExprUndelayed (cenv: cenv) (overallTy: OverallTy) env tpenv (synExpr: SynE
57955795
let _, tpenv = suppressErrorReporting (fun () -> TcExpr cenv overallTy env tpenv expr1)
57965796
mkDefault(m, overallTy.Commit), tpenv
57975797

5798-
| SynExpr.Sequential (sp, dir, synExpr1, synExpr2, m) ->
5798+
| SynExpr.Sequential (sp, dir, synExpr1, synExpr2, m, _) ->
57995799
TcExprSequential cenv overallTy env tpenv (synExpr, sp, dir, synExpr1, synExpr2, m)
58005800

58015801
// Used to implement the type-directed 'implicit yield' rule for computation expressions
@@ -10337,7 +10337,7 @@ and TcLinearExprs bodyChecker cenv env overallTy tpenv isCompExpr synExpr cont =
1033710337
let g = cenv.g
1033810338

1033910339
match synExpr with
10340-
| SynExpr.Sequential (sp, true, expr1, expr2, m) when not isCompExpr ->
10340+
| SynExpr.Sequential (sp, true, expr1, expr2, m, _) when not isCompExpr ->
1034110341
let expr1R, _ =
1034210342
let env1 = { env with eIsControlFlow = (match sp with | DebugPointAtSequential.SuppressNeither | DebugPointAtSequential.SuppressExpr -> true | _ -> false) }
1034310343
TcStmtThatCantBeCtorBody cenv env1 tpenv expr1

src/Compiler/Interactive/fsi.fs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4258,7 +4258,14 @@ type FsiInteractionProcessor
42584258
let m = expr.Range
42594259
// Make this into "(); expr" to suppress generalization and compilation-as-function
42604260
let exprWithSeq =
4261-
SynExpr.Sequential(DebugPointAtSequential.SuppressExpr, true, SynExpr.Const(SynConst.Unit, m.StartRange), expr, m)
4261+
SynExpr.Sequential(
4262+
DebugPointAtSequential.SuppressExpr,
4263+
true,
4264+
SynExpr.Const(SynConst.Unit, m.StartRange),
4265+
expr,
4266+
m,
4267+
SynExprSequentialTrivia.Zero
4268+
)
42624269

42634270
ExecuteParsedExpressionOnMainThread(ctok, diagnosticsLogger, exprWithSeq, istate))
42644271
|> commitResult

src/Compiler/Service/FSharpParseFileResults.fs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ type FSharpParseFileResults(diagnostics: FSharpDiagnostic[], input: ParsedInput,
9696
match expr with
9797

9898
// This lets us dive into subexpressions that may contain the binding we're after
99-
| SynExpr.Sequential(_, _, expr1, expr2, _) ->
99+
| SynExpr.Sequential(expr1 = expr1; expr2 = expr2) ->
100100
if rangeContainsPos expr1.Range pos then
101101
walkBinding expr1 workingRange
102102
else
@@ -714,7 +714,7 @@ type FSharpParseFileResults(diagnostics: FSharpDiagnostic[], input: ParsedInput,
714714
yield! walkFinallySeqPt spFinally
715715

716716
| SynExpr.SequentialOrImplicitYield(spSeq, e1, e2, _, _)
717-
| SynExpr.Sequential(spSeq, _, e1, e2, _) ->
717+
| SynExpr.Sequential(debugPoint = spSeq; expr1 = e1; expr2 = e2) ->
718718
let implicit1 =
719719
match spSeq with
720720
| DebugPointAtSequential.SuppressExpr

src/Compiler/Service/ServiceParsedInputOps.fs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -263,8 +263,8 @@ module ParsedInput =
263263

264264
let rec collect expr acc =
265265
match expr with
266-
| SynExpr.Sequential(_, _, e1, (SynExpr.Sequential _ as e2), _) -> collect e2 (e1 :: acc)
267-
| SynExpr.Sequential(_, _, e1, e2, _) -> e2 :: e1 :: acc
266+
| SynExpr.Sequential(expr1 = e1; expr2 = (SynExpr.Sequential _ as e2)) -> collect e2 (e1 :: acc)
267+
| SynExpr.Sequential(expr1 = e1; expr2 = e2) -> e2 :: e1 :: acc
268268
| _ -> acc
269269

270270
match collect expr [] with

src/Compiler/Service/ServiceStructure.fs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,7 @@ module Structure =
337337
parseExpr argExpr
338338
parseExpr funcExpr
339339

340-
| SynExpr.Sequential(_, _, e1, e2, _) ->
340+
| SynExpr.Sequential(expr1 = e1; expr2 = e2) ->
341341
parseExpr e1
342342
parseExpr e2
343343

src/Compiler/SyntaxTree/SyntaxTree.fs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -630,7 +630,13 @@ type SynExpr =
630630

631631
| Lazy of expr: SynExpr * range: range
632632

633-
| Sequential of debugPoint: DebugPointAtSequential * isTrueSeq: bool * expr1: SynExpr * expr2: SynExpr * range: range
633+
| Sequential of
634+
debugPoint: DebugPointAtSequential *
635+
isTrueSeq: bool *
636+
expr1: SynExpr *
637+
expr2: SynExpr *
638+
range: range *
639+
trivia: SynExprSequentialTrivia
634640

635641
| IfThenElse of
636642
ifExpr: SynExpr *
@@ -835,9 +841,9 @@ type SynExpr =
835841
match e with
836842
// these are better than just .Range, and also commonly applicable inside queries
837843
| SynExpr.Paren(_, m, _, _) -> m
838-
| SynExpr.Sequential(_, _, e1, _, _)
839-
| SynExpr.SequentialOrImplicitYield(_, e1, _, _, _)
840-
| SynExpr.App(_, _, e1, _, _) -> e1.RangeOfFirstPortion
844+
| SynExpr.Sequential(expr1 = e1)
845+
| SynExpr.SequentialOrImplicitYield(expr1 = e1)
846+
| SynExpr.App(funcExpr = e1) -> e1.RangeOfFirstPortion
841847
| SynExpr.ForEach(pat = pat; range = r) ->
842848
let e = (pat.Range: range).Start
843849
withEnd e r

src/Compiler/SyntaxTree/SyntaxTree.fsi

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -754,7 +754,8 @@ type SynExpr =
754754
isTrueSeq: bool *
755755
expr1: SynExpr *
756756
expr2: SynExpr *
757-
range: range
757+
range: range *
758+
trivia: SynExprSequentialTrivia
758759

759760
/// F# syntax: if expr then expr
760761
/// F# syntax: if expr then expr else expr

src/Compiler/SyntaxTree/SyntaxTreeOps.fs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -942,7 +942,7 @@ let rec synExprContainsError inpExpr =
942942

943943
| SynExpr.TryFinally(tryExpr = e1; finallyExpr = e2) -> walkExpr e1 || walkExpr e2
944944

945-
| SynExpr.Sequential(_, _, e1, e2, _) -> walkExpr e1 || walkExpr e2
945+
| SynExpr.Sequential(expr1 = e1; expr2 = e2) -> walkExpr e1 || walkExpr e2
946946

947947
| SynExpr.SequentialOrImplicitYield(_, e1, e2, _, _) -> walkExpr e1 || walkExpr e2
948948

src/Compiler/SyntaxTree/SyntaxTrivia.fs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,14 @@ type SynExprMatchBangTrivia =
115115
[<NoEquality; NoComparison>]
116116
type SynExprAnonRecdTrivia = { OpeningBraceRange: range }
117117

118+
[<NoEquality; NoComparison>]
119+
type SynExprSequentialTrivia =
120+
{
121+
SeparatorRange: range option
122+
}
123+
124+
static member val Zero = { SeparatorRange = None }
125+
118126
[<NoEquality; NoComparison>]
119127
type SynMatchClauseTrivia =
120128
{

src/Compiler/SyntaxTree/SyntaxTrivia.fsi

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,17 @@ type SynExprAnonRecdTrivia =
175175
OpeningBraceRange: range
176176
}
177177

178+
/// Represents additional information for SynExpr.Sequential
179+
[<NoEquality; NoComparison>]
180+
type SynExprSequentialTrivia =
181+
{
182+
/// The syntax range of the `;` token.
183+
/// Could also be the `then` keyword.
184+
SeparatorRange: range option
185+
}
186+
187+
static member Zero: SynExprSequentialTrivia
188+
178189
/// Represents additional information for SynMatchClause
179190
[<NoEquality; NoComparison>]
180191
type SynMatchClauseTrivia =

src/Compiler/pars.fsy

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3895,7 +3895,8 @@ typedSequentialExprEOF:
38953895

38963896
sequentialExpr:
38973897
| declExpr seps sequentialExpr
3898-
{ SynExpr.Sequential(DebugPointAtSequential.SuppressNeither, true, $1, $3, unionRanges $1.Range $3.Range) }
3898+
{ let trivia = { SeparatorRange = $2 }
3899+
SynExpr.Sequential(DebugPointAtSequential.SuppressNeither, true, $1, $3, unionRanges $1.Range $3.Range, trivia) }
38993900

39003901
| declExpr seps
39013902
{ $1 }
@@ -3904,10 +3905,12 @@ sequentialExpr:
39043905
{ $1 }
39053906

39063907
| declExpr THEN sequentialExpr %prec prec_then_before
3907-
{ SynExpr.Sequential(DebugPointAtSequential.SuppressNeither, false, $1, $3, unionRanges $1.Range $3.Range) }
3908+
{ let trivia = { SeparatorRange = Some (rhs parseState 2) }
3909+
SynExpr.Sequential(DebugPointAtSequential.SuppressNeither, false, $1, $3, unionRanges $1.Range $3.Range, trivia) }
39083910

39093911
| declExpr OTHEN OBLOCKBEGIN typedSequentialExpr oblockend %prec prec_then_before
3910-
{ SynExpr.Sequential(DebugPointAtSequential.SuppressNeither, false, $1, $4, unionRanges $1.Range $4.Range) }
3912+
{ let trivia = { SeparatorRange = Some (rhs parseState 2) }
3913+
SynExpr.Sequential(DebugPointAtSequential.SuppressNeither, false, $1, $4, unionRanges $1.Range $4.Range, trivia) }
39113914

39123915
| hardwhiteLetBindings %prec prec_args_error
39133916
{ let hwlb, m, mIn = $1
@@ -6658,10 +6661,10 @@ opt_topSeparators:
66586661

66596662
/* Seprators in either #light or non-#light */
66606663
seps:
6661-
| OBLOCKSEP { }
6662-
| SEMICOLON { }
6663-
| OBLOCKSEP SEMICOLON { }
6664-
| SEMICOLON OBLOCKSEP { }
6664+
| OBLOCKSEP { None }
6665+
| SEMICOLON { Some (rhs parseState 1) }
6666+
| OBLOCKSEP SEMICOLON { Some (rhs parseState 2) }
6667+
| SEMICOLON OBLOCKSEP { Some (rhs parseState 1) }
66656668

66666669
/* An 'end' that's optional only in #light, where an ODECLEND gets inserted, and explicit 'end's get converted to OEND */
66676670
declEnd:

0 commit comments

Comments
 (0)