Skip to content

Commit 3520967

Browse files
committed
Modularize compilation steps
1 parent 1b129cd commit 3520967

File tree

4 files changed

+73
-18
lines changed

4 files changed

+73
-18
lines changed

repl/src/dotty/tools/repl/Repl.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import dotc.{ Compiler, Driver }
1313
import AmmoniteReader._
1414
import results._
1515

16-
case class State(objects: Int, freeValues: Int, history: History, ictx: Context)
16+
case class State(objectIndex: Int, valIndex: Int, history: History, ictx: Context)
1717
object State {
1818
def initial(ctx: Context): State = new State(0, 0, Nil, ctx)
1919
}

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

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -67,20 +67,20 @@ class ReplCompiler(ictx: Context) extends Compiler {
6767
)
6868
}
6969

70-
def freeToAssigned(trees: Seq[untpd.Tree], state: State)
71-
(implicit ctx: Context): (State, Seq[untpd.Tree]) = {
70+
def freeToAssigned(trees: Seq[untpd.Tree], state: State): (State, Seq[untpd.Tree]) = {
7271
import untpd._
72+
implicit val ctx = state.ictx
7373

7474
def freeExpression(t: Tree) =
7575
t.isTerm && !t.isInstanceOf[Assign]
7676

7777
val (exps, other) = trees.partition(freeExpression)
7878
val resX = exps.zipWithIndex.map { (exp, i) =>
79-
ValDef(s"res${i + state.freeValues}".toTermName, TypeTree(), exp)
79+
ValDef(s"res${i + state.valIndex}".toTermName, TypeTree(), exp)
8080
.withPos(exp.pos)
8181
}
8282

83-
(state.copy(freeValues = state.freeValues + resX.length), resX ++ other)
83+
(state.copy(valIndex = state.valIndex + resX.length), resX ++ other)
8484
}
8585

8686
def wrapped(trees: Seq[untpd.Tree], nextId: Int)(implicit ctx: Context): untpd.PackageDef = {
@@ -93,28 +93,39 @@ class ReplCompiler(ictx: Context) extends Compiler {
9393

9494
val tmpl = Template(emptyConstructor, Nil, EmptyValDef, imports ++ trees)
9595
PackageDef(Ident(nme.NO_NAME),
96-
ModuleDef(("ReplSession$" + nextId).toTermName, tmpl)
96+
ModuleDef(s"ReplSession$$$nextId".toTermName, tmpl)
9797
.withMods(new Modifiers(Module | Final))
9898
.withPos(Position(trees.head.pos.start, trees.last.pos.end)) :: Nil
9999
)
100100
}
101101

102-
def compile(parsed: Parsed, state: State)(implicit ctx: Context): Result[State] = {
103-
val reporter = new StoreReporter(null) with UniqueMessagePositions with HideNonSensicalMessages
104-
105-
val unit = new CompilationUnit(new SourceFile("ReplSession$" + (state.objects + 1), parsed.sourceCode))
106-
val (stateAfterAssign, trees) = freeToAssigned(parsed.trees, state)
107-
unit.untpdTree = wrapped(trees, 0)
102+
def createUnit(trees: Seq[untpd.Tree], objectIndex: Int, sourceCode: String)(implicit ctx: Context): Result[CompilationUnit] = {
103+
val unit = new CompilationUnit(new SourceFile(s"ReplsSession$$$objectIndex", sourceCode))
104+
unit.untpdTree = wrapped(trees, objectIndex)
105+
unit
106+
}
108107

108+
def runCompilation(unit: CompilationUnit, state: State): Result[State] = {
109+
implicit val ctx = state.ictx
110+
val reporter = new StoreReporter(null) with UniqueMessagePositions with HideNonSensicalMessages
109111
val run = newRun(ctx.fresh.setReporter(reporter))
110112
run.compileUnits(unit :: Nil)
111113

112114
val errs = reporter.removeBufferedMessages
113115
if (errs.isEmpty) state.copy(
114-
freeValues = stateAfterAssign.freeValues,
115-
objects = state.objects + 1,
116-
ictx = run.runContext
116+
objectIndex = state.objectIndex + 1,
117+
valIndex = state.valIndex,
118+
ictx = run.runContext
117119
)
118120
else Errors(errs)
119121
}
122+
123+
def compile(parsed: Parsed, state: State): Result[State] = {
124+
implicit val ctx = state.ictx
125+
for {
126+
stateAndTrees <- freeToAssigned(parsed.trees, state)
127+
unit <- createUnit(stateAndTrees._2, state.objectIndex, parsed.sourceCode)
128+
state <- runCompilation(unit, stateAndTrees._1)
129+
} yield state
130+
}
120131
}

repl/test/dotty/tools/repl/CompilerTests.scala

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,55 @@ package repl
44
import org.junit.Assert._
55
import org.junit.Test
66

7+
import dotc.ast.untpd
8+
9+
import results._
10+
711
class ReplCompilerTests extends ReplTest {
8-
@Test def typeCheck = {
12+
@Test def compileSingle = {
913
val parsed @ Parsed(_,_) = ParseResult("def foo: 1 = 1")(myCtx)
10-
val compiler = new ReplCompiler(myCtx)
11-
val res = compiler.compile(parsed, State.initial(myCtx))(myCtx)
14+
val res = compiler.compile(parsed, State.initial(myCtx))
1215
assert(res.isInstanceOf[State],
1316
s"Assumed value of `typeCheck` would be TypedTrees - but got: $res")
1417
}
18+
19+
@Test def compileTwo = {
20+
val parsed @ Parsed(_,_) = ParseResult("def foo: 1 = 1")(myCtx)
21+
22+
compiler
23+
.compile(parsed, State.initial(myCtx))
24+
.flatMap { state =>
25+
val parsed @ Parsed(_,_) = ParseResult("def foo(i: Int): i.type = i")(state.ictx)
26+
compiler.compile(parsed, state.copy(ictx = myCtx))
27+
}
28+
.fold(
29+
error =>
30+
fail(s"Expected no errors, got: \n${ error.msgs.map(_.message).mkString("\n") }"),
31+
state =>
32+
assert(state.objectIndex == 2,
33+
s"Wrong object offset: expected 2 got ${state.objectIndex}")
34+
)
35+
}
36+
37+
@Test def inspectSingle = {
38+
val parsed @ Parsed(_,_) = ParseResult("def foo: 1 = 1")(myCtx)
39+
val res = for {
40+
stateAndTrees <- compiler.freeToAssigned(parsed.trees, State.initial(myCtx))
41+
(State(objectIndex, _, _, ictx), trees) = stateAndTrees
42+
unit <- compiler.createUnit(trees, objectIndex, parsed.sourceCode)(myCtx)
43+
} yield (unit.untpdTree, ictx)
44+
45+
res.fold(
46+
error => fail(s"received errors: ${error.msgs}"),
47+
(tree, ictx) => {
48+
implicit val ctx = ictx
49+
50+
tree match {
51+
case untpd.PackageDef(_, List(mod: untpd.ModuleDef)) =>
52+
assert(mod.name.show == "ReplSession$0", mod.name.show)
53+
case _ => fail(s"Unexpected structure: $tree")
54+
}
55+
}
56+
)
57+
}
1558
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ class ReplTest extends Repl(Array(
1313
/** Make sure the context is new before each test */
1414
@Before def init = {
1515
myCtx = initializeCtx
16+
compiler = new ReplCompiler(myCtx)
1617
}
1718
}
1819

0 commit comments

Comments
 (0)