Skip to content

Commit

Permalink
fix: correctly resolve project's java in doctor and problem resolver
Browse files Browse the repository at this point in the history
  • Loading branch information
kasiaMarek committed Jun 19, 2024
1 parent 78ded80 commit 5b1e040
Show file tree
Hide file tree
Showing 10 changed files with 169 additions and 159 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ final class InteractiveSemanticdbs(
tables: Tables,
compilers: () => Compilers,
semanticdbIndexer: () => SemanticdbIndexer,
javaInteractiveSemanticdb: Option[JavaInteractiveSemanticdb],
javaInteractiveSemanticdb: JavaInteractiveSemanticdb,
buffers: Buffers,
scalaCliServers: => ScalaCliServers,
) extends Cancelable
Expand Down Expand Up @@ -138,9 +138,7 @@ final class InteractiveSemanticdbs(
private def compile(source: AbsolutePath, text: String): Try[s.TextDocument] =
Try {
if (source.isJavaFilename)
javaInteractiveSemanticdb.fold(s.TextDocument())(
_.textDocument(source, text)
)
javaInteractiveSemanticdb.textDocument(source, text)
else compilers().semanticdbTextDocument(source, text)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ import scala.meta.internal.{semanticdb => s}
import scala.meta.io.AbsolutePath

class JavaInteractiveSemanticdb(
jdkVersion: JdkVersion,
pluginJars: List[Path],
workspace: AbsolutePath,
buildTargets: BuildTargets,
) {

private val readonly = workspace.resolve(Directories.readonly)

def textDocument(source: AbsolutePath, text: String): s.TextDocument = {
Expand Down Expand Up @@ -139,34 +139,32 @@ class JavaInteractiveSemanticdb(
//
// Currently there is no infrastucture to detect if package belong to jigsaw module or not
// so this case is covered only for JDK sources.
if (jdkVersion.hasJigsaw) {
source.toRelativeInside(readonly) match {
case Some(rel) =>
val names = rel.toNIO.iterator().asScala.toList.map(_.filename)
names match {
case Directories.dependenciesName :: JdkSources.zipFileName :: moduleName :: _ =>
List("--patch-module", s"$moduleName=$sourceRoot")
case _ =>
Nil
}
case None =>
if (
originalSource.jarPath.exists(_.filename == JdkSources.zipFileName)
) {
originalSource.toNIO
.iterator()
.asScala
.headOption
.map(_.filename)
.map(moduleName =>
List("--patch-module", s"$moduleName=$sourceRoot")
)
.getOrElse(Nil)
} else {
source.toRelativeInside(readonly) match {
case Some(rel) =>
val names = rel.toNIO.iterator().asScala.toList.map(_.filename)
names match {
case Directories.dependenciesName :: JdkSources.zipFileName :: moduleName :: _ =>
List("--patch-module", s"$moduleName=$sourceRoot")
case _ =>
Nil
}
}
} else Nil
}
case None =>
if (
originalSource.jarPath.exists(_.filename == JdkSources.zipFileName)
) {
originalSource.toNIO
.iterator()
.asScala
.headOption
.map(_.filename)
.map(moduleName =>
List("--patch-module", s"$moduleName=$sourceRoot")
)
.getOrElse(Nil)
} else {
Nil
}
}
}
}

Expand All @@ -175,12 +173,10 @@ object JavaInteractiveSemanticdb {
def create(
workspace: AbsolutePath,
buildTargets: BuildTargets,
jdkVersion: JdkVersion,
): JavaInteractiveSemanticdb = {

val pluginJars = Embedded.downloadSemanticdbJavac
new JavaInteractiveSemanticdb(
jdkVersion,
pluginJars,
workspace,
buildTargets,
Expand All @@ -191,10 +187,7 @@ object JavaInteractiveSemanticdb {
case class JdkVersion(
major: Int,
full: String,
) {

def hasJigsaw: Boolean = major >= 9
}
)

object JdkVersion {

Expand Down
17 changes: 17 additions & 0 deletions metals/src/main/scala/scala/meta/internal/metals/JdkInfo.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package scala.meta.internal.metals

import scala.concurrent.ExecutionContext

object JavaInfo {
def getInfo(
userJavaHome: Option[String]
)(implicit ec: ExecutionContext): Option[JavaInfo] =
for {
home <- JdkSources.defaultJavaHome(userJavaHome).headOption
version <- JdkVersion.maybeJdkVersionFromJavaHome(Some(home))
} yield JavaInfo(home.toString, version)
}

case class JavaInfo(home: String, version: JdkVersion) {
def print: String = s"${version.full} located at $home"
}
Original file line number Diff line number Diff line change
Expand Up @@ -170,10 +170,6 @@ abstract class MetalsLspService(
)

def javaHome = userConfig.javaHome
protected val optJavaHome: Option[AbsolutePath] =
JdkSources.defaultJavaHome(javaHome).headOption
protected val maybeJdkVersion: Option[JdkVersion] =
JdkVersion.maybeJdkVersionFromJavaHome(optJavaHome)

protected val fingerprints = new MutableMd5Fingerprints
protected val mtags = new Mtags
Expand Down Expand Up @@ -381,9 +377,8 @@ abstract class MetalsLspService(
}

protected val interactiveSemanticdbs: InteractiveSemanticdbs = {
val javaInteractiveSemanticdb = maybeJdkVersion.map(jdkVersion =>
JavaInteractiveSemanticdb.create(folder, buildTargets, jdkVersion)
)
val javaInteractiveSemanticdb =
JavaInteractiveSemanticdb.create(folder, buildTargets)
register(
new InteractiveSemanticdbs(
folder,
Expand Down Expand Up @@ -1607,10 +1602,8 @@ abstract class MetalsLspService(
tables,
clientConfig,
mtagsResolver,
() => userConfig.javaHome,
maybeJdkVersion,
getVisibleName,
() => projectInfo,
projectInfo,
)

val folderReportsZippper: FolderReportsZippper =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -673,8 +673,30 @@ class ProjectMetalsLspService(
() => bspConnector.resolve(buildTool),
buildTools,
connectionBspStatus,
() => getProjectsJavaInfo,
)

private def getProjectsJavaInfo: Option[JavaInfo] = {
val fromScalaTarget =
for {
scalaTarget <- mainBuildTargetsData.allScala.headOption
home <- scalaTarget.jvmHome.flatMap(_.toAbsolutePathSafe)
version <- scalaTarget.jvmVersion
.flatMap(JdkVersion.parse)
.orElse(JdkVersion.maybeJdkVersionFromJavaHome(Some(home)))
} yield JavaInfo(home.toString(), version)

fromScalaTarget.orElse {
val userJavaHome =
bspSession.flatMap {
// we don't respect `userConfig.javaHome` for Bazel
case bs if bs.main.isBazel => None
case _ => userConfig.javaHome
}
JavaInfo.getInfo(userJavaHome)
}
}

def ammoniteStart(): Future[Unit] = ammonite.start()
def ammoniteStop(): Future[Unit] = ammonite.stop()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,8 @@ import scala.meta.internal.metals.Diagnostics
import scala.meta.internal.metals.FileDecoderProvider
import scala.meta.internal.metals.HtmlBuilder
import scala.meta.internal.metals.Icons
import scala.meta.internal.metals.JavaInfo
import scala.meta.internal.metals.JavaTarget
import scala.meta.internal.metals.JdkSources
import scala.meta.internal.metals.JdkVersion
import scala.meta.internal.metals.Messages.CheckDoctor
import scala.meta.internal.metals.MetalsEnrichments._
import scala.meta.internal.metals.MtagsResolver
Expand Down Expand Up @@ -62,15 +61,13 @@ final class Doctor(
tables: Tables,
clientConfig: ClientConfiguration,
mtagsResolver: MtagsResolver,
javaHome: () => Option[String],
maybeJDKVersion: Option[JdkVersion],
folderName: String,
serviceInfo: () => MetalsServiceInfo,
serviceInfo: => MetalsServiceInfo,
)(implicit ec: ExecutionContext, rc: ReportContext)
extends TargetsInfoProvider {
private val hasProblems = new AtomicBoolean(false)
def currentBuildServer(): Option[BspSession] =
serviceInfo() match {
serviceInfo match {
case FallbackService => None
case projectService: ProjectService =>
projectService.currentBuildServer()
Expand All @@ -81,9 +78,8 @@ final class Doctor(
workspace,
mtagsResolver,
currentBuildServer,
javaHome,
() => clientConfig.isTestExplorerProvider(),
maybeJDKVersion,
() => serviceInfo.getJavaInfo(),
)

def isUnsupportedBloopVersion(): Boolean =
Expand All @@ -108,8 +104,12 @@ final class Doctor(
* Checks if there are any potential problems and if any, notifies the user.
*/
def check(headDoctor: HeadDoctor): Unit = {
scribe.info(s"running doctor check")
val scalaTargets = buildTargets.allScala.toList
val javaTargets = buildTargets.allJava.toList
scribe.info(
s"java targets: ${javaTargets.map(_.info.getDisplayName()).mkString(", ")}"
)
val summary = problemResolver.problemMessage(scalaTargets, javaTargets)
executeReloadDoctor(summary, headDoctor)
summary match {
Expand Down Expand Up @@ -137,7 +137,7 @@ final class Doctor(
buildTargets.allBuildTargetIds

private def selectedBuildToolMessage(): Option[(String, Boolean)] = {
serviceInfo() match {
serviceInfo match {
case FallbackService => None
case projectService: ProjectService =>
val isExplicitChoice =
Expand Down Expand Up @@ -167,7 +167,7 @@ final class Doctor(
* exists. (Message, Explict Choice)
*/
private def selectedBuildServerMessage(): (String, Boolean) = {
serviceInfo() match {
serviceInfo match {
case FallbackService =>
(s"Using scala-cli for fallback service.", false)
case projectInfo: ProjectService =>
Expand Down Expand Up @@ -205,12 +205,6 @@ final class Doctor(
}
}

def getJavaInfo(): Option[String] =
for {
home <- JdkSources.defaultJavaHome(javaHome()).headOption
version <- JdkVersion.maybeJdkVersionFromJavaHome(Some(home))
} yield s"${version.full} located at $home"

def buildTargetsJson(): DoctorFolderResults = {
val targetIds = allTargetIds()
val buildToolHeading = selectedBuildToolMessage().map(_._1)
Expand All @@ -219,7 +213,7 @@ final class Doctor(
val importBuildHeading = selectedImportBuildMessage()
val header =
DoctorFolderHeader(
getJavaInfo(),
serviceInfo.getJavaInfo().map(_.print),
buildToolHeading,
buildServerHeading,
importBuildHeading,
Expand Down Expand Up @@ -333,10 +327,10 @@ final class Doctor(
if (includeWorkspaceFolderName) {
html.element("h2")(_.text(folderName))
}
getJavaInfo().foreach { jdkMsg =>
serviceInfo.getJavaInfo().foreach { jdk =>
html.element("p") { builder =>
builder.bold("Project's Java: ")
builder.text(jdkMsg)
builder.text(jdk.print)
}
}

Expand Down Expand Up @@ -591,7 +585,7 @@ final class Doctor(
}

private def isServerResponsive: Option[Boolean] =
serviceInfo() match {
serviceInfo match {
case FallbackService => None
case projectInfo: ProjectService =>
projectInfo.bspStatus.isBuildServerResponsive
Expand Down Expand Up @@ -752,13 +746,21 @@ trait TargetsInfoProvider {
def getTargetsInfoForReports(): List[Map[String, String]]
}

sealed trait MetalsServiceInfo
sealed trait MetalsServiceInfo {
def getJavaInfo(): Option[JavaInfo]
}
object MetalsServiceInfo {
object FallbackService extends MetalsServiceInfo
object FallbackService extends MetalsServiceInfo {
def getJavaInfo(): Option[JavaInfo] = None
}

case class ProjectService(
currentBuildServer: () => Option[BspSession],
calculateNewBuildServer: () => BspResolvedResult,
buildTools: BuildTools,
bspStatus: ConnectionBspStatus,
) extends MetalsServiceInfo
javaInfo: () => Option[JavaInfo],
) extends MetalsServiceInfo {
def getJavaInfo(): Option[JavaInfo] = javaInfo()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import scala.collection.mutable.ListBuffer
import scala.meta.internal.bsp.BspSession
import scala.meta.internal.metals.BloopServers
import scala.meta.internal.metals.BuildInfo
import scala.meta.internal.metals.JavaInfo
import scala.meta.internal.metals.JavaTarget
import scala.meta.internal.metals.JdkSources
import scala.meta.internal.metals.JdkVersion
Expand All @@ -20,9 +21,8 @@ class ProblemResolver(
workspace: AbsolutePath,
mtagsResolver: MtagsResolver,
currentBuildServer: () => Option[BspSession],
javaHome: () => Option[String],
isTestExplorerProvider: () => Boolean,
maybeJDKVersion: Option[JdkVersion],
javaInfo: () => Option[JavaInfo],
) {

def isUnsupportedBloopVersion(): Boolean = {
Expand Down Expand Up @@ -236,7 +236,7 @@ class ProblemResolver(
case _ => None
}

def javaSourcesProblem = JdkSources(javaHome()) match {
def javaSourcesProblem = JdkSources(javaInfo().map(_.home)) match {
case Left(notFound) => Some(MissingJdkSources(notFound.candidates))
case Right(_) => None
}
Expand Down Expand Up @@ -336,12 +336,12 @@ class ProblemResolver(
javaTarget: JavaTarget
): Option[JavaProblem] = {
val releaseVersion = javaTarget.releaseVersion.flatMap(JdkVersion.parse)
releaseVersion.zip(maybeJDKVersion) match {
releaseVersion.zip(javaInfo().map(_.version)) match {
case Some((releaseVersion, jvmHomeVersion))
if jvmHomeVersion.major < releaseVersion.major =>
Some(
WrongJavaReleaseVersion(
jvmHomeVersion.toString(),
jvmHomeVersion.major.toString(),
releaseVersion.major.toString(),
)
)
Expand Down
Loading

0 comments on commit 5b1e040

Please sign in to comment.