@@ -18,15 +18,16 @@ import transform.TreeChecker
1818import rewrite .Rewrites
1919import java .io .{BufferedWriter , OutputStreamWriter }
2020import printing .XprintMode
21+ import parsing .Parsers .Parser
2122import typer .ImplicitRunInfo
23+ import collection .mutable
2224
2325import scala .annotation .tailrec
2426import dotty .tools .io .VirtualFile
2527import scala .util .control .NonFatal
2628
2729/** 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 {
3031
3132 /** Produces the following contexts, from outermost to innermost
3233 *
@@ -53,12 +54,49 @@ class Run(comp: Compiler, ictx: Context) {
5354 ctx.initialize()(start) // re-initialize the base context with start
5455 def addImport (ctx : Context , refFn : () => TermRef ) =
5556 ctx.fresh.setImportInfo(ImportInfo .rootImport(refFn)(ctx))
56- (start.setRunInfo( new RunInfo (start) ) /: defn.RootImportFns )(addImport)
57+ (start.setRun( this ) /: defn.RootImportFns )(addImport)
5758 }
5859
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
6066 assert(ctx.runId <= Periods .MaxPossibleRunId )
6167
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+
62100 def getSource (fileName : String ): SourceFile = {
63101 val f = new PlainFile (io.Path (fileName))
64102 if (f.isDirectory) {
@@ -78,7 +116,7 @@ class Run(comp: Compiler, ictx: Context) {
78116 compileSources(sources)
79117 } catch {
80118 case NonFatal (ex) =>
81- ctx.echo(i " exception occurred while compiling ${ctx.runInfo. units} %, % " )
119+ ctx.echo(i " exception occurred while compiling $units%, % " )
82120 throw ex
83121 }
84122
@@ -90,17 +128,17 @@ class Run(comp: Compiler, ictx: Context) {
90128 */
91129 def compileSources (sources : List [SourceFile ]) =
92130 if (sources forall (_.exists)) {
93- ctx.runInfo. units = sources map (new CompilationUnit (_))
131+ units = sources map (new CompilationUnit (_))
94132 compileUnits()
95133 }
96134
97135 def compileUnits (us : List [CompilationUnit ]): Unit = {
98- ctx.runInfo. units = us
136+ units = us
99137 compileUnits()
100138 }
101139
102140 def compileUnits (us : List [CompilationUnit ], ctx : Context ): Unit = {
103- ctx.runInfo. units = us
141+ units = us
104142 compileUnits()(ctx)
105143 }
106144
@@ -122,16 +160,16 @@ class Run(comp: Compiler, ictx: Context) {
122160 if (phase.isRunnable)
123161 Stats .trackTime(s " $phase ms " ) {
124162 val start = System .currentTimeMillis
125- ctx.runInfo. units = phase.runOn(ctx.runInfo. units)
163+ units = phase.runOn(units)
126164 if (ctx.settings.Xprint .value.containsPhase(phase)) {
127- for (unit <- ctx.runInfo. units) {
165+ for (unit <- units) {
128166 lastPrintedTree =
129167 printTree(lastPrintedTree)(ctx.fresh.setPhase(phase.next).setCompilationUnit(unit))
130168 }
131169 }
132170 ctx.informTime(s " $phase " , start)
133171 Stats .record(s " total trees at end of $phase" , ast.Trees .ntrees)
134- for (unit <- ctx.runInfo. units)
172+ for (unit <- units)
135173 Stats .record(s " retained typed trees at end of $phase" , unit.tpdTree.treeSize)
136174 }
137175 }
@@ -142,6 +180,22 @@ class Run(comp: Compiler, ictx: Context) {
142180 if (! ctx.reporter.hasErrors) Rewrites .writeBack()
143181 }
144182
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+
145199 private sealed trait PrintedTree
146200 private /* final*/ case class SomePrintedTree (phase : String , tree : String ) extends PrintedTree
147201 private object NoPrintedTree extends PrintedTree
@@ -180,46 +234,19 @@ class Run(comp: Compiler, ictx: Context) {
180234 compileSources(List (new SourceFile (virtualFile, Codec .UTF8 )))
181235 }
182236
183- /** The context created for this run */
184- def runContext = ctx
185-
186237 /** Print summary; return # of errors encountered */
187238 def printSummary (): Reporter = {
188- ctx.runInfo. printMaxConstraint()
239+ printMaxConstraint()
189240 val r = ctx.reporter
190241 r.printSummary
191242 r
192243 }
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
224251 }
225- }
252+ }
0 commit comments