Skip to content

Commit e81ec12

Browse files
authored
Send actionable text edit in data field (#1448)
1 parent 1ea18c8 commit e81ec12

File tree

9 files changed

+46
-33
lines changed

9 files changed

+46
-33
lines changed

modules/build/src/main/scala/scala/build/ConsoleBloopBuildClient.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ class ConsoleBloopBuildClient(
6262
updatedDiag.setRelatedInformation(diag.getRelatedInformation)
6363
updatedDiag.setSeverity(diag.getSeverity)
6464
updatedDiag.setSource(diag.getSource)
65+
updatedDiag.setData(diag.getData)
6566

6667
(originalPath, updatedDiag)
6768
}

modules/build/src/main/scala/scala/build/bsp/BspClient.scala

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,11 @@ import java.nio.file.Paths
88
import java.util.concurrent.{ConcurrentHashMap, ExecutorService}
99

1010
import scala.build.Position.File
11+
import scala.build.bsp.protocol.TextEdit
1112
import scala.build.errors.{BuildException, CompositeBuildException, Diagnostic, Severity}
1213
import scala.build.postprocessing.LineConversion
1314
import scala.build.{BloopBuildClient, GeneratedSource, Logger}
14-
import scala.jdk.CollectionConverters._
15+
import scala.jdk.CollectionConverters.*
1516

1617
class BspClient(
1718
readFilesEs: ExecutorService,
@@ -194,10 +195,9 @@ class BspClient(
194195
val bDiag =
195196
new b.Diagnostic(range, diag.message)
196197

197-
diag.relatedInformation.foreach { relatedInformation =>
198-
val location = new b.Location(path.toNIO.toUri.toASCIIString, range)
199-
val related = new b.DiagnosticRelatedInformation(location, relatedInformation.message)
200-
bDiag.setRelatedInformation(List(related).asJava)
198+
diag.textEdit.foreach { textEdit =>
199+
val bTextEdit = TextEdit(range, textEdit.newText)
200+
bDiag.setData(bTextEdit.toJsonTree())
201201
}
202202
bDiag.setSeverity(diag.severity.toBsp4j)
203203
bDiag.setSource("scala-cli")

modules/build/src/main/scala/scala/build/bsp/package.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ package object bsp {
111111
)
112112
diag0.setSeverity(diag.getSeverity)
113113
diag0.setSource(diag.getSource)
114+
diag0.setData(diag.getData)
114115
diag0
115116
}
116117
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package scala.build.bsp.protocol
2+
3+
import ch.epfl.scala.bsp4j as b
4+
import com.google.gson.Gson
5+
6+
case class TextEdit(range: b.Range, newText: String) {
7+
def toJsonTree() = new Gson().toJsonTree(this)
8+
}

modules/cli/src/main/resources/META-INF/native-image/org.virtuslab/scala-cli-core/reflect-config.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1095,6 +1095,13 @@
10951095
"allDeclaredMethods": true,
10961096
"allDeclaredFields": true
10971097
},
1098+
{
1099+
"name": "scala.build.bsp.protocol.TextEdit",
1100+
"allDeclaredConstructors": true,
1101+
"allPublicConstructors": true,
1102+
"allDeclaredMethods": true,
1103+
"allDeclaredFields": true
1104+
},
10981105
{
10991106
"name": "scala.cli.commands.BloopJson",
11001107
"allDeclaredConstructors": true,

modules/cli/src/main/scala/scala/cli/internal/CliLogger.scala

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import org.scalajs.logging.{Level => ScalaJsLevel, Logger => ScalaJsLogger, Scal
99
import java.io.PrintStream
1010

1111
import scala.build.blooprifle.BloopRifleLogger
12-
import scala.build.errors.Diagnostic.RelatedInformation
12+
import scala.build.bsp.protocol.TextEdit
1313
import scala.build.errors.{BuildException, CompositeBuildException, Diagnostic, Severity}
1414
import scala.build.internal.CustomProgressBarRefreshDisplay
1515
import scala.build.{ConsoleBloopBuildClient, Logger, Position}
@@ -32,7 +32,7 @@ class CliLogger(
3232
d.severity,
3333
d.message,
3434
hashMap,
35-
d.relatedInformation
35+
d.textEdit
3636
)
3737
}
3838
}
@@ -59,7 +59,7 @@ class CliLogger(
5959
severity: Severity,
6060
message: String,
6161
contentCache: mutable.Map[os.Path, Seq[String]],
62-
relatedInformation: Option[RelatedInformation]
62+
textEditOpt: Option[Diagnostic.TextEdit]
6363
) =
6464
if (positions.isEmpty)
6565
out.println(
@@ -83,13 +83,9 @@ class CliLogger(
8383
diag.setSeverity(severity.toBsp4j)
8484
diag.setSource("scala-cli")
8585

86-
for {
87-
filePath <- f.path
88-
info <- relatedInformation
89-
} {
90-
val location = new Location(filePath.toNIO.toUri.toASCIIString, range)
91-
val related = new b.DiagnosticRelatedInformation(location, info.message)
92-
diag.setRelatedInformation(List(related).asJava)
86+
for (textEdit <- textEditOpt) {
87+
val bTextEdit = TextEdit(range, textEdit.newText)
88+
diag.setData(bTextEdit.toJsonTree())
9389
}
9490

9591
for (file <- f.path) {

modules/core/src/main/scala/scala/build/errors/Diagnostic.scala

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
11
package scala.build.errors
22

33
import scala.build.Position
4-
import scala.build.errors.Diagnostic.RelatedInformation
4+
import scala.build.errors.Diagnostic.TextEdit
55

66
trait Diagnostic {
77
def message: String
88
def severity: Severity
99
def positions: Seq[Position]
10-
def relatedInformation: Option[RelatedInformation] = None
10+
def textEdit: Option[TextEdit] = None
1111
}
1212

1313
object Diagnostic {
14-
15-
case class RelatedInformation(message: String)
14+
case class TextEdit(newText: String)
1615
object Messages {
1716
val bloopTooOld =
1817
"JVM that is hosting bloop is older than the requested runtime. Please run `scala-cli bloop exit`, and then use `--jvm` flag to restart Bloop"

modules/integration/src/test/scala/scala/cli/integration/BspTestDefinitions.scala

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ import ch.epfl.scala.bsp4j as b
55
import com.eed3si9n.expecty.Expecty.expect
66
import com.github.plokhotnyuk.jsoniter_scala.core.*
77
import com.github.plokhotnyuk.jsoniter_scala.macros.*
8-
import com.google.gson.Gson
98
import com.google.gson.internal.LinkedTreeMap
9+
import com.google.gson.{Gson, JsonElement}
1010
import org.eclipse.lsp4j.jsonrpc.messages.ResponseError
1111

1212
import java.net.URI
@@ -1187,7 +1187,7 @@ abstract class BspTestDefinitions(val scalaVersionOpt: Option[String])
11871187
|""".stripMargin
11881188
)
11891189
withBsp(inputs, Seq(".", "--actions")) {
1190-
(root, localClient, remoteServer) =>
1190+
(_, localClient, remoteServer) =>
11911191
async {
11921192
// prepare build
11931193
val buildTargetsResp = await(remoteServer.workspaceBuildTargets().asScala)
@@ -1215,11 +1215,16 @@ abstract class BspTestDefinitions(val scalaVersionOpt: Option[String])
12151215
strictlyCheckMessage = false
12161216
)
12171217

1218-
val relatedInformation = updateActionableDiagnostic.getRelatedInformation().asScala.head
1219-
expect(relatedInformation.getMessage.contains("com.lihaoyi::os-lib:"))
1220-
expect(
1221-
relatedInformation.getLocation().getUri() == (root / fileName).toNIO.toUri.toASCIIString
1218+
val textEdit = new Gson().fromJson[TextEdit](
1219+
updateActionableDiagnostic.getData().asInstanceOf[JsonElement],
1220+
classOf[TextEdit]
12221221
)
1222+
1223+
expect(textEdit.newText.contains("com.lihaoyi::os-lib:"))
1224+
expect(textEdit.range.getStart.getLine == 0)
1225+
expect(textEdit.range.getStart.getCharacter == 15)
1226+
expect(textEdit.range.getEnd.getLine == 0)
1227+
expect(textEdit.range.getEnd.getCharacter == 40)
12231228
}
12241229
}
12251230
}
@@ -1304,4 +1309,6 @@ object BspTestDefinitions {
13041309
)
13051310
private val detailsCodec: JsonValueCodec[Details] = JsonCodecMaker.make
13061311

1312+
private final case class TextEdit(range: b.Range, newText: String)
1313+
13071314
}

modules/options/src/main/scala/scala/build/actionable/ActionableDiagnostic.scala

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,18 @@ package scala.build.actionable
33
import dependency._
44

55
import scala.build.Position
6-
import scala.build.errors.Diagnostic.RelatedInformation
6+
import scala.build.errors.Diagnostic.TextEdit
77
import scala.build.errors.{Diagnostic, Severity}
88

99
abstract class ActionableDiagnostic extends Diagnostic {
1010

11-
/** Provide the message of actionable diagnostic
12-
*/
13-
def message: String
14-
1511
/** Provide the new content which will be replaced by actionable diagnostic
1612
*/
1713
def suggestion: String
1814

19-
def positions: Seq[Position]
20-
2115
override def severity = Severity.Hint
2216

23-
override def relatedInformation: Option[RelatedInformation] = Some(RelatedInformation(suggestion))
17+
override def textEdit: Option[TextEdit] = Some(TextEdit(suggestion))
2418
}
2519

2620
object ActionableDiagnostic {

0 commit comments

Comments
 (0)