Skip to content

Commit

Permalink
REPL: Add back :silent command (#22248)
Browse files Browse the repository at this point in the history
  • Loading branch information
natsukagami authored Dec 20, 2024
1 parent 8a2961b commit 3e62731
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 14 deletions.
6 changes: 6 additions & 0 deletions compiler/src/dotty/tools/repl/ParseResult.scala
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,10 @@ object Reset {
val command: String = ":reset"
}

/** Toggle automatic printing of results */
case object Silent extends Command:
val command: String = ":silent"

/** `:quit` exits the repl */
case object Quit extends Command {
val command: String = ":quit"
Expand All @@ -113,6 +117,7 @@ case object Help extends Command {
|:imports show import history
|:reset [options] reset the repl to its initial state, forgetting all session entries
|:settings <options> update compiler options, if possible
|:silent disable/enable automatic printing of results
""".stripMargin
}

Expand All @@ -137,6 +142,7 @@ object ParseResult {
TypeOf.command -> (arg => TypeOf(arg)),
DocOf.command -> (arg => DocOf(arg)),
Settings.command -> (arg => Settings(arg)),
Silent.command -> (_ => Silent),
)

def apply(source: SourceFile)(using state: State): ParseResult = {
Expand Down
25 changes: 11 additions & 14 deletions compiler/src/dotty/tools/repl/ReplDriver.scala
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,14 @@ import scala.util.Using
* @param valIndex the index of next value binding for free expressions
* @param imports a map from object index to the list of user defined imports
* @param invalidObjectIndexes the set of object indexes that failed to initialize
* @param quiet whether we print evaluation results
* @param context the latest compiler context
*/
case class State(objectIndex: Int,
valIndex: Int,
imports: Map[Int, List[tpd.Import]],
invalidObjectIndexes: Set[Int],
quiet: Boolean,
context: Context):
def validObjectIndexes = (1 to objectIndex).filterNot(invalidObjectIndexes.contains(_))

Expand Down Expand Up @@ -114,7 +116,7 @@ class ReplDriver(settings: Array[String],
}

/** the initial, empty state of the REPL session */
final def initialState: State = State(0, 0, Map.empty, Set.empty, rootCtx)
final def initialState: State = State(0, 0, Map.empty, Set.empty, false, rootCtx)

/** Reset state of repl to the initial state
*
Expand Down Expand Up @@ -217,11 +219,6 @@ class ReplDriver(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
Expand Down Expand Up @@ -290,10 +287,10 @@ class ReplDriver(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)
Expand All @@ -311,7 +308,7 @@ class ReplDriver(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
Expand Down Expand Up @@ -362,11 +359,9 @@ class ReplDriver(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
}
Expand Down Expand Up @@ -542,6 +537,8 @@ class ReplDriver(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!
state
Expand Down
25 changes: 25 additions & 0 deletions compiler/test-resources/repl/silent
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
scala>:silent
scala> 1+1
scala> case class A(x: Int)
scala> A("string")
-- [E007] Type Mismatch Error: -------------------------------------------------
1 | A("string")
| ^^^^^^^^
| Found: ("string" : String)
| Required: Int
|
| longer explanation available when compiling with `-explain`
1 error found
scala> Option[Int](2) match { case Some(x) => x }
1 warning found
-- [E029] Pattern Match Exhaustivity Warning: ----------------------------------
1 | Option[Int](2) match { case Some(x) => x }
| ^^^^^^^^^^^^^^
| match may not be exhaustive.
|
| It would fail on pattern case: None
|
| longer explanation available when compiling with `-explain`
scala>:silent
scala> 1 + 2
val res2: Int = 3
1 change: 1 addition & 0 deletions compiler/test/dotty/tools/repl/TabcompleteTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,7 @@ class TabcompleteTests extends ReplTest {
":quit",
":reset",
":settings",
":silent",
":type"
),
tabComplete(":")
Expand Down

0 comments on commit 3e62731

Please sign in to comment.