Skip to content

Commit

Permalink
(#248) LSP: more robust service calls, log more errors
Browse files Browse the repository at this point in the history
  • Loading branch information
ForNeVeR committed Mar 24, 2024
1 parent da0afde commit ca0f32f
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
*/
package com.intellij.plugin.powershell.lang.lsp.ide

import com.intellij.openapi.diagnostic.logger
import com.intellij.openapi.diagnostic.thisLogger
import com.intellij.openapi.progress.ProcessCanceledException
import com.intellij.plugin.powershell.lang.lsp.languagehost.LanguageServerEndpoint
Expand All @@ -22,42 +23,36 @@ class LSPRequestManager(
private fun checkStatus(): Boolean = serverEndpoint.isRunning

suspend fun didClose(params: DidCloseTextDocumentParams) {
if (checkStatus()) {
handleServerError {
if (documentSyncOptions == null || documentSyncOptions.openClose) queue.didClose(params)
}
serviceCall {
if (documentSyncOptions == null || documentSyncOptions.openClose) queue.didClose(params)
}
}

suspend fun didOpen(params: DidOpenTextDocumentParams) {
if (checkStatus()) {
handleServerError {
if (documentSyncOptions == null || documentSyncOptions.openClose) queue.didOpen(params)
}
serviceCall {
if (documentSyncOptions == null || documentSyncOptions.openClose) queue.didOpen(params)
}
}

suspend fun didChange(params: DidChangeTextDocumentParams) {
if (checkStatus()) {
handleServerError {
if (documentSyncOptions == null || documentSyncOptions.change != null) queue.didChange(params)
}
serviceCall {
if (documentSyncOptions == null || documentSyncOptions.change != null) queue.didChange(params)
}
}

suspend fun completion(params: CompletionParams): Either<List<CompletionItem>, CompletionList>? {
if (checkStatus()) {
return handleServerError {
if (capabilities.completionProvider != null)
queue.completion(params)
else null
}
suspend fun completion(params: CompletionParams): Either<List<CompletionItem>, CompletionList>? =
serviceCall {
if (capabilities.completionProvider != null)
queue.completion(params)
else null
}

return null
}
private suspend fun <T> serviceCall(action: suspend () -> T): T? {
if (!checkStatus()) {
logger.error("ServerEndpoint does not report isRunning == true")
return null
}

private suspend fun <T> handleServerError(action: suspend () -> T): T? {
try {
return action()
} catch (e: Throwable) {
Expand All @@ -71,3 +66,5 @@ class LSPRequestManager(
}
}
}

private val logger = logger<LSPRequestManager>()
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,8 @@ private val logger = logger<TextDocumentServiceQueue>()

class TextDocumentServiceQueue(private val textDocumentService: () -> TextDocumentService?) {

private val service: TextDocumentService?
get() = textDocumentService()

private val mutex = Mutex()
private suspend fun <T> executeTask(id: String, logDescription: Any? = null, task: suspend () -> T): T {
private suspend fun <T> executeTask(id: String, logDescription: Any? = null, task: suspend (TextDocumentService) -> T): T? {
logger.trace {
val summary = "$id: operation queued."
val description = logDescription?.toString()
Expand All @@ -32,7 +29,10 @@ class TextDocumentServiceQueue(private val textDocumentService: () -> TextDocume
withContext(Dispatchers.IO) {
logger.trace { "$id: executing on the IO context." }
try {
task()
textDocumentService()?.let { task(it) } ?: run {
logger.error("Cannot get the service to perform task $id.")
null
}
} finally {
logger.trace { "$id: finished." }
}
Expand All @@ -41,31 +41,31 @@ class TextDocumentServiceQueue(private val textDocumentService: () -> TextDocume
}

suspend fun didOpen(params: DidOpenTextDocumentParams) {
executeTask("didOpen notification", params) {
service?.didOpen(params)
executeTask("didOpen notification", params) { service ->
service.didOpen(params)
}
}

suspend fun didClose(params: DidCloseTextDocumentParams) {
executeTask("didClose notification", params) {
service?.didClose(params)
executeTask("didClose notification", params) { service ->
service.didClose(params)
}
}

suspend fun didSave(params: DidSaveTextDocumentParams) {
executeTask("didSave notification", params) {
service?.didSave(params)
executeTask("didSave notification", params) { service ->
service.didSave(params)
}
}

suspend fun didChange(params: DidChangeTextDocumentParams) {
executeTask("didChange notification", params) {
service?.didChange(params)
executeTask("didChange notification", params) { service ->
service.didChange(params)
}
}

suspend fun completion(params: CompletionParams): Either<List<CompletionItem>, CompletionList>? =
executeTask("completion request", params) {
service?.completion(params)?.await()
executeTask("completion request", params) { service ->
service.completion(params)?.await()
}
}

0 comments on commit ca0f32f

Please sign in to comment.