From 20ee9d3819775bf078dced4547a360b8ed22531c Mon Sep 17 00:00:00 2001 From: Florian Verdonck Date: Thu, 19 May 2022 15:16:11 +0200 Subject: [PATCH] Update style of SynExpr.TryWith with a single clause (#2260) * Bump Fantomas * Update style of SynExpr.TryWith with a single clause. Fixes #1881. --- .config/dotnet-tools.json | 2 +- CHANGELOG.md | 1 + ...nkLinesAroundNestedMultilineExpressions.fs | 4 +- .../ColMultilineItemTests.fs | 4 +- src/Fantomas.Core.Tests/CommentTests.fs | 18 ++--- .../CompilerDirectivesTests.fs | 18 +++-- .../ComputationExpressionTests.fs | 3 +- .../ControlStructureTests.fs | 67 +++++++++++++++---- src/Fantomas.Core.Tests/DotGetTests.fs | 4 +- src/Fantomas.Core.Tests/IfThenElseTests.fs | 4 +- .../InterpolatedStringTests.fs | 4 +- .../KeepIndentInBranchTests.fs | 8 +-- src/Fantomas.Core.Tests/LetBindingTests.fs | 3 +- ...ApplicationsInConditionExpressionsTests.fs | 9 ++- src/Fantomas.Core.Tests/OperatorTests.fs | 4 +- .../PatternMatchingTests.fs | 12 ++-- .../FunctionApplicationDualListTests.fs | 4 +- .../FunctionApplicationSingleListTests.fs | 4 +- .../SynMatchClauseExpressionTests.fs | 25 +++---- src/Fantomas.Core.Tests/SynLongIdentTests.fs | 3 +- src/Fantomas.Core/AstTransformer.fs | 15 +++-- src/Fantomas.Core/CodePrinter.fs | 59 +++++++++++++--- src/Fantomas.Core/Context.fs | 11 +-- src/Fantomas.Core/SourceParser.fs | 23 +++++-- src/Fantomas.Core/TriviaTypes.fs | 1 + 25 files changed, 197 insertions(+), 113 deletions(-) diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index b9b13349dd..a03ed10a18 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -21,7 +21,7 @@ ] }, "fantomas": { - "version": "5.0.0-alpha-006", + "version": "5.0.0-alpha-007", "commands": [ "fantomas" ] diff --git a/CHANGELOG.md b/CHANGELOG.md index 21ba925666..e48130d9ff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ ### Changed * Formatting of multi-constrained SRTP functions needs improvement. [#2230](https://github.com/fsprojects/fantomas/issues/2230) +* Try/With with a single clause. [#1881](https://github.com/fsprojects/fantomas/issues/1881) ## [5.0.0-alpha-007] - 2022-05-16 diff --git a/src/Fantomas.Core.Tests/BlankLinesAroundNestedMultilineExpressions.fs b/src/Fantomas.Core.Tests/BlankLinesAroundNestedMultilineExpressions.fs index b92815e96d..5d420992ca 100644 --- a/src/Fantomas.Core.Tests/BlankLinesAroundNestedMultilineExpressions.fs +++ b/src/Fantomas.Core.Tests/BlankLinesAroundNestedMultilineExpressions.fs @@ -81,8 +81,8 @@ let topLevelFunction () = printfn "Something to print" try nothing () - with - | ex -> splash () + with ex -> + splash () () """ diff --git a/src/Fantomas.Core.Tests/ColMultilineItemTests.fs b/src/Fantomas.Core.Tests/ColMultilineItemTests.fs index 86043b3204..4254a460d3 100644 --- a/src/Fantomas.Core.Tests/ColMultilineItemTests.fs +++ b/src/Fantomas.Core.Tests/ColMultilineItemTests.fs @@ -135,8 +135,8 @@ let b (x: int) (y: int) : int = let c () = try 0 - with - | ex -> 1 + with ex -> + 1 """ [] diff --git a/src/Fantomas.Core.Tests/CommentTests.fs b/src/Fantomas.Core.Tests/CommentTests.fs index 409f162a54..3cdd59b9dd 100644 --- a/src/Fantomas.Core.Tests/CommentTests.fs +++ b/src/Fantomas.Core.Tests/CommentTests.fs @@ -1724,10 +1724,10 @@ try try () // xxx - with - | _ -> () -with -| _ -> () + with _ -> + () +with _ -> + () """ [] @@ -1754,7 +1754,8 @@ try with -| b -> c +| b -> + c """ [] @@ -1778,13 +1779,12 @@ with """ try a -with -| b -> +with b -> try c // inner comment - with - | d -> () + with d -> + () """ [] diff --git a/src/Fantomas.Core.Tests/CompilerDirectivesTests.fs b/src/Fantomas.Core.Tests/CompilerDirectivesTests.fs index f50c39edf1..f4d610d32b 100644 --- a/src/Fantomas.Core.Tests/CompilerDirectivesTests.fs +++ b/src/Fantomas.Core.Tests/CompilerDirectivesTests.fs @@ -511,8 +511,7 @@ let start (args: IArgs) = .Run() 0 - with - | ex -> + with ex -> Log.Fatal(ex, "Host terminated unexpectedly") 1 finally @@ -1317,8 +1316,8 @@ try #if DEF () #endif -with -| _ -> () +with _ -> + () """ [] @@ -2350,8 +2349,7 @@ module ReactHookExtensions = do setDeferred (Deferred<'T>.InProgress) let! output = operation do setDeferred (Deferred<'T>.Resolved output) - with - | error -> + with error -> #if DEBUG Browser.Dom.console.log (error) #endif @@ -2742,10 +2740,10 @@ try #if FOO () #endif - with - | _ -> () -with -| _ -> () + with _ -> + () +with _ -> + () """ [] diff --git a/src/Fantomas.Core.Tests/ComputationExpressionTests.fs b/src/Fantomas.Core.Tests/ComputationExpressionTests.fs index acb3f841c3..1b9e24f0e9 100644 --- a/src/Fantomas.Core.Tests/ComputationExpressionTests.fs +++ b/src/Fantomas.Core.Tests/ComputationExpressionTests.fs @@ -1759,8 +1759,7 @@ let sendPushNotifications = let ps = PushSubscription(s.Endpoint, s.P256DH, s.Auth) do! webPushClient.SendNotificationAsync(ps, payload, vapidDetails) - with - | :? WebPushException as wpex -> + with :? WebPushException as wpex -> log.LogError(sprintf "Couldn't send notification to %s, %A" user.UserId wpex) do! diff --git a/src/Fantomas.Core.Tests/ControlStructureTests.fs b/src/Fantomas.Core.Tests/ControlStructureTests.fs index 37d748e40e..799edaeee7 100644 --- a/src/Fantomas.Core.Tests/ControlStructureTests.fs +++ b/src/Fantomas.Core.Tests/ControlStructureTests.fs @@ -135,8 +135,7 @@ let result1 = divide1 100 0 let divide1 x y = try Some(x / y) - with - | :? System.DivideByZeroException -> + with :? System.DivideByZeroException -> printfn "Division by zero!" None @@ -279,8 +278,8 @@ let x = if try true - with - | Failure _ -> false + with Failure _ -> + false then () else @@ -819,7 +818,8 @@ try foo.CreationTime <> defaultTime with // hmm -| :? FileNotFoundException -> false +| :? FileNotFoundException -> + false """ [] @@ -847,7 +847,8 @@ try foo.CreationTime <> defaultTime with // hmm -| :? FileNotFoundException -> false +| :? FileNotFoundException -> + false """ [] @@ -881,7 +882,8 @@ module Foo = failwith "" with // hi! - | :? Exception as e -> failwith "" + | :? Exception as e -> + failwith "" """ [] @@ -914,7 +916,8 @@ module Foo = failwith "" with // hi! - | :? Exception as e -> failwith "" + | :? Exception as e -> + failwith "" """ [] @@ -980,7 +983,8 @@ module Foo = foo.CreationTime <> defaultTime with // hmm - | :? FileNotFoundException -> false + | :? FileNotFoundException -> + false exists @@ -989,7 +993,7 @@ module Foo = """ [] -let ``short catch clause in try/with should have pipe, 1571`` () = +let ``short catch clause in try/with should not have pipe, 1571`` () = formatSourceString false """ @@ -1006,8 +1010,8 @@ with """ try () -with -| exc -> () +with exc -> + () """ [] @@ -1035,8 +1039,43 @@ let isAbstractNonVirtualMember (m: FSharpMemberOrFunctionOrValue) = && (try m.ImplementedAbstractSignatures <> null && m.ImplementedAbstractSignatures.Count = 0 - with - | _ -> true) // exceptions here trying to acces the member means we're safe + with _ -> + true) // exceptions here trying to acces the member means we're safe // this member is not an override && not m.IsOverrideOrExplicitInterfaceImplementation """ + +[] +let ``try/with with a single clause, 1881`` () = + formatSourceString + false + """ +// OK +try + persistState currentState +with ex -> + printfn "Something went wrong: %A" ex + +// OK +try + persistState currentState +with :? System.ApplicationException as ex -> + printfn "Something went wrong: %A" ex +""" + config + |> prepend newline + |> should + equal + """ +// OK +try + persistState currentState +with ex -> + printfn "Something went wrong: %A" ex + +// OK +try + persistState currentState +with :? System.ApplicationException as ex -> + printfn "Something went wrong: %A" ex +""" diff --git a/src/Fantomas.Core.Tests/DotGetTests.fs b/src/Fantomas.Core.Tests/DotGetTests.fs index 7bfb8ace47..b306ebbd12 100644 --- a/src/Fantomas.Core.Tests/DotGetTests.fs +++ b/src/Fantomas.Core.Tests/DotGetTests.fs @@ -992,8 +992,8 @@ type Foobar = .GetSystemAssemblies() .Contains(fileNameWithoutExtension filename)) || tcConfig.FxResolver.IsInReferenceAssemblyPackDirectory filename) - with - | _ -> false + with _ -> + false """ [] diff --git a/src/Fantomas.Core.Tests/IfThenElseTests.fs b/src/Fantomas.Core.Tests/IfThenElseTests.fs index 6417ee6152..a95aaca425 100644 --- a/src/Fantomas.Core.Tests/IfThenElseTests.fs +++ b/src/Fantomas.Core.Tests/IfThenElseTests.fs @@ -1480,8 +1480,8 @@ let main argv = new StreamWriter(outFile) buffer.Flush() - with - | exn -> eprintfn "The following exception occurred while formatting %s: %O" inFile exn + with exn -> + eprintfn "The following exception occurred while formatting %s: %O" inFile exn 0 """ diff --git a/src/Fantomas.Core.Tests/InterpolatedStringTests.fs b/src/Fantomas.Core.Tests/InterpolatedStringTests.fs index 698c6692ec..54ab2f2b27 100644 --- a/src/Fantomas.Core.Tests/InterpolatedStringTests.fs +++ b/src/Fantomas.Core.Tests/InterpolatedStringTests.fs @@ -327,8 +327,8 @@ $" let b = y let c = 9 foo () - with - | ex -> interpolationFailed ()} + with ex -> + interpolationFailed ()} " """ diff --git a/src/Fantomas.Core.Tests/KeepIndentInBranchTests.fs b/src/Fantomas.Core.Tests/KeepIndentInBranchTests.fs index 63e8ce10ec..ff17ea3112 100644 --- a/src/Fantomas.Core.Tests/KeepIndentInBranchTests.fs +++ b/src/Fantomas.Core.Tests/KeepIndentInBranchTests.fs @@ -732,10 +732,10 @@ type Foo() = try try cleanUp () - with - | :? IOException -> foo () - with - | exc -> foooo () + with :? IOException -> + foo () + with exc -> + foooo () """ [] diff --git a/src/Fantomas.Core.Tests/LetBindingTests.fs b/src/Fantomas.Core.Tests/LetBindingTests.fs index 4688a69a59..f6c00a5b39 100644 --- a/src/Fantomas.Core.Tests/LetBindingTests.fs +++ b/src/Fantomas.Core.Tests/LetBindingTests.fs @@ -894,8 +894,7 @@ let private authenticateRequest (logger: ILogger) header = logger.LogError(sprintf "User has a valid token but lacks the correct permission") return None } - with - | exn -> + with exn -> logger.LogError(sprintf "Could not authenticate token %s\n%A" token exn) task { return None } """ diff --git a/src/Fantomas.Core.Tests/MultilineFunctionApplicationsInConditionExpressionsTests.fs b/src/Fantomas.Core.Tests/MultilineFunctionApplicationsInConditionExpressionsTests.fs index c423c0a8d4..934fb507b3 100644 --- a/src/Fantomas.Core.Tests/MultilineFunctionApplicationsInConditionExpressionsTests.fs +++ b/src/Fantomas.Core.Tests/MultilineFunctionApplicationsInConditionExpressionsTests.fs @@ -95,11 +95,10 @@ module ElectrumClient = stratumClient.ServerVersion CLIENT_NAME_SENT_TO_STRATUM_SERVER_WHEN_HELLO PROTOCOL_VERSION_SUPPORTED - with - | :? ElectrumServerReturningErrorException as except when - except.Message.EndsWith - (PROTOCOL_VERSION_SUPPORTED.ToString()) - -> + with :? ElectrumServerReturningErrorException as except when + except.Message.EndsWith( + PROTOCOL_VERSION_SUPPORTED.ToString() + ) -> failwith "xxx" diff --git a/src/Fantomas.Core.Tests/OperatorTests.fs b/src/Fantomas.Core.Tests/OperatorTests.fs index d749df6845..822e8683e1 100644 --- a/src/Fantomas.Core.Tests/OperatorTests.fs +++ b/src/Fantomas.Core.Tests/OperatorTests.fs @@ -234,8 +234,8 @@ try item.MethodInfo.Method.Invoke(null, ipa) |> (fun x -> x?Invoke (true)) |> fun (t: Task) -> t.Wait() -with -| _ -> () +with _ -> + () """ [] diff --git a/src/Fantomas.Core.Tests/PatternMatchingTests.fs b/src/Fantomas.Core.Tests/PatternMatchingTests.fs index 1903ffa9cb..c0fa1f4c1c 100644 --- a/src/Fantomas.Core.Tests/PatternMatchingTests.fs +++ b/src/Fantomas.Core.Tests/PatternMatchingTests.fs @@ -244,8 +244,8 @@ try s' = s0 && can (type_match ty ty0) []) (!the_interface) ) -with -| Failure _ -> s0 +with Failure _ -> + s0 """ [] @@ -1263,8 +1263,8 @@ let private formatResponse<'options> () = return sendBadRequest content - with - | exn -> return sendBadRequest (sprintf "%A" exn) + with exn -> + return sendBadRequest (sprintf "%A" exn) | Error err -> return sendInternalError (err) } """ @@ -1851,8 +1851,8 @@ match x with | _ -> try somethingElse () - with - | e -> printfn "failure %A" e) + with e -> + printfn "failure %A" e) --*-- bar """ diff --git a/src/Fantomas.Core.Tests/Stroustrup/FunctionApplicationDualListTests.fs b/src/Fantomas.Core.Tests/Stroustrup/FunctionApplicationDualListTests.fs index d7d5755a70..16ee007437 100644 --- a/src/Fantomas.Core.Tests/Stroustrup/FunctionApplicationDualListTests.fs +++ b/src/Fantomas.Core.Tests/Stroustrup/FunctionApplicationDualListTests.fs @@ -92,8 +92,8 @@ fn b (try somethingDangerous - with - | ex -> printfn "meh") + with ex -> + printfn "meh") c [ a1 // hey a2 diff --git a/src/Fantomas.Core.Tests/Stroustrup/FunctionApplicationSingleListTests.fs b/src/Fantomas.Core.Tests/Stroustrup/FunctionApplicationSingleListTests.fs index d7c56312c7..3079d8d32f 100644 --- a/src/Fantomas.Core.Tests/Stroustrup/FunctionApplicationSingleListTests.fs +++ b/src/Fantomas.Core.Tests/Stroustrup/FunctionApplicationSingleListTests.fs @@ -95,8 +95,8 @@ fn b (try somethingDangerous - with - | ex -> printfn "meh") + with ex -> + printfn "meh") c [ b1 // comment diff --git a/src/Fantomas.Core.Tests/Stroustrup/SynMatchClauseExpressionTests.fs b/src/Fantomas.Core.Tests/Stroustrup/SynMatchClauseExpressionTests.fs index d34efbb091..b45cbb7238 100644 --- a/src/Fantomas.Core.Tests/Stroustrup/SynMatchClauseExpressionTests.fs +++ b/src/Fantomas.Core.Tests/Stroustrup/SynMatchClauseExpressionTests.fs @@ -211,8 +211,8 @@ match x with (try somethingDangerous () true - with - | ex -> false) + with ex -> + false) -> { A = longTypeName @@ -240,8 +240,7 @@ with ex -> """ try foo () -with -| ex -> { +with ex -> { A = longTypeName B = someOtherVariable C = ziggyBarX @@ -265,8 +264,7 @@ with ex -> """ try foo () -with -| ex -> +with ex -> { astContext with IsInsideMatchClausePattern = true } @@ -291,8 +289,7 @@ with ex -> """ try foo () -with -| ex -> {| +with ex -> {| A = longTypeName B = someOtherVariable C = ziggyBarX @@ -319,8 +316,7 @@ with ex -> """ try foo () -with -| ex -> struct {| +with ex -> struct {| A = longTypeName B = someOtherVariable C = ziggyBarX @@ -348,8 +344,7 @@ with """ try foo () -with -| ex -> task { +with ex -> task { // some computation here () } @@ -377,8 +372,7 @@ with """ try foo () -with -| ex -> [ +with ex -> [ itemOne itemTwo itemThree @@ -409,8 +403,7 @@ with """ try foo () -with -| ex -> [| +with ex -> [| itemOne itemTwo itemThree diff --git a/src/Fantomas.Core.Tests/SynLongIdentTests.fs b/src/Fantomas.Core.Tests/SynLongIdentTests.fs index 9dc0197c2c..962f00f09a 100644 --- a/src/Fantomas.Core.Tests/SynLongIdentTests.fs +++ b/src/Fantomas.Core.Tests/SynLongIdentTests.fs @@ -154,8 +154,7 @@ let main _ = |> ignore 0 - with - | ex -> + with ex -> Log.Fatal(ex, "Service terminated unexpectedly") 1 diff --git a/src/Fantomas.Core/AstTransformer.fs b/src/Fantomas.Core/AstTransformer.fs index ba862956ae..33fca4471b 100644 --- a/src/Fantomas.Core/AstTransformer.fs +++ b/src/Fantomas.Core/AstTransformer.fs @@ -753,13 +753,14 @@ module private Ast = and visitSynMatchClause (mc: SynMatchClause) : TriviaNodeAssigner list = match mc with - | SynMatchClause (pat, e1, e2, _range, _, trivia) -> - mkNode SynMatchClause_ mc.Range // _range is the same range as pat, see https://github.com/dotnet/fsharp/issues/10877 - :: [ yield! visitSynPat pat - if e1.IsSome then - yield! visitSynExpr e1.Value - yield! mkNodeOption SynMatchClause_Arrow trivia.ArrowRange - yield! visitSynExpr e2 ] + | SourceParser.Clause (barRange, pat, eo, arrowRange, e, range) -> + [ yield mkNode SynMatchClause_ range + yield! visitSynPat pat + yield! mkNodeOption SynMatchClause_Bar barRange + if eo.IsSome then + yield! visitSynExpr eo.Value + yield! mkNodeOption SynMatchClause_Arrow arrowRange + yield! visitSynExpr e ] and visitSynExprAndBang (SynExprAndBang (_, _, _, pat, body, range, trivia)) : TriviaNodeAssigner list = [ yield mkNode SynExprAndBang_ range diff --git a/src/Fantomas.Core/CodePrinter.fs b/src/Fantomas.Core/CodePrinter.fs index 22b8a96471..8823690fa1 100644 --- a/src/Fantomas.Core/CodePrinter.fs +++ b/src/Fantomas.Core/CodePrinter.fs @@ -2019,10 +2019,43 @@ and genExpr astContext synExpr ctx = collectMultilineItemForLetOrUses astContext bs (collectMultilineItemForSynExpr astContext e) atCurrentColumn (colWithNlnWhenItemIsMultilineUsingConfig items) - // Could customize a bit if e is single line + + | TryWithSingleClause (tryKeyword, e, withKeyword, barRange, p, eo, arrowRange, catchExpr, clauseRange) -> + let genClause = + leadingExpressionResult + (enterNodeFor SynMatchClause_ clauseRange + +> genTriviaForOption SynMatchClause_Bar barRange sepNone) + (fun ((linesBefore, _), (linesAfter, _)) -> + onlyIfCtx + (fun ctx -> + linesAfter > linesBefore + || hasWriteBeforeNewlineContent ctx) + sepBar) + +> genPat astContext p + +> optSingle + (fun e -> + !- " when" + +> sepSpaceOrIndentAndNlnIfExpressionExceedsPageWidth (genExpr astContext e)) + eo + +> genTriviaForOption SynMatchClause_Arrow arrowRange sepArrow + +> autoIndentAndNlnExpressUnlessRagnarok (genExpr astContext) catchExpr + +> leaveNodeFor SynMatchClause_ clauseRange + + atCurrentColumn ( + genTriviaFor SynExpr_TryWith_Try tryKeyword !- "try" + +> indent + +> sepNln + +> genExpr astContext e + +> unindent + +> sepNln + +> genTriviaFor SynExpr_TryWith_With withKeyword (!- "with") + +> sepSpace + +> genClause + ) + | TryWith (tryKeyword, e, withKeyword, cs) -> atCurrentColumn ( - genTriviaFor SynExpr_TryWith_Try tryKeyword !- "try " + genTriviaFor SynExpr_TryWith_Try tryKeyword !- "try" +> indent +> sepNln +> genExpr astContext e @@ -2034,7 +2067,7 @@ and genExpr astContext synExpr ctx = let hasMultipleClausesWhereOneHasRagnarok = hasMultipleClausesWhereOneHasStroustrup ctx.Config.ExperimentalStroustrupStyle cs - col sepNln cs (genClause astContext true hasMultipleClausesWhereOneHasRagnarok) ctx) + col sepNln cs (genClause astContext hasMultipleClausesWhereOneHasRagnarok) ctx) ) | TryFinally (tryKeyword, e1, finallyKeyword, e2) -> @@ -4517,9 +4550,8 @@ and genInterfaceImpl astContext (InterfaceImpl (t, withKeywordRange, bs, members and genClause (astContext: ASTContext) - (hasBar: bool) (hasMultipleClausesWhereOneHasRagnarok: bool) - (Clause (p, eo, arrowRange, e) as ce) + (Clause (barRange, p, eo, arrowRange, e, clauseRange)) = let astCtx = { astContext with IsInsideMatchClausePattern = true } @@ -4565,7 +4597,12 @@ and genClause +> autoIndentAndNlnIfExpressionExceedsPageWidthUnlessRagnarok (genExpr astContext) e) ctx) - (onlyIf hasBar sepBar + let genBar = + match barRange with + | Some barRange -> genTriviaFor SynMatchClause_Bar barRange sepBar + | None -> sepBar + + (genBar +> (fun ctx -> if hasMultipleClausesWhereOneHasRagnarok then // avoid edge case @@ -4586,13 +4623,13 @@ and genClause atCurrentColumn patAndBody ctx else patAndBody ctx) - |> genTriviaFor SynMatchClause_ ce.Range) + |> genTriviaFor SynMatchClause_ clauseRange) and genClauses astContext cs (ctx: Context) = col sepNln cs - (genClause astContext true (hasMultipleClausesWhereOneHasStroustrup ctx.Config.ExperimentalStroustrupStyle cs)) + (genClause astContext (hasMultipleClausesWhereOneHasStroustrup ctx.Config.ExperimentalStroustrupStyle cs)) ctx /// Each multiline member definition has a pre and post new line. @@ -5486,13 +5523,13 @@ and genKeepIndentMatch clauses (fun idx -> if idx < lastClauseIndex then - genClause astContext true hasMultipleClausesWhereOneHasRagnarok + genClause astContext hasMultipleClausesWhereOneHasRagnarok else genLastClauseKeepIdent astContext) ctx) |> genTriviaFor triviaType range -and genLastClauseKeepIdent (astContext: ASTContext) (Clause (pat, whenExpr, arrowRange, expr)) = +and genLastClauseKeepIdent (astContext: ASTContext) (Clause (_, pat, whenExpr, arrowRange, expr, _)) = sepBar +> genPat astContext pat +> sepSpace @@ -5708,7 +5745,7 @@ and genLambdaArrowWithTrivia |> genTriviaFor SynExpr_Lambda_Arrow arrowRange) arrowRange +> (fun ctx -> - if String.isNotNullOrEmpty ctx.WriterModel.WriteBeforeNewline then + if hasWriteBeforeNewlineContent ctx then (indent +> sepNln +> (bodyExpr body) +> unindent) ctx else autoIndentAndNlnIfExpressionExceedsPageWidthUnlessRagnarok bodyExpr body ctx) diff --git a/src/Fantomas.Core/Context.fs b/src/Fantomas.Core/Context.fs index 99b9d4dcd2..69c5b0a9d0 100644 --- a/src/Fantomas.Core/Context.fs +++ b/src/Fantomas.Core/Context.fs @@ -266,8 +266,11 @@ let internal writerEvent e ctx = ctx' +let internal hasWriteBeforeNewlineContent ctx = + String.isNotNullOrEmpty ctx.WriterModel.WriteBeforeNewline + let internal finalizeWriterModel (ctx: Context) = - if ctx.WriterModel.WriteBeforeNewline <> "" then + if hasWriteBeforeNewlineContent ctx then writerEvent (Write ctx.WriterModel.WriteBeforeNewline) ctx else ctx @@ -1243,19 +1246,19 @@ let internal sepNlnTypeAndMembers ctx let internal sepNlnWhenWriteBeforeNewlineNotEmpty fallback (ctx: Context) = - if String.isNotNullOrEmpty ctx.WriterModel.WriteBeforeNewline then + if hasWriteBeforeNewlineContent ctx then sepNln ctx else fallback ctx let internal sepSpaceUnlessWriteBeforeNewlineNotEmpty (ctx: Context) = - if String.isNotNullOrEmpty ctx.WriterModel.WriteBeforeNewline then + if hasWriteBeforeNewlineContent ctx then ctx else sepSpace ctx let internal autoIndentAndNlnWhenWriteBeforeNewlineNotEmpty (f: Context -> Context) (ctx: Context) = - if String.isNotNullOrEmpty ctx.WriterModel.WriteBeforeNewline then + if hasWriteBeforeNewlineContent ctx then (indent +> sepNln +> f +> unindent) ctx else f ctx diff --git a/src/Fantomas.Core/SourceParser.fs b/src/Fantomas.Core/SourceParser.fs index 4991a0e378..edfdb93fec 100644 --- a/src/Fantomas.Core/SourceParser.fs +++ b/src/Fantomas.Core/SourceParser.fs @@ -1251,7 +1251,22 @@ let (|RecordField|) = function | SynField (ats, _, ido, _, _, px, ao, _) -> (ats, px, ao, ido) -let (|Clause|) (SynMatchClause (p, eo, e, _, _, trivia)) = (p, eo, trivia.ArrowRange, e) +let (|Clause|) (SynMatchClause (p, eo, e, range, _, trivia)) = + let fullRange = + match trivia.BarRange with + | None -> range + | Some barRange -> Range.unionRanges barRange range + + (trivia.BarRange, p, eo, trivia.ArrowRange, e, fullRange) + +let (|TryWithSingleClause|_|) = + function + | TryWith (tryKeyword, e, withKeyword, [ (Clause (barRange, p, eo, arrowRange, catchExpr, clauseRange)) ]) -> + match p with + | SynPat.Or _ + | SynPat.As (SynPat.Or _, _, _) -> None + | _ -> Some(tryKeyword, e, withKeyword, barRange, p, eo, arrowRange, catchExpr, clauseRange) + | _ -> None /// Process compiler-generated matches in an appropriate way let rec private skipGeneratedLambdas expr = @@ -1765,7 +1780,7 @@ let (|KeepIndentMatch|_|) (e: SynExpr) = let mapClauses matchKeyword matchExpr withKeyword clauses range t = match clauses with | [] -> None - | [ (Clause (_, _, _, lastClause)) ] -> + | [ (Clause (_, _, _, _, lastClause, _)) ] -> if shouldNotIndentBranch lastClause [] then Some(matchKeyword, matchExpr, withKeyword, clauses, range, t) else @@ -1774,9 +1789,9 @@ let (|KeepIndentMatch|_|) (e: SynExpr) = let firstClauses = clauses |> List.take (clauses.Length - 1) - |> List.map (fun (Clause (_, _, _, expr)) -> expr) + |> List.map (fun (Clause (_, _, _, _, expr, _)) -> expr) - let (Clause (_, _, _, lastClause)) = List.last clauses + let (Clause (_, _, _, _, lastClause, _)) = List.last clauses if shouldNotIndentBranch lastClause firstClauses then Some(matchKeyword, matchExpr, withKeyword, clauses, range, t) diff --git a/src/Fantomas.Core/TriviaTypes.fs b/src/Fantomas.Core/TriviaTypes.fs index 87702739eb..264deed1da 100644 --- a/src/Fantomas.Core/TriviaTypes.fs +++ b/src/Fantomas.Core/TriviaTypes.fs @@ -183,6 +183,7 @@ type FsAstType = | SynIndexerArg_Two | SynMatchClause_ | SynMatchClause_Arrow + | SynMatchClause_Bar | ArgOptions_ | SynInterfaceImpl_ | SynInterfaceImpl_With