Skip to content

Commit 3e62731

Browse files
authored
REPL: Add back :silent command (#22248)
1 parent 8a2961b commit 3e62731

File tree

4 files changed

+43
-14
lines changed

4 files changed

+43
-14
lines changed

compiler/src/dotty/tools/repl/ParseResult.scala

+6
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,10 @@ object Reset {
9393
val command: String = ":reset"
9494
}
9595

96+
/** Toggle automatic printing of results */
97+
case object Silent extends Command:
98+
val command: String = ":silent"
99+
96100
/** `:quit` exits the repl */
97101
case object Quit extends Command {
98102
val command: String = ":quit"
@@ -113,6 +117,7 @@ case object Help extends Command {
113117
|:imports show import history
114118
|:reset [options] reset the repl to its initial state, forgetting all session entries
115119
|:settings <options> update compiler options, if possible
120+
|:silent disable/enable automatic printing of results
116121
""".stripMargin
117122
}
118123

@@ -137,6 +142,7 @@ object ParseResult {
137142
TypeOf.command -> (arg => TypeOf(arg)),
138143
DocOf.command -> (arg => DocOf(arg)),
139144
Settings.command -> (arg => Settings(arg)),
145+
Silent.command -> (_ => Silent),
140146
)
141147

142148
def apply(source: SourceFile)(using state: State): ParseResult = {

compiler/src/dotty/tools/repl/ReplDriver.scala

+11-14
Original file line numberDiff line numberDiff line change
@@ -60,12 +60,14 @@ import scala.util.Using
6060
* @param valIndex the index of next value binding for free expressions
6161
* @param imports a map from object index to the list of user defined imports
6262
* @param invalidObjectIndexes the set of object indexes that failed to initialize
63+
* @param quiet whether we print evaluation results
6364
* @param context the latest compiler context
6465
*/
6566
case class State(objectIndex: Int,
6667
valIndex: Int,
6768
imports: Map[Int, List[tpd.Import]],
6869
invalidObjectIndexes: Set[Int],
70+
quiet: Boolean,
6971
context: Context):
7072
def validObjectIndexes = (1 to objectIndex).filterNot(invalidObjectIndexes.contains(_))
7173

@@ -114,7 +116,7 @@ class ReplDriver(settings: Array[String],
114116
}
115117

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

119121
/** Reset state of repl to the initial state
120122
*
@@ -217,11 +219,6 @@ class ReplDriver(settings: Array[String],
217219
interpret(ParseResult.complete(input))
218220
}
219221

220-
final def runQuietly(input: String)(using State): State = runBody {
221-
val parsed = ParseResult(input)
222-
interpret(parsed, quiet = true)
223-
}
224-
225222
protected def runBody(body: => State): State = rendering.classLoader()(using rootCtx).asContext(withRedirectedOutput(body))
226223

227224
// TODO: i5069
@@ -290,10 +287,10 @@ class ReplDriver(settings: Array[String],
290287
.getOrElse(Nil)
291288
end completions
292289

293-
protected def interpret(res: ParseResult, quiet: Boolean = false)(using state: State): State = {
290+
protected def interpret(res: ParseResult)(using state: State): State = {
294291
res match {
295292
case parsed: Parsed if parsed.trees.nonEmpty =>
296-
compile(parsed, state, quiet)
293+
compile(parsed, state)
297294

298295
case SyntaxErrors(_, errs, _) =>
299296
displayErrors(errs)
@@ -311,7 +308,7 @@ class ReplDriver(settings: Array[String],
311308
}
312309

313310
/** Compile `parsed` trees and evolve `state` in accordance */
314-
private def compile(parsed: Parsed, istate: State, quiet: Boolean = false): State = {
311+
private def compile(parsed: Parsed, istate: State): State = {
315312
def extractNewestWrapper(tree: untpd.Tree): Name = tree match {
316313
case PackageDef(_, (obj: untpd.ModuleDef) :: Nil) => obj.name.moduleClassName
317314
case _ => nme.NO_NAME
@@ -362,11 +359,9 @@ class ReplDriver(settings: Array[String],
362359
given Ordering[Diagnostic] =
363360
Ordering[(Int, Int, Int)].on(d => (d.pos.line, -d.level, d.pos.column))
364361

365-
if (!quiet) {
366-
(definitions ++ warnings)
367-
.sorted
368-
.foreach(printDiagnostic)
369-
}
362+
(if istate.quiet then warnings else definitions ++ warnings)
363+
.sorted
364+
.foreach(printDiagnostic)
370365

371366
updatedState
372367
}
@@ -542,6 +537,8 @@ class ReplDriver(settings: Array[String],
542537
rootCtx = setupRootCtx(tokenize(arg).toArray, rootCtx)
543538
state.copy(context = rootCtx)
544539

540+
case Silent => state.copy(quiet = !state.quiet)
541+
545542
case Quit =>
546543
// end of the world!
547544
state

compiler/test-resources/repl/silent

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
scala>:silent
2+
scala> 1+1
3+
scala> case class A(x: Int)
4+
scala> A("string")
5+
-- [E007] Type Mismatch Error: -------------------------------------------------
6+
1 | A("string")
7+
| ^^^^^^^^
8+
| Found: ("string" : String)
9+
| Required: Int
10+
|
11+
| longer explanation available when compiling with `-explain`
12+
1 error found
13+
scala> Option[Int](2) match { case Some(x) => x }
14+
1 warning found
15+
-- [E029] Pattern Match Exhaustivity Warning: ----------------------------------
16+
1 | Option[Int](2) match { case Some(x) => x }
17+
| ^^^^^^^^^^^^^^
18+
| match may not be exhaustive.
19+
|
20+
| It would fail on pattern case: None
21+
|
22+
| longer explanation available when compiling with `-explain`
23+
scala>:silent
24+
scala> 1 + 2
25+
val res2: Int = 3

compiler/test/dotty/tools/repl/TabcompleteTests.scala

+1
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,7 @@ class TabcompleteTests extends ReplTest {
217217
":quit",
218218
":reset",
219219
":settings",
220+
":silent",
220221
":type"
221222
),
222223
tabComplete(":")

0 commit comments

Comments
 (0)