Skip to content

Commit

Permalink
Merge pull request #157 from tgodzik/update-fork-16-11-2023
Browse files Browse the repository at this point in the history
chore: Update fork to current changes in main Bloop [16.11.2023]
  • Loading branch information
tgodzik committed Nov 16, 2023
2 parents c2bfcb5 + c8764ad commit e1a6468
Show file tree
Hide file tree
Showing 9 changed files with 219 additions and 77 deletions.
14 changes: 7 additions & 7 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
name: Formatting
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
submodules: true
fetch-depth: 0
Expand All @@ -31,7 +31,7 @@ jobs:
matrix:
os: [ubuntu-latest, windows-latest, macOS-latest]
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
submodules: true
fetch-depth: 0
Expand All @@ -53,7 +53,7 @@ jobs:
os: [ubuntu-latest, windows-latest, macOS-latest]
name: Server tests
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
submodules: true
fetch-depth: 0
Expand All @@ -75,7 +75,7 @@ jobs:
name: Client JVM tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
fetch-depth: 0
submodules: true
Expand All @@ -101,7 +101,7 @@ jobs:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
fetch-depth: 0
submodules: true
Expand Down Expand Up @@ -142,7 +142,7 @@ jobs:
runs-on: ubuntu-latest
if: github.event_name == 'push'
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
fetch-depth: 0
submodules: true
Expand All @@ -163,7 +163,7 @@ jobs:
runs-on: ubuntu-latest
if: github.event_name == 'push'
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
submodules: true
fetch-depth: 0
Expand Down
2 changes: 1 addition & 1 deletion .scalafmt.conf
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version = "3.7.14"
version = "3.7.15"

align.preset = more
maxColumn = 100
Expand Down
112 changes: 84 additions & 28 deletions backend/src/main/scala/bloop/Compiler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import java.util.concurrent.Executor

import scala.collection.mutable
import scala.concurrent.Promise
import scala.util.control.NonFatal

import bloop.io.AbsolutePath
import bloop.io.ParallelOps
Expand All @@ -23,6 +24,7 @@ import bloop.task.Task
import bloop.tracing.BraveTracer
import bloop.util.AnalysisUtils
import bloop.util.CacheHashCode
import bloop.util.JavaRuntime
import bloop.util.UUIDUtil

import monix.execution.Scheduler
Expand Down Expand Up @@ -278,39 +280,14 @@ object Compiler {
)
}

var isFatalWarningsEnabled: Boolean = false
val isFatalWarningsEnabled: Boolean =
compileInputs.scalacOptions.exists(_ == "-Xfatal-warnings")
def getInputs(compilers: Compilers): Inputs = {
val options = getCompilationOptions(compileInputs)
val options = getCompilationOptions(compileInputs, logger, newClassesDir)
val setup = getSetup(compileInputs)
Inputs.of(compilers, options, setup, compileInputs.previousResult)
}

def getCompilationOptions(inputs: CompileInputs): CompileOptions = {
// Sources are all files
val sources = inputs.sources.map(path => converter.toVirtualFile(path.underlying))
val classpath = inputs.classpath.map(path => converter.toVirtualFile(path.underlying))
val optionsWithoutFatalWarnings = inputs.scalacOptions.flatMap { option =>
if (option != "-Xfatal-warnings") List(option)
else {
if (!isFatalWarningsEnabled) isFatalWarningsEnabled = true
Nil
}
}

// Enable fatal warnings in the reporter if they are enabled in the build
if (isFatalWarningsEnabled)
inputs.reporter.enableFatalWarnings()

CompileOptions
.create()
.withClassesDirectory(newClassesDir)
.withSources(sources)
.withClasspath(classpath)
.withScalacOptions(optionsWithoutFatalWarnings)
.withJavacOptions(inputs.javacOptions)
.withOrder(inputs.compileOrder)
}

def getSetup(compileInputs: CompileInputs): Setup = {
val skip = false
val empty = Array.empty[T2[String, String]]
Expand Down Expand Up @@ -627,6 +604,85 @@ object Compiler {
}
}

