Skip to content

Commit

Permalink
Keep Subsequent identifier links on the same line. (#2713)
Browse files Browse the repository at this point in the history
* Keep Subsequent identifier links on the same line.

* Print all simple links out using the max_line_length

* Update src/Fantomas.Core.Tests/ChainTests.fs

Co-authored-by: dawe <[email protected]>

Co-authored-by: dawe <[email protected]>
  • Loading branch information
nojaf and dawedawe authored Jan 14, 2023
1 parent 8ca54ac commit 0d0cab0
Show file tree
Hide file tree
Showing 6 changed files with 92 additions and 21 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
### Fixed
* Trivia before open statement is not preserved. [#2704](https://github.com/fsprojects/fantomas/issues/2704)
* Type app identifier is considered as an expression. [#2705](https://github.com/fsprojects/fantomas/issues/2705)
* Subsequent identifier links in chain should be on the same line. [#2712](https://github.com/fsprojects/fantomas/issues/2712)

## [5.2.0-alpha-011] - 2023-01-12

Expand Down
72 changes: 72 additions & 0 deletions src/Fantomas.Core.Tests/ChainTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -299,3 +299,75 @@ Map
Map.empty<_, obj>
.Add("headerAction", modifyHeader.Action.ArmValue)
"""

[<Test>]
let ``all simple links should be on the same line, 2712`` () =
formatSourceString
false
"""
type Duck() =
member this.Duck = Duck ()
member this.Goose() = Duck()
let d = Duck()
d.Duck.Duck.Duck.Goose().Duck.Goose().Duck.Duck.Goose().Duck.Duck.Duck.Goose().Duck.Duck.Duck.Duck.Goose()
"""
config
|> prepend newline
|> should
equal
"""
type Duck() =
member this.Duck = Duck()
member this.Goose() = Duck()
let d = Duck()
d.Duck.Duck.Duck
.Goose()
.Duck.Goose()
.Duck.Duck.Goose()
.Duck.Duck.Duck.Goose()
.Duck.Duck.Duck.Duck.Goose()
"""

[<Test>]
let ``very long chain with a some index expressions`` () =
formatSourceString
false
"""
Universe.Galaxy.SolarSystem.Planet.[3].Countries.[9].People.Count
"""
{ config with
MaxDotGetExpressionWidth = 0
MaxLineLength = 50 }
|> prepend newline
|> should
equal
"""
Universe.Galaxy.SolarSystem.Planet.[3].Countries
.[9].People.Count
"""

[<Test>]
let ``even longer chain with only simple links`` () =
formatSourceString
false
"""
Fooooooooooo.Baaaaaaaaaaaaaaaaar.Foooooooooooooooooo.Baaaaaaaar.Basssss.Baazzzzzzzzzzzzzzzzzz.[0].Meeeeeeeeeeeeeeeeeh
.Moooooooooooooooo.Booooooooooooooooooooh.Yooooooooooooooou.Meeeeeeh.Meh2
"""
{ config with
MaxDotGetExpressionWidth = 0
MaxLineLength = 50 }
|> prepend newline
|> should
equal
"""
Fooooooooooo.Baaaaaaaaaaaaaaaaar
.Foooooooooooooooooo.Baaaaaaaar.Basssss
.Baazzzzzzzzzzzzzzzzzz.[0].Meeeeeeeeeeeeeeeeeh
.Moooooooooooooooo.Booooooooooooooooooooh
.Yooooooooooooooou.Meeeeeeh.Meh2
"""
4 changes: 1 addition & 3 deletions src/Fantomas.Core.Tests/LambdaTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -319,9 +319,7 @@ CloudStorageAccount.SetConfigurationSettingPublisher(fun configName configSettin
if hostedService then
RoleEnvironment.GetConfigurationSettingValue(configName)
else
ConfigurationManager
.ConnectionStrings.[configName]
.ConnectionString
ConfigurationManager.ConnectionStrings.[configName].ConnectionString
configSettingPublisher.Invoke(connectionString)
|> ignore)
Expand Down
10 changes: 3 additions & 7 deletions src/Fantomas.Core.Tests/LetBindingTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1078,9 +1078,7 @@ let ``don't add additional newline before SynExpr.New, 1049`` () =
"""
let getVersion () =
let version =
let assembly =
typeof<FSharp.Compiler.SourceCodeServices.FSharpChecker>
.Assembly
let assembly = typeof<FSharp.Compiler.SourceCodeServices.FSharpChecker>.Assembly
let version = assembly.GetName().Version
sprintf "%i.%i.%i" version.Major version.Minor version.Revision
Expand Down Expand Up @@ -1252,8 +1250,7 @@ let x =
if tcref.IsILTycon then
tcref.ILTyconRawMetadata.CustomAttrs.AsArray
|> Array.exists (fun attr ->
attr.Method.DeclaringType.TypeSpec.Name = typeof<TypeProviderEditorHideMethodsAttribute>
.FullName)
attr.Method.DeclaringType.TypeSpec.Name = typeof<TypeProviderEditorHideMethodsAttribute>.FullName)
else
false
"""
Expand Down Expand Up @@ -1315,8 +1312,7 @@ let x =
if tcref.IsILTycon then
tcref.ILTyconRawMetadata.CustomAttrs.AsArray
|> Array.exists (fun attr ->
attr.Method.DeclaringType.TypeSpec.Name = typeof<TypeProviderEditorHideMethodsAttribute>
.FullName)
attr.Method.DeclaringType.TypeSpec.Name = typeof<TypeProviderEditorHideMethodsAttribute>.FullName)
else
false
"""
Expand Down
4 changes: 1 addition & 3 deletions src/Fantomas.Core.Tests/TypeDeclarationTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -824,9 +824,7 @@ type BlobHelper(Account: CloudStorageAccount) =
if hostedService then
RoleEnvironment.GetConfigurationSettingValue(configName)
else
ConfigurationManager
.ConnectionStrings.[configName]
.ConnectionString
ConfigurationManager.ConnectionStrings.[configName].ConnectionString
configSettingPublisher.Invoke(connectionString)
|> ignore)
Expand Down
22 changes: 14 additions & 8 deletions src/Fantomas.Core/CodePrinter.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1093,20 +1093,26 @@ let genExpr (e: Expr) =
let isLast = List.isEmpty rest
let genDotAndLink = genSingleTextNode dot +> genLink isLast link
let currentIsSimple = ((|SimpleChain|_|) >> Option.isSome) link
let currentLinkFitsOnRestOfLine = not (futureNlnCheck genDotAndLink ctx)

if lastLinkWasSimple && not (futureNlnCheck genDotAndLink ctx) then
if lastLinkWasSimple && currentLinkFitsOnRestOfLine then
// The last link was an identifier and the current link fits on the remainder of the current line.
genIndentedLinks currentIsSimple rest ((genDotAndLink +> onlyIfNot isLast sepNln) ctx)
genIndentedLinks currentIsSimple rest (genDotAndLink ctx)
else
let ctx' =
onlyIf
(not // Last link was `.Foo()`
lastLinkWasSimple
// `.Foo.Bar` but `Bar` crossed the max_line_length
|| (lastLinkWasSimple && currentIsSimple && not currentLinkFitsOnRestOfLine))
sepNlnUnlessLastEventIsNewline
ctx

genIndentedLinks
currentIsSimple
rest
// Print the current link
((genDotAndLink
// Don't suffix with a newline if we are at the end of the chain,
// or if the current link is an identifier.
+> onlyIfNot (isLast || currentIsSimple) sepNln)
ctx)
(genDotAndLink ctx')
| _ -> failwith "Expected dot in chain at this point"

let genFirstLinkAndIndentOther (firstLink: ChainLink) (others: ChainLink list) =
Expand All @@ -1123,7 +1129,7 @@ let genExpr (e: Expr) =
short
(match leadingChain with
| [] -> sepNone
| head :: links -> genFirstLinkAndIndentOther head links)
| head :: links -> genLink false head +> indent +> genIndentedLinks true links +> unindent)
ctx
| _ ->
expressionFitsOnRestOfLine
Expand Down

0 comments on commit 0d0cab0

Please sign in to comment.