Skip to content

Commit 9bb0cd6

Browse files
authored
Merge pull request #3218 from nojaf/fix-3135
Fix dynamic operator on qualified function call result
2 parents 3b1b2d1 + 31d2fd9 commit 9bb0cd6

File tree

3 files changed

+25
-1
lines changed

3 files changed

+25
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
- Multiline function type inside parentheses gets extra indentation to avoid compiler error. [#3043](https://github.com/fsprojects/fantomas/issues/3043)
1212
- Trivia around paren lambda with conditional compilation no longer causes merge error. [#2844](https://github.com/fsprojects/fantomas/issues/2844)
1313
- Type app closing angle bracket padded by previous expression length. [#3179](https://github.com/fsprojects/fantomas/issues/3179)
14+
- Dynamic operator on result of qualified function call causes formatting error. [#3135](https://github.com/fsprojects/fantomas/issues/3135)
1415

1516
## [8.0.0-alpha-002] - 2025-12-15
1617

src/Fantomas.Core.Tests/DynamicOperatorTests.fs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,3 +125,17 @@ let statusBarHeight = (window?getComputedStyle document.documentElement)?getProp
125125
let statusBarHeight =
126126
(window?getComputedStyle document.documentElement)?getPropertyValue "--statusBarHeight"
127127
"""
128+
129+
[<Test>]
130+
let ``dynamic operator on result of long ident paren arg, 3135`` () =
131+
formatSourceString
132+
"""
133+
Jest.expect(json)?oMatchSnapshot ()
134+
"""
135+
config
136+
|> prepend newline
137+
|> should
138+
equal
139+
"""
140+
Jest.expect(json)?oMatchSnapshot ()
141+
"""

src/Fantomas.Core/CodePrinter.fs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ let rec (|UppercaseExpr|LowercaseExpr|) (expr: Expr) =
5757
| Expr.DotIndexedGet node -> (|UppercaseExpr|LowercaseExpr|) node.ObjectExpr
5858
| Expr.TypeApp node -> (|UppercaseExpr|LowercaseExpr|) node.Identifier
5959
| Expr.Dynamic node -> (|UppercaseExpr|LowercaseExpr|) node.FuncExpr
60+
| Expr.AppLongIdentAndSingleParenArg node -> lastFragmentInList node.FunctionName
6061
| Expr.AppSingleParenArg node -> (|UppercaseExpr|LowercaseExpr|) node.FunctionExpr
6162
| Expr.Paren node -> (|UppercaseExpr|LowercaseExpr|) node.Expr
6263
| Expr.App node -> (|UppercaseExpr|LowercaseExpr|) node.FunctionExpr
@@ -721,7 +722,15 @@ let genExpr (e: Expr) =
721722
+> genExpr node.Expr
722723
+> genSingleTextNode node.ClosingParen
723724
|> genNode node
724-
| Expr.Dynamic node -> genExpr node.FuncExpr +> !-"?" +> genExpr node.ArgExpr |> genNode node
725+
| Expr.Dynamic node ->
726+
// Use sepNone for AppLongIdentAndSingleParenArg to preserve atomic application (no space before paren).
727+
// Adding a space would change the AST from `(Jest.expect(json))?oMatchSnapshot` to `Jest.expect ((json)?oMatchSnapshot)`. See #3135.
728+
let genFuncExpr =
729+
match node.FuncExpr with
730+
| Expr.AppLongIdentAndSingleParenArg appNode -> genAppLongIdentAndSingleParenArgExpr sepNone appNode
731+
| _ -> genExpr node.FuncExpr
732+
733+
genFuncExpr +> !-"?" +> genExpr node.ArgExpr |> genNode node
725734
| Expr.PrefixApp node ->
726735
let genWithoutSpace = genSingleTextNode node.Operator +> genExpr node.Expr
727736
let genWithSpace = genSingleTextNode node.Operator +> sepSpace +> genExpr node.Expr

0 commit comments

Comments
 (0)