Skip to content

Commit

Permalink
Consider simple function application as short branch expr. (#1640)
Browse files Browse the repository at this point in the history
* Consider simple function application as short branch expr. Fixes #1638.

* Single clause match expression with function application object expression.
  • Loading branch information
nojaf committed Apr 14, 2021
1 parent 6d1c30f commit 1b24c7e
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 5 deletions.
113 changes: 113 additions & 0 deletions src/Fantomas.Tests/KeepIndentInBranchTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1063,3 +1063,116 @@ let main (args : Options) =
0
"""

[<Test>]
let ``single pattern match should keep indent, 1638`` () =
formatSourceString
false
"""
[<NoEquality ; NoComparison>]
type Foo<'context, 'a> =
| Apply of ApplyCrate<'context, 'a>
and [<CustomEquality ; NoComparison>] Bar<'context, 'a> =
internal {
Hash : int
Foo : Foo<'a, 'b>
}
member this.InnerEquals<'innerContextLongLongLong, 'd, 'e> (a : Foo<'innerContextLongLongLong, 'd>) (b : Foo<'innerContext, 'd>) (cont : bool -> 'e) : 'e =
if a.Hash <> b.Hash then cont false
else
match a.Foo, b.Foo with
| Foo.Apply a, Foo.Apply b ->
a.Apply { new ApplyEval<_, _, _> with
member __.Eval<'bb> (a : Foo<'innerContextLongLongLong, 'bb -> 'b> * Foo<'innerContextLongLongLong, 'bb>) =
let (af, av) = a
b.Apply { new ApplyEval<_, _, _> with
member __.Eval<'cb> (b : Foo<'innerContextLongLongLong, 'cb -> 'b> * Foo<'innerContextLongLongLong, 'bc>) =
let (bf, bv) = b
if typeof<'bb> = typeof<'cb> then
let bv = unbox<Foo<'innerContextLongLongLong, 'bb>> bv
this.InnerEquals av bv (fun inner ->
if inner then
let bv = unbox<Foo<'innerContextLongLongLong, 'bb -> 'b>> bf
this.InnerEquals af bf cont
else cont false
)
else cont false
}
}
"""
{ config with
MaxLineLength = 100
SpaceBeforeUppercaseInvocation = true
SpaceBeforeClassConstructor = true
SpaceBeforeMember = true
SpaceBeforeColon = true
SpaceBeforeSemicolon = true
MultilineBlockBracketsOnSameColumn = true
KeepIfThenInSameLine = true
KeepIndentInBranch = true
AlignFunctionSignatureToIndentation = true
AlternativeLongMemberDefinitions = true
MultiLineLambdaClosingNewline = true }
|> prepend newline
|> should
equal
"""
[<NoEquality ; NoComparison>]
type Foo<'context, 'a> = Apply of ApplyCrate<'context, 'a>
and [<CustomEquality ; NoComparison>] Bar<'context, 'a> =
internal
{
Hash : int
Foo : Foo<'a, 'b>
}
member this.InnerEquals<'innerContextLongLongLong, 'd, 'e>
(a : Foo<'innerContextLongLongLong, 'd>)
(b : Foo<'innerContext, 'd>)
(cont : bool -> 'e)
: 'e
=
if a.Hash <> b.Hash then
cont false
else
match a.Foo, b.Foo with
| Foo.Apply a, Foo.Apply b ->
a.Apply
{ new ApplyEval<_, _, _> with
member __.Eval<'bb>
(a : Foo<'innerContextLongLongLong, 'bb -> 'b> * Foo<'innerContextLongLongLong, 'bb>)
=
let (af, av) = a
b.Apply
{ new ApplyEval<_, _, _> with
member __.Eval<'cb>
(b : Foo<'innerContextLongLongLong, 'cb -> 'b> * Foo<'innerContextLongLongLong, 'bc>)
=
let (bf, bv) = b
if typeof<'bb> = typeof<'cb> then
let bv =
unbox<Foo<'innerContextLongLongLong, 'bb>> bv
this.InnerEquals
av
bv
(fun inner ->
if inner then
let bv =
unbox<Foo<'innerContextLongLongLong, 'bb -> 'b>>
bf
this.InnerEquals af bf cont
else
cont false
)
else
cont false
}
}
"""
1 change: 0 additions & 1 deletion src/Fantomas.Tests/TypeDeclarationTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -2763,7 +2763,6 @@ and [<CustomEquality ; NoComparison>] Bar<'context, 'a> =
SpaceBeforeSemicolon = true
MultilineBlockBracketsOnSameColumn = true
KeepIfThenInSameLine = true
KeepIndentInBranch = true
AlignFunctionSignatureToIndentation = true
AlternativeLongMemberDefinitions = true
MultiLineLambdaClosingNewline = true }
Expand Down
14 changes: 10 additions & 4 deletions src/Fantomas/SourceParser.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1669,15 +1669,17 @@ let private shouldNotIndentBranch e es =
let isShortIfBranch e =
match e with
| SimpleExpr _
| Sequential (_, _, true) -> true
| Sequential (_, _, true)
| App (SimpleExpr _, [ SimpleExpr _ ]) -> true
| _ -> false

let isLongElseBranch e =
match e with
| LetOrUses _
| Sequential _
| Match _
| TryWith _ -> true
| TryWith _
| App (_, [ ObjExpr _ ]) -> true
| _ -> false

List.forall isShortIfBranch es
Expand All @@ -1686,8 +1688,12 @@ let private shouldNotIndentBranch e es =
let (|KeepIndentMatch|_|) (e: SynExpr) =
let mapClauses matchExpr clauses range t =
match clauses with
| []
| [ _ ] -> None
| [] -> None
| [ (Clause (_, lastClause, _)) ] ->
if shouldNotIndentBranch lastClause [] then
Some(matchExpr, clauses, range, t)
else
None
| clauses ->
let firstClauses =
clauses
Expand Down

0 comments on commit 1b24c7e

Please sign in to comment.