Skip to content

Commit

Permalink
Format long member binding and constructors according to the F# style…
Browse files Browse the repository at this point in the history
… guide. (#898)
  • Loading branch information
nojaf committed Jun 8, 2020
1 parent 97e8cd6 commit 098a395
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 98 deletions.
3 changes: 1 addition & 2 deletions src/Fantomas.Tests/FunctionDefinitionTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -280,8 +280,7 @@ open Accessibility
[<DllImport("oleacc.dll")>]
extern int AccessibleChildren(IAccessible paccContainer, int iChildStart, int cChildren, [<Out; MarshalAs(UnmanagedType.LPArray,
SizeParamIndex =
4s)>] System.Object []
rgvarChildren, int* pcObtained)
4s)>] System.Object [] rgvarChildren, int* pcObtained)
"""

[<Test>]
Expand Down
128 changes: 71 additions & 57 deletions src/Fantomas.Tests/TypeDeclarationTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1061,11 +1061,9 @@ let ``long type members should have parameters on separate lines, 719`` () =
|> prepend newline
|> should equal """
type C () =
member __.LongMethodWithLotsOfParameters(
aVeryLongType: AVeryLongTypeThatYouNeedToUse,
aSecondVeryLongType: AVeryLongTypeThatYouNeedToUse,
aThirdVeryLongType: AVeryLongTypeThatYouNeedToUse)
=
member __.LongMethodWithLotsOfParameters(aVeryLongType: AVeryLongTypeThatYouNeedToUse,
aSecondVeryLongType: AVeryLongTypeThatYouNeedToUse,
aThirdVeryLongType: AVeryLongTypeThatYouNeedToUse) =
aVeryLongType aSecondVeryLongType aThirdVeryLongType
"""

Expand All @@ -1077,12 +1075,9 @@ let ``long type member with return type should have parameters on separate lines
|> prepend newline
|> should equal """
type C () =
member __.LongMethodWithLotsOfParameters(
aVeryLongType: AVeryLongTypeThatYouNeedToUse,
aSecondVeryLongType: AVeryLongTypeThatYouNeedToUse,
aThirdVeryLongType: AVeryLongTypeThatYouNeedToUse)
: int
=
member __.LongMethodWithLotsOfParameters(aVeryLongType: AVeryLongTypeThatYouNeedToUse,
aSecondVeryLongType: AVeryLongTypeThatYouNeedToUse,
aThirdVeryLongType: AVeryLongTypeThatYouNeedToUse): int =
aVeryLongType aSecondVeryLongType aThirdVeryLongType
"""

Expand All @@ -1093,11 +1088,9 @@ let ``long constructors should have parameters on separate lines`` () =
""" ({ config with SpaceBeforeClassConstructor = true })
|> prepend newline
|> should equal """
type C (
aVeryLongType: AVeryLongTypeThatYouNeedToUse,
aSecondVeryLongType: AVeryLongTypeThatYouNeedToUse,
aThirdVeryLongType: AVeryLongTypeThatYouNeedToUse)
=
type C (aVeryLongType: AVeryLongTypeThatYouNeedToUse,
aSecondVeryLongType: AVeryLongTypeThatYouNeedToUse,
aThirdVeryLongType: AVeryLongTypeThatYouNeedToUse) =
member this.X = 42
"""

