Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixing shutdown routine #53

Merged
merged 4 commits into from
Nov 23, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions build.sbt
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
inThisBuild(
List(
version ~= { old =>
if (sys.env.contains("CI")) old
else "0.1-SNAPSHOT" // to avoid manually updating extension.js
},
scalaVersion := "2.12.3",
organization := "org.scalameta",
licenses := Seq(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class LanguageServer(inStream: InputStream, outStream: OutputStream) extends Laz

case (_, Shutdown()) =>
shutdown()
ShutdownResult(0) // the value is a dummy, because Play Json needs to serialize something
ShutdownResult()
case c =>
logger.error(s"Unknown command $c")
sys.error("Unknown command")
Expand All @@ -40,6 +40,7 @@ class LanguageServer(inStream: InputStream, outStream: OutputStream) extends Laz
protected val documentManager = new TextDocumentManager(connection)

connection.notificationHandlers += {
case Exit() => onExit()
case DidOpenTextDocumentParams(td) => onOpenTextDocument(td)
case DidChangeTextDocumentParams(td, changes) => onChangeTextDocument(td, changes)
case DidSaveTextDocumentParams(td) => onSaveTextDocument(td)
Expand All @@ -52,6 +53,12 @@ class LanguageServer(inStream: InputStream, outStream: OutputStream) extends Laz
connection.start()
}

def onExit(): Unit = {
logger.debug("exit")
// TODO: should exit with success code 0 if the shutdown request has been received before; otherwise with error code 1
sys.exit(0)
}

def onOpenTextDocument(td: TextDocumentItem) = {
logger.debug(s"openTextDocuemnt $td")
}
Expand Down Expand Up @@ -82,9 +89,7 @@ class LanguageServer(inStream: InputStream, outStream: OutputStream) extends Laz
CompletionList(isIncomplete = false, Nil)
}

def shutdown(): Unit = {

}
def shutdown(): Unit = {}

def gotoDefinitionRequest(textDocument: TextDocumentIdentifier, position: Position): DefinitionResult = {
DefinitionResult(Seq.empty[Location])
Expand Down
35 changes: 26 additions & 9 deletions languageserver/src/main/scala/langserver/messages/Commands.scala
Original file line number Diff line number Diff line change
Expand Up @@ -141,13 +141,13 @@ object CompletionList {
case class InitializeResult(capabilities: ServerCapabilities) extends ResultResponse

case class Shutdown() extends ServerCommand
object Shutdown {
implicit val format: Format[Shutdown] = OFormat(
Reads(jsValue => JsSuccess(Shutdown())),
OWrites[Shutdown](s => Json.obj()))
}

case class ShutdownResult(dummy: Int) extends ResultResponse
case class ShutdownResult() extends ResultResponse
object ShutdownResult {
implicit val format: Format[ShutdownResult] = OFormat(
Reads(jsValue => JsSuccess(ShutdownResult())),
OWrites[ShutdownResult](s => Json.obj()))
}

case class ShowMessageRequestParams(
/**
Expand Down Expand Up @@ -193,13 +193,20 @@ object ServerCommand extends CommandCompanion[ServerCommand] {

override val CommandFormats = Message.MessageFormats(
"initialize" -> Json.format[InitializeParams],
"shutdown" -> Shutdown.format,
"textDocument/completion" -> valueFormat(TextDocumentCompletionRequest)(_.params),
"textDocument/definition" -> valueFormat(TextDocumentDefinitionRequest)(_.params),
"textDocument/hover" -> valueFormat(TextDocumentHoverRequest)(_.params),
"textDocument/documentSymbol" -> Json.format[DocumentSymbolParams],
"textDocument/formatting" -> valueFormat(TextDocumentFormattingRequest)(_.params)
)

// NOTE: this is a workaround to read `shutdown` request which doesn't have parameters (scala-json-rpc requires parameters for all requests)
override def read(jsonRpcRequestMessage: JsonRpcRequestMessage): JsResult[_ <: ServerCommand] = {
jsonRpcRequestMessage.method match {
case "shutdown" => JsSuccess(Shutdown())
case _ => super.read(jsonRpcRequestMessage)
}
}
}

object ClientCommand extends CommandCompanion[ClientCommand] {
Expand All @@ -217,7 +224,8 @@ case class PublishDiagnostics(uri: String, diagnostics: Seq[Diagnostic]) extends

// from client to server

case class ExitNotification() extends Notification
case class Exit() extends Notification

case class DidOpenTextDocumentParams(textDocument: TextDocumentItem) extends Notification
case class DidChangeTextDocumentParams(
textDocument: VersionedTextDocumentIdentifier,
Expand Down Expand Up @@ -259,6 +267,14 @@ object Notification extends NotificationCompanion[Notification] {
"initialized" -> Initialized.format,
"$/cancelRequest" -> Json.format[CancelRequest]
)

// NOTE: this is a workaround to read `exit` notification which doesn't have parameters (scala-json-rpc requires parameters for all notifications)
override def read(jsonRpcNotificationMessage: JsonRpcNotificationMessage): JsResult[_ <: Notification] = {
jsonRpcNotificationMessage.method match {
case "exit" => JsSuccess(Exit())
case _ => super.read(jsonRpcNotificationMessage)
}
}
}

case class DocumentSymbolResult(params: Seq[SymbolInformation]) extends ResultResponse
Expand All @@ -275,5 +291,6 @@ object ResultResponse extends ResponseCompanion[Any] {
"textDocument/hover" -> Json.format[Hover],
"textDocument/documentSymbol" -> valueFormat(DocumentSymbolResult)(_.params),
"textDocument/formatting" -> valueFormat(DocumentFormattingResult)(_.params),
"shutdown" -> Json.format[ShutdownResult])
"shutdown" -> ShutdownResult.format
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -155,27 +155,20 @@ class ScalametaLanguageServer(
td: TextDocumentIdentifier,
options: FormattingOptions
): List[TextEdit] = {
try {
val path = Uri.toPath(td.uri).get
val contents = buffers.read(path)
val fullDocumentRange = Range(
start = Position(0, 0),
end = Position(Int.MaxValue, Int.MaxValue)
)
val config = cwd.resolve(".scalafmt.conf")
if (Files.isRegularFile(config.toNIO)) {
val formattedContent =
scalafmt.format(contents, path.toString(), config)
List(TextEdit(fullDocumentRange, formattedContent))
} else {
connection.showMessage(MessageType.Info, s"Missing $config")
Nil
}
} catch {
case NonFatal(e) =>
connection.showMessage(MessageType.Error, e.getMessage)
logger.error(e.getMessage, e)
Nil
val path = Uri.toPath(td.uri).get
val contents = buffers.read(path)
val fullDocumentRange = Range(
start = Position(0, 0),
end = Position(Int.MaxValue, Int.MaxValue)
)
val config = cwd.resolve(".scalafmt.conf")
if (Files.isRegularFile(config.toNIO)) {
val formattedContent =
scalafmt.format(contents, path.toString(), config)
List(TextEdit(fullDocumentRange, formattedContent))
} else {
connection.showMessage(MessageType.Info, s"Missing $config")
Nil
}
}

Expand Down Expand Up @@ -263,27 +256,21 @@ class ScalametaLanguageServer(
td: TextDocumentIdentifier,
position: Position
): ResultResponse = {
try {
val completions = compiler.autocomplete(
Uri.toPath(td.uri).get,
position.line,
position.character
)
CompletionList(
isIncomplete = false,
items = completions.map {
case (signature, name) =>
CompletionItem(
label = name,
detail = Some(signature)
)
}
)
} catch {
case NonFatal(e) =>
onError(e)
ShutdownResult(-1)
}
val completions = compiler.autocomplete(
Uri.toPath(td.uri).get,
position.line,
position.character
)
CompletionList(
isIncomplete = false,
items = completions.map {
case (signature, name) =>
CompletionItem(
label = name,
detail = Some(signature)
)
}
)
}

override def hoverRequest(
Expand Down