@@ -36,23 +36,56 @@ class InteractiveDriver(val settings: List[String]) extends Driver {
36
36
}
37
37
38
38
private [this ] var myCtx : Context = myInitCtx
39
-
40
39
def currentCtx : Context = myCtx
41
40
41
+ private val compiler : Compiler = new InteractiveCompiler
42
+
42
43
private val myOpenedFiles = new mutable.LinkedHashMap [URI , SourceFile ] {
43
44
override def default (key : URI ) = NoSource
44
45
}
46
+ def openedFiles : Map [URI , SourceFile ] = myOpenedFiles
45
47
46
48
private val myOpenedTrees = new mutable.LinkedHashMap [URI , List [SourceTree ]] {
47
49
override def default (key : URI ) = Nil
48
50
}
51
+ def openedTrees : Map [URI , List [SourceTree ]] = myOpenedTrees
49
52
50
53
private val myCompilationUnits = new mutable.LinkedHashMap [URI , CompilationUnit ]
51
-
52
- def openedFiles : Map [URI , SourceFile ] = myOpenedFiles
53
- def openedTrees : Map [URI , List [SourceTree ]] = myOpenedTrees
54
54
def compilationUnits : Map [URI , CompilationUnit ] = myCompilationUnits
55
55
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
+
56
89
/**
57
90
* The trees for all the source files in this project.
58
91
*
@@ -109,6 +142,45 @@ class InteractiveDriver(val settings: List[String]) extends Driver {
109
142
(fromSource ++ fromClassPath).distinct
110
143
}
111
144
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
+
112
184
/**
113
185
* The `SourceTree`s that define the class `className` and/or module `className`.
114
186
*
@@ -128,39 +200,6 @@ class InteractiveDriver(val settings: List[String]) extends Driver {
128
200
List (tree(className, id), tree(className.moduleClassName, id)).flatten
129
201
}
130
202
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
-
164
203
// FIXME: classfiles in directories may change at any point, so we retraverse
165
204
// the directories each time, if we knew when classfiles changed (sbt
166
205
// server-mode might help here), we could do cache invalidation instead.
@@ -222,8 +261,6 @@ class InteractiveDriver(val settings: List[String]) extends Driver {
222
261
trees.toList
223
262
}
224
263
225
- private val compiler : Compiler = new InteractiveCompiler
226
-
227
264
/** Remove attachments and error out completers. The goal is to avoid
228
265
* having a completer hanging in a typed tree which can capture the context
229
266
* 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 {
261
298
new SourceFile (virtualFile, Codec .UTF8 )
262
299
}
263
300
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
- }
302
301
}
303
302
304
303
object InteractiveDriver {
0 commit comments