diff --git a/README.md b/README.md index 792ed8a..dcda4c2 100644 --- a/README.md +++ b/README.md @@ -624,9 +624,8 @@ While maven central jar releases are created for each commit on master (a new ve cd /path/to/dotty git fetch -OLD=3.4.2 # set to version that was used before you bumped it -NEW=3.5.2-RC2 # set to version that you bumped it to -git checkout $NEW +OLD=3.5.2-RC2 # set to version that was used before you bumped it +NEW=3.6.4 # set to version that you bumped it to git diff $OLD..$NEW compiler/src/dotty/tools/repl ``` * check if any of those changes need to be reapplied to this repo diff --git a/build.sbt b/build.sbt index c33893e..66309fd 100644 --- a/build.sbt +++ b/build.sbt @@ -2,7 +2,7 @@ name := "scala-repl-pp-root" publish/skip := true ThisBuild / organization := "com.michaelpollmeier" -ThisBuild / scalaVersion := "3.5.2" +ThisBuild / scalaVersion := "3.6.4" lazy val ScalaTestVersion = "3.2.18" lazy val Slf4jVersion = "2.0.16" diff --git a/core/src/main/scala/replpp/DottyRandomStuff.scala b/core/src/main/scala/replpp/DottyRandomStuff.scala index 40c8f5b..001f974 100644 --- a/core/src/main/scala/replpp/DottyRandomStuff.scala +++ b/core/src/main/scala/replpp/DottyRandomStuff.scala @@ -13,7 +13,10 @@ private[replpp] object DottyRandomStuff { new StoreReporter(null) with UniqueMessagePositions with HideNonSensicalMessages } - /** copied from https://github.com/lampepfl/dotty/blob/3.3.0-RC5/compiler/src/dotty/tools/repl/ParseResult.scala#L130 */ + /** Based on https://github.com/scala/scala3/blob/3.6.4/compiler/src/dotty/tools/repl/ParseResult.scala#L135 + * change: removed [private] classifier so we can access it... + * alternatively we could use reflection... + */ object ParseResult { val commands: List[(String, String => ParseResult)] = List( Quit.command -> (_ => Quit), @@ -25,6 +28,7 @@ private[replpp] object DottyRandomStuff { TypeOf.command -> (arg => TypeOf(arg)), DocOf.command -> (arg => DocOf(arg)), Settings.command -> (arg => Settings(arg)), + Silent.command -> (_ => Silent), ) } } diff --git a/core/src/main/scala/replpp/DottyReplDriver.scala b/core/src/main/scala/replpp/DottyReplDriver.scala index 38a6f3b..61d07db 100644 --- a/core/src/main/scala/replpp/DottyReplDriver.scala +++ b/core/src/main/scala/replpp/DottyReplDriver.scala @@ -44,7 +44,7 @@ import scala.language.implicitConversions import scala.util.control.NonFatal import scala.util.Using -/** Based on https://github.com/lampepfl/dotty/blob/3.4.2/compiler/src/dotty/tools/repl/ReplDriver.scala +/** Based on https://github.com/lampepfl/dotty/blob/3.6.4/compiler/src/dotty/tools/repl/ReplDriver.scala * Main REPL instance, orchestrating input, compilation and presentation * */ class DottyReplDriver(settings: Array[String], @@ -66,8 +66,21 @@ class DottyReplDriver(settings: Array[String], setupRootCtx(this.settings ++ settings, rootCtx) } + private val incompatibleOptions: Seq[String] = Seq( + initCtx.settings.YbestEffort.name, + initCtx.settings.YwithBestEffortTasty.name + ) + private def setupRootCtx(settings: Array[String], rootCtx: Context): Context = { - setup(settings, rootCtx) match + val incompatible = settings.intersect(incompatibleOptions) + val filteredSettings = + if !incompatible.isEmpty then + inContext(rootCtx) { + out.println(i"Options incompatible with repl will be ignored: ${incompatible.mkString(", ")}") + } + settings.filter(!incompatible.contains(_)) + else settings + setup(filteredSettings, rootCtx) match case Some((files, ictx)) => inContext(ictx) { shouldStart = true if files.nonEmpty then out.println(i"Ignoring spurious arguments: $files%, %") @@ -81,7 +94,11 @@ class DottyReplDriver(settings: Array[String], /** the initial, empty state of the REPL session */ final def initialState: State = - State(0, 0, Map.empty, Set.empty, rootCtx) + val emptyState = State(0, 0, Map.empty, Set.empty, false, rootCtx) + val initScript = rootCtx.settings.replInitScript.value(using rootCtx) + initScript.trim() match + case "" => emptyState + case script => run(script)(using emptyState) /** Reset state of repl to the initial state * @@ -184,11 +201,6 @@ class DottyReplDriver(settings: Array[String], interpret(ParseResult.complete(input)) } - final def runQuietly(input: String)(using State): State = runBody { - val parsed = ParseResult(input) - interpret(parsed, quiet = true) - } - protected def runBody(body: => State): State = rendering.classLoader()(using rootCtx).asContext(withRedirectedOutput(body)) // TODO: i5069 @@ -256,10 +268,10 @@ class DottyReplDriver(settings: Array[String], .getOrElse(Nil) end completions - protected def interpret(res: ParseResult, quiet: Boolean = false)(using state: State): State = { + protected def interpret(res: ParseResult)(using state: State): State = { res match { case parsed: Parsed if parsed.trees.nonEmpty => - compile(parsed, state, quiet) + compile(parsed, state) case SyntaxErrors(_, errs, _) => displayErrors(errs) @@ -277,7 +289,7 @@ class DottyReplDriver(settings: Array[String], } /** Compile `parsed` trees and evolve `state` in accordance */ - private def compile(parsed: Parsed, istate: State, quiet: Boolean = false): State = { + private def compile(parsed: Parsed, istate: State): State = { def extractNewestWrapper(tree: untpd.Tree): Name = tree match { case PackageDef(_, (obj: untpd.ModuleDef) :: Nil) => obj.name.moduleClassName case _ => nme.NO_NAME @@ -328,11 +340,9 @@ class DottyReplDriver(settings: Array[String], given Ordering[Diagnostic] = Ordering[(Int, Int, Int)].on(d => (d.pos.line, -d.level, d.pos.column)) - if (!quiet) { - (definitions ++ warnings) - .sorted - .foreach(printDiagnostic) - } + (if istate.quiet then warnings else definitions ++ warnings) + .sorted + .foreach(printDiagnostic) updatedState } @@ -507,6 +517,8 @@ class DottyReplDriver(settings: Array[String], rootCtx = setupRootCtx(tokenize(arg).toArray, rootCtx) state.copy(context = rootCtx) + case Silent => state.copy(quiet = !state.quiet) + case Quit => // end of the world! // MP: slight variation from original DottyReplDriver to support exiting via the Quit command diff --git a/core/src/main/scala/replpp/InteractiveShell.scala b/core/src/main/scala/replpp/InteractiveShell.scala index c5069fb..a70cf67 100644 --- a/core/src/main/scala/replpp/InteractiveShell.scala +++ b/core/src/main/scala/replpp/InteractiveShell.scala @@ -23,19 +23,14 @@ object InteractiveShell { if (verbose) println(s"compiler arguments: ${compilerArgs.mkString(",")}") - var state: State = replDriver.initialState + var state: State = replDriver.initialState.copy(quiet = !verbose) var expectedStateObjectIndex = 0 Seq(DefaultRunBeforeLines, globalRunBeforeLines, config.runBefore).foreach { runBeforeLines => val runBeforeCode = runBeforeLines.mkString("\n").trim if (runBeforeCode.nonEmpty) { expectedStateObjectIndex += 1 - state = - if (verbose) { - println(s"executing runBeforeCode: $runBeforeCode") - replDriver.run(runBeforeCode)(using state) - } else { - replDriver.runQuietly(runBeforeCode)(using state) - } + if (verbose) println(s"executing runBeforeCode: $runBeforeCode") + state = replDriver.run(runBeforeCode)(using state) } } @@ -44,6 +39,7 @@ object InteractiveShell { s"compilation error(s) for predef code - see error above ^^^" ) + state = state.copy(quiet = false) replDriver.runUntilQuit(using state)() }