Skip to content

Commit

Permalink
save delegate info
Browse files Browse the repository at this point in the history
  • Loading branch information
kasiaMarek committed Apr 5, 2024
1 parent 9cc2b74 commit 258ce9f
Show file tree
Hide file tree
Showing 5 changed files with 131 additions and 9 deletions.
Original file line number Diff line number Diff line change
@@ -1,15 +1,48 @@
package scala.meta.internal.metals

import scala.meta.io.AbsolutePath
import MetalsEnrichments._
import scala.util.control.NonFatal

class DelegatingFolderService(
folder: AbsolutePath,
folderVisibleName: Option[String],
val service: MetalsLspService,
) extends Folder(folder, folderVisibleName, isKnownMetalsProject = true)
with FolderService
with FolderService {

def writeSetting() = {
try {
DelegateSetting.writeDeleteSetting(folder, service.path)
} catch {
case NonFatal(_) =>
}
}

}

object DelegatingFolderService {
def apply(folder: Folder, service: MetalsLspService) =
new DelegatingFolderService(folder.path, folder.visibleName, service)
}

object DelegateSetting {
private val settingName = "delegate"

def writeDeleteSetting(folder: AbsolutePath, servicePath: AbsolutePath) = {
val relPath = servicePath.toRelative(folder)
val jsonText = ujson.Obj(settingName -> relPath.toString()).toString()
folder.resolve(Directories.metalsSettings).writeText(jsonText)

}

def readDeleteSetting(folder: AbsolutePath): Option[AbsolutePath] =
for {
text <- folder.resolve(Directories.metalsSettings).readTextOpt
json = ujson.read(text)
relPath <- json(settingName).strOpt
path = folder.resolve(relPath).dealias
if path.exists
} yield path

}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ object Directories {
RelativePath(".bazelbsp")
def bsp: RelativePath =
RelativePath(".bsp")
def metalsSettings: RelativePath =
RelativePath(".metals").resolve("settings.json")

val stacktraceFilename = "stacktrace.scala"
val dependenciesName = "dependencies"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import java.util.concurrent.atomic.AtomicReference
import scala.concurrent.ExecutionContext
import scala.concurrent.Future

import scala.meta.internal.metals.MetalsEnrichments.XtensionBuildTarget
import scala.meta.internal.metals.MetalsEnrichments._
import scala.meta.internal.metals.logging.MetalsLogger

class WorkspaceFolders(
Expand All @@ -23,9 +23,22 @@ class WorkspaceFolders(
case (Nil, nonScala) => (List(nonScala.head), nonScala.tail)
case t => t
}
val services = scalaProjects.map(createService(_))
val scalaServices =
scalaProjects.filter(_.optDelegatePath.isEmpty).map(createService)
val delegating = scalaProjects.flatMap { folder =>
for {
delegate <- folder.optDelegatePath
service <- scalaServices.find(_.path == delegate)
} yield DelegatingFolderService(folder, service)
}
val allServices = scalaServices ++ delegating
val other = scalaProjects.filterNot(isIn(allServices, _)).map(createService)
new AtomicReference(
WorkspaceFoldersServices(services, Nil, nonScalaProjects)
WorkspaceFoldersServices(
scalaServices ++ other,
delegating,
nonScalaProjects,
)
)
}

Expand All @@ -44,7 +57,7 @@ class WorkspaceFolders(
def shouldBeRemoved(folder: Folder) =
actualToRemove.exists(_.path == folder.path)

val WorkspaceFoldersServices(prev, _, _) =
val WorkspaceFoldersServices(prev, prevDel, _) =
folderServices.getAndUpdate {
case WorkspaceFoldersServices(
services,
Expand Down Expand Up @@ -99,6 +112,7 @@ class WorkspaceFolders(
shutdownMetals()
} else {
setupLogger()
delegatingServices.filterNot(isIn(prevDel, _)).foreach(_.writeSetting())

val services = getFolderServices.filterNot(isIn(prev, _))
for {
Expand Down Expand Up @@ -143,9 +157,9 @@ class WorkspaceFolders(
.map(_ => service.initialized())
Some(service)
case None =>
delegating.collectFirst {
case del if del.path == folder.path => del.service
}
val delService = delegating.find(_.path == folder.path)
delService.foreach(_.writeSetting())
delService.map(_.service)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1286,6 +1286,10 @@ class Folder(
lazy val isMetalsProject: Boolean =
isKnownMetalsProject || path.resolve(".metals").exists || path
.isMetalsProject()

lazy val optDelegatePath: Option[AbsolutePath] =
DelegateSetting.readDeleteSetting(path)

def nameOrUri: String = visibleName.getOrElse(path.toString())
}

Expand Down
71 changes: 70 additions & 1 deletion tests/slow/src/test/scala/tests/sbt/WorkspaceFolderSuite.scala
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import org.eclipse.lsp4j.WorkspaceFolder
import org.eclipse.lsp4j.WorkspaceFoldersChangeEvent
import tests.BaseImportSuite
import tests.QuickBuild
import scala.meta.internal.metals.DelegateSetting

class WorkspaceFolderSuite extends BaseImportSuite("sbt-workspace-suite") {

Expand All @@ -21,7 +22,7 @@ class WorkspaceFolderSuite extends BaseImportSuite("sbt-workspace-suite") {
override def currentDigest(workspace: AbsolutePath): Option[String] =
SbtDigest.current(projectRoot)

test("add-workspace-project") {
test("add-delegating-service") {
cleanWorkspace()
val libraryFolder = "library-folder"

Expand Down Expand Up @@ -117,6 +118,74 @@ class WorkspaceFolderSuite extends BaseImportSuite("sbt-workspace-suite") {
| ^
|""".stripMargin,
)
_ = assertEquals(
DelegateSetting.readDeleteSetting(workspace.resolve(libraryFolder)),
Some(workspace.resolve("main-folder")),
)
} yield ()
}

test("open-delegating-service") {
cleanWorkspace()
val libraryFolder = "library-folder"

writeLayout(
s"""|/$libraryFolder/project/build.properties
|sbt.version=${V.sbtVersion}
|/$libraryFolder/project/plugins.sbt
|addSbtPlugin("ch.epfl.scala" % "sbt-bloop" % "${V.sbtBloopVersion}")
|/$libraryFolder/build.sbt
|scalaVersion := "${V.scala213}"
|lazy val libraryProject = project.in(file("."))
|/$libraryFolder/metals.json
|{
| "libraryProject": {
| "scalaVersion": "${V.scala213}"
| }
|}
|/$libraryFolder/src/main/scala/example/A.scala
|package example
|object A {
| val i = 3
|}
|""".stripMargin
)

DelegateSetting.writeDeleteSetting(
workspace.resolve(libraryFolder),
workspace.resolve("main-folder"),
)

QuickBuild.bloopInstall(workspace.resolve(libraryFolder))

for {
_ <- initialize(
Map(
libraryFolder ->
"",
"main-folder" ->
s"""|/project/build.properties
|sbt.version=${V.sbtVersion}
|/build.sbt
|scalaVersion := "${V.scala213}"
|lazy val root = project.in(file(".")).dependsOn(ProjectRef(file("../$libraryFolder"), "libraryProject"))
|/src/main/scala/a/Main.scala
|package a
|import example.A
|object Main {
| val j: Int = A.i
|}
|""".stripMargin,
),
expectError = false,
)
_ <- server.didOpen("main-folder/src/main/scala/a/Main.scala")
_ = assertNoDiagnostics()
_ = assertEquals(
server.fullServer.folderServices.size,
1,
"should not create folder service for project ref",
)
} yield ()
}
}

0 comments on commit 258ce9f

Please sign in to comment.