Skip to content

Commit 6fc069f

Browse files
committed
Merge pull request #989 from dotty-staging/add/callback
Add initial CompilerCallback implementation for IntelliJ
2 parents 7e63af3 + ccf7f8a commit 6fc069f

File tree

4 files changed

+76
-1
lines changed

4 files changed

+76
-1
lines changed

src/dotty/tools/backend/jvm/GenBCode.scala

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import Symbols._
2323
import Denotations._
2424
import Phases._
2525
import java.lang.AssertionError
26+
import java.io.{ File => JFile }
2627
import scala.tools.asm
2728
import scala.tools.asm.tree._
2829
import dotty.tools.dotc.util.{Positions, DotClass}
@@ -47,6 +48,8 @@ class GenBCodePipeline(val entryPoints: List[Symbol], val int: DottyBackendInter
4748

4849
var tree: Tree = _
4950

51+
val sourceJFile: JFile = ctx.compilationUnit.source.file.file
52+
5053
final class PlainClassBuilder(cunit: CompilationUnit) extends SyncAndTryBuilder(cunit)
5154

5255

@@ -300,6 +303,9 @@ class GenBCodePipeline(val entryPoints: List[Symbol], val int: DottyBackendInter
300303
bytecodeWriter.close()
301304
// Statistics.stopTimer(BackendStats.bcodeTimer, bcodeStart)
302305

306+
if (ctx.compilerCallback != null)
307+
ctx.compilerCallback.onSourceCompiled(sourceJFile)
308+
303309
/* TODO Bytecode can be verified (now that all classfiles have been written to disk)
304310
*
305311
* (1) asm.util.CheckAdapter.verify()
@@ -363,6 +369,11 @@ class GenBCodePipeline(val entryPoints: List[Symbol], val int: DottyBackendInter
363369
if (outFolder == null) null
364370
else getFileForClassfile(outFolder, jclassName, ".class")
365371
bytecodeWriter.writeClass(jclassName, jclassName, jclassBytes, outFile)
372+
373+
val outJFile = outFile.file
374+
val className = jclassName.replace('/', '.')
375+
if (ctx.compilerCallback != null)
376+
ctx.compilerCallback.onClassGenerated(sourceJFile, outJFile, className)
366377
}
367378
catch {
368379
case e: FileConflictException =>
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package dotty.tools.dotc
2+
3+
import java.io.File
4+
5+
/** This trait contains methods that can be overriden to execute code during the
6+
* compilation process.
7+
*
8+
* NOTE: This trait is experimental and may be subject to arbitrary changes.
9+
*
10+
* Example usage:
11+
* {{{
12+
* val args: Array[String] = ...
13+
* val callback = new CompilerCallback {
14+
* override def onClassGenerated(source: File, generatedClass: File, className: String) =
15+
* println(s"onClassGenerated($source, $generatedClass, $className)")
16+
* override def onSourceCompiled(source: File) =
17+
* println(s"onSourceCompiled($source)")
18+
* }
19+
* dotty.tools.dotc.process(args, callback)
20+
* // Or, if you have a custom root context `rootCtx`:
21+
* dotty.tools.dotc.process(args, rootCtx.setCompilerCallback(callback))
22+
* }}}
23+
*/
24+
trait CompilerCallback {
25+
/** Called when a class has been generated.
26+
*
27+
* @param source The source file corresponding to this class.
28+
* Example: ./src/library/scala/collection/Seq.scala
29+
* @param generatedClass The generated classfile for this class.
30+
* Example: ./scala/collection/Seq$.class
31+
* @param className The name of this class.
32+
* Example: scala.collection.Seq$
33+
*/
34+
def onClassGenerated(source: File, generatedClass: File, className: String): Unit = {}
35+
36+
/** Called when every class for this file has been generated.
37+
*
38+
* @param source The source file.
39+
* Example: ./src/library/scala/collection/Seq.scala
40+
*/
41+
def onSourceCompiled(source: File): Unit = {}
42+
}

src/dotty/tools/dotc/Driver.scala

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,10 @@ abstract class Driver extends DotClass {
3434

3535
def setup(args: Array[String], rootCtx: Context): (List[String], Context) = {
3636
val summary = CompilerCommand.distill(args)(rootCtx)
37-
implicit val ctx: Context = initCtx.fresh.setSettings(summary.sstate)
37+
// FIXME: We should reuse rootCtx instead of creating newCtx, but this
38+
// makes some tests fail with "denotation module _root_ invalid in run 2."
39+
val newCtx = initCtx.setCompilerCallback(rootCtx.compilerCallback)
40+
implicit val ctx: Context = newCtx.fresh.setSettings(summary.sstate)
3841
val fileNames = CompilerCommand.checkUsage(summary, sourcesRequired)
3942
(fileNames, ctx)
4043
}
@@ -44,6 +47,10 @@ abstract class Driver extends DotClass {
4447
doCompile(newCompiler(), fileNames)(ctx)
4548
}
4649

50+
def process(args: Array[String], callback: CompilerCallback): Reporter = {
51+
process(args, initCtx.setCompilerCallback(callback))
52+
}
53+
4754
// We overload `process` instead of using a default argument so that we
4855
// can easily call this method using reflection from `RawCompiler` in sbt.
4956
def process(args: Array[String]): Reporter = {

src/dotty/tools/dotc/core/Contexts.scala

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,11 +72,23 @@ object Contexts {
7272
def next = { val c = current; current = current.outer; c }
7373
}
7474

75+
/** Set the compiler callback, shared by all contexts with the same `base` */
76+
def setCompilerCallback(callback: CompilerCallback): this.type = {
77+
base.compilerCallback = callback; this
78+
}
79+
7580
/** The outer context */
7681
private[this] var _outer: Context = _
7782
protected def outer_=(outer: Context) = _outer = outer
7883
def outer: Context = _outer
7984

85+
// protected def compilerCallback_=(callback: CompilerCallback) =
86+
// _compilerCallback = callback
87+
// def compilerCallback: CompilerCallback = _compilerCallback
88+
// def setCompilerCallback(callback: CompilerCallback): this.type = {
89+
// this.compilerCallback = callback; this
90+
// }
91+
8092
/** The current context */
8193
private[this] var _period: Period = _
8294
protected def period_=(period: Period) = {
@@ -525,6 +537,9 @@ object Contexts {
525537
/** The essential mutable state of a context base, collected into a common class */
526538
class ContextState {
527539

540+
/** The compiler callback implementation, or null if unset */
541+
var compilerCallback: CompilerCallback = _
542+
528543
// Symbols state
529544

530545
/** A counter for unique ids */

0 commit comments

Comments
 (0)