Skip to content

Commit a807b30

Browse files
committed
Implement showing of basic results
1 parent a43e3f5 commit a807b30

File tree

3 files changed

+54
-16
lines changed

3 files changed

+54
-16
lines changed

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

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
package dotty.tools
22
package repl
33

4+
import java.net.{URL, URLClassLoader}
5+
import java.lang.ClassLoader
6+
47
import scala.annotation.tailrec
58

69
import dotc.reporting.MessageRendering
@@ -15,13 +18,17 @@ import dotc.core.Types.{ ExprType, ConstantType }
1518
import dotc.config.CompilerCommand
1619
import dotc.{ Compiler, Driver }
1720
import dotc.printing.SyntaxHighlighting
21+
import dotc.repl.AbstractFileClassLoader // FIXME
1822

1923
import AmmoniteReader._
2024
import results._
2125

2226
case class State(objectIndex: Int, valIndex: Int, history: History)
2327

24-
class Repl(settings: Array[String]) extends Driver {
28+
class Repl(
29+
settings: Array[String],
30+
parentClassLoader: Option[ClassLoader] = None
31+
) extends Driver {
2532

2633
// FIXME: Change the Driver API to not require implementing this method
2734
override protected def newCompiler(implicit ctx: Context): Compiler =
@@ -35,6 +42,25 @@ class Repl(settings: Array[String]) extends Driver {
3542
ictx
3643
}
3744

45+
private[this] var _classLoader: ClassLoader = _
46+
def classLoader(implicit ctx: Context): ClassLoader = {
47+
if (_classLoader eq null) _classLoader = {
48+
/** the compiler's classpath, as URL's */
49+
val compilerClasspath: Seq[URL] = ctx.platform.classPath(ctx).asURLs
50+
51+
lazy val parent = new URLClassLoader(compilerClasspath.toArray,
52+
classOf[Repl].getClassLoader)
53+
54+
new AbstractFileClassLoader(compiler.virtualDirectory,
55+
parentClassLoader.getOrElse(parent))
56+
}
57+
58+
// Set the current Java "context" class loader to this interpreter's
59+
// class loader
60+
Thread.currentThread.setContextClassLoader(_classLoader)
61+
_classLoader
62+
}
63+
3864
protected[this] var myCtx = initializeCtx: Context
3965
protected[this] var compiler = new ReplCompiler(myCtx)
4066

@@ -94,8 +120,8 @@ class Repl(settings: Array[String]) extends Driver {
94120

95121
(
96122
defs.map(Rendering.renderMethod) ++
97-
vals.map(Rendering.renderVal)
98-
).foreach(println)
123+
vals.map(Rendering.renderVal(_, classLoader))
124+
).foreach(str => println(SyntaxHighlighting(str)))
99125
}
100126

101127
def displayTypeDef(tree: tpd.TypeDef) = {
@@ -108,8 +134,7 @@ class Repl(settings: Array[String]) extends Driver {
108134
else if (sym.is(Module)) "object"
109135
else "class"
110136

111-
112-
println(SyntaxHighlighting(s"defined $kind $name"))
137+
println(SyntaxHighlighting(s"// defined $kind $name"))
113138
}
114139

115140

@@ -138,6 +163,7 @@ class Repl(settings: Array[String]) extends Driver {
138163

139164
case Reset => {
140165
myCtx = initCtx.fresh
166+
_classLoader = null
141167
run()
142168
}
143169

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

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,13 @@ class ReplCompiler(ictx: Context) extends Compiler {
2323

2424
type NextRes = Int
2525

26+
/** Directory to save class files to */
27+
final val virtualDirectory =
28+
if (ictx.settings.d.isDefault(ictx))
29+
new VirtualDirectory("(memory)", None)
30+
else
31+
new PlainDirectory(new Directory(new JFile(ictx.settings.d.value(ictx))))
32+
2633
private class REPLFrontEnd extends FrontEnd {
2734
override def phaseName = "replFrontEnd"
2835

@@ -42,14 +49,6 @@ class ReplCompiler(ictx: Context) extends Compiler {
4249
/** A GenBCode phase that outputs to a virtual directory */
4350
private class REPLGenBCode extends GenBCode {
4451
override def phaseName = "replGenBCode"
45-
46-
/** Directory to save class files to */
47-
private val virtualDirectory =
48-
if (ictx.settings.d.isDefault(ictx))
49-
new VirtualDirectory("(memory)", None)
50-
else
51-
new PlainDirectory(new Directory(new JFile(ictx.settings.d.value(ictx))))
52-
5352
override def outputDir(implicit ctx: Context) = virtualDirectory
5453
}
5554

repl/src/dotty/tools/repl/render.scala

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,25 @@
11
package dotty.tools
22
package repl
33

4+
import scala.util.control.NonFatal
5+
46
import dotc.core.Types._
57
import dotc.core.Contexts.Context
68
import dotc.core.Denotations.Denotation
79
import dotc.core.Flags
10+
import dotc.core.Symbols.Symbol
811

912
object Rendering {
13+
/** Load the value of the symbol using reflection */
14+
private[this] def valueOf(sym: Symbol, classLoader: ClassLoader)(implicit ctx: Context): String = {
15+
val objectName = "$none$." + sym.owner.name.show
16+
val resObj: Class[_] = Class.forName(objectName, true, classLoader)
17+
val objInstance = resObj.newInstance()
18+
objInstance
19+
.getClass()
20+
.getDeclaredMethods.find(_.getName == sym.name.show).get
21+
.invoke(objInstance).toString
22+
}
1023

1124
def renderMethod(d: Denotation)(implicit ctx: Context): String = {
1225
def params(tpe: Type): String = tpe match {
@@ -31,13 +44,13 @@ object Rendering {
3144
s"def ${d.symbol.name.show}${params(d.info)}"
3245
}
3346

34-
def renderVal(d: Denotation)(implicit ctx: Context): String = {
47+
def renderVal(d: Denotation, classLoader: ClassLoader)(implicit ctx: Context): String = {
3548
val prefix = if (d.symbol.is(Flags.Mutable)) "var" else "val"
3649
val tpe = d.info match {
3750
case ConstantType(c) => c.value.toString
3851
case tpe => tpe.show
3952
}
40-
s"$prefix ${d.symbol.name.show}: $tpe"
53+
val res = valueOf(d.symbol, classLoader)
54+
s"$prefix ${d.symbol.name.show}: $tpe = $res"
4155
}
42-
4356
}

0 commit comments

Comments
 (0)