Add a key for Zinc listeners.

Expose what the incremental compiler is doing behind the scenes. The RunProfiler interface has been part of Zinc for a while, but this allows the build itself, or an Sbt plugin, to hook their own implementation.

We expose a list of such listeners to avoid plugins stepping on each other and replacing an existing listener.
This commit is contained in:
Iulian Dragos 2023-04-24 12:33:09 +02:00
parent 9301bc2589
commit 6dfebc689b
No known key found for this signature in database
GPG Key ID: A38C8E571FA4621E
3 changed files with 61 additions and 2 deletions

View File

@ -946,11 +946,16 @@ object Defaults extends BuildCommon {
compileAnalysisTargetRoot.value / compileAnalysisFilename.value
},
externalHooks := IncOptions.defaultExternal,
zincCompilationListeners := Seq.empty,
incOptions := {
val old = incOptions.value
val extHooks = externalHooks.value
val newExtHooks = extHooks.withInvalidationProfiler(
() => new DefaultRunProfiler(zincCompilationListeners.value)
)
old
.withAuxiliaryClassFiles(auxiliaryClassFiles.value.toArray)
.withExternalHooks(externalHooks.value)
.withExternalHooks(newExtHooks)
.withClassfileManagerType(
Option(
TransactionalManagerType

View File

@ -248,7 +248,8 @@ object Keys {
val copyResources = taskKey[Seq[(File, File)]]("Copies resources to the output directory.").withRank(AMinusTask)
val aggregate = settingKey[Boolean]("Configures task aggregation.").withRank(BMinusSetting)
val sourcePositionMappers = taskKey[Seq[xsbti.Position => Option[xsbti.Position]]]("Maps positions in generated source files to the original source it was generated from").withRank(DTask)
val externalHooks = taskKey[ExternalHooks]("The external hooks used by zinc.")
private[sbt] val externalHooks = taskKey[ExternalHooks]("The external hooks used by zinc.")
val zincCompilationListeners = settingKey[Seq[RunProfiler]]("Listeners that receive information about incremental compiler decisions.").withRank(DSetting)
val auxiliaryClassFiles = taskKey[Seq[AuxiliaryClassFiles]]("The auxiliary class files that must be managed by Zinc (for instance the TASTy files)")
val fileConverter = settingKey[FileConverter]("The file converter used to convert between Path and VirtualFile")
val allowMachinePath = settingKey[Boolean]("Allow machine-specific paths during conversion.")

View File

@ -0,0 +1,53 @@
/*
* sbt
* Copyright 2011 - 2018, Lightbend, Inc.
* Copyright 2008 - 2010, Mark Harrah
* Licensed under Apache License 2.0 (see LICENSE)
*/
package sbt.internal
import xsbti.VirtualFileRef
import xsbti.compile.{ APIChange, InitialChanges, RunProfiler }
class DefaultRunProfiler(profilers: Seq[RunProfiler]) extends RunProfiler {
override def timeCompilation(startNanos: Long, durationNanos: Long): Unit =
profilers.foreach(_.timeCompilation(startNanos, durationNanos))
override def registerInitial(changes: InitialChanges): Unit =
profilers.foreach(_.registerInitial(changes))
override def registerEvent(
kind: String,
inputs: Array[String],
outputs: Array[String],
reason: String
): Unit =
profilers.foreach(_.registerEvent(kind, inputs, outputs, reason))
override def registerCycle(
invalidatedClasses: Array[String],
invalidatedPackageObjects: Array[String],
initialSources: Array[VirtualFileRef],
invalidatedSources: Array[VirtualFileRef],
recompiledClasses: Array[String],
changesAfterRecompilation: Array[APIChange],
nextInvalidations: Array[String],
shouldCompileIncrementally: Boolean
): Unit =
profilers.foreach(
_.registerCycle(
invalidatedClasses,
invalidatedPackageObjects,
initialSources,
invalidatedSources,
recompiledClasses,
changesAfterRecompilation,
nextInvalidations,
shouldCompileIncrementally
)
)
override def registerRun(): Unit =
profilers.foreach(_.registerRun())
}