Skip to content

Commit

Permalink
Never add a space in application with parentheses followed by an inde…
Browse files Browse the repository at this point in the history
…xer expression. (#2966)

* Never add a space in application with parentheses followed by an indexer expression.

* Update src/Fantomas.Core/CodePrinter.fs

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

---------

Co-authored-by: dawe <[email protected]>
  • Loading branch information
nojaf and dawedawe authored Oct 18, 2023
1 parent dfc886f commit 0d7da4c
Show file tree
Hide file tree
Showing 5 changed files with 122 additions and 49 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Changelog

## 6.2.2 - 2023-10-18

### Fixed
* Space before should not be introduced for index expression. [#2965](https://github.com/fsprojects/fantomas/issues/2965)

## 6.2.1 - 2023-09-18

### Fixed
Expand Down
4 changes: 2 additions & 2 deletions src/Fantomas.Core.Tests/AppTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -603,8 +603,8 @@ module SomeModule =
()
: Option<WatchWalletInfo> =
let initialAbs =
initialFeeWithAMinimumGasPriceInWeiDictatedByAvailablePublicFullNodes.CalculateAbsoluteValue
()
initialFeeWithAMinimumGasPriceInWeiDictatedByAvailablePublicFullNodes
.CalculateAbsoluteValue()
initialAbs / 100
"""
Expand Down
60 changes: 60 additions & 0 deletions src/Fantomas.Core.Tests/SpaceBeforeUppercaseInvocationTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -357,3 +357,63 @@ let f = OptimizedClosures.FSharpFunc<_, _, _>.Adapt (mapping)
"""
let f = OptimizedClosures.FSharpFunc<_, _, _>.Adapt(mapping)
"""

[<Test>]
let ``space should not be added when expression is indexed, 2965`` () =
formatSourceString
false
"""
fooo.Bar()[key]
"""
spaceBeforeConfig
|> prepend newline
|> should
equal
"""
fooo.Bar()[key]
"""

[<Test>]
let ``space should not be added when expression is indexed, single ident application`` () =
formatSourceString
false
"""
Bar()[key]
"""
spaceBeforeConfig
|> prepend newline
|> should
equal
"""
Bar()[key]
"""

[<Test>]
let ``space should not be added when expression is indexed, parentheses argument`` () =
formatSourceString
false
"""
fooo.Bar(1)[key]
"""
spaceBeforeConfig
|> prepend newline
|> should
equal
"""
fooo.Bar(1)[key]
"""

[<Test>]
let ``space should not be added when expression is indexed, single ident application with parentheses argument`` () =
formatSourceString
false
"""
Bar(1)[key]
"""
spaceBeforeConfig
|> prepend newline
|> should
equal
"""
Bar(1)[key]
"""
2 changes: 1 addition & 1 deletion src/Fantomas.Core/ASTTransformer.fs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
module internal rec Fantomas.Core.ASTTransformer

open System
open System.Collections.Generic
open System.Text.RegularExpressions
open Fantomas.FCS.Text
Expand Down Expand Up @@ -875,6 +874,7 @@ let (|ChainExpr|_|) (e: SynExpr) : LinkExpr list option =
let (|AppSingleParenArg|_|) =
function
| App(SynExpr.DotGet _, [ (SynExpr.Paren(expr = SynExpr.Tuple _)) ]) -> None
| App(e, [ UnitExpr _ as px ]) -> Some(e, px)
| App(e, [ SynExpr.Paren(expr = singleExpr) as px ]) ->
match singleExpr with
| SynExpr.Lambda _
Expand Down
100 changes: 54 additions & 46 deletions src/Fantomas.Core/CodePrinter.fs
Original file line number Diff line number Diff line change
Expand Up @@ -851,9 +851,15 @@ let genExpr (e: Expr) =
ctx

| Expr.IndexWithoutDot node ->
let genIdentifierExpr =
match node.Identifier with
| Expr.AppLongIdentAndSingleParenArg appNode -> genAppLongIdentAndSingleParenArgExpr sepNone appNode
| Expr.AppSingleParenArg appNode -> genAppSingleParenArgExpr sepNone appNode
| _ -> genExpr node.Identifier

let genIndexExpr = genExpr node.Index

genExpr node.Identifier
genIdentifierExpr
+> sepOpenLFixed
+> expressionFitsOnRestOfLine genIndexExpr (atCurrentColumnIndent genIndexExpr)
+> sepCloseLFixed
Expand Down Expand Up @@ -1016,53 +1022,11 @@ let genExpr (e: Expr) =
(Expr.OptVar(ExprOptVarNode(false, node.FunctionName, node.FunctionName.Range)))
node.ArgExpr

let shortLids = genIdentListNode node.FunctionName
let short = shortLids +> addSpace +> genExpr node.ArgExpr

let long =
let args =
addSpace
+> expressionFitsOnRestOfLine
(genExpr node.ArgExpr)
(genMultilineFunctionApplicationArguments node.ArgExpr)

ifElseCtx
(futureNlnCheck shortLids)
(genFunctionNameWithMultilineLids args node.FunctionName)
(shortLids +> args)

expressionFitsOnRestOfLine short long |> genNode node
genAppLongIdentAndSingleParenArgExpr addSpace node
// fn (a, b, c)
| Expr.AppSingleParenArg node ->
let short =
genExpr node.FunctionExpr
+> sepSpaceBeforeParenInFuncInvocation node.FunctionExpr node.ArgExpr
+> genExpr node.ArgExpr

let long ctx =
let genDefaultLong =
genExpr node.FunctionExpr
+> sepSpaceBeforeParenInFuncInvocation node.FunctionExpr node.ArgExpr
+> genMultilineFunctionApplicationArguments node.ArgExpr

match node.ArgExpr with
| Expr.Paren parenNode when parenNode.HasContentBefore ->
// We make a copy of the parenthesis argument (without the trivia being copied).
// Then we check if that is was multiline or not.
let parenNode' =
mkExprParenNode parenNode.OpeningParen parenNode.Expr parenNode.ClosingParen parenNode.Range

let isSingleLineWithoutTriviaBefore = futureNlnCheck (genExpr parenNode') ctx

if not isSingleLineWithoutTriviaBefore then
(genExpr node.FunctionExpr +> indentSepNlnUnindent (genExpr node.ArgExpr)) ctx
else
(genExpr node.FunctionExpr
+> indentSepNlnUnindent (genMultilineFunctionApplicationArguments node.ArgExpr))
ctx
| _ -> genDefaultLong ctx

expressionFitsOnRestOfLine short long |> genNode node
let addSpace = sepSpaceBeforeParenInFuncInvocation node.FunctionExpr node.ArgExpr
genAppSingleParenArgExpr addSpace node

// functionName arg1 arg2 (fun x y z -> ...)
| Expr.AppWithLambda node ->
Expand Down Expand Up @@ -2032,6 +1996,50 @@ let genLambdaAux (includeClosingParen: bool) (node: ExprLambdaNode) =
let genLambda = genLambdaAux false
let genLambdaWithParen = genLambdaAux true

let genAppLongIdentAndSingleParenArgExpr (addSpace: Context -> Context) (node: ExprAppLongIdentAndSingleParenArgNode) =
let shortLids = genIdentListNode node.FunctionName
let short = shortLids +> addSpace +> genExpr node.ArgExpr

let long =
let args =
addSpace
+> expressionFitsOnRestOfLine (genExpr node.ArgExpr) (genMultilineFunctionApplicationArguments node.ArgExpr)

ifElseCtx
(futureNlnCheck shortLids)
(genFunctionNameWithMultilineLids args node.FunctionName)
(shortLids +> args)

expressionFitsOnRestOfLine short long |> genNode node

let genAppSingleParenArgExpr (addSpace: Context -> Context) (node: ExprAppSingleParenArgNode) =
let short = genExpr node.FunctionExpr +> addSpace +> genExpr node.ArgExpr

let long ctx =
let genDefaultLong =
genExpr node.FunctionExpr
+> addSpace
+> genMultilineFunctionApplicationArguments node.ArgExpr

match node.ArgExpr with
| Expr.Paren parenNode when parenNode.HasContentBefore ->
// We make a copy of the parenthesis argument (without the trivia being copied).
// Then we check if that is multiline or not.
let parenNode' =
mkExprParenNode parenNode.OpeningParen parenNode.Expr parenNode.ClosingParen parenNode.Range

let isSingleLineWithoutTriviaBefore = futureNlnCheck (genExpr parenNode') ctx

if not isSingleLineWithoutTriviaBefore then
(genExpr node.FunctionExpr +> indentSepNlnUnindent (genExpr node.ArgExpr)) ctx
else
(genExpr node.FunctionExpr
+> indentSepNlnUnindent (genMultilineFunctionApplicationArguments node.ArgExpr))
ctx
| _ -> genDefaultLong ctx

expressionFitsOnRestOfLine short long |> genNode node

let genClauses (clauses: MatchClauseNode list) =
let lastIndex = clauses.Length - 1

Expand Down

0 comments on commit 0d7da4c

Please sign in to comment.