@@ -18,15 +18,16 @@ import transform.TreeChecker
18
18
import rewrite .Rewrites
19
19
import java .io .{BufferedWriter , OutputStreamWriter }
20
20
import printing .XprintMode
21
+ import parsing .Parsers .Parser
21
22
import typer .ImplicitRunInfo
23
+ import collection .mutable
22
24
23
25
import scala .annotation .tailrec
24
26
import dotty .tools .io .VirtualFile
25
27
import scala .util .control .NonFatal
26
28
27
29
/** A compiler run. Exports various methods to compile source files */
28
- class Run (comp : Compiler , ictx : Context ) {
29
- import Run ._
30
+ class Run (comp : Compiler , ictx : Context ) extends ImplicitRunInfo with ConstraintRunInfo {
30
31
31
32
/** Produces the following contexts, from outermost to innermost
32
33
*
@@ -53,12 +54,49 @@ class Run(comp: Compiler, ictx: Context) {
53
54
ctx.initialize()(start) // re-initialize the base context with start
54
55
def addImport (ctx : Context , refFn : () => TermRef ) =
55
56
ctx.fresh.setImportInfo(ImportInfo .rootImport(refFn)(ctx))
56
- (start.setRunInfo( new RunInfo (start) ) /: defn.RootImportFns )(addImport)
57
+ (start.setRun( this ) /: defn.RootImportFns )(addImport)
57
58
}
58
59
59
- protected [this ] implicit val ctx : Context = rootContext(ictx)
60
+ private [this ] var myCtx = rootContext(ictx)
61
+
62
+ /** The context created for this run */
63
+ def runContext = myCtx
64
+
65
+ protected [this ] implicit def ctx : Context = myCtx
60
66
assert(ctx.runId <= Periods .MaxPossibleRunId )
61
67
68
+ private [this ] var myUnits : List [CompilationUnit ] = _
69
+ private [this ] var myUnitsCached : List [CompilationUnit ] = _
70
+ private [this ] var myFiles : Set [AbstractFile ] = _
71
+ private [this ] val myLateUnits = mutable.ListBuffer [CompilationUnit ]()
72
+ private [this ] var myLateFiles = mutable.Set [AbstractFile ]()
73
+
74
+ /** The compilation units currently being compiled, this may return different
75
+ * results over time.
76
+ */
77
+ def units : List [CompilationUnit ] = myUnits
78
+
79
+ private def units_= (us : List [CompilationUnit ]): Unit =
80
+ myUnits = us
81
+
82
+ /** The files currently being compiled, this may return different results over time.
83
+ * These files do not have to be source files since it's possible to compile
84
+ * from TASTY.
85
+ */
86
+ def files : Set [AbstractFile ] = {
87
+ if (myUnits ne myUnitsCached) {
88
+ myUnitsCached = myUnits
89
+ myFiles = myUnits.map(_.source.file).toSet
90
+ }
91
+ myFiles
92
+ }
93
+
94
+ /** Units that are added from source completers but that are not compiled in current run. */
95
+ def lateUnits : List [CompilationUnit ] = myLateUnits.toList
96
+
97
+ /** The source files of all late units, as a set */
98
+ def lateFiles : collection.Set [AbstractFile ] = myLateFiles
99
+
62
100
def getSource (fileName : String ): SourceFile = {
63
101
val f = new PlainFile (io.Path (fileName))
64
102
if (f.isDirectory) {
@@ -78,7 +116,7 @@ class Run(comp: Compiler, ictx: Context) {
78
116
compileSources(sources)
79
117
} catch {
80
118
case NonFatal (ex) =>
81
- ctx.echo(i " exception occurred while compiling ${ctx.runInfo. units} %, % " )
119
+ ctx.echo(i " exception occurred while compiling $units%, % " )
82
120
throw ex
83
121
}
84
122
@@ -90,17 +128,17 @@ class Run(comp: Compiler, ictx: Context) {
90
128
*/
91
129
def compileSources (sources : List [SourceFile ]) =
92
130
if (sources forall (_.exists)) {
93
- ctx.runInfo. units = sources map (new CompilationUnit (_))
131
+ units = sources map (new CompilationUnit (_))
94
132
compileUnits()
95
133
}
96
134
97
135
def compileUnits (us : List [CompilationUnit ]): Unit = {
98
- ctx.runInfo. units = us
136
+ units = us
99
137
compileUnits()
100
138
}
101
139
102
140
def compileUnits (us : List [CompilationUnit ], ctx : Context ): Unit = {
103
- ctx.runInfo. units = us
141
+ units = us
104
142
compileUnits()(ctx)
105
143
}
106
144
@@ -122,16 +160,16 @@ class Run(comp: Compiler, ictx: Context) {
122
160
if (phase.isRunnable)
123
161
Stats .trackTime(s " $phase ms " ) {
124
162
val start = System .currentTimeMillis
125
- ctx.runInfo. units = phase.runOn(ctx.runInfo. units)
163
+ units = phase.runOn(units)
126
164
if (ctx.settings.Xprint .value.containsPhase(phase)) {
127
- for (unit <- ctx.runInfo. units) {
165
+ for (unit <- units) {
128
166
lastPrintedTree =
129
167
printTree(lastPrintedTree)(ctx.fresh.setPhase(phase.next).setCompilationUnit(unit))
130
168
}
131
169
}
132
170
ctx.informTime(s " $phase " , start)
133
171
Stats .record(s " total trees at end of $phase" , ast.Trees .ntrees)
134
- for (unit <- ctx.runInfo. units)
172
+ for (unit <- units)
135
173
Stats .record(s " retained typed trees at end of $phase" , unit.tpdTree.treeSize)
136
174
}
137
175
}
@@ -142,6 +180,22 @@ class Run(comp: Compiler, ictx: Context) {
142
180
if (! ctx.reporter.hasErrors) Rewrites .writeBack()
143
181
}
144
182
183
+ /** Enter top-level definitions of classes and objects contain in Scala source file `file`.
184
+ * The newly added symbols replace any previously entered symbols.
185
+ */
186
+ def enterRoots (file : AbstractFile )(implicit ctx : Context ): Unit =
187
+ if (! files.contains(file) && ! lateFiles.contains(file)) {
188
+ val unit = new CompilationUnit (getSource(file.path))
189
+ myLateUnits += unit
190
+ myLateFiles += file
191
+ enterRoots(unit)(runContext.fresh.setCompilationUnit(unit))
192
+ }
193
+
194
+ private def enterRoots (unit : CompilationUnit )(implicit ctx : Context ): Unit = {
195
+ unit.untpdTree = new Parser (unit.source).parse()
196
+ ctx.typer.lateEnter(unit.untpdTree)
197
+ }
198
+
145
199
private sealed trait PrintedTree
146
200
private /* final*/ case class SomePrintedTree (phase : String , tree : String ) extends PrintedTree
147
201
private object NoPrintedTree extends PrintedTree
@@ -180,46 +234,19 @@ class Run(comp: Compiler, ictx: Context) {
180
234
compileSources(List (new SourceFile (virtualFile, Codec .UTF8 )))
181
235
}
182
236
183
- /** The context created for this run */
184
- def runContext = ctx
185
-
186
237
/** Print summary; return # of errors encountered */
187
238
def printSummary (): Reporter = {
188
- ctx.runInfo. printMaxConstraint()
239
+ printMaxConstraint()
189
240
val r = ctx.reporter
190
241
r.printSummary
191
242
r
192
243
}
193
- }
194
-
195
- object Run {
196
- /** Info that changes on each compiler run */
197
- class RunInfo (initctx : Context ) extends ImplicitRunInfo with ConstraintRunInfo {
198
- implicit val ctx : Context = initctx
199
-
200
- private [this ] var myUnits : List [CompilationUnit ] = _
201
- private [this ] var myUnitsCached : List [CompilationUnit ] = _
202
- private [this ] var myFiles : Set [AbstractFile ] = _
203
-
204
- /** The compilation units currently being compiled, this may return different
205
- * results over time.
206
- */
207
- def units : List [CompilationUnit ] = myUnits
208
-
209
- private [Run ] def units_= (us : List [CompilationUnit ]): Unit =
210
- myUnits = us
211
-
212
-
213
- /** The files currently being compiled, this may return different results over time.
214
- * These files do not have to be source files since it's possible to compile
215
- * from TASTY.
216
- */
217
- def files : Set [AbstractFile ] = {
218
- if (myUnits ne myUnitsCached) {
219
- myUnitsCached = myUnits
220
- myFiles = myUnits.map(_.source.file).toSet
221
- }
222
- myFiles
223
- }
244
+
245
+ override def reset () = {
246
+ super [ImplicitRunInfo ].reset()
247
+ super [ConstraintRunInfo ].reset()
248
+ myCtx = null
249
+ myUnits = null
250
+ myUnitsCached = null
224
251
}
225
- }
252
+ }
0 commit comments