Skip to content

Commit e1a6468

Browse files
authored
Merge pull request #157 from tgodzik/update-fork-16-11-2023
chore: Update fork to current changes in main Bloop [16.11.2023]
2 parents c2bfcb5 + c8764ad commit e1a6468

File tree

9 files changed

+219
-77
lines changed

9 files changed

+219
-77
lines changed

.github/workflows/ci.yml

+7-7
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ jobs:
1212
name: Formatting
1313
runs-on: ubuntu-latest
1414
steps:
15-
- uses: actions/checkout@v3
15+
- uses: actions/checkout@v4
1616
with:
1717
submodules: true
1818
fetch-depth: 0
@@ -31,7 +31,7 @@ jobs:
3131
matrix:
3232
os: [ubuntu-latest, windows-latest, macOS-latest]
3333
steps:
34-
- uses: actions/checkout@v3
34+
- uses: actions/checkout@v4
3535
with:
3636
submodules: true
3737
fetch-depth: 0
@@ -53,7 +53,7 @@ jobs:
5353
os: [ubuntu-latest, windows-latest, macOS-latest]
5454
name: Server tests
5555
steps:
56-
- uses: actions/checkout@v3
56+
- uses: actions/checkout@v4
5757
with:
5858
submodules: true
5959
fetch-depth: 0
@@ -75,7 +75,7 @@ jobs:
7575
name: Client JVM tests
7676
runs-on: ubuntu-latest
7777
steps:
78-
- uses: actions/checkout@v3
78+
- uses: actions/checkout@v4
7979
with:
8080
fetch-depth: 0
8181
submodules: true
@@ -101,7 +101,7 @@ jobs:
101101
matrix:
102102
os: [ubuntu-latest, windows-latest, macos-latest]
103103
steps:
104-
- uses: actions/checkout@v3
104+
- uses: actions/checkout@v4
105105
with:
106106
fetch-depth: 0
107107
submodules: true
@@ -142,7 +142,7 @@ jobs:
142142
runs-on: ubuntu-latest
143143
if: github.event_name == 'push'
144144
steps:
145-
- uses: actions/checkout@v3
145+
- uses: actions/checkout@v4
146146
with:
147147
fetch-depth: 0
148148
submodules: true
@@ -163,7 +163,7 @@ jobs:
163163
runs-on: ubuntu-latest
164164
if: github.event_name == 'push'
165165
steps:
166-
- uses: actions/checkout@v3
166+
- uses: actions/checkout@v4
167167
with:
168168
submodules: true
169169
fetch-depth: 0

.scalafmt.conf

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
version = "3.7.14"
1+
version = "3.7.15"
22

33
align.preset = more
44
maxColumn = 100

backend/src/main/scala/bloop/Compiler.scala

+84-28
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import java.util.concurrent.Executor
88

99
import scala.collection.mutable
1010
import scala.concurrent.Promise
11+
import scala.util.control.NonFatal
1112

1213
import bloop.io.AbsolutePath
1314
import bloop.io.ParallelOps
@@ -23,6 +24,7 @@ import bloop.task.Task
2324
import bloop.tracing.BraveTracer
2425
import bloop.util.AnalysisUtils
2526
import bloop.util.CacheHashCode
27+
import bloop.util.JavaRuntime
2628
import bloop.util.UUIDUtil
2729

2830
import monix.execution.Scheduler
@@ -278,39 +280,14 @@ object Compiler {
278280
)
279281
}
280282

281-
var isFatalWarningsEnabled: Boolean = false
283+
val isFatalWarningsEnabled: Boolean =
284+
compileInputs.scalacOptions.exists(_ == "-Xfatal-warnings")
282285
def getInputs(compilers: Compilers): Inputs = {
283-
val options = getCompilationOptions(compileInputs)
286+
val options = getCompilationOptions(compileInputs, logger, newClassesDir)
284287
val setup = getSetup(compileInputs)
285288
Inputs.of(compilers, options, setup, compileInputs.previousResult)
286289
}
287290

