Repository: scalameta/scalameta (scala)

Issue:
When I define a Float with value 3.4028235e38f and run scalafmt, an error occurs.
Hi,

When I define a Float with value 3.4028235e38f and run scalafmt, an error occurs.

Running compile or run does not result in an error.
Is this a bug?

scala version: 3.3.3
scalafmt version: 3.8.0

## Configuration (required) ##

Please paste the contents of your `.scalafmt.conf` file here:
```
version = 3.8.0
runner.dialect = scala3 // Occurs in others such as scala213 and scala212
```

## Command-line parameters (required) ##

```shell
scalafmt src/main/scala/Main.scala
```

## Steps

Given code like this:
```scala
@main def main(): Unit =
  println(3.4028235e38f)
```

## Problem

Scalafmt reports errors like this.

```scala
error: [dialect scala3] floating point number too large
  println(3.4028235e38f)
```

## Expectation

No errors

## Workaround

Define in scala using Java methods.

```scala
java.lang.Float.intBitsToFloat(2139095039)
```

## Notes

Is this the same kind of problem reported in the old Scala bug?

https://github.com/scala/bug/issues/10148

Pull request:
Fixes #3654.

Patch:
diff --git a/scalameta/tokenizers/shared/src/main/scala/scala/meta/internal/tokenizers/LegacyTokenData.scala b/scalameta/tokenizers/shared/src/main/scala/scala/meta/internal/tokenizers/LegacyTokenData.scala
index ef5905d231..6492c559d5 100644
--- a/scalameta/tokenizers/shared/src/main/scala/scala/meta/internal/tokenizers/LegacyTokenData.scala
+++ b/scalameta/tokenizers/shared/src/main/scala/scala/meta/internal/tokenizers/LegacyTokenData.scala
@@ -2,6 +2,9 @@ package scala.meta
 package internal
 package tokenizers
 
+import java.math.MathContext
+import java.math.RoundingMode
+
 import scala.meta.inputs._
 
 trait LegacyTokenData {
@@ -114,6 +117,9 @@ trait LegacyTokenData {
 }
 
 object LegacyTokenData {
-  private val bigDecimalMaxFloat = BigDecimal(Float.MaxValue)
-  private val bigDecimalMaxDouble = BigDecimal(Double.MaxValue)
+  // add a bit more, JS doesn't handle it well
+  private val bigDecimalMaxFloat =
+    BigDecimal.binary(Float.MaxValue, new MathContext(8, RoundingMode.UP))
+  private val bigDecimalMaxDouble =
+    BigDecimal.binary(Double.MaxValue, new MathContext(32, RoundingMode.UP))
 }


Test patch:
diff --git a/tests/shared/src/test/scala/scala/meta/tests/parsers/LitSuite.scala b/tests/shared/src/test/scala/scala/meta/tests/parsers/LitSuite.scala
index e19adbc7c3..7831566775 100644
--- a/tests/shared/src/test/scala/scala/meta/tests/parsers/LitSuite.scala
+++ b/tests/shared/src/test/scala/scala/meta/tests/parsers/LitSuite.scala
@@ -374,4 +374,136 @@ class LitSuite extends ParseSuite {
     runTestAssert[Stat](code)(tree)
   }
 
+  Seq(
+    ("0d", 0d),
+    ("0.0", 0d),
+    ("00e0", 0d),
+    ("00e0f", 0f),
+    ("0xe1", 225),
+    ("0xd", 13),
+    ("0f", 0f),
+    ("0.0f", 0f),
+    ("0xf", 15),
+    ("0", 0),
+    ("0l", 0L),
+    ("0L", 0L),
+    ("0x80000000", -2147483648),
+    ("0x8000000000000000L", -9223372036854775808L),
+    ("3.4028235e38f", Float.MaxValue),
+    ("-3.4028235e38f", Float.MinValue),
+    ("1.7976931348623157e+308d", Double.MaxValue),
+    ("-1.7976931348623157e+308d", Double.MinValue),
+    ("0b00101010", 42),
+    ("0B_0010_1010", 42),
+    ("0b_0010_1010L", 42L)
+  ).foreach { case (code, expected) =>
+    test(s"numeric literal ok scala213: $code") {
+      parseStat(code, Scala213) match {
+        case lit: Lit => assertEquals(lit.value, expected)
+      }
+    }
+  }
+
+  Seq(
+    (
+      "0.f",
+      Term.Select(lit(0), tname("f"))
+    ),
+    (
+      "1.0 + 2.0f",
+      Term.ApplyInfix(lit(1d), tname("+"), Nil, List(lit(2f)))
+    ),
+    (
+      "1d + 2f",
+      Term.ApplyInfix(lit(1d), tname("+"), Nil, List(lit(2f)))
+    ),
+    (
+      "0b01.toString",
+      Term.Select(lit(1), tname("toString"))
+    )
+  ).foreach { case (code, tree: Tree) =>
+    test(s"expr with numeric literal ok scala213: $code") {
+      runTestAssert[Stat](code, None)(tree)
+    }
+  }
+
+  Seq(
+    (
+      "00",
+      """|<input>:1: error: Non-zero integral values may not have a leading zero.
+         |00
+         |^""".stripMargin
+    ),
+    (
+      "00l",
+      """|<input>:1: error: Non-zero integral values may not have a leading zero.
+         |00l
+         |^""".stripMargin
+    ),
+    (
+      "0b01d",
+      """|<input>:1: error: Invalid literal number, followed by identifier character
+         |0b01d
+         |    ^""".stripMargin
+    ),
+    (
+      "0b01f",
+      """|<input>:1: error: Invalid literal number, followed by identifier character
+         |0b01f
+         |    ^""".stripMargin
+    ),
+    (
+      "0b0123",
+      """|<input>:1: error: Invalid literal number, followed by identifier character
+         |0b0123
+         |    ^""".stripMargin
+    ),
+    (
+      "0b01.2",
+      """|<input>:1: error: ; expected but double constant found
+         |0b01.2
+         |    ^""".stripMargin
+    ),
+    (
+      "1. + 2.",
+      """|<input>:1: error: ; expected but integer constant found
+         |1. + 2.
+         |     ^""".stripMargin
+    ),
+    (
+      ".f",
+      """|<input>:1: error: illegal start of definition .
+         |.f
+         |^""".stripMargin
+    ),
+    (
+      "3.4028236e38f",
+      """|<input>:1: error: floating-point value out of range for Float
+         |3.4028236e38f
+         |^""".stripMargin
+    ),
+    (
+      "-3.4028236e38f",
+      """|<input>:1: error: floating-point value out of range for Float
+         |-3.4028236e38f
+         | ^""".stripMargin
+    ),
+    (
+      "1.7976931348623158e+308d",
+      """|<input>:1: error: floating-point value out of range for Double
+         |1.7976931348623158e+308d
+         |^""".stripMargin
+    ),
+    (
+      "-1.7976931348623158e+308d",
+      """|<input>:1: error: floating-point value out of range for Double
+         |-1.7976931348623158e+308d
+         | ^""".stripMargin
+    )
+  ).foreach { case (code, error) =>
+    test(s"numeric literal fail scala213: $code") {
+      runTestError[Stat](code, error)
+    }
+  }
+
 }
