From 26f9ccfea08056765391b7535f5911a006a36a71 Mon Sep 17 00:00:00 2001 From: Albert Meltzer <7529386+kitbellew@users.noreply.github.com> Date: Tue, 19 Nov 2024 15:45:09 -0800 Subject: [PATCH] Error: add a wrapper Exception `WithCode` --- .../src/main/scala/org/scalafmt/Error.scala | 2 ++ .../src/main/scala/org/scalafmt/Scalafmt.scala | 18 ++++++++++-------- .../scala/org/scalafmt/rewrite/Rewrite.scala | 12 ++++-------- .../test/scala/org/scalafmt/FormatTests.scala | 11 +++++++++-- .../scala/org/scalafmt/util/CanRunTests.scala | 4 +++- .../org/scalafmt/util/FormatException.scala | 3 --- 6 files changed, 28 insertions(+), 22 deletions(-) delete mode 100644 scalafmt-tests/shared/src/test/scala/org/scalafmt/util/FormatException.scala diff --git a/scalafmt-core/shared/src/main/scala/org/scalafmt/Error.scala b/scalafmt-core/shared/src/main/scala/org/scalafmt/Error.scala index 604473f195..c7ad8c3108 100644 --- a/scalafmt-core/shared/src/main/scala/org/scalafmt/Error.scala +++ b/scalafmt-core/shared/src/main/scala/org/scalafmt/Error.scala @@ -120,4 +120,6 @@ object Error { case object MegaTestFailed extends Error("Mega test failed.") + case class WithCode(error: Throwable, code: String) extends Exception(error) + } diff --git a/scalafmt-core/shared/src/main/scala/org/scalafmt/Scalafmt.scala b/scalafmt-core/shared/src/main/scala/org/scalafmt/Scalafmt.scala index 03e6f36534..ab17cea27e 100644 --- a/scalafmt-core/shared/src/main/scala/org/scalafmt/Scalafmt.scala +++ b/scalafmt-core/shared/src/main/scala/org/scalafmt/Scalafmt.scala @@ -105,14 +105,16 @@ object Scalafmt { ): Try[String] = { val runner = style.runner val codeToInput: String => Input = toInput(_, file) - val parsed = runner.parse(Rewrite(codeToInput(code), style, codeToInput)) - parsed.fold( - _.details match { - case ed: ParseException => - val dialect = runner.dialectName - val msg = s"[dialect $dialect] ${ed.shortMessage}" - Failure(new ParseException(ed.pos, msg)) - case ed => Failure(ed) + val original = codeToInput(code) + val rewritten = Rewrite(original, style) + runner.parse(rewritten.fold(original)(codeToInput)).fold( + x => { + val err = x.details match { + case ParseException(pos, msg) => + ParseException(pos, s"[dialect ${runner.dialectName}] $msg") + case ed => ed + } + Failure(Error.WithCode(err, rewritten.getOrElse(code))) }, tree => { implicit val formatOps = new FormatOps(tree, style, file) diff --git a/scalafmt-core/shared/src/main/scala/org/scalafmt/rewrite/Rewrite.scala b/scalafmt-core/shared/src/main/scala/org/scalafmt/rewrite/Rewrite.scala index 0db6f2bddf..e608d19cb5 100644 --- a/scalafmt-core/shared/src/main/scala/org/scalafmt/rewrite/Rewrite.scala +++ b/scalafmt-core/shared/src/main/scala/org/scalafmt/rewrite/Rewrite.scala @@ -137,13 +137,9 @@ object Rewrite { val default: Seq[Rewrite] = name2rewrite.values.toSeq - def apply( - input: Input, - style: ScalafmtConfig, - toInput: String => Input, - ): Input = { + def apply(input: Input, style: ScalafmtConfig): Option[String] = { val rewrites = style.rewrite.rewriteFactoryRules - if (rewrites.isEmpty) input + if (rewrites.isEmpty) None else style.runner.parse(input) match { case Parsed.Success(ast) => val ctx = RewriteCtx(style, input, ast) @@ -155,8 +151,8 @@ object Rewrite { } } traverser(ast) - toInput(ctx.applyPatches) - case _ => input + Some(ctx.applyPatches) + case _ => None } } diff --git a/scalafmt-tests/shared/src/test/scala/org/scalafmt/FormatTests.scala b/scalafmt-tests/shared/src/test/scala/org/scalafmt/FormatTests.scala index ff96c1fd57..779ec0e9d8 100644 --- a/scalafmt-tests/shared/src/test/scala/org/scalafmt/FormatTests.scala +++ b/scalafmt-tests/shared/src/test/scala/org/scalafmt/FormatTests.scala @@ -52,7 +52,8 @@ class FormatTests extends FunSuite with CanRunTests with FormatAssertions { case Left(e) if err.nonEmpty && e.getMessage.contains(err) => t.expected case Left(e: Incomplete) => e.formattedCode case Left(e: SearchStateExploded) => logger.elem(e); e.partialOutput - case Left(e) => throw FormatException(e, t.original) + case Left(e: Error.WithCode) => throw e + case Left(e) => throw Error.WithCode(e, t.original) case Right(code) => code } def assertVisits( @@ -101,7 +102,13 @@ class FormatTests extends FunSuite with CanRunTests with FormatAssertions { "test does not parse: " + parseException2Message(e, obtained), t.expected, ) - case Left(e) => throw FormatException(e, obtained) + case Left(Error.WithCode(e: ParseException, code)) if !onlyManual => + assertEquals( + "test does not parse: " + parseException2Message(e, code), + t.expected, + ) + case Left(e: Error.WithCode) => throw e + case Left(e) => throw Error.WithCode(e, obtained) case Right(code) => if (onlyManual) { assertEquals(code, obtained, "Idempotency violated") diff --git a/scalafmt-tests/shared/src/test/scala/org/scalafmt/util/CanRunTests.scala b/scalafmt-tests/shared/src/test/scala/org/scalafmt/util/CanRunTests.scala index 24d5546b8d..6016c6bbba 100644 --- a/scalafmt-tests/shared/src/test/scala/org/scalafmt/util/CanRunTests.scala +++ b/scalafmt-tests/shared/src/test/scala/org/scalafmt/util/CanRunTests.scala @@ -1,5 +1,7 @@ package org.scalafmt.util +import org.scalafmt.Error + import scala.meta.parsers.ParseException import munit.FunSuite @@ -16,7 +18,7 @@ trait CanRunTests extends FunSuite with HasTests { else test(paddedName) { try run(t) catch { - case FormatException(e: ParseException, code) => + case Error.WithCode(e: ParseException, code) => fail("test does not parse\n" + parseException2Message(e, code), e) } } diff --git a/scalafmt-tests/shared/src/test/scala/org/scalafmt/util/FormatException.scala b/scalafmt-tests/shared/src/test/scala/org/scalafmt/util/FormatException.scala deleted file mode 100644 index e5692fa763..0000000000 --- a/scalafmt-tests/shared/src/test/scala/org/scalafmt/util/FormatException.scala +++ /dev/null @@ -1,3 +0,0 @@ -package org.scalafmt.util - -case class FormatException(exc: Throwable, code: String) extends Exception(exc)