Expand Down Expand Up @@ -1129,10 +1122,8 @@ let ``keep correct indentation after multiline member definition, 845`` () =
|> prepend newline
|> should equal """
type SomeType() =
member SomeMember(
looooooooooooooooooooooooooooooooooong1: A,
looooooooooooooooooooooooooooooooooong2: A)
=
member SomeMember(looooooooooooooooooooooooooooooooooong1: A,
looooooooooooooooooooooooooooooooooong2: A) =
printfn "a"
"a"
Expand All @@ -1152,11 +1143,8 @@ let ``keep correct indentation after multiline typed member definition`` () =
|> prepend newline
|> should equal """
type SomeType() =
member SomeMember(
looooooooooooooooooooooooooooooooooong1: A,
looooooooooooooooooooooooooooooooooong2: A)
: string
=
member SomeMember(looooooooooooooooooooooooooooooooooong1: A,
looooooooooooooooooooooooooooooooooong2: A): string =
printfn "a"
"a"
Expand All @@ -1173,11 +1161,8 @@ let ``split multiple parameters over multiple lines`` () =
|> prepend newline
|> should equal """
type SomeType =
static member SomeMember
(looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong1: string)
(looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong2: string)
: string
=
static member SomeMember (looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong1: string)
(looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong2: string): string =
printfn "a"
"b"
"""
Expand All @@ -1194,11 +1179,8 @@ let ``split multiple parameters over multiple lines and have correct indentation
|> prepend newline
|> should equal """
type SomeType =
static member SomeMember
(looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong1: string)
(looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong2: string)
: string
=
static member SomeMember (looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong1: string)
(looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong2: string): string =
printfn "a"
"b"
Expand All @@ -1215,10 +1197,7 @@ let ``member with one long parameter and return type, 850`` () =
|> prepend newline
|> should equal """
type SomeType =
static member SomeMember
loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong1
: string
=
static member SomeMember loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong1: string =
printfn "a"
"b"
"""
Expand All @@ -1233,9 +1212,7 @@ let ``member with one long parameter and no return type, 850`` () =
|> prepend newline
|> should equal """
type SomeType =
static member SomeMember
loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong1
=
static member SomeMember loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong1 =
printfn "a"
"b"
"""
Expand All @@ -1253,21 +1230,14 @@ let ``multiple members with one long parameter`` () =
|> prepend newline
|> should equal """
type SomeType =
static member SomeMember
loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong1
=
static member SomeMember loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong1 =
printfn "a"
"b"
static member Serialize(
loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong2: SomeType)
=
static member Serialize(loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong2: SomeType) =
Encode.string v.Meh
static member Deserialize(
loooooooooooooooooooooooooooooooooooooooooooooooooooooonnnnnnnnnnnnnnnnnnnnngggggggggggJsonVaaaaalueeeeeeeeeeeeeeee)
: SomeType
=
static member Deserialize(loooooooooooooooooooooooooooooooooooooooooooooooooooooonnnnnnnnnnnnnnnnnnnnngggggggggggJsonVaaaaalueeeeeeeeeeeeeeee): SomeType =
Decode.SomeType
loooooooooooooooooooooooooooooooooooooooooooooooooooooonnnnnnnnnnnnnnnnnnnnngggggggggggJsonVaaaaalueeeeeeeeeeeeeeee
"""
Expand All @@ -1286,10 +1256,54 @@ type INotifications<'a, 'b, 'c, 'd, 'e> =
class
end
type DeviceNotificationHandler<'Notification, 'CallbackId, 'RegisterInputData, 'RegisterOutputData, 'UnregisterOutputData>
private (client: INotifications<'Notification, 'CallbackId, 'RegisterInputData, 'RegisterOutputData, 'UnregisterOutputData>,
callbackId: 'CallbackId,
validateUnregisterOutputData: 'UnregisterOutputData -> unit)
=
type DeviceNotificationHandler<'Notification, 'CallbackId, 'RegisterInputData, 'RegisterOutputData, 'UnregisterOutputData> private (client: INotifications<'Notification, 'CallbackId, 'RegisterInputData, 'RegisterOutputData, 'UnregisterOutputData>,
callbackId: 'CallbackId,
validateUnregisterOutputData: 'UnregisterOutputData -> unit) =
let a = 5
"""


[<Test>]
let ``long type members should be in multiple lines, 868`` () =
formatSourceString false """
type C() =
member _.LongMethodWithLotsOfParameters(aVeryLongType: int, aSecondVeryLongType: int, aThirdVeryLongType: int) : int =
aVeryLongType + aSecondVeryLongType + aThirdVeryLongType
""" { config with PageWidth = 80; SpaceBeforeColon = true; MaxInfixOperatorExpression = 80 }
|> prepend newline
|> should equal """
type C() =
member _.LongMethodWithLotsOfParameters(aVeryLongType : int,
aSecondVeryLongType : int,
aThirdVeryLongType : int) : int =
aVeryLongType + aSecondVeryLongType + aThirdVeryLongType
"""

[<Test>]
let ``long type members should be in multiple lines, no return type`` () =
formatSourceString false """
type C() =
member _.LongMethodWithLotsOfParameters(aVeryLongType: int, aSecondVeryLongType: int, aThirdVeryLongType: int) =
aVeryLongType + aSecondVeryLongType + aThirdVeryLongType
""" { config with PageWidth = 80; SpaceBeforeColon = true; MaxInfixOperatorExpression = 80 }
|> prepend newline
|> should equal """
type C() =
member _.LongMethodWithLotsOfParameters(aVeryLongType : int,
aSecondVeryLongType : int,
aThirdVeryLongType : int) =
aVeryLongType + aSecondVeryLongType + aThirdVeryLongType
"""

[<Test>]
let ``long type constructors should be in multiple lines, 868`` () =
formatSourceString false """
type VersionMismatchDuringDeserializationException(message: string, innerException: System.Exception) =
inherit System.Exception(message, innerException)
""" { config with PageWidth = 80; SpaceBeforeColon = true }
|> prepend newline
|> should equal """
type VersionMismatchDuringDeserializationException(message : string,
innerException : System.Exception) =
inherit System.Exception(message, innerException)
"""
59 changes: 20 additions & 39 deletions src/Fantomas/CodePrinter.fs
Original file line number Diff line number Diff line change
Expand Up @@ -681,19 +681,17 @@ and genMemberBinding astContext b =
match e with
| TypedExpr(Typed, e, t) ->
genAttributesAndXmlDoc
+> leadingExpressionIsMultiline prefix (fun prefixIsLong ->
ifElse
prefixIsLong
(indent +> sepNln +> sepColon +> genType astContext false t +> sepNln +> !- "=" +> sepNln +> genExpr astContext e +> unindent)
(sepColon +> genType astContext false t +> sepEq +> sepSpaceOrIndentAndNlnIfExpressionExceedsPageWidth (genExpr astContext e)))
+> prefix
+> sepColon
+> genType astContext false t
+> sepEq
+> sepSpaceOrIndentAndNlnIfExpressionExceedsPageWidth (genExpr astContext e)

