From b71f235118cf8d1a1c6a393c282db9bef18f9060 Mon Sep 17 00:00:00 2001
From: SeeBasTStick <sebastian.stock@hhu.de>
Date: Thu, 6 Aug 2020 17:20:56 +0200
Subject: [PATCH] added ability to send debug messages

---
 src/main/kotlin/b/language/server/App.kt      |  1 +
 .../b/language/server/BDocumentService.kt     | 47 ++++++++-------
 src/main/kotlin/b/language/server/Server.kt   | 19 +++---
 src/main/kotlin/b/language/server/Util.kt     |  3 +-
 .../server/communication/Communicator.kt      | 60 +++++++++++++++++++
 .../communication/CommunicatorInterface.kt    | 41 +++++++++++++
 .../b/language/server/dataStorage/Settings.kt |  3 +-
 .../proBMangement/ProBCommandLineAccess.kt    |  9 ++-
 8 files changed, 152 insertions(+), 31 deletions(-)
 create mode 100644 src/main/kotlin/b/language/server/communication/Communicator.kt
 create mode 100644 src/main/kotlin/b/language/server/communication/CommunicatorInterface.kt

diff --git a/src/main/kotlin/b/language/server/App.kt b/src/main/kotlin/b/language/server/App.kt
index 75b38ea..014cb39 100644
--- a/src/main/kotlin/b/language/server/App.kt
+++ b/src/main/kotlin/b/language/server/App.kt
@@ -16,6 +16,7 @@ fun startServer(inputStream: InputStream, outputStream: OutputStream){
     val server = Server()
     val launcher : Launcher<LanguageClient> = LSPLauncher.createServerLauncher(server, inputStream, outputStream)
     val startListing : Future<*> = launcher.startListening()
+
     server.setRemoteProxy(launcher.remoteProxy)
     startListing.get()
 }
diff --git a/src/main/kotlin/b/language/server/BDocumentService.kt b/src/main/kotlin/b/language/server/BDocumentService.kt
index 2448022..a855090 100644
--- a/src/main/kotlin/b/language/server/BDocumentService.kt
+++ b/src/main/kotlin/b/language/server/BDocumentService.kt
@@ -1,5 +1,6 @@
 package b.language.server
 
+import b.language.server.communication.CommunicatorInterface
 import b.language.server.proBMangement.CommandCouldNotBeExecutedException
 import b.language.server.proBMangement.PathCouldNotBeCreatedException
 import b.language.server.proBMangement.ProBCommandLineAccess
@@ -8,7 +9,7 @@ import org.eclipse.lsp4j.*
 import org.eclipse.lsp4j.services.TextDocumentService
 import java.util.concurrent.ConcurrentHashMap
 