/**
* Bloop runs Scala compilation in the same process as the main server,
* so the compilation process will use the same JDK that Bloop is using.
* That's why we must ensure that produce class files will be compliant with expected JDK version
* and compilation errors will show up when using wrong JDK API.
*/
private def adjustScalacReleaseOptions(
scalacOptions: Array[String],
javacBin: Option[AbsolutePath],
logger: Logger
): Array[String] = {
def existsReleaseSetting = scalacOptions.exists(opt =>
opt.startsWith("-release") ||
opt.startsWith("--release") ||
opt.startsWith("-java-output-version")
)
def sameHome = javacBin match {
case Some(bin) => bin.getParent.getParent == JavaRuntime.home
case None => false
}

javacBin.flatMap(binary =>
// <JAVA_HOME>/bin/java
JavaRuntime.getJavaVersionFromJavaHome(binary.getParent.getParent)
) match {
case None => scalacOptions
case Some(_) if existsReleaseSetting || sameHome => scalacOptions
case Some(version) =>
try {
val numVer = if (version.startsWith("1.8")) 8 else version.takeWhile(_.isDigit).toInt
val bloopNumVer = JavaRuntime.version.takeWhile(_.isDigit).toInt
if (bloopNumVer > numVer) {
scalacOptions ++ List("-release", numVer.toString())
} else {
logger.warn(
s"Bloop is runing with ${JavaRuntime.version} but your code requires $version to compile, " +
"this might cause some compilation issues when using JDK API unsupported by the Bloop's current JVM version"
)
scalacOptions
}
} catch {
case NonFatal(_) =>
scalacOptions
}
}
}

private def getCompilationOptions(
inputs: CompileInputs,
logger: Logger,
newClassesDir: Path
): CompileOptions = {
// Sources are all files
val sources = inputs.sources.map(path => converter.toVirtualFile(path.underlying))
val classpath = inputs.classpath.map(path => converter.toVirtualFile(path.underlying))

val scalacOptions = adjustScalacReleaseOptions(
scalacOptions = inputs.scalacOptions,
javacBin = inputs.javacBin,
logger = logger
)

val optionsWithoutFatalWarnings = scalacOptions.filter(_ != "-Xfatal-warnings")
val areFatalWarningsEnabled = scalacOptions.length != optionsWithoutFatalWarnings.length

// Enable fatal warnings in the reporter if they are enabled in the build
if (areFatalWarningsEnabled)
inputs.reporter.enableFatalWarnings()

CompileOptions
.create()
.withClassesDirectory(newClassesDir)
.withSources(sources)
.withClasspath(classpath)
.withScalacOptions(optionsWithoutFatalWarnings)
.withJavacOptions(inputs.javacOptions)
.withOrder(inputs.compileOrder)
}

