Skip to content

Commit

Permalink
Take combo sequentials, LetOrUse into account for KeepIndentInBranch …
Browse files Browse the repository at this point in the history
…setting.

Fixes fsprojects#1621.
  • Loading branch information
nojaf committed Apr 8, 2021
1 parent 660b03c commit 59829ed
Show file tree
Hide file tree
Showing 3 changed files with 221 additions and 141 deletions.
2 changes: 1 addition & 1 deletion src/Fantomas.Tests/Fantomas.Tests.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@
<Compile Include="DotIndexedGetTests.fs" />
<Compile Include="DotIndexedSetTests.fs" />
<Compile Include="MultilineFunctionApplicationsInConditionExpressionsTests.fs" />
<Compile Include="KeepIndentInBranch.fs" />
<Compile Include="KeepIndentInBranchTests.fs" />
<Compile Include="BlankLinesAroundNestedMultilineExpressions.fs" />
</ItemGroup>
<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module Fantomas.Tests.KeepIndentInBranch
module Fantomas.Tests.KeepIndentInBranchTests

open NUnit.Framework
open FsUnit
Expand Down Expand Up @@ -907,3 +907,159 @@ module Foo =
Thing.execute bar baz (thing, instructions)
0
"""

[<Test>]
let ``sequential, let bindings, keep indent match, 1621`` () =
formatSourceString
false
"""
let main (args : Options) =
log.LogDebug ("Command line options: {Options}", args.ToString())
let includes =
if ArgParser.defaultArg args.Flag then
Flag.Include
else
Flag.Exclude
match dryRunMode with
| DryRunMode.Dry ->
log.LogInformation ("No changes made due to --dry-run.")
0
| DryRunMode.Wet ->
match requested with
| None ->
log.LogWarning ("No changes required; no action taken.")
0
| Some branched ->
branched
|> blah
|> fun i -> log.LogInformation ("Done:\n{It}", i)
0
"""
{ config with
MaxLineLength = 100
SpaceBeforeUppercaseInvocation = true
SpaceBeforeClassConstructor = true
SpaceBeforeMember = true
SpaceBeforeColon = true
SpaceBeforeSemicolon = true
IndentOnTryWith = true
MultilineBlockBracketsOnSameColumn = true
NewlineBetweenTypeDefinitionAndMembers = true
AlignFunctionSignatureToIndentation = true
AlternativeLongMemberDefinitions = true
MultiLineLambdaClosingNewline = true
DisableElmishSyntax = true
KeepIndentInBranch = true }
|> prepend newline
|> should
equal
"""
let main (args : Options) =
log.LogDebug ("Command line options: {Options}", args.ToString ())
let includes =
if ArgParser.defaultArg args.Flag then
Flag.Include
else
Flag.Exclude
match dryRunMode with
| DryRunMode.Dry ->
log.LogInformation ("No changes made due to --dry-run.")
0
| DryRunMode.Wet ->
match requested with
| None ->
log.LogWarning ("No changes required; no action taken.")
0
| Some branched ->
branched
|> blah
|> fun i -> log.LogInformation ("Done:\n{It}", i)
0
"""

[<Test>]
let ``sequential, let bindings, keep indent if`` () =
formatSourceString
false
"""
let main (args : Options) =
log.LogDebug ("Command line options: {Options}", args.ToString())
let includes =
if ArgParser.defaultArg args.Flag then
Flag.Include
else
Flag.Exclude
if dryRunMode then
log.LogInformation ("No changes made due to --dry-run.")
0
else
match requested with
| None ->
log.LogWarning ("No changes required; no action taken.")
0
| Some branched ->
branched
|> blah
|> fun i -> log.LogInformation ("Done:\n{It}", i)
0
"""
{ config with
MaxLineLength = 100
SpaceBeforeUppercaseInvocation = true
SpaceBeforeClassConstructor = true
SpaceBeforeMember = true
SpaceBeforeColon = true
SpaceBeforeSemicolon = true
IndentOnTryWith = true
MultilineBlockBracketsOnSameColumn = true
NewlineBetweenTypeDefinitionAndMembers = true
AlignFunctionSignatureToIndentation = true
AlternativeLongMemberDefinitions = true
MultiLineLambdaClosingNewline = true
DisableElmishSyntax = true
KeepIndentInBranch = true }
|> prepend newline
|> should
equal
"""
let main (args : Options) =
log.LogDebug ("Command line options: {Options}", args.ToString ())
let includes =
if ArgParser.defaultArg args.Flag then
Flag.Include
else
Flag.Exclude
if dryRunMode then
log.LogInformation ("No changes made due to --dry-run.")
0
else
match requested with
| None ->
log.LogWarning ("No changes required; no action taken.")
0
| Some branched ->
branched
|> blah
|> fun i -> log.LogInformation ("Done:\n{It}", i)
0
"""
202 changes: 63 additions & 139 deletions src/Fantomas/CodePrinter.fs
Original file line number Diff line number Diff line change
Expand Up @@ -5295,155 +5295,79 @@ and genParenTupleWithIndentAndNewlines ps astContext =

and genExprKeepIndentInBranch (astContext: ASTContext) (e: SynExpr) : Context -> Context =
let keepIndentExpr =
match e with
| Sequential (e1, (KeepIndentMatch (me, clauses, matchRange, matchTriviaType) as e2), true) ->
let items =
[ ColMultilineItem(
genExpr astContext e1,
(let t, r = synExprToFsAstType e1 in sepNlnConsideringTriviaContentBeforeForMainNode t r),
e1.Range
)
ColMultilineItem(
genKeepIndentMatch astContext me clauses matchRange matchTriviaType,
sepNlnConsideringTriviaContentBeforeForMainNode matchTriviaType matchRange,
e2.Range
) ]

colWithNlnWhenItemIsMultilineUsingConfig items
| LetOrUses (bs, (KeepIndentMatch (me, clauses, matchRange, matchTriviaType) as em)) ->
let bs =
List.map
(fun (s, synBinding: SynBinding) ->
let range = synBinding.RangeOfBindingAndRhs

let expr =
enterNodeFor (synBindingToFsAstType synBinding) range
+> genLetBinding astContext s synBinding

let genOtherExprItem (e: SynExpr) : ColMultilineItem =
ColMultilineItem(
genExpr astContext e,
(let t, r = synExprToFsAstType e in sepNlnConsideringTriviaContentBeforeForMainNode t r),
e.Range
)

let sepNln =
sepNlnConsideringTriviaContentBeforeForMainNode (synBindingToFsAstType synBinding) range
let genBindingItems (bs: (string * SynBinding) list) : ColMultilineItem list =
List.map
(fun (s, synBinding: SynBinding) ->
let range = synBinding.RangeOfBindingAndRhs

ColMultilineItem(expr, sepNln, range))
bs
let expr =
enterNodeFor (synBindingToFsAstType synBinding) range
+> genLetBinding astContext s synBinding

let m =
ColMultilineItem(
genKeepIndentMatch astContext me clauses matchRange matchTriviaType,
sepNlnConsideringTriviaContentBeforeForMainNode matchTriviaType matchRange,
em.Range
)

colWithNlnWhenItemIsMultilineUsingConfig [ yield! bs
yield m ]
| LetOrUses (bs, Sequential (e1, KeepIndentMatch (me, clauses, matchRange, matchTriviaType), true)) ->
let bs =
List.map
(fun (s, synBinding: SynBinding) ->
let range = synBinding.RangeOfBindingAndRhs
let sepNln =
sepNlnConsideringTriviaContentBeforeForMainNode (synBindingToFsAstType synBinding) range

let expr =
enterNodeFor (synBindingToFsAstType synBinding) range
+> genLetBinding astContext s synBinding
ColMultilineItem(expr, sepNln, range))
bs

let sepNln =
sepNlnConsideringTriviaContentBeforeForMainNode (synBindingToFsAstType synBinding) range

ColMultilineItem(expr, sepNln, range))
bs

let e1 =
ColMultilineItem(
genExpr astContext e1,
(let t, r = synExprToFsAstType e1 in sepNlnConsideringTriviaContentBeforeForMainNode t r),
e1.Range
)
let genKeepIndentMatchItem
((me, clauses, matchRange, matchTriviaType): SynExpr * SynMatchClause list * Range * FsAstType)
: ColMultilineItem =
ColMultilineItem(
genKeepIndentMatch astContext me clauses matchRange matchTriviaType,
sepNlnConsideringTriviaContentBeforeForMainNode matchTriviaType matchRange,
matchRange
)

let m =
ColMultilineItem(
genKeepIndentMatch astContext me clauses matchRange matchTriviaType,
sepNlnConsideringTriviaContentBeforeForMainNode matchTriviaType matchRange,
matchRange
)
let genKeepIndentIfThenElseItem
((branches, elseBranch, ifElseRange): (SynExpr * SynExpr * Range * Range * SynExpr) list * SynExpr * Range)
: ColMultilineItem =
ColMultilineItem(
genKeepIdentIf astContext branches elseBranch ifElseRange,
sepNlnConsideringTriviaContentBeforeForMainNode SynExpr_IfThenElse ifElseRange,
ifElseRange
)

colWithNlnWhenItemIsMultilineUsingConfig [ yield! bs
yield e1
yield m ]
match e with
| Sequential (e1, (KeepIndentMatch kim), true) ->
colWithNlnWhenItemIsMultilineUsingConfig [ genOtherExprItem e1
genKeepIndentMatchItem kim ]
| Sequential (e1, LetOrUses (bs, (KeepIndentMatch kim)), true) ->
colWithNlnWhenItemIsMultilineUsingConfig [ yield genOtherExprItem e1
yield! genBindingItems bs
yield genKeepIndentMatchItem kim ]
| LetOrUses (bs, (KeepIndentMatch kim)) ->
colWithNlnWhenItemIsMultilineUsingConfig [ yield! genBindingItems bs
yield genKeepIndentMatchItem kim ]
| LetOrUses (bs, Sequential (e1, KeepIndentMatch kim, true)) ->
colWithNlnWhenItemIsMultilineUsingConfig [ yield! genBindingItems bs
yield genOtherExprItem e1
yield genKeepIndentMatchItem kim ]
| KeepIndentMatch (me, clauses, matchRange, matchTriviaType) ->
genKeepIndentMatch astContext me clauses matchRange matchTriviaType
| Sequential (e1, (KeepIndentIfThenElse (branches, elseBranch, ifElseRange) as e2), true) ->
let items =
[ ColMultilineItem(
genExpr astContext e1,
(let t, r = synExprToFsAstType e1 in sepNlnConsideringTriviaContentBeforeForMainNode t r),
e1.Range
)
ColMultilineItem(
genKeepIdentIf astContext branches elseBranch ifElseRange,
sepNlnConsideringTriviaContentBeforeForMainNode SynExpr_IfThenElse ifElseRange,
e2.Range
) ]

colWithNlnWhenItemIsMultilineUsingConfig items
| LetOrUses (bs, (KeepIndentIfThenElse (branches, elseBranch, ifElseRange))) ->
let bs =
List.map
(fun (s, synBinding: SynBinding) ->
let range = synBinding.RangeOfBindingAndRhs

let expr =
enterNodeFor (synBindingToFsAstType synBinding) range
+> genLetBinding astContext s synBinding


let sepNln =
sepNlnConsideringTriviaContentBeforeForMainNode (synBindingToFsAstType synBinding) range

ColMultilineItem(expr, sepNln, range))
bs

let ifElse =
ColMultilineItem(
genKeepIdentIf astContext branches elseBranch ifElseRange,
sepNlnConsideringTriviaContentBeforeForMainNode SynExpr_IfThenElse ifElseRange,
ifElseRange
)

colWithNlnWhenItemIsMultilineUsingConfig [ yield! bs
yield ifElse ]
| LetOrUses (bs, Sequential (e1, KeepIndentIfThenElse (branches, elseBranch, ifElseRange), true)) ->
let bs =
List.map
(fun (s, synBinding: SynBinding) ->
let range = synBinding.RangeOfBindingAndRhs

let expr =
enterNodeFor (synBindingToFsAstType synBinding) range
+> genLetBinding astContext s synBinding

let sepNln =
sepNlnConsideringTriviaContentBeforeForMainNode (synBindingToFsAstType synBinding) range

ColMultilineItem(expr, sepNln, range))
bs

let e1 =
ColMultilineItem(
genExpr astContext e1,
(let t, r = synExprToFsAstType e1 in sepNlnConsideringTriviaContentBeforeForMainNode t r),
e1.Range
)

let ifElse =
ColMultilineItem(
genKeepIdentIf astContext branches elseBranch ifElseRange,
sepNlnConsideringTriviaContentBeforeForMainNode SynExpr_IfThenElse ifElseRange,
ifElseRange
)

colWithNlnWhenItemIsMultilineUsingConfig [ yield! bs
yield e1
yield ifElse ]
| Sequential (e1, (KeepIndentIfThenElse kii), true) ->
colWithNlnWhenItemIsMultilineUsingConfig [ genOtherExprItem e1
genKeepIndentIfThenElseItem kii ]
| Sequential (e1, LetOrUses (bs, (KeepIndentIfThenElse kii)), true) ->
colWithNlnWhenItemIsMultilineUsingConfig [ yield genOtherExprItem e1
yield! genBindingItems bs
yield genKeepIndentIfThenElseItem kii ]
| LetOrUses (bs, (KeepIndentIfThenElse kii)) ->
colWithNlnWhenItemIsMultilineUsingConfig [ yield! genBindingItems bs
yield genKeepIndentIfThenElseItem kii ]
| LetOrUses (bs, Sequential (e1, KeepIndentIfThenElse kii, true)) ->

colWithNlnWhenItemIsMultilineUsingConfig [ yield! genBindingItems bs
yield genOtherExprItem e1
yield genKeepIndentIfThenElseItem kii ]
| KeepIndentIfThenElse (branches, elseBranch, ifElseRange) ->
genKeepIdentIf astContext branches elseBranch ifElseRange
| _ -> genExpr astContext e
Expand Down

0 comments on commit 59829ed

Please sign in to comment.