From 22166d228b25b15a955d65718c46ea4719a608c6 Mon Sep 17 00:00:00 2001 From: Eugene Auduchinok Date: Fri, 8 Oct 2021 17:19:05 +0300 Subject: [PATCH] Parser: correct range for recovered match clause --- src/fsharp/pars.fsy | 61 +++++++++++++++++------------------- tests/service/ParserTests.fs | 14 +++++++++ 2 files changed, 43 insertions(+), 32 deletions(-) diff --git a/src/fsharp/pars.fsy b/src/fsharp/pars.fsy index 337b01db69b..be345126916 100644 --- a/src/fsharp/pars.fsy +++ b/src/fsharp/pars.fsy @@ -3478,15 +3478,15 @@ declExpr: | anonLambdaExpr %prec expr_fun { $1 } - | MATCH typedSequentialExpr withClauses %prec expr_match - { let mMatch = (rhs parseState 1) - let mWith, (clauses, mLast) = $3 - let spBind = DebugPointAtBinding.Yes(unionRanges mMatch mWith) + | MATCH typedSequentialExpr withClauses %prec expr_match + { let mMatch = rhs parseState 1 + let mWith, (clauses, mLast) = $3 + let spBind = DebugPointAtBinding.Yes(unionRanges mMatch mWith) SynExpr.Match (spBind, $2, clauses, unionRanges mMatch mLast) } - | MATCH typedSequentialExpr recover %prec expr_match + | MATCH typedSequentialExpr recover %prec expr_match { if not $3 then reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsUnexpectedEndOfFileMatch()) - // Produce approximate expression during error recovery + // Produce approximate expression during error recovery exprFromParseError $2 } | MATCH_BANG typedSequentialExpr withClauses %prec expr_match @@ -3998,52 +3998,49 @@ withPatternClauses: patternAndGuard: | parenPattern patternGuard - { $1, $2, rhs parseState 1 } - -patternClauses: + { $1, $2 } + +patternClauses: | patternAndGuard patternResult %prec prec_pat_pat_action - { let pat, guard, patm = $1 + { let pat, guard = $1 let mArrow, resultExpr = $2 let mLast = resultExpr.Range - let m = unionRanges resultExpr.Range patm - [SynMatchClause(pat, guard, (Some mArrow), resultExpr, m, DebugPointAtTarget.Yes)], mLast } + let m = unionRanges resultExpr.Range pat.Range + [SynMatchClause(pat, guard, (Some mArrow), resultExpr, m, DebugPointAtTarget.Yes)], mLast } - | patternAndGuard patternResult BAR patternClauses - { let pat, guard, patm = $1 + | patternAndGuard patternResult BAR patternClauses + { let pat, guard = $1 let mArrow, resultExpr = $2 let clauses, mLast = $4 - let m = unionRanges resultExpr.Range patm + let m = unionRanges resultExpr.Range pat.Range (SynMatchClause(pat, guard, (Some mArrow), resultExpr, m, DebugPointAtTarget.Yes) :: clauses), mLast } - | patternAndGuard error BAR patternClauses - { let pat, guard, patm = $1 + | patternAndGuard error BAR patternClauses + { let pat, guard = $1 let clauses, mLast = $4 + let patm = pat.Range let m = guard |> Option.map (fun e -> unionRanges patm e.Range) |> Option.defaultValue patm (SynMatchClause(pat, guard, None, arbExpr ("patternClauses1", m.EndRange), m, DebugPointAtTarget.Yes) :: clauses), mLast } | patternAndGuard patternResult BAR error - { let pat, guard, patm = $1 + { let pat, guard = $1 let mArrow, resultExpr = $2 let mLast = rhs parseState 3 - let m = unionRanges resultExpr.Range patm - // silent recovery + let m = unionRanges resultExpr.Range pat.Range [SynMatchClause(pat, guard, (Some mArrow), resultExpr, m, DebugPointAtTarget.Yes)], mLast } - | patternAndGuard patternResult error - { let pat, guard, patm = $1 + | patternAndGuard patternResult error + { let pat, guard = $1 let mArrow, resultExpr = $2 - let mLast = resultExpr.Range - let m = unionRanges resultExpr.Range patm - // silent recovery - [SynMatchClause(pat, guard, (Some mArrow), resultExpr, m, DebugPointAtTarget.Yes)], mLast } + let m = unionRanges resultExpr.Range pat.Range + [SynMatchClause(pat, guard, (Some mArrow), resultExpr, m, DebugPointAtTarget.Yes)], m } - | patternAndGuard error - { let pat, guard, patm = $1 - let mLast = rhs parseState 2 + | patternAndGuard error + { let pat, guard = $1 + let patm = pat.Range let m = guard |> Option.map (fun e -> unionRanges patm e.Range) |> Option.defaultValue patm - // silent recovery - [SynMatchClause(pat, guard, None, arbExpr ("patternClauses2", m.EndRange), m, DebugPointAtTarget.Yes)], mLast } - + [SynMatchClause(pat, guard, None, arbExpr ("patternClauses2", m.EndRange), m, DebugPointAtTarget.Yes)], m } + patternGuard: | WHEN declExpr { Some $2 } diff --git a/tests/service/ParserTests.fs b/tests/service/ParserTests.fs index 003092a758b..e90888280b8 100644 --- a/tests/service/ParserTests.fs +++ b/tests/service/ParserTests.fs @@ -2,6 +2,7 @@ open FSharp.Compiler.Service.Tests.Common open FSharp.Compiler.Syntax +open FSharp.Compiler.Text open NUnit.Framework [] @@ -135,6 +136,19 @@ match () with | _ -> failwith "Unexpected pattern" | _ -> failwith "Unexpected tree" +[] +let ``Match clause 08 - Range`` () = + let parseResults = getParseResults """ +match () with +| a +b +""" + match getSingleModuleMemberDecls parseResults with + | [ SynModuleDecl.DoExpr (_, (SynExpr.Match _ as m), _); SynModuleDecl.DoExpr (_, (SynExpr.Ident _ as i), _) ] -> + Assert.True(Position.posLt m.Range.End i.Range.Start) + | _ -> failwith "Unexpected tree" + + [] let ``Let - Parameter - Paren 01`` () = let parseResults = getParseResults """