def toBackgroundTasks(
tasks: List[(AbsolutePath, Reporter, BraveTracer) => Task[Unit]]
): CompileBackgroundTasks = {
Expand Down
35 changes: 33 additions & 2 deletions backend/src/main/scala/bloop/util/JavaRuntime.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@ import scala.util.Try

import bloop.io.AbsolutePath

import com.typesafe.config.ConfigException
import com.typesafe.config.ConfigFactory
import com.typesafe.config.ConfigParseOptions
import com.typesafe.config.ConfigSyntax
import scala.collection.concurrent.TrieMap
import scala.util.Properties

sealed trait JavaRuntime
object JavaRuntime {
case object JDK extends JavaRuntime
Expand All @@ -17,10 +24,33 @@ object JavaRuntime {
val home: AbsolutePath = AbsolutePath(sys.props("java.home"))
val version: String = sys.props("java.version")
val javac: Option[AbsolutePath] = javacBinaryFromJavaHome(home)

private val versions: TrieMap[AbsolutePath, Option[String]] =
TrieMap.empty[AbsolutePath, Option[String]]
// Has to be a def, not a val, otherwise we get "loader constraint violation"
def javaCompiler: Option[JavaCompiler] = Option(ToolProvider.getSystemJavaCompiler)

def getJavaVersionFromJavaHome(javaHome: AbsolutePath): Option[String] = versions.getOrElseUpdate(
javaHome, {
val releaseFile = javaHome.resolve("release")
def rtJar = javaHome.resolve("lib").resolve("rt.jar")
if (releaseFile.exists) {
val properties = ConfigFactory.parseFile(
releaseFile.toFile,
ConfigParseOptions.defaults().setSyntax(ConfigSyntax.PROPERTIES)
)
try Some(properties.getString("JAVA_VERSION").stripPrefix("\"").stripSuffix("\""))
catch {
case _: ConfigException =>
None
}
} else if (rtJar.exists) {
Some("1.8")
} else {
None
}
}
)

/**
* Detects the runtime of the running JDK instance.
*/
Expand All @@ -45,7 +75,8 @@ object JavaRuntime {
* appropriately.
*/
def javacBinaryFromJavaHome(home: AbsolutePath): Option[AbsolutePath] = {
def toJavaBinary(home: AbsolutePath) = home.resolve("bin").resolve("javac")
val binaryName = if (Properties.isWin) "javac.exe" else "javac"
def toJavaBinary(home: AbsolutePath) = home.resolve("bin").resolve(binaryName)
if (!home.exists) None
else {
Option(toJavaBinary(home))
Expand Down
14 changes: 7 additions & 7 deletions build.sc
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ object Dependencies {

def scalaVersions = Seq(scala212, scala213)

def asmVersion = "9.5"
def asmVersion = "9.6"
def coursierVersion = "2.1.0-M6-53-gb4f448130"
def graalvmVersion = "22.2.0"
def jsoniterVersion = "2.13.3.2"
Expand All @@ -30,8 +30,8 @@ object Dependencies {
def asmUtil = ivy"org.ow2.asm:asm-util:$asmVersion"
def bloopConfig = ivy"ch.epfl.scala::bloop-config:1.5.5"
def brave = ivy"io.zipkin.brave:brave:5.16.0"
def bsp4j = ivy"ch.epfl.scala:bsp4j:2.1.0-M6"
def bsp4s = ivy"ch.epfl.scala::bsp4s:2.1.0-M6"
def bsp4j = ivy"ch.epfl.scala:bsp4j:2.1.0-M7"
def bsp4s = ivy"ch.epfl.scala::bsp4s:2.1.0-M7"
def caseApp = ivy"com.github.alexarchambault::case-app:2.0.6"
def caseApp21 = ivy"com.github.alexarchambault::case-app:2.1.0-M15"
def collectionCompat = ivy"org.scala-lang.modules::scala-collection-compat:2.9.0"
Expand All @@ -49,15 +49,15 @@ object Dependencies {
def junit = ivy"com.github.sbt:junit-interface:0.13.3"
def libdaemonjvm = ivy"io.github.alexarchambault.libdaemon::libdaemon:0.0.11"
def libraryManagement = ivy"org.scala-sbt::librarymanagement-ivy:1.9.3"
def log4j = ivy"org.apache.logging.log4j:log4j-core:2.20.0"
def log4j = ivy"org.apache.logging.log4j:log4j-core:2.21.1"
def logback = ivy"ch.qos.logback:logback-classic:1.4.6"
def macroParadise = ivy"org.scalamacros:::paradise:2.1.1"
def monix = ivy"io.monix::monix:3.2.0"
def munit = ivy"org.scalameta::munit:0.7.29"
def nailgun = ivy"io.github.alexarchambault.bleep:nailgun-server:1.0.7"
def osLib = ivy"com.lihaoyi::os-lib:0.9.0"
def pprint = ivy"com.lihaoyi::pprint:0.8.1"
def sbtTestAgent = ivy"org.scala-sbt:test-agent:1.9.6"
def sbtTestAgent = ivy"org.scala-sbt:test-agent:1.9.7"
def sbtTestInterface = ivy"org.scala-sbt:test-interface:1.0"
def scalaDebugAdapter = ivy"ch.epfl.scala::scala-debug-adapter:3.1.4"
def scalaJsLinker1 = ivy"org.scala-js::scalajs-linker:$scalaJs1Version"
Expand All @@ -66,12 +66,12 @@ object Dependencies {
def scalaJsEnvJsdomNode1 = ivy"org.scala-js::scalajs-env-jsdom-nodejs:1.1.0"
def scalaJsSbtTestAdapter1 = ivy"org.scala-js::scalajs-sbt-test-adapter:$scalaJs1Version"
def scalaJsLogging1 = ivy"org.scala-js::scalajs-logging:1.1.1"
def scalaNativeTools04 = ivy"org.scala-native::tools:0.4.15"
def scalaNativeTools04 = ivy"org.scala-native::tools:0.4.16"
def scalazCore = ivy"org.scalaz::scalaz-core:7.3.7"
def snailgun = ivy"io.github.alexarchambault.scala-cli.snailgun::snailgun-core:0.4.1-sc2"
def sourcecode = ivy"com.lihaoyi::sourcecode:0.3.1"
def svm = ivy"org.graalvm.nativeimage:svm:$graalvmVersion"
def utest = ivy"com.lihaoyi::utest:0.8.1"
def utest = ivy"com.lihaoyi::utest:0.8.2"
def xxHashLibrary = ivy"net.jpountz.lz4:lz4:1.3.0"
def zinc = ivy"org.scala-sbt::zinc:1.9.5"
def zipkinSender = ivy"io.zipkin.reporter2:zipkin-sender-urlconnection:2.16.4"
Expand Down
40 changes: 9 additions & 31 deletions frontend/src/main/scala/bloop/data/Project.scala
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,8 @@ import bloop.io.ByteHasher
import bloop.logging.DebugFilter
import bloop.logging.Logger
import bloop.task.Task
import bloop.util.JavaRuntime

import com.typesafe.config.ConfigException
import com.typesafe.config.ConfigFactory
import com.typesafe.config.ConfigParseOptions
import com.typesafe.config.ConfigSyntax
import scalaz.Cord
import xsbti.compile.ClasspathOptions
import xsbti.compile.CompileOrder
Expand Down Expand Up @@ -225,39 +222,20 @@ final case class Project(
case i => i
}
}
def getJavaVersionFromJavaHome(javaHome: AbsolutePath): String = {
val releaseFile = javaHome.resolve("release")
def rtJar = javaHome.resolve("lib").resolve("rt.jar")
if (releaseFile.exists) {
val properties = ConfigFactory.parseFile(
releaseFile.toFile,
ConfigParseOptions.defaults().setSyntax(ConfigSyntax.PROPERTIES)
)
try properties.getString("JAVA_VERSION").stripPrefix("\"").stripSuffix("\"")
catch {
case _: ConfigException =>
logger.error(
s"$javaHome release file missing JAVA_VERSION property - using Bloop's JVM version ${Properties.javaVersion}"
)
Properties.javaVersion
}
} else if (rtJar.exists) {
// jdk 8 doesn't have `release` file
"1.8.0"
} else {
logger.error(
s"No `release` file found in $javaHome - using Bloop's JVM version ${Properties.javaVersion}"
)
Properties.javaVersion
}
}

val compileVersion = compileJdkConfig
.map(f =>
if (f.javaHome == AbsolutePath(Properties.javaHome))
Properties.javaVersion
else
getJavaVersionFromJavaHome(f.javaHome)
JavaRuntime.getJavaVersionFromJavaHome(f.javaHome).getOrElse {

logger.error(
s"${f.javaHome} release file missing JAVA_VERSION property - using Bloop's JVM version ${Properties.javaVersion}"
)

Properties.javaVersion
}
)
.getOrElse(Properties.javaVersion)
.split("-")
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/main/scala/bloop/testing/TestInternals.scala
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ object TestInternals {
* @return A function that determines whether a test should be run given its FQCN.
*/
def parseFilters(filters: List[String]): String => Boolean = {
val (exclusionFilters, inclusionFilters) = filters.partition(_.startsWith("-"))
val (exclusionFilters, inclusionFilters) = filters.map(_.trim).partition(_.startsWith("-"))
val inc = inclusionFilters.map(toPattern)
val exc = exclusionFilters.map(f => toPattern(f.tail))

Expand Down

0 comments on commit e1a6468

Please sign in to comment.