Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error: add a wrapper Exception WithCode #4565

Merged
merged 1 commit into from
Nov 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package org.scalafmt.cli

import org.scalafmt.Error.MisformattedFile
import org.scalafmt.Error._
import org.scalafmt.dynamic.exceptions.ScalafmtException
import org.scalafmt.interfaces.PositionException
import org.scalafmt.interfaces.ScalafmtReporter
Expand All @@ -10,6 +10,7 @@ import java.io.PrintWriter
import java.nio.file.Path
import java.util.concurrent.atomic.AtomicReference

import scala.annotation.tailrec
import scala.util.control.NoStackTrace

class ScalafmtCliReporter(options: CliOptions) extends ScalafmtReporter {
Expand All @@ -22,7 +23,9 @@ class ScalafmtCliReporter(options: CliOptions) extends ScalafmtReporter {
options.common.err.println(s"$message: $file")
exitCode.getAndUpdate(ExitCode.merge(ExitCode.UnexpectedError, _))
}
override def error(file: Path, e: Throwable): Unit = e match {
@tailrec
override final def error(file: Path, e: Throwable): Unit = e match {
case WithCode(e, _) => error(file, e)
case _: PositionException if !options.ignoreWarnings =>
options.common.err.println(s"${e.toString}: $file")
exitCode.getAndUpdate(ExitCode.merge(ExitCode.ParseError, _))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import scala.meta.tokenizers.TokenizeException

import java.util.concurrent.atomic.AtomicReference

import scala.annotation.tailrec

import util.control.Breaks

object ScalafmtCoreRunner extends ScalafmtRunner {
Expand Down Expand Up @@ -72,19 +74,22 @@ object ScalafmtCoreRunner extends ScalafmtRunner {
): ExitCode = {
val input = inputMethod.readInput(options)
val filename = inputMethod.path.toString
val formatResult = Scalafmt
.formatCode(input, scalafmtConfig, options.range, filename)
formatResult.formatted match {
case Formatted.Success(formatted) => inputMethod
.write(formatted, input, options)
case _: Formatted.Failure if scalafmtConfig.runner.ignoreWarnings =>
ExitCode.Ok // do nothing
case Formatted.Failure(e @ (_: ParseException | _: TokenizeException)) =>
@tailrec
def handleError(e: Throwable): ExitCode = e match {
case Error.WithCode(e, _) => handleError(e)
case _: ParseException | _: TokenizeException =>
options.common.err.println(e.toString)
ExitCode.ParseError
case Formatted.Failure(e) =>
case e =>
new FailedToFormat(filename, e).printStackTrace(options.common.err)
ExitCode.UnexpectedError
}
Scalafmt.formatCode(input, scalafmtConfig, options.range, filename)
.formatted match {
case Formatted.Success(x) => inputMethod.write(x, input, options)
case x: Formatted.Failure =>
if (scalafmtConfig.runner.ignoreWarnings) ExitCode.Ok // do nothing
else handleError(x.e)
}
}
}
2 changes: 2 additions & 0 deletions scalafmt-core/shared/src/main/scala/org/scalafmt/Error.scala
Original file line number Diff line number Diff line change
Expand Up @@ -120,4 +120,6 @@ object Error {

case object MegaTestFailed extends Error("Mega test failed.")

case class WithCode(error: Throwable, code: String) extends Exception(error)

}
18 changes: 10 additions & 8 deletions scalafmt-core/shared/src/main/scala/org/scalafmt/Scalafmt.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -155,8 +151,8 @@ object Rewrite {
}
}
traverser(ast)
toInput(ctx.applyPatches)
case _ => input
Some(ctx.applyPatches)
case _ => None
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down Expand Up @@ -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")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package org.scalafmt.util

import org.scalafmt.Error

import scala.meta.parsers.ParseException

import munit.FunSuite
Expand All @@ -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)
}
}
Expand Down

This file was deleted.