-class BDocumentService(private val server: Server) : TextDocumentService {
+class BDocumentService(private val server: Server, private val communicator: CommunicatorInterface) : TextDocumentService {
 
     private val documents = ConcurrentHashMap<String, String>()
     private val issueTracker : ConcurrentHashMap<String, Set<String>> = ConcurrentHashMap()
@@ -33,45 +34,47 @@ class BDocumentService(private val server: Server) : TextDocumentService {
      */
     override fun didSave(params: DidSaveTextDocumentParams?) {
 
-   //     server.languageClient.showMessage(MessageParams(MessageType.Log,"Penis"))
-
-        val currentUri = params!!.textDocument.uri
-        checkUri(currentUri)
+        communicator.sendDebugMessage("document ${params!!.textDocument.uri} was saved", MessageType.Info)
+        val currentUri = params.textDocument.uri
+        checkDocument(currentUri)
 
     }
 
     /**
-     *
+     * checks a document via prob an the set options
      * @param the uri to perform actions on
      */
-    fun checkUri(currentUri : String){
-        val clientSettings = server.getDocumentSettings(currentUri)
+    fun checkDocument(currentUri : String){
 
-   //     server.languageClient.showMessage(MessageParams(MessageType.Log,clientSettings.toString()))
+        val clientSettings = server.getDocumentSettings(currentUri)
+        communicator.sendDebugMessage("waiting for document settings", MessageType.Info)
 
         clientSettings.thenAccept{ settings ->
-            val prob : ProBInterface = ProBCommandLineAccess()
-      //      server.languageClient.showMessage(MessageParams(MessageType.Log,settings.toString()))
+            communicator.setDebugMode(settings.debugMode)
+            val prob : ProBInterface = ProBCommandLineAccess(communicator)
+            communicator.sendDebugMessage("settings are $settings", MessageType.Info)
 
             try{
                 val diagnostics: List<Diagnostic> = prob.checkDocument(currentUri, settings)
-
-                server.languageClient.publishDiagnostics(PublishDiagnosticsParams(currentUri, diagnostics))
+                communicator.sendDebugMessage("created diagnostics $diagnostics", MessageType.Info)
+                communicator.publishDiagnostics(PublishDiagnosticsParams(currentUri, diagnostics))
                 val filesWithProblems = diagnostics.map { diagnostic -> diagnostic.source }
-                calculateToInvalidate(currentUri, filesWithProblems)
-                        .forEach{uri -> server.languageClient.publishDiagnostics(PublishDiagnosticsParams(uri, listOf()))}
+                val invalidFiles = calculateToInvalidate(currentUri, filesWithProblems)
+                invalidFiles.forEach{uri -> communicator.publishDiagnostics(PublishDiagnosticsParams(uri, listOf()))}
+                communicator.sendDebugMessage("invalidating old files $invalidFiles", MessageType.Info)
                 issueTracker[currentUri] = filesWithProblems.toSet()
             }catch (e : PathCouldNotBeCreatedException ){
-                server.languageClient.showMessage(MessageParams(MessageType.Error, e.message))
+                communicator.showMessage(e.message!!, MessageType.Error)
             }catch (e : CommandCouldNotBeExecutedException){
-                server.languageClient.showMessage(MessageParams(MessageType.Error, e.message))
+                communicator.showMessage(e.message!!, MessageType.Error)
             }
         }
+
     }
 
     /**
      * Gets all uris that are no longer contain problems
-     * @param currentUri the uri of the current main file
+     * @param currentUri the uri of the curre   nt main file
      * @param filesWithProblems uris of files containing problems
      */
     fun calculateToInvalidate(currentUri : String, filesWithProblems : List<String>) : List<String>{
@@ -88,7 +91,8 @@ class BDocumentService(private val server: Server) : TextDocumentService {
      * Registration Options: TextDocumentRegistrationOptions
      */
     override fun didClose(params: DidCloseTextDocumentParams?) {
-        server.documentSettings.remove(params!!.textDocument.uri)
+        communicator.sendDebugMessage("document ${params!!.textDocument.uri} was closed - removing meta data", MessageType.Info)
+        server.documentSettings.remove(params.textDocument.uri)
     }
 
     /**
@@ -98,8 +102,9 @@ class BDocumentService(private val server: Server) : TextDocumentService {
      * Registration Options: TextDocumentChangeRegistrationOptions
      */
     override fun didChange(params: DidChangeTextDocumentParams?) {
-        val currentUri = params!!.textDocument.uri
-        checkUri(currentUri)
+        communicator.sendDebugMessage("document ${params!!.textDocument.uri} was changed", MessageType.Info)
+        val currentUri = params.textDocument.uri
+        checkDocument(currentUri)
     }
 
 }
\ No newline at end of file
diff --git a/src/main/kotlin/b/language/server/Server.kt b/src/main/kotlin/b/language/server/Server.kt
index d1b11c3..ab657f7 100644
--- a/src/main/kotlin/b/language/server/Server.kt
+++ b/src/main/kotlin/b/language/server/Server.kt
@@ -1,30 +1,31 @@
 package b.language.server
 
+import b.language.server.communication.Communicator
 import b.language.server.dataStorage.Settings
 import com.google.gson.JsonObject
 import org.eclipse.lsp4j.*
 import org.eclipse.lsp4j.jsonrpc.messages.Either
-import org.eclipse.lsp4j.services.LanguageClient
-import org.eclipse.lsp4j.services.LanguageServer
-import org.eclipse.lsp4j.services.TextDocumentService
-import org.eclipse.lsp4j.services.WorkspaceService
+import org.eclipse.lsp4j.jsonrpc.services.JsonNotification
+import org.eclipse.lsp4j.services.*
 import java.util.concurrent.CompletableFuture
 import kotlin.collections.HashMap
 import kotlin.system.exitProcess
 
 
-class Server : LanguageServer {
+class Server : LanguageServer{
 
     private val textDocumentService : TextDocumentService
     private val bWorkspaceService : WorkspaceService
-    lateinit var languageClient : LanguageClient
+     lateinit var languageClient : LanguageClient
     var globalSettings : Settings = Settings()
     val documentSettings : HashMap<String, CompletableFuture<Settings>> = HashMap()
     var configurationAbility : Boolean = true
 
+
     init {
-        textDocumentService = BDocumentService(this)
+        textDocumentService = BDocumentService(this, Communicator)
         bWorkspaceService = BWorkspaceService(this)
+
     }
 
 
@@ -74,6 +75,7 @@ class Server : LanguageServer {
 
     fun setRemoteProxy(remoteProxy: LanguageClient) {
         this.languageClient = remoteProxy
+        Communicator.client = remoteProxy
     }
 
 
@@ -84,6 +86,7 @@ class Server : LanguageServer {
      * @return settings of the document requested
      */
     fun getDocumentSettings(uri : String) : CompletableFuture<Settings> {
+        Communicator.sendDebugMessage("received configuration Data of the document $uri", MessageType.Info)
         if(!configurationAbility){
             val returnValue = CompletableFuture<Settings>()
             returnValue.complete(globalSettings)
@@ -104,4 +107,6 @@ class Server : LanguageServer {
             documentSettings[uri]!!
         }
     }
+
+
 }
\ No newline at end of file
diff --git a/src/main/kotlin/b/language/server/Util.kt b/src/main/kotlin/b/language/server/Util.kt
index a42106e..d1d0d31 100644
--- a/src/main/kotlin/b/language/server/Util.kt
+++ b/src/main/kotlin/b/language/server/Util.kt
@@ -17,5 +17,6 @@ fun castJsonToSetting(json : JsonObject) : Settings {
             Gson().fromJson(json.get("wdChecks"), Boolean::class.java),
             Gson().fromJson(json.get("strictChecks"), Boolean::class.java),
             Gson().fromJson(json.get("performanceHints"), Boolean::class.java),
-            File(Gson().fromJson(json.get("probHome"), String::class.java)))
+            File(Gson().fromJson(json.get("probHome"), String::class.java)),
+            Gson().fromJson(json.get("debugMode"), Boolean::class.java))
 }
diff --git a/src/main/kotlin/b/language/server/communication/Communicator.kt b/src/main/kotlin/b/language/server/communication/Communicator.kt
new file mode 100644
index 0000000..7b8f591
--- /dev/null
+++ b/src/main/kotlin/b/language/server/communication/Communicator.kt
@@ -0,0 +1,60 @@
+package b.language.server.communication
+
+import org.eclipse.lsp4j.MessageParams
+import org.eclipse.lsp4j.MessageType
+import org.eclipse.lsp4j.PublishDiagnosticsParams
+import org.eclipse.lsp4j.services.LanguageClient
+
+
+object Communicator : CommunicatorInterface {
+
+
+    /**
+     * Will be set in the server an encapsulates the client
+     */
+    lateinit var client : LanguageClient
+
+    private var debugMode : Boolean = true
+
+    /**
+     * Sends the diagnostics
+     *
+     * @param diagnostics object containing the Diagnostics
+     */
+    override fun publishDiagnostics(diagnostics: PublishDiagnosticsParams) {
+        client.publishDiagnostics(diagnostics)
+    }
+
+    /**
+     * Sends a debug message resulting in a output channel message
+     *
+     * @param message the message to send
+     * @param severity the Severity of the message (Error/Info/Warning)
+     */
+    override fun sendDebugMessage(message: String, severity: MessageType) {
+        if(debugMode) {
+            client.logMessage(MessageParams(severity, message))
+        }
+
+    }
+
+    /**
+     * Sends a popup message resulting in a popup message
+     *
+     * @param message the message to send
+     * @param severity the Severity of the message (Error/Info/Warning)
+     */
+    override fun showMessage(message: String, severity: MessageType) {
+        client.showMessage(MessageParams(severity, message))
+    }
+
+
+    /**
+     * To enable/disable debug mode
+     *
+     * @param mode the new state of the debug mode
+     */
+    override fun setDebugMode(mode : Boolean){
+        debugMode = mode
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/b/language/server/communication/CommunicatorInterface.kt b/src/main/kotlin/b/language/server/communication/CommunicatorInterface.kt
new file mode 100644
index 0000000..b9096f0
--- /dev/null
+++ b/src/main/kotlin/b/language/server/communication/CommunicatorInterface.kt
@@ -0,0 +1,41 @@
+package b.language.server.communication
+
+import org.eclipse.lsp4j.MessageType
+import org.eclipse.lsp4j.PublishDiagnosticsParams
+
+/**
+ * Describes the basic functions used to communicate with the outside world
+ */
+interface CommunicatorInterface {
+
+    /**
+     * Sends the diagnostics
+     *
+     * @param diagnostics object containing the Diagnostics
+     */
+    fun publishDiagnostics(diagnostics : PublishDiagnosticsParams)
+
+    /**
+     * Sends a debug message resulting in a output channel message
+     *
+     * @param message the message to send
+     * @param severity the Severity of the message (Error/Info/Warning)
+     */
+    fun sendDebugMessage(message: String, severity: MessageType)
+
+
+    /**
+     * Sends a popup message resulting in a popup message
+     *
+     * @param message the message to send
+     * @param severity the Severity of the message (Error/Info/Warning)
+     */
+    fun showMessage(message : String, severity : MessageType)
+
+    /**
+     * To enable/disable debug mode
+     *
+     * @param mode the new state of the debug mode
+     */
+    fun setDebugMode(mode : Boolean)
+}
\ No newline at end of file
diff --git a/src/main/kotlin/b/language/server/dataStorage/Settings.kt b/src/main/kotlin/b/language/server/dataStorage/Settings.kt
index 9a2ca6f..0cc9534 100644
--- a/src/main/kotlin/b/language/server/dataStorage/Settings.kt
+++ b/src/main/kotlin/b/language/server/dataStorage/Settings.kt
@@ -3,4 +3,5 @@ package b.language.server.dataStorage
 import java.io.File
 
 data class Settings(val maxNumberOfProblem : Int = 1000, val strictChecks : Boolean = true,  val wdChecks : Boolean = true,
-                    val performanceHints : Boolean = true , val probHome : File = File("~/prob_prolog/probcli.sh"))
+                    val performanceHints : Boolean = true , val probHome : File = File("~/prob_prolog/probcli.sh"),
+                    val debugMode : Boolean = true)
diff --git a/src/main/kotlin/b/language/server/proBMangement/ProBCommandLineAccess.kt b/src/main/kotlin/b/language/server/proBMangement/ProBCommandLineAccess.kt
index 35af31f..bd34568 100644
--- a/src/main/kotlin/b/language/server/proBMangement/ProBCommandLineAccess.kt
+++ b/src/main/kotlin/b/language/server/proBMangement/ProBCommandLineAccess.kt
@@ -1,5 +1,7 @@
 package b.language.server.proBMangement
 
+import b.language.server.communication.Communicator
+import b.language.server.communication.CommunicatorInterface
 import b.language.server.dataStorage.Problem
 import b.language.server.dataStorage.Settings
 import com.google.gson.Gson
@@ -11,13 +13,14 @@ import java.net.URI
 /**
  * Access ProB via command line
  */
-class ProBCommandLineAccess : ProBInterface{
+class ProBCommandLineAccess(val communicator : CommunicatorInterface) : ProBInterface{
     /**
      * Checks the given document with the help of ProB; Will setup all needed steps to ensure a clean process
      * @param uri the source to check
      * @return a list of all problems found
      */
     override fun checkDocument(uri : String, settings: Settings): List<Diagnostic> {
+        communicator.sendDebugMessage("checking document ($uri) with proB", MessageType.Info )
         val realUri = URI(uri)
         val path = File(realUri.path)
         val errorPath = File(path.parent + "/tmp/_error.json")
@@ -27,11 +30,14 @@ class ProBCommandLineAccess : ProBInterface{
          if(!result){
             throw PathCouldNotBeCreatedException("The Path leading to $errorPath has not been created due some issue.")
         }
+        communicator.sendDebugMessage("creation successful", MessageType.Info)
         val command = buildCommand(settings, path, errorPath)
+        communicator.sendDebugMessage("sending command <$command> to proB", MessageType.Info)
 
         performActionOnDocument(command)
 
         val problems = readProblems(errorPath.path)
+        communicator.sendDebugMessage("found the following problems: $problems", MessageType.Info)
 
         return transformProblems(problems)
     }
@@ -84,6 +90,7 @@ class ProBCommandLineAccess : ProBInterface{
      * @return success of the action
      */
     fun createFolder(errorDict : File, errorPath: File) : Boolean{
+        communicator.sendDebugMessage("creating errorDict $errorDict and errorFile $errorPath", MessageType.Info)
         errorDict.mkdirs()
         FileWriter(errorPath, false).close()
         return errorDict.exists() && errorPath.exists()
-- 
GitLab