Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update formatting types in signatures #1994

Merged
merged 2 commits into from
Jan 7, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 22 additions & 22 deletions src/Fantomas.Tests/InterfaceTests.fs
Original file line number Diff line number Diff line change
@@ -274,18 +274,18 @@ type Test =
"""
type Test =
abstract RunJobs:
folder: string
* ?jobs: string
* ?ctm: string
* ?createDuplicate: bool
* ?hold: bool
* ?ignoreCriteria: bool
* ?independentFlow: bool
* ?orderDate: string
* ?orderIntoFolder: string
* ?variables: Dictionary<string, string> []
* ?waitForOrderDate: bool ->
string
folder: string *
?jobs: string *
?ctm: string *
?createDuplicate: bool *
?hold: bool *
?ignoreCriteria: bool *
?independentFlow: bool *
?orderDate: string *
?orderIntoFolder: string *
?variables: Dictionary<string, string> [] *
?waitForOrderDate: bool ->
string

override this.RunJobs
(
@@ -384,7 +384,7 @@ type IFoo =
foo : string ->
bar : string ->
baz : string ->
int
int
"""

[<Test>]
@@ -409,7 +409,7 @@ type IFoo =
string ->
int ->
string ->
string
string
"""

[<Test>]
@@ -429,9 +429,9 @@ type IFoo =
"""
type IFoo =
abstract Bar :
[<Path "bar">] bar : string
* [<Path "baz">] baz : string ->
Task<Foo>
[<Path "bar">] bar : string *
[<Path "baz">] baz : string ->
Task<Foo>
"""

[<Test>]
@@ -453,7 +453,7 @@ type IFoo =
abstract Bar :
i : int ->
a : string * foo : int ->
string
string
"""

[<Test>]
@@ -474,10 +474,10 @@ type IFoo =
type IFoo =
abstract Bar :
i : int ->
a : string
* foo : int
* someReallyLongNameThatMakesTheTupleMultiLine : string ->
string
a : string *
foo : int *
someReallyLongNameThatMakesTheTupleMultiLine : string ->
string
"""

[<Test>]
186 changes: 181 additions & 5 deletions src/Fantomas.Tests/SignatureTests.fs
Original file line number Diff line number Diff line change
@@ -604,7 +604,7 @@ type CodeFormatter =
/// Parse a source string using given config
static member ParseAsync:
fileName: string * source: SourceOrigin * parsingOptions: FSharpParsingOptions * checker: FSharpChecker ->
Async<(ParsedInput * string list) array>
Async<(ParsedInput * string list) array>
"""

[<Test>]
@@ -1256,7 +1256,7 @@ val create:
something_really_long: unit ->
another_really_long_thing: unit ->
and_another_to_make_the_line_long_enough: unit ->
unit
unit
"""

[<Test>]
@@ -1586,9 +1586,9 @@ type Bar =
member Hello :
thing : XLongLongLongLongLongLongLongLong<bool -> 'a, bool -> 'b, bool -> 'c, bool -> 'd, bool
-> ('e -> 'f)
-> 'g, ('h -> 'i) -> 'j>
* item : int list ->
LongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLong
-> 'g, ('h -> 'i) -> 'j> *
item : int list ->
LongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLong
"""

[<Test>]
@@ -1711,3 +1711,179 @@ open FSharp.Compiler.AbstractIL.IL
[<NoEquality; NoComparison>]
exception SyntaxError of obj * range: range
"""

[<Test>]
let ``multiline tupled signature`` () =
formatSourceString
true
"""
namespace Oslo
type Meh =
member ResolveDependencies:
scriptDirectory: string
* scriptName: string
* scriptExt: string
* timeout: int ->
obj
"""
{ config with MaxLineLength = 60 }
|> prepend newline
|> should
equal
"""
namespace Oslo

type Meh =
member ResolveDependencies:
scriptDirectory: string *
scriptName: string *
scriptExt: string *
timeout: int ->
obj
"""

[<Test>]
let ``add extra indent when the next parameter is a tuple`` () =
formatSourceString
true
"""
namespace Oslo

type Meh =
member ResolveDependencies:
scriptDirectory: string * scriptName: string ->
scriptName: string
* scriptExt: string
* timeout: int ->
obj
"""
{ config with MaxLineLength = 5 }
|> prepend newline
|> should
equal
"""
namespace Oslo