288-
def getCompilationOptions(inputs: CompileInputs): CompileOptions = {
289-
// Sources are all files
290-
val sources = inputs.sources.map(path => converter.toVirtualFile(path.underlying))
291-
val classpath = inputs.classpath.map(path => converter.toVirtualFile(path.underlying))
292-
val optionsWithoutFatalWarnings = inputs.scalacOptions.flatMap { option =>
293-
if (option != "-Xfatal-warnings") List(option)
294-
else {
295-
if (!isFatalWarningsEnabled) isFatalWarningsEnabled = true
296-
Nil
297-
}
298-
}
299-
300-
// Enable fatal warnings in the reporter if they are enabled in the build
301-
if (isFatalWarningsEnabled)
302-
inputs.reporter.enableFatalWarnings()
303-
304-
CompileOptions
305-
.create()
306-
.withClassesDirectory(newClassesDir)
307-
.withSources(sources)
308-
.withClasspath(classpath)
309-
.withScalacOptions(optionsWithoutFatalWarnings)
310-
.withJavacOptions(inputs.javacOptions)
311-
.withOrder(inputs.compileOrder)
312-
}
313-
314291
def getSetup(compileInputs: CompileInputs): Setup = {
315292
val skip = false
316293
val empty = Array.empty[T2[String, String]]
@@ -627,6 +604,85 @@ object Compiler {
627604
}
628605
}
629606

