Merge pull request #3779 from eed3si9n/wip/onNotification

LSP: added handler for notification messages
This commit is contained in:
Dale Wijnand 2017-11-29 08:10:42 +00:00 committed by GitHub
commit c02baa177e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 32 additions and 8 deletions

View File

@ -34,6 +34,15 @@ private[sbt] trait LanguageServerProtocol extends CommandChannel {
protected def log: Logger
protected def onSettingQuery(execId: Option[String], req: Q): Unit
protected def onNotification(notification: JsonRpcNotificationMessage): Unit = {
log.debug(s"onNotification: $notification")
notification.method match {
case "textDocument/didSave" =>
append(Exec(";compile; collectAnalyses", None, Some(CommandSource(name))))
case u => log.debug(s"Unhandled notification received: $u")
}
}
protected def onRequestMessage(request: JsonRpcRequestMessage): Unit = {
import sbt.internal.langserver.codec.JsonProtocol._
import internalJsonProtocol._
@ -57,8 +66,6 @@ private[sbt] trait LanguageServerProtocol extends CommandChannel {
setInitialized(true)
append(Exec(s"collectAnalyses", Some(request.id), Some(CommandSource(name))))
langRespond(InitializeResult(serverCapabilities), Option(request.id))
case "textDocument/didSave" =>
append(Exec(";compile; collectAnalyses", Some(request.id), Some(CommandSource(name))))
case "textDocument/definition" =>
import scala.concurrent.ExecutionContext.Implicits.global
Definition.lspDefinition(json, request.id, CommandSource(name), log)

View File

@ -18,6 +18,7 @@ import sbt.protocol._
import sbt.internal.langserver.ErrorCodes
import sbt.internal.util.{ ObjectEvent, StringEvent }
import sbt.internal.util.codec.JValueFormats
import sbt.internal.protocol.{ JsonRpcRequestMessage, JsonRpcNotificationMessage }
import sbt.util.Logger
final class NetworkChannel(val name: String,
@ -166,8 +167,8 @@ final class NetworkChannel(val name: String,
def handleBody(chunk: Vector[Byte]): Unit = {
if (isLanguageServerProtocol) {
Serialization.deserializeJsonRequest(chunk) match {
case Right(req) =>
Serialization.deserializeJsonMessage(chunk) match {
case Right(req: JsonRpcRequestMessage) =>
try {
onRequestMessage(req)
} catch {
@ -175,6 +176,16 @@ final class NetworkChannel(val name: String,
log.debug(s"sending error: $code: $message")
langError(Option(req.id), code, message)
}
case Right(ntf: JsonRpcNotificationMessage) =>
try {
onNotification(ntf)
} catch {
case LangServerError(code, message) =>
log.debug(s"sending error: $code: $message")
langError(None, code, message) // new id?
}
case Right(msg) =>
log.debug(s"Unhandled message: $msg")
case Left(errorDesc) =>
val msg = s"Got invalid chunk from client (${new String(chunk.toArray, "UTF-8")}): " + errorDesc
langError(None, ErrorCodes.ParseError, msg)

View File

@ -15,6 +15,7 @@ import java.nio.ByteBuffer
import scala.util.{ Success, Failure }
import sbt.internal.util.StringEvent
import sbt.internal.protocol.{
JsonRpcMessage,
JsonRpcRequestMessage,
JsonRpcResponseMessage,
JsonRpcNotificationMessage
@ -143,15 +144,20 @@ object Serialization {
}
}
private[sbt] def deserializeJsonRequest(
bytes: Seq[Byte]): Either[String, JsonRpcRequestMessage] = {
private[sbt] def deserializeJsonMessage(bytes: Seq[Byte]): Either[String, JsonRpcMessage] = {
val buffer = ByteBuffer.wrap(bytes.toArray)
Parser.parseFromByteBuffer(buffer) match {
case Success(json) =>
import sbt.internal.protocol.codec.JsonRPCProtocol._
Converter.fromJson[JsonRpcRequestMessage](json) match {
case Success(msg) => Right(msg)
case Failure(e) => throw e
case Success(request) if (request.id.nonEmpty) => Right(request)
case Failure(e) => throw e
case _ => {
Converter.fromJson[JsonRpcNotificationMessage](json) match {
case Success(notification) => Right(notification)
case Failure(e) => throw e
}
}
}
case Failure(e) =>
Left(s"Parse error: ${e.getMessage}")