Skip to content

Commit 905ada0

Browse files
committed
Clean up compilation logic, make union decorator work
1 parent 0a3532d commit 905ada0

File tree

5 files changed

+113
-20
lines changed

5 files changed

+113
-20
lines changed
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package dotty.tools
2+
package repl
3+
4+
import dotc.core.Contexts.Context
5+
import dotc.ast.tpd._
6+
7+
import results._
8+
9+
case class InjectableTree(obj: TypeDef, nextId: Int)
10+
11+
object InjectableTree {
12+
def apply()(implicit ctx: Context) = new InjectableTree({
13+
???
14+
}, 0)
15+
16+
def patch(tree: InjectableTree, res: TypedTrees)
17+
(implicit ctx: Context): Result[InjectableTree] =
18+
???
19+
}

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

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import dotc.config.CompilerCommand
1111
import dotc.{ Compiler, Driver }
1212

1313
import AmmoniteReader._
14+
import results._
1415

1516
class Repl(settings: Array[String]) extends Driver {
1617

@@ -26,21 +27,23 @@ class Repl(settings: Array[String]) extends Driver {
2627
ictx
2728
}
2829

29-
private[this] var myCtx = initializeCtx
30-
private[this] var typer = new ReplTyper(myCtx)
30+
private[this] var myCtx = initializeCtx
31+
private[this] var typer = new ReplTyper(myCtx)
32+
private[this] var compiler = new ReplCompiler(myCtx)
3133

3234
private def readLine(history: History) =
3335
AmmoniteReader(history)(myCtx).prompt()
3436

3537
@tailrec
36-
final def run(history: History = Nil): Unit =
38+
final def run(history: History = Nil,
39+
tree: InjectableTree = InjectableTree()(myCtx)): Unit =
3740
readLine(history) match {
3841
case (parsed: Parsed, history) =>
39-
compile(parsed, history.length)
40-
run(history)
42+
val newTree = compile(parsed, tree)(myCtx)
43+
run(history, newTree)
4144

4245
case (SyntaxErrors(errs, ctx), history) =>
43-
displaySyntaxErrors(errs)(ctx)
46+
displayErrors(errs)(ctx)
4447
run(history)
4548

4649
case (Newline, history) =>
@@ -50,8 +53,22 @@ class Repl(settings: Array[String]) extends Driver {
5053
interpretCommand(cmd, history)
5154
}
5255

53-
def compile(parsed: Parsed, line: Int): Unit =
54-
typer.typeCheck(parsed, line)(myCtx)
56+
def compile(parsed: Parsed, tree: InjectableTree)(implicit ctx: Context): InjectableTree = {
57+
val res = for {
58+
typed <- typer.typeCheck(parsed, tree.nextId)
59+
injected <- InjectableTree.patch(tree, typed)
60+
_ <- compiler.compile(injected.obj)
61+
} yield injected
62+
63+
// Fold over result, on failure - report errors and return old `tree`:
64+
res.fold(
65+
errors => {
66+
displayErrors(errors.msgs)
67+
tree
68+
},
69+
id
70+
)
71+
}
5572

5673
def interpretCommand(cmd: Command, history: History): Unit = cmd match {
5774
case UnknownCommand(cmd) => {
@@ -87,6 +104,6 @@ class Repl(settings: Array[String]) extends Driver {
87104
private def renderMessage(cont: MessageContainer): Context => String =
88105
messageRenderer.messageAndPos(cont.contained(), cont.pos, messageRenderer.diagnosticLevel(cont))
89106

90-
def displaySyntaxErrors(errs: Seq[MessageContainer])(implicit ctx: Context): Unit =
107+
def displayErrors(errs: Seq[MessageContainer])(implicit ctx: Context): Unit =
91108
errs.map(renderMessage(_)(ctx)).foreach(println)
92109
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package dotty.tools
2+
package repl
3+
4+
import dotc.ast.tpd
5+
import dotc.core.{ Phases, Decorators, Flags }
6+
import dotc.core.Contexts.Context
7+
import dotc.{ CompilationUnit, Compiler }
8+
import backend.jvm.GenBCode
9+
import io._
10+
import results._
11+
12+
class ReplCompiler(ictx: Context) extends Compiler {
13+
/** A GenBCode phase that outputs to a virtual directory */
14+
private class REPLGenBCode extends GenBCode {
15+
override def phaseName = "replGenBCode"
16+
17+
/** Directory to save class files to */
18+
private val virtualDirectory =
19+
if (ictx.settings.d.isDefault(ictx))
20+
new VirtualDirectory("(memory)", None)
21+
else
22+
new PlainDirectory(new Directory(new JFile(ictx.settings.d.value(ictx))))
23+
24+
override def outputDir(implicit ctx: Context) = virtualDirectory
25+
}
26+
27+
/** Phases without `FrontEnd`, and a modified `GenBCode` */
28+
override def phases = Phases.replace(
29+
classOf[GenBCode],
30+
_ => new REPLGenBCode :: Nil,
31+
super.phases.tail
32+
)
33+
34+
def compile(tree: tpd.Tree)(implicit ctx: Context): Result[Unit] = ()
35+
}

repl/src/dotty/tools/repl/ReplTyper.scala

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,16 @@ import dotc.core.{ Phases, Decorators, Flags }
1010
import Decorators._, Flags._
1111
import dotc.util.SourceFile
1212
import dotc.typer.FrontEnd
13-
import backend.jvm.GenBCode
1413
import dotc.core.Contexts.Context
1514
import dotc.util.Positions._
1615
import dotc.reporting.diagnostic.MessageContainer
1716
import dotc.reporting._
1817
import io._
1918

19+
import results._
20+
21+
case class TypedTrees(nextId: Int, trees: Seq[tpd.Tree])
22+
2023
class ReplTyper(ictx: Context) extends Compiler {
2124

2225
type NextRes = Int
@@ -70,11 +73,7 @@ class ReplTyper(ictx: Context) extends Compiler {
7073
case _ => Nil
7174
}
7275

73-
sealed trait Result
74-
case class TypedTrees(trees: Seq[tpd.Tree]) extends Result
75-
case class TypeErrors(msgs: Seq[MessageContainer]) extends Result
76-
77-
def typeCheck(parsed: Parsed, currentRes: Int)(implicit ctx: Context): (NextRes, Result) = {
76+
def typeCheck(parsed: Parsed, currentRes: Int)(implicit ctx: Context): Result[TypedTrees] = {
7877
val reporter = new StoreReporter(null) with UniqueMessagePositions with HideNonSensicalMessages
7978

8079
val unit = new CompilationUnit(new SourceFile(s"repl-run-$currentRes", parsed.sourceCode))
@@ -85,10 +84,7 @@ class ReplTyper(ictx: Context) extends Compiler {
8584
run.compileUnits(unit :: Nil)
8685

8786
val errs = reporter.removeBufferedMessages
88-
val res =
89-
if (errs.isEmpty) TypedTrees(extractStats(unit.tpdTree))
90-
else TypeErrors(errs)
91-
92-
(newRes, res)
87+
if (errs.isEmpty) TypedTrees(newRes, extractStats(unit.tpdTree))
88+
else Errors(errs)
9389
}
9490
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package dotty.tools
2+
package repl
3+
4+
import dotc.reporting.diagnostic.MessageContainer
5+
6+
object results {
7+
type Result[A] = Errors | A
8+
9+
case class Errors(msgs: Seq[MessageContainer])
10+
11+
implicit class RichResult[A](val res: Result[A]) /*extends AnyVal */{
12+
def map[B](f: A => B): Result[B] = res match {
13+
case errs: Errors => errs
14+
case a: A => f(a)
15+
}
16+
17+
def flatMap[B](f: A => Result[B]): Result[B] = map(f)
18+
19+
def fold[B](left: Errors => B, right: A => B): B = res match {
20+
case errors: Errors => left(errors)
21+
case a: A => right(a)
22+
}
23+
}
24+
25+
def id[A](a: A): a.type = a
26+
}

0 commit comments

Comments
 (0)