607+
/**
608+
* Bloop runs Scala compilation in the same process as the main server,
609+
* so the compilation process will use the same JDK that Bloop is using.
610+
* That's why we must ensure that produce class files will be compliant with expected JDK version
611+
* and compilation errors will show up when using wrong JDK API.
612+
*/
613+
private def adjustScalacReleaseOptions(
614+
scalacOptions: Array[String],
615+
javacBin: Option[AbsolutePath],
616+
logger: Logger
617+
): Array[String] = {
618+
def existsReleaseSetting = scalacOptions.exists(opt =>
619+
opt.startsWith("-release") ||
620+
opt.startsWith("--release") ||
621+
opt.startsWith("-java-output-version")
622+
)
623+
def sameHome = javacBin match {
624+
case Some(bin) => bin.getParent.getParent == JavaRuntime.home
625+
case None => false
626+
}
627+
628+
javacBin.flatMap(binary =>
629+
// <JAVA_HOME>/bin/java
630+
JavaRuntime.getJavaVersionFromJavaHome(binary.getParent.getParent)
631+
) match {
632+
case None => scalacOptions
633+
case Some(_) if existsReleaseSetting || sameHome => scalacOptions
634+
case Some(version) =>
635+
try {
636+
val numVer = if (version.startsWith("1.8")) 8 else version.takeWhile(_.isDigit).toInt
637+
val bloopNumVer = JavaRuntime.version.takeWhile(_.isDigit).toInt
638+
if (bloopNumVer > numVer) {
639+
scalacOptions ++ List("-release", numVer.toString())
640+
} else {
641+
logger.warn(
642+
s"Bloop is runing with ${JavaRuntime.version} but your code requires $version to compile, " +
643+
"this might cause some compilation issues when using JDK API unsupported by the Bloop's current JVM version"
644+
)
645+
scalacOptions
646+
}
647+
} catch {
648+
case NonFatal(_) =>
649+
scalacOptions
650+
}
651+
}
652+
}
653+
654+
private def getCompilationOptions(
655+
inputs: CompileInputs,
656+
logger: Logger,
657+
newClassesDir: Path
658+
): CompileOptions = {
659+
// Sources are all files
660+
val sources = inputs.sources.map(path => converter.toVirtualFile(path.underlying))
661+
val classpath = inputs.classpath.map(path => converter.toVirtualFile(path.underlying))
662+
663+
val scalacOptions = adjustScalacReleaseOptions(
664+
scalacOptions = inputs.scalacOptions,
665+
javacBin = inputs.javacBin,
666+
logger = logger
667+
)
668+
669+
val optionsWithoutFatalWarnings = scalacOptions.filter(_ != "-Xfatal-warnings")
670+
val areFatalWarningsEnabled = scalacOptions.length != optionsWithoutFatalWarnings.length
671+
672+
// Enable fatal warnings in the reporter if they are enabled in the build
673+
if (areFatalWarningsEnabled)
674+
inputs.reporter.enableFatalWarnings()
675+
676+
CompileOptions
677+
.create()
678+
.withClassesDirectory(newClassesDir)
679+
.withSources(sources)
680+
.withClasspath(classpath)
681+
.withScalacOptions(optionsWithoutFatalWarnings)
682+
.withJavacOptions(inputs.javacOptions)
683+
.withOrder(inputs.compileOrder)
684+
}
685+
630686
def toBackgroundTasks(
631687
tasks: List[(AbsolutePath, Reporter, BraveTracer) => Task[Unit]]
632688
): CompileBackgroundTasks = {

backend/src/main/scala/bloop/util/JavaRuntime.scala

+33-2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,13 @@ import scala.util.Try
99

1010
import bloop.io.AbsolutePath
1111

12+
import com.typesafe.config.ConfigException
13+
import com.typesafe.config.ConfigFactory
14+
import com.typesafe.config.ConfigParseOptions
15+
import com.typesafe.config.ConfigSyntax
16+
import scala.collection.concurrent.TrieMap
17+
import scala.util.Properties
18+
1219
sealed trait JavaRuntime
1320
object JavaRuntime {
1421
case object JDK extends JavaRuntime
@@ -17,10 +24,33 @@ object JavaRuntime {
1724
val home: AbsolutePath = AbsolutePath(sys.props("java.home"))
1825
val version: String = sys.props("java.version")
1926
val javac: Option[AbsolutePath] = javacBinaryFromJavaHome(home)
20-
27+
private val versions: TrieMap[AbsolutePath, Option[String]] =
28+
TrieMap.empty[AbsolutePath, Option[String]]
2129
// Has to be a def, not a val, otherwise we get "loader constraint violation"
2230
def javaCompiler: Option[JavaCompiler] = Option(ToolProvider.getSystemJavaCompiler)
2331

32+
def getJavaVersionFromJavaHome(javaHome: AbsolutePath): Option[String] = versions.getOrElseUpdate(
33+
javaHome, {
34+
val releaseFile = javaHome.resolve("release")
35+
def rtJar = javaHome.resolve("lib").resolve("rt.jar")
36+
if (releaseFile.exists) {
37+
val properties = ConfigFactory.parseFile(
38+
releaseFile.toFile,
39+
ConfigParseOptions.defaults().setSyntax(ConfigSyntax.PROPERTIES)
40+
)
41+
try Some(properties.getString("JAVA_VERSION").stripPrefix("\"").stripSuffix("\""))
42+
catch {
43+
case _: ConfigException =>
44+
None
45+
}
46+
} else if (rtJar.exists) {
47+
Some("1.8")
48+
} else {
49+
None
50+
}
51+
}
52+
)
53+
2454
/**
2555
* Detects the runtime of the running JDK instance.
2656
*/
@@ -45,7 +75,8 @@ object JavaRuntime {
4575
* appropriately.
4676
*/
4777
def javacBinaryFromJavaHome(home: AbsolutePath): Option[AbsolutePath] = {
48-
def toJavaBinary(home: AbsolutePath) = home.resolve("bin").resolve("javac")
78+
val binaryName = if (Properties.isWin) "javac.exe" else "javac"
79+
def toJavaBinary(home: AbsolutePath) = home.resolve("bin").resolve(binaryName)
4980
if (!home.exists) None
5081
else {
5182
Option(toJavaBinary(home))

build.sc

+7-7
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ object Dependencies {
1919

2020
def scalaVersions = Seq(scala212, scala213)
2121

22-
def asmVersion = "9.5"
22+
def asmVersion = "9.6"
2323
def coursierVersion = "2.1.0-M6-53-gb4f448130"
2424
def graalvmVersion = "22.2.0"
2525
def jsoniterVersion = "2.13.3.2"
@@ -30,8 +30,8 @@ object Dependencies {
3030
def asmUtil = ivy"org.ow2.asm:asm-util:$asmVersion"
3131
def bloopConfig = ivy"ch.epfl.scala::bloop-config:1.5.5"
3232
def brave = ivy"io.zipkin.brave:brave:5.16.0"
33-
def bsp4j = ivy"ch.epfl.scala:bsp4j:2.1.0-M6"
34-
def bsp4s = ivy"ch.epfl.scala::bsp4s:2.1.0-M6"
33+
def bsp4j = ivy"ch.epfl.scala:bsp4j:2.1.0-M7"
34+
def bsp4s = ivy"ch.epfl.scala::bsp4s:2.1.0-M7"
3535
def caseApp = ivy"com.github.alexarchambault::case-app:2.0.6"
3636
def caseApp21 = ivy"com.github.alexarchambault::case-app:2.1.0-M15"
3737
def collectionCompat = ivy"org.scala-lang.modules::scala-collection-compat:2.9.0"
@@ -49,15 +49,15 @@ object Dependencies {
4949
def junit = ivy"com.github.sbt:junit-interface:0.13.3"
5050
def libdaemonjvm = ivy"io.github.alexarchambault.libdaemon::libdaemon:0.0.11"
5151
def libraryManagement = ivy"org.scala-sbt::librarymanagement-ivy:1.9.3"
52-
def log4j = ivy"org.apache.logging.log4j:log4j-core:2.20.0"
52+
def log4j = ivy"org.apache.logging.log4j:log4j-core:2.21.1"
5353
def logback = ivy"ch.qos.logback:logback-classic:1.4.6"
5454
def macroParadise = ivy"org.scalamacros:::paradise:2.1.1"
5555
def monix = ivy"io.monix::monix:3.2.0"
5656
def munit = ivy"org.scalameta::munit:0.7.29"
5757
def nailgun = ivy"io.github.alexarchambault.bleep:nailgun-server:1.0.7"
5858
def osLib = ivy"com.lihaoyi::os-lib:0.9.0"
5959
def pprint = ivy"com.lihaoyi::pprint:0.8.1"
60-
def sbtTestAgent = ivy"org.scala-sbt:test-agent:1.9.6"
60+
def sbtTestAgent = ivy"org.scala-sbt:test-agent:1.9.7"
6161
def sbtTestInterface = ivy"org.scala-sbt:test-interface:1.0"
6262
def scalaDebugAdapter = ivy"ch.epfl.scala::scala-debug-adapter:3.1.4"
6363
def scalaJsLinker1 = ivy"org.scala-js::scalajs-linker:$scalaJs1Version"
@@ -66,12 +66,12 @@ object Dependencies {
6666
def scalaJsEnvJsdomNode1 = ivy"org.scala-js::scalajs-env-jsdom-nodejs:1.1.0"
6767
def scalaJsSbtTestAdapter1 = ivy"org.scala-js::scalajs-sbt-test-adapter:$scalaJs1Version"
6868
def scalaJsLogging1 = ivy"org.scala-js::scalajs-logging:1.1.1"
69-
def scalaNativeTools04 = ivy"org.scala-native::tools:0.4.15"
69+
def scalaNativeTools04 = ivy"org.scala-native::tools:0.4.16"
7070
def scalazCore = ivy"org.scalaz::scalaz-core:7.3.7"
7171
def snailgun = ivy"io.github.alexarchambault.scala-cli.snailgun::snailgun-core:0.4.1-sc2"
7272
def sourcecode = ivy"com.lihaoyi::sourcecode:0.3.1"
7373
def svm = ivy"org.graalvm.nativeimage:svm:$graalvmVersion"
74-
def utest = ivy"com.lihaoyi::utest:0.8.1"
74+
def utest = ivy"com.lihaoyi::utest:0.8.2"
7575
def xxHashLibrary = ivy"net.jpountz.lz4:lz4:1.3.0"
7676
def zinc = ivy"org.scala-sbt::zinc:1.9.5"
7777
def zipkinSender = ivy"io.zipkin.reporter2:zipkin-sender-urlconnection:2.16.4"

frontend/src/main/scala/bloop/data/Project.scala

+9-31
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,8 @@ import bloop.io.ByteHasher
2323
import bloop.logging.DebugFilter
2424
import bloop.logging.Logger
2525
import bloop.task.Task
26+
import bloop.util.JavaRuntime
2627

27-
import com.typesafe.config.ConfigException
28-
import com.typesafe.config.ConfigFactory
29-
import com.typesafe.config.ConfigParseOptions
30-
import com.typesafe.config.ConfigSyntax
3128
import scalaz.Cord
3229
import xsbti.compile.ClasspathOptions
3330
import xsbti.compile.CompileOrder
@@ -225,39 +222,20 @@ final case class Project(
225222
case i => i
226223
}
227224
}
228-
def getJavaVersionFromJavaHome(javaHome: AbsolutePath): String = {
229-
val releaseFile = javaHome.resolve("release")
230-
def rtJar = javaHome.resolve("lib").resolve("rt.jar")
231-
if (releaseFile.exists) {
232-
val properties = ConfigFactory.parseFile(
233-
releaseFile.toFile,
234-
ConfigParseOptions.defaults().setSyntax(ConfigSyntax.PROPERTIES)
235-
)
236-
try properties.getString("JAVA_VERSION").stripPrefix("\"").stripSuffix("\"")
237-
catch {
238-
case _: ConfigException =>
239-
logger.error(
240-
s"$javaHome release file missing JAVA_VERSION property - using Bloop's JVM version ${Properties.javaVersion}"
241-
)
242-
Properties.javaVersion
243-
}
244-
} else if (rtJar.exists) {
245-
// jdk 8 doesn't have `release` file
246-
"1.8.0"
247-
} else {
248-
logger.error(
249-
s"No `release` file found in $javaHome - using Bloop's JVM version ${Properties.javaVersion}"
250-
)
251-
Properties.javaVersion
252-
}
253-
}
254225

255226
val compileVersion = compileJdkConfig
256227
.map(f =>
257228
if (f.javaHome == AbsolutePath(Properties.javaHome))
258229
Properties.javaVersion
259230
else
260-
getJavaVersionFromJavaHome(f.javaHome)
231+
JavaRuntime.getJavaVersionFromJavaHome(f.javaHome).getOrElse {
232+
233+
logger.error(
234+
s"${f.javaHome} release file missing JAVA_VERSION property - using Bloop's JVM version ${Properties.javaVersion}"
235+
)
236+
237+
Properties.javaVersion
238+
}
261239
)
262240
.getOrElse(Properties.javaVersion)
263241
.split("-")

frontend/src/main/scala/bloop/testing/TestInternals.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ object TestInternals {
7979
* @return A function that determines whether a test should be run given its FQCN.
8080
*/
8181
def parseFilters(filters: List[String]): String => Boolean = {
82-
val (exclusionFilters, inclusionFilters) = filters.partition(_.startsWith("-"))
82+
val (exclusionFilters, inclusionFilters) = filters.map(_.trim).partition(_.startsWith("-"))
8383
val inc = inclusionFilters.map(toPattern)
8484
val exc = exclusionFilters.map(f => toPattern(f.tail))
8585

0 commit comments

Comments
 (0)