Skip to content

Commit

Permalink
Dont use let .. in when multiline after "in"or formatting from AST. S…
Browse files Browse the repository at this point in the history
…hould fix #384 (#393)

dont use let .. in when formatting from AST
  • Loading branch information
jindraivanek authored and nojaf committed Jan 18, 2019
1 parent e7ac8f8 commit 44a0b20
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 9 deletions.
18 changes: 14 additions & 4 deletions src/Fantomas.Tests/FormatAstTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,23 @@ open NUnit.Framework
open FsUnit
open Fantomas.Tests.TestHelper

[<Test>]
let ``Format the ast works correctly with no source code``() =
let formatAst code =
let inputExp =
"()" |> Input
code |> Input
|> toSynExprs
|> List.head

fromSynExpr inputExp
|> function Input x -> x.TrimEnd('\r', '\n')
|> should equal "()"
|> fun s -> s.Replace("\r\n", "\n")

[<Test>]
let ``Format the ast works correctly with no source code``() =
formatAst "()"
|> should equal "()"

[<Test>]
let ``let in should not be used``() =
formatAst "let x = 1 in ()"
|> should equal """let x = 1
()"""
48 changes: 48 additions & 0 deletions src/Fantomas.Tests/LetBindingTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,52 @@ let f () =
let x = 1 // the "in" keyword is available in F#
let y = 2
x + y
"""

[<Test>]
let ``multiple let in lines, should remove in, block comment`` () =
let codeSnippet = """
let f () =
let x = 1 in (* the "in" keyword is available in F# *)
let y = 2 in
x + y
"""

formatSourceString false codeSnippet config
|> should equal """let f() =
let x = 1 (* the "in" keyword is available in F# *)
let y = 2
x + y
"""

[<Test>]
let ``multiline let in, should remove in`` () =
let codeSnippet = """
let f () =
let x = 1 in if true
then x
else x
"""

formatSourceString false codeSnippet config
|> should equal """let f() =
let x = 1
if true then x
else x
"""

[<Test>]
let ``multiline let in, should remove in 2`` () =
let codeSnippet = """
let f () =
let x = 1 in (while true do ()
x)
"""

formatSourceString false codeSnippet config
|> should equal """let f() =
let x = 1
(while true do
()
x)
"""
8 changes: 5 additions & 3 deletions src/Fantomas/CodePrinter.fs
Original file line number Diff line number Diff line change
Expand Up @@ -658,11 +658,13 @@ and genExpr astContext synExpr =

| TypeApp(e, ts) -> genExpr astContext e -- "<" +> col sepComma ts (genType astContext false) -- ">"
| LetOrUses(bs, e) ->
let isInSameLine =
let isFromAst (ctx: Context) = ctx.Content = String.Empty
let isInSameLine ctx =
match bs with
| [_, LetBinding(ats, px, ao, isInline, isMutable, p, _)] -> p.Range.EndLine = e.Range.StartLine
| [_, LetBinding(ats, px, ao, isInline, isMutable, p, _)] ->
not (isFromAst ctx) && p.Range.EndLine = e.Range.StartLine && not(checkBreakForExpr e)
| _ -> false
atCurrentColumn (genLetOrUseList astContext bs +> ifElse isInSameLine (!- " in ") sepNln +> genExpr astContext e)
atCurrentColumn (genLetOrUseList astContext bs +> ifElseCtx isInSameLine (!- " in ") sepNln +> genExpr astContext e)

// Could customize a bit if e is single line
| TryWith(e, cs) ->
Expand Down
3 changes: 3 additions & 0 deletions src/Fantomas/Context.fs
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,9 @@ let internal optPre (f2 : _ -> Context) (f1 : Context -> _) o f (ctx : Context)
let internal ifElse b (f1 : Context -> Context) f2 (ctx : Context) =
if b then f1 ctx else f2 ctx

let internal ifElseCtx cond (f1 : Context -> Context) f2 (ctx : Context) =
if cond ctx then f1 ctx else f2 ctx

/// Repeat application of a function n times
let internal rep n (f : Context -> Context) (ctx : Context) =
[1..n] |> List.fold (fun c _ -> f c) ctx
Expand Down
6 changes: 4 additions & 2 deletions src/Fantomas/TokenMatcher.fs
Original file line number Diff line number Diff line change
Expand Up @@ -694,8 +694,10 @@ let integrateComments (config:Fantomas.FormatConfig.FormatConfig) compilationDef
| (Marked(inToken,_,_)::oldTokens), (NewLine newTokText :: moreNewTokens) ->
Debug.WriteLine(sprintf "emitting newline in new tokens '%s'" newTokText)
let nextOldTokens =
match (inToken) with
| Tok(fsInToken,_) when (fsInToken.TokenName = "IN") ->
match (inToken, oldTokens) with
| Tok(fsInToken,_), (WhiteSpaceTokens (_, LineCommentToken false _ :: _))
| Tok(fsInToken,_), (WhiteSpaceTokens (_, BlockCommentToken _ :: _))
when (fsInToken.TokenName = "IN") ->
// find tokens before newline in old source
let tokensBeforeNewline =
oldTokens
Expand Down

0 comments on commit 44a0b20

Please sign in to comment.