| e ->
genAttributesAndXmlDoc
+> leadingExpressionIsMultiline prefix
(fun prefixIsLong ->
ifElse
prefixIsLong
(indent +> sepNln +> !- "=" +> sepNln +> genExpr astContext e +> unindent)
(sepEq +> sepSpaceOrIndentAndNlnIfExpressionExceedsPageWidth (genExpr astContext e)))
+> prefix
+> sepEq
+> sepSpaceOrIndentAndNlnIfExpressionExceedsPageWidth (genExpr astContext e)

| ExplicitCtor(ats, px, ao, p, e, so) ->
let prefix =
Expand Down Expand Up @@ -2048,11 +2046,8 @@ and genTypeDefn astContext (TypeDef(ats, px, ao, tds, tcs, tdr, ms, s, preferPos

| ObjectModel(_, MemberDefnList(impCtor, others), _) ->
typeName
+> leadingExpressionIsMultiline
(opt sepNone impCtor (fun mdf ->
sepSpaceBeforeClassConstructor
+> genMemberDefn { astContext with InterfaceRange = None } mdf))
(fun longCtor -> ifElse longCtor (indent +> sepNln +> !- "=" +> unindent) sepEq)
+> opt sepNone impCtor (fun mdf -> sepSpaceBeforeClassConstructor +> genMemberDefn { astContext with InterfaceRange = None } mdf)
+> sepEq
+> indent
+> genMemberDefnList { astContext with InterfaceRange = None } others
+> unindent
Expand Down Expand Up @@ -2552,24 +2547,10 @@ and genMemberDefn astContext node =
+> sepOpenT
+> col sepComma (simplePats ps) (genSimplePat astContext)
+> sepCloseT)
(match ao with
| Some ao ->
indent
+> sepNln
+> sepSpace
+> genAccess ao
+> sepSpace
+> sepOpenT
+> atCurrentColumn (col (sepComma +> sepNln) (simplePats ps) (genSimplePat astContext))
+> sepCloseT
+> unindent
| None ->
sepOpenT
+> indent
+> sepNln
+> col (sepComma +> sepNln) (simplePats ps) (genSimplePat astContext)
+> unindent
+> sepCloseT)
(optPre sepSpace sepSpace ao genAccess
+> sepOpenT
+> atCurrentColumn (col (sepComma +> sepNln) (simplePats ps) (genSimplePat astContext))
+> sepCloseT)

// In implicit constructor, attributes should come even before access qualifiers
ifElse ats.IsEmpty sepNone (sepSpace +> genOnelinerAttributes astContext ats)
Expand Down Expand Up @@ -2697,7 +2678,7 @@ and genPat astContext pat =
ifElse astContext.IsCStylePattern (genTypeByLookup astContext t +> sepSpace +> genPat astContext p)
(genPat astContext p +> sepColon +> genType astContext false t)
| PatNamed(ao, PatNullary PatWild, s) ->
autoIndentAndNlnIfExpressionExceedsPageWidth (opt sepSpace ao genAccess +> infixOperatorFromTrivia pat.Range s)
opt sepSpace ao genAccess +> infixOperatorFromTrivia pat.Range s
| PatNamed(ao, p, s) -> opt sepSpace ao genAccess +> genPat astContext p -- sprintf " as %s" s
| PatLongIdent(ao, s, ps, tpso) ->
let aoc = opt sepSpace ao genAccess
Expand All @@ -2719,9 +2700,9 @@ and genPat astContext pat =
let genName = aoc -- s +> tpsoc +> sepSpace

let genParameters =
(expressionFitsOnRestOfLine
(atCurrentColumn (col (ifElse hasBracket sepSemi sepSpace) ps (genPatWithIdent astContext)) +> indent)
(indent +> sepNln +> col sepNln ps (genPatWithIdent astContext)) +> unindent)
expressionFitsOnRestOfLine
(atCurrentColumn (col (ifElse hasBracket sepSemi sepSpace) ps (genPatWithIdent astContext)))
(atCurrentColumn (col sepNln ps (genPatWithIdent astContext)))

genName
+> ifElse hasBracket sepOpenT sepNone
Expand All @@ -2733,7 +2714,7 @@ and genPat astContext pat =
| PatTuple ps ->
expressionFitsOnRestOfLine
(col sepComma ps (genPat astContext))
(autoIndentAndNlnIfExpressionExceedsPageWidth (col (sepComma +> sepNln) ps (genPat astContext)))
(atCurrentColumn (col (sepComma +> sepNln) ps (genPat astContext)))
| PatStructTuple ps ->
!- "struct " +> sepOpenT +> atCurrentColumn (colAutoNlnSkip0 sepComma ps (genPat astContext)) +> sepCloseT
| PatSeq(PatList, ps) ->
Expand Down

0 comments on commit 098a395

Please sign in to comment.