diff --git a/tests/shared/src/test/scala/scala/meta/tests/tokenizers/TokenizerSuite.scala b/tests/shared/src/test/scala/scala/meta/tests/tokenizers/TokenizerSuite.scala
index 48e56d9e24..8d883a9963 100644
--- a/tests/shared/src/test/scala/scala/meta/tests/tokenizers/TokenizerSuite.scala
+++ b/tests/shared/src/test/scala/scala/meta/tests/tokenizers/TokenizerSuite.scala
@@ -1493,33 +1493,33 @@ class TokenizerSuite extends BaseTokenizerSuite {
          |""".stripMargin
     ),
     (
-      "3.40e+38f",
+      "3.4028235e38f",
       """|BOF [0..0)
-         |Constant.Float(3.40e+38f) [0..9)
-         |EOF [9..9)
+         |Constant.Float(3.4028235e38f) [0..13)
+         |EOF [13..13)
          |""".stripMargin
     ),
     (
-      "-3.40e+38f",
+      "-3.4028235e38f",
       """|BOF [0..0)
          |Ident(-) [0..1)
-         |Constant.Float(3.40e+38f) [1..10)
-         |EOF [10..10)
+         |Constant.Float(3.4028235e38f) [1..14)
+         |EOF [14..14)
          |""".stripMargin
     ),
     (
-      "1.79e+308d",
+      "1.7976931348623157e+308d",
       """|BOF [0..0)
-         |Constant.Double(1.79e+308d) [0..10)
-         |EOF [10..10)
+         |Constant.Double(1.7976931348623157e+308d) [0..24)
+         |EOF [24..24)
          |""".stripMargin
     ),
     (
-      "-1.79e+308d",
+      "-1.7976931348623157e+308d",
       """|BOF [0..0)
          |Ident(-) [0..1)
-         |Constant.Double(1.79e+308d) [1..11)
-         |EOF [11..11)
+         |Constant.Double(1.7976931348623157e+308d) [1..25)
+         |EOF [25..25)
          |""".stripMargin
     ),
     (
@@ -1598,27 +1598,27 @@ class TokenizerSuite extends BaseTokenizerSuite {
          |    ^""".stripMargin
     ),
     (
-      "3.41e+38f",
+      "3.4028236e38f",
       """|<input>:1: error: floating-point value out of range for Float
-         |3.41e+38f
+         |3.4028236e38f
          |^""".stripMargin
     ),
     (
-      "-3.41e+38f",
+      "-3.4028236e38f",
       """|<input>:1: error: floating-point value out of range for Float
-         |-3.41e+38f
+         |-3.4028236e38f
          | ^""".stripMargin
     ),
     (
-      "1.80e+308d",
+      "1.7976931348623158e+308d",
       """|<input>:1: error: floating-point value out of range for Double
-         |1.80e+308d
+         |1.7976931348623158e+308d
          |^""".stripMargin
     ),
     (
-      "-1.80e+308d",
+      "-1.7976931348623158e+308d",
       """|<input>:1: error: floating-point value out of range for Double
-         |-1.80e+308d
+         |-1.7976931348623158e+308d
          | ^""".stripMargin
     )
   ).foreach { case (code, error) =>