type Meh =
member ResolveDependencies:
scriptDirectory: string *
scriptName: string ->
scriptName: string *
scriptExt: string *
timeout: int ->
obj
"""

[<Test>]
let ``mixed curried and tupled arguments`` () =
formatSourceString
true
"""
namespace Oslo

type Meh =
member ResolveDependencies:
scriptDirectory: string * scriptName: string ->
scriptName: string ->
obj
"""
{ config with MaxLineLength = 30 }
|> prepend newline
|> should
equal
"""
namespace Oslo

type Meh =
member ResolveDependencies:
scriptDirectory: string *
scriptName: string ->
scriptName: string ->
obj
"""

[<Test>]
let ``unindent correctly after type signature`` () =
formatSourceString
true
"""
namespace Oslo

type Meh =
member ResolveDependencies:
scriptDirectory: string * scriptName: string ->
scriptName: string ->
obj

val x : int
"""
{ config with MaxLineLength = 30 }
|> prepend newline
|> should
equal
"""
namespace Oslo

type Meh =
member ResolveDependencies:
scriptDirectory: string *
scriptName: string ->
scriptName: string ->
obj

val x: int
"""

[<Test>]
let ``only indent after tuple in non last position`` () =
formatSourceString
true
"""
namespace Oslo

type Meh =
member ResolveDependencies:
criptName: string -> foo: string -> scriptDirectory: string * scriptName: string -> // after a tuple, mixed needs an indent
scriptName: string -> obj
"""
{ config with MaxLineLength = 30 }
|> prepend newline
|> should
equal
"""
namespace Oslo

type Meh =
member ResolveDependencies:
criptName: string ->
foo: string ->
scriptDirectory: string *
scriptName: string -> // after a tuple, mixed needs an indent
scriptName: string ->
obj
"""

[<Test>]
let ``tupled function signature`` () =
formatSourceString
true
"""
namespace StyleGuide

val SampleTupledFunction:
arg1: string * arg2: string * arg3: int * arg4: int -> int list
"""
{ config with MaxLineLength = 15 }
|> prepend newline
|> should
equal
"""
namespace StyleGuide

val SampleTupledFunction:
arg1: string *
arg2: string *
arg3: int *
arg4: int ->
int list
"""
34 changes: 32 additions & 2 deletions src/Fantomas/CodePrinter.fs
Original file line number Diff line number Diff line change
@@ -4599,7 +4599,7 @@ and genTypeList astContext node =
col sepBefore ts' (snd >> genType astContext hasBracket)

let shortExpr = gt sepStar
let longExpr = gt (sepNln +> sepStarFixed)
let longExpr = gt (sepSpace +> sepStarFixed +> sepNln)
expressionFitsOnRestOfLine shortExpr longExpr

| _, [ ArgInfo (ats, so, isOpt) ] ->
@@ -4621,7 +4621,37 @@ and genTypeList astContext node =

let shortExpr = col sepArrow node gt

let longExpr = col (sepArrow +> sepNln) node gt
let longExpr =
let lastIndex = node.Length - 1

let isTupleOrLastIndex index =
index = lastIndex
|| match List.tryItem (index - 1) node with
| Some (TTuple _, _) -> true
| _ -> false

let resetIndent =
if lastIndex < 0 then
id
else
[ 0 .. lastIndex ]
|> List.choose
(fun idx ->
if isTupleOrLastIndex idx then
Some unindent
else
None)
|> List.reduce (+>)

colii
(fun idx ->
sepSpace
+> sepArrowFixed
+> onlyIf (isTupleOrLastIndex idx) indent
+> sepNln)
node
(fun _ -> gt)
+> resetIndent

expressionFitsOnRestOfLine shortExpr longExpr

18 changes: 18 additions & 0 deletions src/Fantomas/Context.fs
Original file line number Diff line number Diff line change
@@ -557,6 +557,24 @@ let internal coli f' (c: seq<'T>) f (ctx: Context) =

st

/// Similar to coli, and supply index as well to f'
let internal colii f' (c: seq<'T>) f (ctx: Context) =
let mutable tryPick = true
let mutable st = ctx
let mutable i = 0
let e = c.GetEnumerator()

while (e.MoveNext()) do
if tryPick then
tryPick <- false
else
st <- f' i st

st <- f i e.Current st
i <- i + 1

st

/// Process collection - keeps context through the whole processing
/// calls f for every element in sequence and f' between every two elements
/// as a separator. This is a variant that works on typed collections.