Repository: scalameta/scalameta
Pull request #3623 (2024-03-07 15:22:02)

ScalametaParser: fail if literal looks like apply


Patch:
diff --git a/scalameta/parsers/shared/src/main/scala/scala/meta/internal/parsers/ScalametaParser.scala b/scalameta/parsers/shared/src/main/scala/scala/meta/internal/parsers/ScalametaParser.scala
index 12ace6b0c..cc70f761a 100644
--- a/scalameta/parsers/shared/src/main/scala/scala/meta/internal/parsers/ScalametaParser.scala
+++ b/scalameta/parsers/shared/src/main/scala/scala/meta/internal/parsers/ScalametaParser.scala
@@ -2331,6 +2331,7 @@ class ScalametaParser(input: Input)(implicit dialect: Dialect) { parser =>
 
   @tailrec
   private def simpleExprRest(t: Term, canApply: Boolean, startPos: Int): Term = {
+    val tokenBefore = prevToken
     @inline def addPos(body: Term): Term = autoEndPos(startPos)(body)
     if (canApply) {
       if (dialect.allowSignificantIndentation) {
@@ -2363,6 +2364,8 @@ class ScalametaParser(input: Input)(implicit dialect: Dialect) { parser =>
             addPos(t)
         }
       case tok @ (_: LeftParen | _: LeftBrace) if canApply =>
+        if (t.is[Lit] && tokenBefore.is[Constant[_]])
+          syntaxError(s"`${tokenBefore.text}` does not take parameters", at = tok)
         def argClause =
           if (tok.is[LeftBrace]) getArgClauseOnBrace() else getArgClauseOnParen()
         val arguments = addPos(Term.Apply(t, argClause))


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 330afe67a..0349edd44 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
@@ -272,62 +272,92 @@ class LitSuite extends ParseSuite {
 
   test("unary: +1") {
     runTestAssert[Stat]("+1")(Term.ApplyUnary(tname("+"), lit(1)))
-    runTestAssert[Stat]("+1(0)")(Term.ApplyUnary(tname("+"), Term.Apply(lit(1), List(lit(0)))))
+    val error =
+      """|<input>:1: error: `1` does not take parameters
+         |+1(0)
+         |  ^""".stripMargin
+    runTestError[Stat]("+1(0)", error)
   }
 
   test("unary: -1") {
     runTestAssert[Stat]("-1")(int(-1))
-    runTestAssert[Stat]("-1(0)")(Term.Apply(lit(-1), List(lit(0))))
+    val error =
+      """|<input>:1: error: `1` does not take parameters
+         |-1(0)
+         |  ^""".stripMargin
+    runTestError[Stat]("-1(0)", error)
   }
 
   test("unary: ~1") {
     runTestAssert[Stat]("~1")(Term.ApplyUnary(tname("~"), lit(1)))
-    runTestAssert[Stat]("~1(0)")(Term.ApplyUnary(tname("~"), Term.Apply(lit(1), List(lit(0)))))
+    val error =
+      """|<input>:1: error: `1` does not take parameters
+         |~1(0)
+         |  ^""".stripMargin
+    runTestError[Stat]("~1(0)", error)
   }
 
   test("unary: !1") {
     runTestAssert[Stat]("!1")(Term.ApplyUnary(tname("!"), lit(1)))
-    runTestAssert[Stat]("!1(0)")(Term.ApplyUnary(tname("!"), Term.Apply(lit(1), List(lit(0)))))
+    val error =
+      """|<input>:1: error: `1` does not take parameters
+         |!1(0)
+         |  ^""".stripMargin
+    runTestError[Stat]("!1(0)", error)
   }
 
   test("unary: +1.0") {
     runTestAssert[Stat]("+1.0", "+1.0d")(Term.ApplyUnary(tname("+"), lit(1d)))
-    runTestAssert[Stat]("+1.0(0)", "+1.0d(0)")(
-      Term.ApplyUnary(tname("+"), Term.Apply(lit(1d), List(lit(0))))
-    )
+    val error =
+      """|<input>:1: error: `1.0` does not take parameters
+         |+1.0(0)
+         |    ^""".stripMargin
+    runTestError[Stat]("+1.0(0)", error)
   }
 
   test("unary: -1.0") {
     runTestAssert[Stat]("-1.0", "-1.0d")(lit(-1d))
-    runTestAssert[Stat]("-1.0(0)", "-1.0d(0)")(Term.Apply(lit(-1d), List(lit(0))))
+    val error =
+      """|<input>:1: error: `1.0` does not take parameters
+         |-1.0(0)
+         |    ^""".stripMargin
+    runTestError[Stat]("-1.0(0)", error)
   }
 
   test("unary: ~1.0") {
     runTestAssert[Stat]("~1.0", "~1.0d")(Term.ApplyUnary(tname("~"), lit(1d)))
-    runTestAssert[Stat]("~1.0(0)", "~1.0d(0)")(
-      Term.ApplyUnary(tname("~"), Term.Apply(lit(1d), List(lit(0))))
-    )
+    val error =
+      """|<input>:1: error: `1.0` does not take parameters
+         |~1.0(0)
+         |    ^""".stripMargin
+    runTestError[Stat]("~1.0(0)", error)
   }
 
   test("unary: !1.0") {
     runTestAssert[Stat]("!1.0", "!1.0d")(Term.ApplyUnary(tname("!"), lit(1d)))
-    runTestAssert[Stat]("!1.0(0)", "!1.0d(0)")(
-      Term.ApplyUnary(tname("!"), Term.Apply(lit(1d), List(lit(0))))
-    )
+    val error =
+      """|<input>:1: error: `1.0` does not take parameters
+         |!1.0(0)
+         |    ^""".stripMargin
+    runTestError[Stat]("!1.0(0)", error)
   }
 
   test("unary: !true") {
     runTestAssert[Stat]("!true")(Term.ApplyUnary(tname("!"), lit(true)))
-    runTestAssert[Stat]("!true(0)")(
-      Term.ApplyUnary(tname("!"), Term.Apply(lit(true), List(lit(0))))
-    )
+    val error =
+      """|<input>:1: error: `true` does not take parameters
+         |!true(0)
+         |     ^""".stripMargin
+    runTestError[Stat]("!true(0)", error)
   }
 
   test("unary: !false") {
     runTestAssert[Stat]("!false")(Term.ApplyUnary(tname("!"), lit(false)))
-    runTestAssert[Stat]("!false(0)")(
-      Term.ApplyUnary(tname("!"), Term.Apply(lit(false), List(lit(0))))
-    )
+    val error =
+      """|<input>:1: error: `false` does not take parameters
+         |!false(0)
+         |      ^""".stripMargin
+    runTestError[Stat]("!false(0)", error)
   }
 
 }