diff --git a/main/src/main/scala/sbt/internal/server/LanguageServerProtocol.scala b/main/src/main/scala/sbt/internal/server/LanguageServerProtocol.scala index 761073591..8dc514d40 100644 --- a/main/src/main/scala/sbt/internal/server/LanguageServerProtocol.scala +++ b/main/src/main/scala/sbt/internal/server/LanguageServerProtocol.scala @@ -10,6 +10,7 @@ package internal package server import sjsonnew.JsonFormat +import sjsonnew.shaded.scalajson.ast.unsafe.JValue import sjsonnew.support.scalajson.unsafe.Converter import sbt.protocol.Serialization import sbt.protocol.{ SettingQuery => Q } @@ -81,9 +82,7 @@ private[sbt] object LanguageServerProtocol { }) } -/** - * Implements Language Server Protocol . - */ +/** Implements Language Server Protocol . */ private[sbt] trait LanguageServerProtocol extends CommandChannel { self => lazy val internalJsonProtocol = new InitializeOptionFormats with sjsonnew.BasicJsonProtocol {} @@ -136,9 +135,7 @@ private[sbt] trait LanguageServerProtocol extends CommandChannel { self => } } - /** - * Respond back to Language Server's client. - */ + /** Respond back to Language Server's client. */ private[sbt] def jsonRpcRespond[A: JsonFormat](event: A, execId: Option[String]): Unit = { val m = JsonRpcResponseMessage("2.0", execId, Option(Converter.toJson[A](event).get), None) @@ -146,34 +143,32 @@ private[sbt] trait LanguageServerProtocol extends CommandChannel { self => publishBytes(bytes) } - /** - * Respond back to Language Server's client. - */ - private[sbt] def jsonRpcRespondError(execId: Option[String], - code: Long, - message: String): Unit = { - val e = JsonRpcResponseError(code, message, None) + /** Respond back to Language Server's client. */ + private[sbt] def jsonRpcRespondError(execId: Option[String], code: Long, message: String): Unit = + jsonRpcRespondErrorImpl(execId, code, message, None) + + /** Respond back to Language Server's client. */ + private[sbt] def jsonRpcRespondError[A: JsonFormat]( + execId: Option[String], + code: Long, + message: String, + data: A, + ): Unit = + jsonRpcRespondErrorImpl(execId, code, message, Option(Converter.toJson[A](data).get)) + + private[this] def jsonRpcRespondErrorImpl( + execId: Option[String], + code: Long, + message: String, + data: Option[JValue], + ): Unit = { + val e = JsonRpcResponseError(code, message, data) val m = JsonRpcResponseMessage("2.0", execId, None, Option(e)) val bytes = Serialization.serializeResponseMessage(m) publishBytes(bytes) } - /** - * Respond back to Language Server's client. - */ - private[sbt] def jsonRpcRespondError[A: JsonFormat](execId: Option[String], - code: Long, - message: String, - data: A): Unit = { - val e = JsonRpcResponseError(code, message, Option(Converter.toJson[A](data).get)) - val m = JsonRpcResponseMessage("2.0", execId, None, Option(e)) - val bytes = Serialization.serializeResponseMessage(m) - publishBytes(bytes) - } - - /** - * Notify to Language Server's client. - */ + /** Notify to Language Server's client. */ private[sbt] def jsonRpcNotify[A: JsonFormat](method: String, params: A): Unit = { val m = JsonRpcNotificationMessage("2.0", method, Option(Converter.toJson[A](params).get)) diff --git a/protocol/src/main/scala/sbt/protocol/Serialization.scala b/protocol/src/main/scala/sbt/protocol/Serialization.scala index 75b9e7c83..21d798b80 100644 --- a/protocol/src/main/scala/sbt/protocol/Serialization.scala +++ b/protocol/src/main/scala/sbt/protocol/Serialization.scala @@ -8,7 +8,7 @@ package sbt package protocol -import sjsonnew.JsonFormat +import sjsonnew.{ JsonFormat, JsonWriter } import sjsonnew.support.scalajson.unsafe.{ Parser, Converter, CompactPrinter } import sjsonnew.shaded.scalajson.ast.unsafe.{ JValue, JObject, JString } import java.nio.ByteBuffer @@ -41,37 +41,31 @@ object Serialization { CompactPrinter(json).getBytes("UTF-8") } - /** - * This formats the message according to JSON-RPC. - * http://www.jsonrpc.org/specification - */ + /** This formats the message according to JSON-RPC. http://www.jsonrpc.org/specification */ private[sbt] def serializeResponseMessage(message: JsonRpcResponseMessage): Array[Byte] = { import sbt.internal.protocol.codec.JsonRPCProtocol._ - val json: JValue = Converter.toJson[JsonRpcResponseMessage](message).get - val body = CompactPrinter(json) - val bodyBytes = body.getBytes("UTF-8") - - (s"Content-Length: ${bodyBytes.size}\r\n" + - s"Content-Type: $VsCode\r\n" + - "\r\n" + - body).getBytes("UTF-8") + serializeResponse(message) } - /** - * This formats the message according to JSON-RPC. - * http://www.jsonrpc.org/specification - */ + /** This formats the message according to JSON-RPC. http://www.jsonrpc.org/specification */ private[sbt] def serializeNotificationMessage( - message: JsonRpcNotificationMessage): Array[Byte] = { + message: JsonRpcNotificationMessage, + ): Array[Byte] = { import sbt.internal.protocol.codec.JsonRPCProtocol._ - val json: JValue = Converter.toJson[JsonRpcNotificationMessage](message).get - val body = CompactPrinter(json) - val bodyBytes = body.getBytes("UTF-8") + serializeResponse(message) + } - (s"Content-Length: ${bodyBytes.size}\r\n" + - s"Content-Type: $VsCode\r\n" + - "\r\n" + - body).getBytes("UTF-8") + private[sbt] def serializeResponse[A: JsonWriter](message: A): Array[Byte] = { + val json: JValue = Converter.toJson[A](message).get + val body = CompactPrinter(json) + val bodyLength = body.getBytes("UTF-8").length + + Iterator( + s"Content-Length: $bodyLength", + s"Content-Type: $VsCode", + "", + body + ).mkString("\r\n").getBytes("UTF-8") } /**