Skip to content

Commit 966ad3e

Browse files
MangelMaximeclaude
andauthored
[JS/TS] Fix invalid syntax emitted when negating negative literals (#4440)
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 0eef9ef commit 966ad3e

4 files changed

Lines changed: 28 additions & 1 deletion

File tree

src/Fable.Cli/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99

1010
### Fixed
1111

12+
* [JS/TS] Fix invalid syntax emitted when negating negative literals (fix #4251) (by @MangelMaxime)
1213
* [Rust] Fixed negative counting in CallInfo.GenericArgs (by @ncave)
1314
* [JS/TS] Improve `Regex.Escape` and `Regex.Unescape` handling (by @MangelMaxime)
1415
* [All] Fix allow plugins to target .NET6 target framework (by @MangelMaxime)

src/Fable.Compiler/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99

1010
### Fixed
1111

12+
* [JS/TS] Fix invalid syntax emitted when negating negative literals (fix #4251) (by @MangelMaxime)
1213
* [Rust] Fixed negative counting in CallInfo.GenericArgs (by @ncave)
1314
* [JS/TS] Improve `Regex.Escape` and `Regex.Unescape` handling (by @MangelMaxime)
1415
* [All] Fix allow plugins to target .NET6 target framework (by @MangelMaxime)

src/Fable.Transforms/BabelPrinter.fs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1265,14 +1265,30 @@ module PrinterExtensions =
12651265
operator + " "
12661266
)
12671267

1268+
// When negating a negative numeric literal (e.g. -(-5)), we must wrap
1269+
// it in parens to avoid emitting --5, which JS parses as a decrement.
1270+
let needsParens =
1271+
not isSuffix
1272+
&& operator = "-"
1273+
&& (
1274+
match argument with
1275+
| Literal(NumericLiteral(value, _)) -> value < 0.0
1276+
| UnaryExpression(_, op, isSuffix, _) -> op = "-" && not isSuffix
1277+
| _ -> false
1278+
)
1279+
12681280
printer.AddLocation(loc)
12691281

12701282
if isSuffix then
12711283
printer.ComplexExpressionWithParens(argument)
12721284
printOp ()
12731285
else
12741286
printOp ()
1275-
printer.ComplexExpressionWithParens(argument)
1287+
1288+
if needsParens then
1289+
printer.WithParens(argument)
1290+
else
1291+
printer.ComplexExpressionWithParens(argument)
12761292

12771293
member printer.PrintUpdateExpression(prefix, argument, operator, loc) =
12781294
printer.AddLocation(loc)

tests/Js/Main/ArithmeticTests.fs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,15 @@ let tests =
3333
testCase "Unary negation with negative literal values works" <| fun () ->
3434
-literalNegativeValue |> equal 345
3535

36+
testCase "Negating negative literals inlined in computation expressions works" <| fun () -> // #4251
37+
let f x = x
38+
let result =
39+
[
40+
let x = -5.0
41+
f (-x)
42+
]
43+
result |> equal [5.0]
44+
3645
testCase "Unary negation with integer MinValue works" <| fun () ->
3746
-(-128y) |> equal SByte.MinValue
3847
-(-32768s) |> equal Int16.MinValue

0 commit comments

Comments
 (0)