@@ -36,23 +36,56 @@ class InteractiveDriver(val settings: List[String]) extends Driver {
3636 }
3737
3838 private [this ] var myCtx : Context = myInitCtx
39-
4039 def currentCtx : Context = myCtx
4140
41+ private val compiler : Compiler = new InteractiveCompiler
42+
4243 private val myOpenedFiles = new mutable.LinkedHashMap [URI , SourceFile ] {
4344 override def default (key : URI ) = NoSource
4445 }
46+ def openedFiles : Map [URI , SourceFile ] = myOpenedFiles
4547
4648 private val myOpenedTrees = new mutable.LinkedHashMap [URI , List [SourceTree ]] {
4749 override def default (key : URI ) = Nil
4850 }
51+ def openedTrees : Map [URI , List [SourceTree ]] = myOpenedTrees
4952
5053 private val myCompilationUnits = new mutable.LinkedHashMap [URI , CompilationUnit ]
51-
52- def openedFiles : Map [URI , SourceFile ] = myOpenedFiles
53- def openedTrees : Map [URI , List [SourceTree ]] = myOpenedTrees
5454 def compilationUnits : Map [URI , CompilationUnit ] = myCompilationUnits
5555
56+ // Presence of a file with one of these suffixes indicates that the
57+ // corresponding class has been pickled with TASTY.
58+ private val tastySuffixes = List (" .hasTasty" , " .tasty" )
59+
60+ // FIXME: All the code doing classpath handling is very fragile and ugly,
61+ // improving this requires changing the dotty classpath APIs to handle our usecases.
62+ // We also need something like sbt server-mode to be informed of changes on
63+ // the classpath.
64+
65+ private val (zipClassPaths, dirClassPaths) = currentCtx.platform.classPath(currentCtx) match {
66+ case AggregateClassPath (cps) =>
67+ // FIXME: We shouldn't assume that ClassPath doesn't have other
68+ // subclasses. For now, the only other subclass is JrtClassPath on Java
69+ // 9+, we can safely ignore it for now because it's only used for the
70+ // standard Java library, but this will change once we start supporting
71+ // adding entries to the modulepath.
72+ val zipCps = cps.collect { case cp : ZipArchiveFileLookup [_] => cp }
73+ val dirCps = cps.collect { case cp : JFileDirectoryLookup [_] => cp }
74+ (zipCps, dirCps)
75+ case _ =>
76+ (Seq (), Seq ())
77+ }
78+
79+ // Like in `ZipArchiveFileLookup` we assume that zips are immutable
80+ private val zipClassPathClasses : Seq [String ] = {
81+ val names = new mutable.ListBuffer [String ]
82+ zipClassPaths.foreach { zipCp =>
83+ val zipFile = new ZipFile (zipCp.zipFile)
84+ classesFromZip(zipFile, names)
85+ }
86+ names
87+ }
88+
5689 /**
5790 * The trees for all the source files in this project.
5891 *
@@ -109,6 +142,45 @@ class InteractiveDriver(val settings: List[String]) extends Driver {
109142 (fromSource ++ fromClassPath).distinct
110143 }
111144
145+ def run (uri : URI , sourceCode : String ): List [MessageContainer ] = run(uri, toSource(uri, sourceCode))
146+
147+ def run (uri : URI , source : SourceFile ): List [MessageContainer ] = {
148+ val previousCtx = myCtx
149+ try {
150+ val reporter =
151+ new StoreReporter (null ) with UniqueMessagePositions with HideNonSensicalMessages
152+
153+ val run = compiler.newRun(myInitCtx.fresh.setReporter(reporter))
154+ myCtx = run.runContext
155+
156+ implicit val ctx = myCtx
157+
158+ myOpenedFiles(uri) = source
159+
160+ run.compileSources(List (source))
161+ run.printSummary()
162+ val unit = ctx.run.units.head
163+ val t = unit.tpdTree
164+ cleanup(t)
165+ myOpenedTrees(uri) = topLevelClassTrees(t, source)
166+ myCompilationUnits(uri) = unit
167+
168+ reporter.removeBufferedMessages
169+ }
170+ catch {
171+ case ex : FatalError =>
172+ myCtx = previousCtx
173+ close(uri)
174+ Nil
175+ }
176+ }
177+
178+ def close (uri : URI ): Unit = {
179+ myOpenedFiles.remove(uri)
180+ myOpenedTrees.remove(uri)
181+ myCompilationUnits.remove(uri)
182+ }
183+
112184 /**
113185 * The `SourceTree`s that define the class `className` and/or module `className`.
114186 *
@@ -128,39 +200,6 @@ class InteractiveDriver(val settings: List[String]) extends Driver {
128200 List (tree(className, id), tree(className.moduleClassName, id)).flatten
129201 }
130202
131- // Presence of a file with one of these suffixes indicates that the
132- // corresponding class has been pickled with TASTY.
133- private val tastySuffixes = List (" .hasTasty" , " .tasty" )
134-
135- // FIXME: All the code doing classpath handling is very fragile and ugly,
136- // improving this requires changing the dotty classpath APIs to handle our usecases.
137- // We also need something like sbt server-mode to be informed of changes on
138- // the classpath.
139-
140- private val (zipClassPaths, dirClassPaths) = currentCtx.platform.classPath(currentCtx) match {
141- case AggregateClassPath (cps) =>
142- // FIXME: We shouldn't assume that ClassPath doesn't have other
143- // subclasses. For now, the only other subclass is JrtClassPath on Java
144- // 9+, we can safely ignore it for now because it's only used for the
145- // standard Java library, but this will change once we start supporting
146- // adding entries to the modulepath.
147- val zipCps = cps.collect { case cp : ZipArchiveFileLookup [_] => cp }
148- val dirCps = cps.collect { case cp : JFileDirectoryLookup [_] => cp }
149- (zipCps, dirCps)
150- case _ =>
151- (Seq (), Seq ())
152- }
153-
154- // Like in `ZipArchiveFileLookup` we assume that zips are immutable
155- private val zipClassPathClasses : Seq [String ] = {
156- val names = new mutable.ListBuffer [String ]
157- zipClassPaths.foreach { zipCp =>
158- val zipFile = new ZipFile (zipCp.zipFile)
159- classesFromZip(zipFile, names)
160- }
161- names
162- }
163-
164203 // FIXME: classfiles in directories may change at any point, so we retraverse
165204 // the directories each time, if we knew when classfiles changed (sbt
166205 // server-mode might help here), we could do cache invalidation instead.
@@ -222,8 +261,6 @@ class InteractiveDriver(val settings: List[String]) extends Driver {
222261 trees.toList
223262 }
224263
225- private val compiler : Compiler = new InteractiveCompiler
226-
227264 /** Remove attachments and error out completers. The goal is to avoid
228265 * having a completer hanging in a typed tree which can capture the context
229266 * of a previous run. Note that typed trees can have untyped or partially
@@ -261,44 +298,6 @@ class InteractiveDriver(val settings: List[String]) extends Driver {
261298 new SourceFile (virtualFile, Codec .UTF8 )
262299 }
263300
264- def run (uri : URI , sourceCode : String ): List [MessageContainer ] = run(uri, toSource(uri, sourceCode))
265-
266- def run (uri : URI , source : SourceFile ): List [MessageContainer ] = {
267- val previousCtx = myCtx
268- try {
269- val reporter =
270- new StoreReporter (null ) with UniqueMessagePositions with HideNonSensicalMessages
271-
272- val run = compiler.newRun(myInitCtx.fresh.setReporter(reporter))
273- myCtx = run.runContext
274-
275- implicit val ctx = myCtx
276-
277- myOpenedFiles(uri) = source
278-
279- run.compileSources(List (source))
280- run.printSummary()
281- val unit = ctx.run.units.head
282- val t = unit.tpdTree
283- cleanup(t)
284- myOpenedTrees(uri) = topLevelClassTrees(t, source)
285- myCompilationUnits(uri) = unit
286-
287- reporter.removeBufferedMessages
288- }
289- catch {
290- case ex : FatalError =>
291- myCtx = previousCtx
292- close(uri)
293- Nil
294- }
295- }
296-
297- def close (uri : URI ): Unit = {
298- myOpenedFiles.remove(uri)
299- myOpenedTrees.remove(uri)
300- myCompilationUnits.remove(uri)
301- }
302301}
303302
304303object InteractiveDriver {
0 commit comments