Skip to content

Commit

Permalink
wip - compile
Browse files Browse the repository at this point in the history
  • Loading branch information
eed3si9n committed Nov 16, 2023
1 parent 552bbba commit 59d00c4
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 35 deletions.
103 changes: 69 additions & 34 deletions main/src/main/scala/sbt/Defaults.scala
Original file line number Diff line number Diff line change
Expand Up @@ -947,7 +947,6 @@ object Defaults extends BuildCommon {
},
internalDependencyConfigurations := InternalDependencies.configurations.value,
manipulateBytecode := compileSplit.value,
compileIncremental := compileIncrementalTask.tag(Tags.Compile, Tags.CPU).value,
printWarnings := printWarningsTask.value,
compileAnalysisFilename := {
// Here, if the user wants cross-scala-versioning, we also append it
Expand Down Expand Up @@ -1042,7 +1041,9 @@ object Defaults extends BuildCommon {
// note that we use the same runner and mainClass as plain run
mainBgRunMainTaskForConfig(This),
mainBgRunTaskForConfig(This)
) ++ inTask(run)(runnerSettings ++ newRunnerSettings)
) ++ inTask(run)(runnerSettings ++ newRunnerSettings) ++ compileIncrementalTaskSettings(
compileIncremental
)

private[this] lazy val configGlobal = globalDefaults(
Seq(
Expand Down Expand Up @@ -1938,17 +1939,6 @@ object Defaults extends BuildCommon {
}
}

@deprecated("The configuration(s) should not be decided based on the classifier.", "1.0.0")
def artifactConfigurations(
base: Artifact,
scope: Configuration,
classifier: Option[String]
): Iterable[Configuration] =
classifier match {
case Some(c) => Artifact.classifierConf(c) :: Nil
case None => scope :: Nil
}

def packageTaskSettings(
key: TaskKey[VirtualFileRef],
mappingsTask: Initialize[Task[Seq[(HashedVirtualFileRef, String)]]]
Expand Down Expand Up @@ -2371,20 +2361,22 @@ object Defaults extends BuildCommon {
private[sbt] def compileScalaBackendTask: Initialize[Task[CompileResult]] = Def.task {
val setup: Setup = compileIncSetup.value
val useBinary: Boolean = enableBinaryCompileAnalysis.value
val analysisResult: CompileResult = compileIncremental.value
val _ = compileIncremental.value
val exportP = exportPipelining.value
// Save analysis midway if pipelining is enabled
if (analysisResult.hasModified && exportP) {
val store =
MixedAnalyzingCompiler.staticCachedStore(setup.cacheFile.toPath, !useBinary)
val contents = AnalysisContents.create(analysisResult.analysis(), analysisResult.setup())
store.set(contents)
val store = MixedAnalyzingCompiler.staticCachedStore(setup.cachePath, !useBinary)
val contents = store.unsafeGet()
if (exportP) {
// this stores the eary analysis (again) in case the subproject contains a macro
setup.earlyAnalysisStore.toOption map { earlyStore =>
earlyStore.set(contents)
}
}
analysisResult
CompileResult.of(
contents.getAnalysis(),
contents.getMiniSetup(),
contents.getAnalysis().readCompilations().getAllCompilations().nonEmpty
)
}

/**
Expand All @@ -2408,6 +2400,7 @@ object Defaults extends BuildCommon {
compile.value
}
}

def compileTask: Initialize[Task[CompileAnalysis]] = Def.task {
val setup: Setup = compileIncSetup.value
val useBinary: Boolean = enableBinaryCompileAnalysis.value
Expand All @@ -2428,17 +2421,56 @@ object Defaults extends BuildCommon {
}
analysis
}
def compileIncrementalTask = Def.task {
val s = streams.value
val ci = (compile / compileInputs).value
val ping = earlyOutputPing.value
val reporter = (compile / bspReporter).value
BspCompileTask.compute(bspTargetIdentifier.value, thisProjectRef.value, configuration.value) {
task =>
// TODO - Should readAnalysis + saveAnalysis be scoped by the compile task too?
compileIncrementalTaskImpl(task, s, ci, ping, reporter)
}
}

def compileIncrementalTaskSettings(key: TaskKey[(Boolean, VirtualFileRef)]) =
inTask(key)(
Seq(
(TaskZero / key) := (Def
.cachedTask {
val s = streams.value
val ci = (compile / compileInputs).value
val ping = (TaskZero / earlyOutputPing).value
val reporter = (compile / bspReporter).value
val setup: Setup = (TaskZero / compileIncSetup).value
val useBinary: Boolean = enableBinaryCompileAnalysis.value
val c = fileConverter.value
val analysisResult: CompileResult =
BspCompileTask
.compute(bspTargetIdentifier.value, thisProjectRef.value, configuration.value) {
bspTask =>
// TODO - Should readAnalysis + saveAnalysis be scoped by the compile task too?
compileIncrementalTaskImpl(bspTask, s, ci, ping, reporter)
}
val analysisOut = c.toVirtualFile(setup.cachePath())
val store =
MixedAnalyzingCompiler.staticCachedStore(setup.cachePath, !useBinary)
val contents =
AnalysisContents.create(analysisResult.analysis(), analysisResult.setup())
store.set(contents)
Def.declareOutput(analysisOut)
val pkgConfig = packageConfiguration.value
val out = Pkg(
pkgConfig,
c,
s.log,
Pkg.timeFromConfiguration(pkgConfig)
)
Def.declareOutput(out)
analysisResult.hasModified() -> (out: VirtualFileRef)
})
.tag(Tags.Compile, Tags.CPU)
.value,
packageConfiguration := packageConfigurationTask.value,
packagedArtifact := {
val (hasModified, out) = key.value
artifact.value -> out
},
artifact := artifactSetting.value,
artifactClassifier := Some("noresources"),
artifactPath := artifactPathSetting(artifact).value,
)
)

private val incCompiler = ZincUtil.defaultIncrementalCompiler
private[sbt] def compileJavaTask: Initialize[Task[CompileResult]] = Def.task {
val s = streams.value
Expand All @@ -2460,6 +2492,7 @@ object Defaults extends BuildCommon {
throw e
}
}

private[this] def compileIncrementalTaskImpl(
task: BspCompileTask,
s: TaskStreams,
Expand Down Expand Up @@ -2502,9 +2535,10 @@ object Defaults extends BuildCommon {
x.close() // workaround for #937
}
}

def compileIncSetupTask = Def.task {
val cp = dependencyPicklePath.value
val lookup = new PerClasspathEntryLookup {
val lookup = new PerClasspathEntryLookup:
private val cachedAnalysisMap: VirtualFile => Option[CompileAnalysis] =
analysisMap(cp)
private val cachedPerEntryDefinesClassLookup: VirtualFile => DefinesClass =
Expand All @@ -2513,12 +2547,12 @@ object Defaults extends BuildCommon {
cachedAnalysisMap(classpathEntry).toOptional
override def definesClass(classpathEntry: VirtualFile): DefinesClass =
cachedPerEntryDefinesClassLookup(classpathEntry)
}
val extra = extraIncOptions.value.map(t2)
val useBinary: Boolean = enableBinaryCompileAnalysis.value
val eapath = earlyCompileAnalysisFile.value.toPath
val eaOpt =
if (exportPipelining.value) Some(MixedAnalyzingCompiler.staticCachedStore(eapath, !useBinary))
if exportPipelining.value then
Some(MixedAnalyzingCompiler.staticCachedStore(eapath, !useBinary))
else None
Setup.of(
lookup,
Expand All @@ -2532,6 +2566,7 @@ object Defaults extends BuildCommon {
extra.toArray,
)
}

def compileInputsSettings: Seq[Setting[_]] =
compileInputsSettings(dependencyPicklePath)
def compileInputsSettings(classpathTask: TaskKey[VirtualClasspath]): Seq[Setting[_]] = {
Expand Down
16 changes: 15 additions & 1 deletion main/src/main/scala/sbt/Keys.scala
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,12 @@ object Keys {
val buildDependencies = settingKey[BuildDependencies]("Definitive source of inter-project dependencies for compilation and dependency management.\n\tThis is populated by default by the dependencies declared on Project instances, but may be modified.\n\tThe main restriction is that new builds may not be introduced.").withRank(DSetting)
val appConfiguration = settingKey[xsbti.AppConfiguration]("Provides access to the launched sbt configuration, including the ScalaProvider, Launcher, and GlobalLock.").withRank(DSetting)
val thisProject = settingKey[ResolvedProject]("Provides the current project for the referencing scope.").withRank(CSetting)

@cacheOptOut(reason = "contains file path")
val thisProjectRef = settingKey[ProjectRef]("Provides a fully-resolved reference to the current project for the referencing scope.").withRank(CSetting)
val configurationStr = StringAttributeKey("configuration")

@cacheOptOut("")
val configuration = settingKey[Configuration]("Provides the current configuration of the referencing scope.").withRank(CSetting)
val commands = settingKey[Seq[Command]]("Defines commands to be registered when this project or build is the current selected one.").withRank(CSetting)
val initialize = settingKey[Unit]("A convenience setting for performing side-effects during initialization.").withRank(BSetting)
Expand Down Expand Up @@ -192,6 +196,8 @@ object Keys {
val cleanupCommands = settingKey[String]("Commands to execute before the Scala interpreter exits.").withRank(BMinusSetting)
val asciiGraphWidth = settingKey[Int]("Determines maximum width of the settings graph in ASCII mode").withRank(AMinusSetting)
val compileOptions = taskKey[CompileOptions]("Collects basic options to configure compilers").withRank(DTask)

@cacheOptOut(reason = "contains uncachable settings")
val compileInputs = taskKey[Inputs]("Collects all inputs needed for compilation.").withRank(DTask)
val scalaHome = settingKey[Option[File]]("If Some, defines the local Scala installation to use for compilation, running, and testing.").withRank(ASetting)
val scalaInstance = taskKey[ScalaInstance]("Defines the Scala instance to use for compilation, running, and testing.").withRank(DTask)
Expand Down Expand Up @@ -230,11 +236,13 @@ object Keys {
val consoleProject = taskKey[Unit]("Starts the Scala interpreter with the sbt and the build definition on the classpath and useful imports.").withRank(AMinusTask)
val compile = taskKey[CompileAnalysis]("Compiles sources.").withRank(APlusTask)
val manipulateBytecode = taskKey[CompileResult]("Manipulates generated bytecode").withRank(BTask)
val compileIncremental = taskKey[CompileResult]("Actually runs the incremental compilation").withRank(DTask)
val compileIncremental = taskKey[(Boolean, VirtualFileRef)]("Actually runs the incremental compilation").withRank(DTask)
val previousCompile = taskKey[PreviousResult]("Read the incremental compiler analysis from disk").withRank(DTask)
val tastyFiles = taskKey[Seq[File]]("Returns the TASTy files produced by compilation").withRank(DTask)
private[sbt] val compileScalaBackend = taskKey[CompileResult]("Compiles only Scala sources if pipelining is enabled. Compiles both Scala and Java sources otherwise").withRank(Invisible)
private[sbt] val compileEarly = taskKey[CompileAnalysis]("Compiles only Scala sources if pipelining is enabled, and produce an early output (pickle JAR)").withRank(Invisible)

@cacheOptOut("this is just for timing signal, so no need to cache")
private[sbt] val earlyOutputPing = taskKey[PromiseWrap[Boolean]]("When pipelining is enabled, this returns true when early output (pickle JAR) is created; false otherwise").withRank(Invisible)
private[sbt] val compileJava = taskKey[CompileResult]("Compiles only Java sources (called only for pipelining)").withRank(Invisible)
private[sbt] val compileSplit = taskKey[CompileResult]("When pipelining is enabled, compile Scala then Java; otherwise compile both").withRank(Invisible)
Expand All @@ -246,6 +254,8 @@ object Keys {
val earlyCompileAnalysisTargetRoot = settingKey[File]("The output directory to produce Zinc Analysis files").withRank(DSetting)
val compileAnalysisFile = taskKey[File]("Zinc analysis storage.").withRank(DSetting)
val earlyCompileAnalysisFile = taskKey[File]("Zinc analysis storage for early compilation").withRank(DSetting)

@cacheOptOut
val compileIncSetup = taskKey[Setup]("Configures aspects of incremental compilation.").withRank(DTask)
val compilerCache = taskKey[GlobalsCache]("Cache of scala.tools.nsc.Global instances. This should typically be cached so that it isn't recreated every task run.").withRank(DTask)
val stateCompilerCache = AttributeKey[GlobalsCache]("stateCompilerCache", "Internal use: Global cache.")
Expand Down Expand Up @@ -411,6 +421,8 @@ object Keys {
val bspConfig = taskKey[Unit]("Create or update the BSP connection files").withRank(DSetting)
val bspEnabled = SettingKey[Boolean](BasicKeys.bspEnabled)
val bspSbtEnabled = settingKey[Boolean]("Should BSP export meta-targets for the SBT build itself?")

@cacheOptOut(reason = "target identifier includes file path")
val bspTargetIdentifier = settingKey[BuildTargetIdentifier]("Build target identifier of a project and configuration.").withRank(DSetting)
val bspWorkspace = settingKey[Map[BuildTargetIdentifier, Scope]]("Mapping of BSP build targets to sbt scopes").withRank(DSetting)
private[sbt] val bspFullWorkspace = settingKey[BspFullWorkspace]("Mapping of BSP build targets to sbt scopes and meta-targets for the SBT build itself").withRank(DSetting)
Expand Down Expand Up @@ -441,6 +453,8 @@ object Keys {
val bspScalaTestClassesItem = taskKey[Seq[ScalaTestClassesItem]]("").withRank(DTask)
val bspScalaMainClasses = inputKey[Unit]("Corresponds to buildTarget/scalaMainClasses request").withRank(DTask)
val bspScalaMainClassesItem = taskKey[ScalaMainClassesItem]("").withRank(DTask)

@cacheOptOut(reason = "no need to invalidate based on this")
val bspReporter = taskKey[BuildServerReporter]("").withRank(DTask)

val useCoursier = settingKey[Boolean]("Use Coursier for dependency resolution.").withRank(BSetting)
Expand Down

0 comments on commit 59d00c4

Please sign in to comment.