Skip to content

Commit a0f48c9

Browse files
committed
Simplify compiler run creation in REPL
1 parent e8d9bd4 commit a0f48c9

File tree

4 files changed

+30
-42
lines changed

4 files changed

+30
-42
lines changed

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

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -119,17 +119,17 @@ object ParseResult {
119119
case TypeOf.command => TypeOf(arg)
120120
case _ => UnknownCommand(cmd)
121121
}
122-
case _ => {
123-
val stats = parseStats(sourceCode)
122+
case _ =>
123+
val reporter = newStoreReporter
124+
val stats = parseStats(sourceCode)(ctx.fresh.setReporter(reporter))
124125

125-
if (ctx.reporter.hasErrors) {
126-
SyntaxErrors(sourceCode,
127-
ctx.flushBufferedMessages(),
128-
stats)
129-
}
126+
if (reporter.hasErrors)
127+
SyntaxErrors(
128+
sourceCode,
129+
reporter.removeBufferedMessages,
130+
stats)
130131
else
131132
Parsed(sourceCode, stats)
132-
}
133133
}
134134

135135
/** Check if the input is incomplete

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

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ class ReplCompiler(val directory: AbstractFile) extends Compiler {
4242

4343
def newRun(initCtx: Context, objectIndex: Int) = new Run(this, initCtx) {
4444
override protected[this] def rootContext(implicit ctx: Context) =
45-
addMagicImports(super.rootContext.fresh.setReporter(newStoreReporter))
45+
addMagicImports(super.rootContext)
4646

4747
private def addMagicImports(initCtx: Context): Context = {
4848
def addImport(path: TermName)(implicit ctx: Context) = {
@@ -145,13 +145,13 @@ class ReplCompiler(val directory: AbstractFile) extends Compiler {
145145
else run.runContext.flushBufferedMessages().errors
146146
}
147147

148-
def compile(parsed: Parsed)(implicit state: State): Result[(CompilationUnit, State)] = {
148+
final def compile(parsed: Parsed)(implicit state: State): Result[(CompilationUnit, State)] = {
149149
val defs = definitions(parsed.trees, state)
150150
val unit = createUnit(defs, parsed.sourceCode)
151151
runCompilationUnit(unit, defs.state)
152152
}
153153

154-
def typeOf(expr: String)(implicit state: State): Result[String] =
154+
final def typeOf(expr: String)(implicit state: State): Result[String] =
155155
typeCheck(expr).map { tree =>
156156
import dotc.ast.Trees._
157157
implicit val ctx = state.run.runContext
@@ -165,7 +165,7 @@ class ReplCompiler(val directory: AbstractFile) extends Compiler {
165165
}
166166
}
167167

168-
def typeCheck(expr: String, errorsAllowed: Boolean = false)(implicit state: State): Result[tpd.ValDef] = {
168+
final def typeCheck(expr: String, errorsAllowed: Boolean = false)(implicit state: State): Result[tpd.ValDef] = {
169169

170170
def wrapped(expr: String, sourceFile: SourceFile, state: State)(implicit ctx: Context): Result[untpd.PackageDef] = {
171171
def wrap(trees: Seq[untpd.Tree]): untpd.PackageDef = {
@@ -219,16 +219,17 @@ class ReplCompiler(val directory: AbstractFile) extends Compiler {
219219

220220

221221
val run = state.run
222-
val reporter = state.run.runContext.reporter
222+
val reporter = newStoreReporter
223223
val src = new SourceFile(s"EvaluateExpr", expr)
224224
val runCtx =
225225
run.runContext.fresh
226+
.setReporter(reporter)
226227
.setSetting(run.runContext.settings.YstopAfter, List("frontend"))
227228

228229
wrapped(expr, src, state)(runCtx).flatMap { pkg =>
229230
val unit = new CompilationUnit(src)
230231
unit.untpdTree = pkg
231-
run.compileUnits(unit :: Nil, runCtx.fresh.setReporter(newStoreReporter))
232+
run.compileUnits(unit :: Nil, runCtx)
232233

233234
if (errorsAllowed || !reporter.hasErrors)
234235
unwrapped(unit.tpdTree, src)(runCtx)

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

Lines changed: 14 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,7 @@ import scala.collection.JavaConverters._
5151
case class State(objectIndex: Int,
5252
valIndex: Int,
5353
imports: List[untpd.Import],
54-
run: Run) {
55-
56-
def newRun(comp: ReplCompiler, rootCtx: Context): State =
57-
copy(run = comp.newRun(rootCtx, objectIndex))
58-
}
54+
run: Run)
5955

6056
/** Main REPL instance, orchestrating input, compilation and presentation */
6157
class ReplDriver(settings: Array[String],
@@ -101,7 +97,7 @@ class ReplDriver(settings: Array[String],
10197

10298
protected[this] var rootCtx: Context = _
10399
protected[this] var compiler: ReplCompiler = _
104-
protected[this] var rendering: Rendering = _
100+
private[this] var rendering: Rendering = _
105101

106102
// initialize the REPL session as part of the constructor so that once `run`
107103
// is called, we're in business
@@ -135,14 +131,8 @@ class ReplDriver(settings: Array[String],
135131

136132
@tailrec def loop(state: State): State = {
137133
val res = readLine(state)
138-
139134
if (res == Quit) state
140-
else {
141-
// readLine potentially destroys the run, so a new one is needed for the
142-
// rest of the interpretation:
143-
val freshState = state.newRun(compiler, rootCtx)
144-
loop(interpret(res)(freshState))
145-
}
135+
else loop(interpret(res)(state))
146136
}
147137

148138
try withRedirectedOutput { loop(initState) }
@@ -151,12 +141,16 @@ class ReplDriver(settings: Array[String],
151141

152142
final def run(input: String)(implicit state: State): State = withRedirectedOutput {
153143
val parsed = ParseResult(input)(state.run.runContext)
154-
interpret(parsed)(state.newRun(compiler, rootCtx))
144+
interpret(parsed)
155145
}
156146

157147
private def withRedirectedOutput(op: => State): State =
158148
Console.withOut(out) { Console.withErr(out) { op } }
159149

150+
private def newRun(state: State) = {
151+
val newRun = compiler.newRun(rootCtx.fresh.setReporter(newStoreReporter), state.objectIndex)
152+
state.copy(run = newRun)
153+
}
160154

161155
/** Extract possible completions at the index of `cursor` in `expr` */
162156
protected[this] final def completions(cursor: Int, expr: String, state0: State): List[Candidate] = {
@@ -172,7 +166,7 @@ class ReplDriver(settings: Array[String],
172166
/* complete = */ false // if true adds space when completing
173167
)
174168
}
175-
implicit val state = state0.newRun(compiler, rootCtx)
169+
implicit val state = newRun(state0)
176170
compiler
177171
.typeCheck(expr, errorsAllowed = true)
178172
.map { tree =>
@@ -193,7 +187,7 @@ class ReplDriver(settings: Array[String],
193187
private def interpret(res: ParseResult)(implicit state: State): State = {
194188
val newState = res match {
195189
case parsed: Parsed if parsed.trees.nonEmpty =>
196-
compile(parsed).newRun(compiler, rootCtx)
190+
compile(parsed, state)
197191

198192
case SyntaxErrors(src, errs, _) =>
199193
displayErrors(errs)
@@ -213,12 +207,13 @@ class ReplDriver(settings: Array[String],
213207
}
214208

215209
/** Compile `parsed` trees and evolve `state` in accordance */
216-
protected[this] final def compile(parsed: Parsed)(implicit state: State): State = {
210+
private def compile(parsed: Parsed, istate: State): State = {
217211
def extractNewestWrapper(tree: untpd.Tree): Name = tree match {
218212
case PackageDef(_, (obj: untpd.ModuleDef) :: Nil) => obj.name.moduleClassName
219213
case _ => nme.NO_NAME
220214
}
221215

216+
implicit val state = newRun(istate)
222217
compiler
223218
.compile(parsed)
224219
.fold(
@@ -331,22 +326,15 @@ class ReplDriver(settings: Array[String],
331326
val file = new java.io.File(path)
332327
if (file.exists) {
333328
val contents = scala.io.Source.fromFile(file).mkString
334-
ParseResult(contents)(state.run.runContext) match {
335-
case parsed: Parsed =>
336-
compile(parsed)
337-
case SyntaxErrors(_, errors, _) =>
338-
displayErrors(errors)
339-
case _ =>
340-
state
341-
}
329+
run(contents)
342330
}
343331
else {
344332
out.println(s"""Couldn't find file "${file.getCanonicalPath}"""")
345333
state
346334
}
347335

348336
case TypeOf(expr) =>
349-
compiler.typeOf(expr).fold(
337+
compiler.typeOf(expr)(newRun(state)).fold(
350338
displayErrors,
351339
res => out.println(SyntaxHighlighting(res))
352340
)

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ class ReplTest private (out: ByteArrayOutputStream) extends ReplDriver(
3636
op(initState)
3737

3838
implicit class TestingState(state: State) {
39-
def andThen[A](op: State => A): A =
40-
op(state.newRun(compiler, rootCtx))
39+
def andThen[A](op: State => A): A = op(state)
4140
}
4241
}

0 commit comments

Comments
 (0)