Skip to content

Commit

Permalink
Long function signatures have indent if parameters are on separate li…
Browse files Browse the repository at this point in the history
…ne. (#897)

* Long function signatures have indent if parameters are on separate line.

* Count the identifiers in the function definition to bypass futureNln check.
  • Loading branch information
nojaf committed Jun 8, 2020
1 parent 098a395 commit 1fa24a9
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 7 deletions.
29 changes: 29 additions & 0 deletions src/Fantomas.Tests/FunctionDefinitionTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -542,4 +542,33 @@ let private addTaskToScheduler
.Build()
1
"""

[<Test>]
let ``long function signature should align with equal sign, 883`` () =
formatSourceString false """let readModel (updateState : 'State -> EventEnvelope<'Event> list -> 'State) (initState : 'State) : ReadModel<'Event, 'State> =
()
""" { config with IndentSpaceNum = 2; SpaceBeforeColon = true }
|> prepend newline
|> should equal """
let readModel
(updateState : 'State -> EventEnvelope<'Event> list -> 'State)
(initState : 'State)
: ReadModel<'Event, 'State>
=
()
"""

[<Test>]
let ``long function signature should align with equal sign, no return type`` () =
formatSourceString false """let readModel (updateState : 'State -> EventEnvelope<'Event> list -> 'State) (initState : 'State) =
()
""" { config with IndentSpaceNum = 2; SpaceBeforeColon = true; PageWidth = 80 }
|> prepend newline
|> should equal """
let readModel
(updateState : 'State -> EventEnvelope<'Event> list -> 'State)
(initState : 'State)
=
()
"""
28 changes: 22 additions & 6 deletions src/Fantomas/CodePrinter.fs
Original file line number Diff line number Diff line change
Expand Up @@ -544,6 +544,7 @@ and genLetBinding astContext pref b =
ifElse astContext.IsFirstChild
(genAttributes astContext ats -- pref)
(!- pref +> genOnelinerAttributes astContext ats)

let afterLetKeyword =
opt sepSpace ao genAccess
+> ifElse isMutable (!- "mutable ") sepNone
Expand Down Expand Up @@ -2748,10 +2749,10 @@ and genPatWithReturnType ao s ps tpso (t:SynType option) (astContext: ASTContext

let hasBracket = ps |> Seq.map fst |> Seq.exists Option.isSome
let genName = aoc -- s +> tpsoc +> sepSpace

let genParametersInitial =
colAutoNlnSkip0 (ifElse hasBracket sepSemi sepSpace) ps (genPatWithIdent astContext)


let genReturnType, newlineBeforeReturnType =
match t with
| Some t -> genType astContext false t, sepNln
Expand All @@ -2760,17 +2761,32 @@ and genPatWithReturnType ao s ps tpso (t:SynType option) (astContext: ASTContext
let genParametersWithNewlines =
(sepNln +> col sepNln ps (genPatWithIdent astContext) +> newlineBeforeReturnType)

let isLongFunctionSignature ctx=
futureNlnCheck (genName +> genParametersInitial +> genReturnType) ctx
let isLongFunctionSignature (ctx: Context) =
let space = 1
let colon = if ctx.Config.SpaceBeforeColon then 3 else 2
let lengthByAST =
getSynAccessLength ao
+ lengthWhenSome (fun _ -> space) ao
+ s.Length
+ space
+ List.sumBy (snd >> getSynPatLength >> (+) space) ps
+ lengthWhenSome (fun _ -> colon) t
+ lengthWhenSome getSynTypeLength t

(ctx.Column + lengthByAST > ctx.Config.PageWidth)
|| futureNlnCheck (genName +> genParametersInitial +> genReturnType) ctx

atCurrentColumn (fun ctx ->
fun ctx ->
let isLong = isLongFunctionSignature ctx

let expr =
genName
+> ifElse hasBracket sepOpenT sepNone
+> ifElse isLong genParametersWithNewlines genParametersInitial
+> ifElse isLong (indent +> genParametersWithNewlines +> unindent) genParametersInitial
+> ifElse hasBracket sepCloseT sepNone
expr ctx)

expr ctx

and genConst (c:SynConst) (r:range) =
match c with
| SynConst.Unit ->
Expand Down
46 changes: 45 additions & 1 deletion src/Fantomas/SourceTransformer.fs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
module internal Fantomas.SourceTransformer

open FSharp.Compiler.SyntaxTree
open Fantomas.Context
open Fantomas.SourceParser

Expand Down Expand Up @@ -128,4 +129,47 @@ let addParenForTupleWhen f synExpr ctx =
| FSharp.Compiler.SyntaxTree.SynExpr.Lambda _ -> true
|_ -> false // "if .. then .. else" have precedence over ","
let expr = f synExpr
ifElse (condition synExpr) (sepOpenT +> expr +> sepCloseT) expr ctx
ifElse (condition synExpr) (sepOpenT +> expr +> sepCloseT) expr ctx

let lengthWhenSome f o =
match o with
| Some x -> f x
| None -> 0

let getSynAccessLength ao =
lengthWhenSome (function | SynAccess.Internal -> 8 | SynAccess.Private -> 7 | SynAccess.Public -> 6) ao

let rec getSynTypeLength (synType: SynType) =
match synType with
| TFun (t1, t2) ->
getSynTypeLength t1 + (* -> *) 2 + getSynTypeLength t2
| TVar(Typar(id, _)) ->
id.Length
| TApp(t, ts, _) ->
getSynTypeLength t + List.sumBy getSynTypeLength ts
| TLongIdent s ->
s.Length
| _ ->
0

let rec getSynPatLength (synPat: SynPat) =
match synPat with
| PatLongIdent(ao, s, ps, _) ->
let accessLength = getSynAccessLength ao
let patternLength =
ps
|> List.sumBy (fun (ident, pat) ->
let identLength = lengthWhenSome String.length ident
identLength + getSynPatLength pat)
accessLength + patternLength + s.Length

| PatParen pat -> 2 + getSynPatLength pat

| PatNamed(ao,p,s) ->
let accessLength = getSynAccessLength ao
accessLength + getSynPatLength p + s.Length

| PatTyped (p,t) ->
getSynPatLength p + getSynTypeLength t

| _ -> 0

0 comments on commit 1fa24a9

Please sign in to comment.