Kaynağa Gözat

HackStudio: Attach previous Language Client when detaching

Previously, if a new LanguageClient was created & destroyed, the
ServerConnection to the language server would be left without an
attached LanguageClient.
As a result, auto-completion results would not be updated in the UI.

Starting with this commit, the LanguageClient holds a WeakPtr to the
previous LanguageClient that was attached to the ServerConnection,
and re-attaches it after detaching itself.
Itamar 4 yıl önce
ebeveyn
işleme
8ed96eb27c

+ 5 - 2
Userland/DevTools/HackStudio/LanguageClient.cpp

@@ -32,8 +32,11 @@ namespace HackStudio {
 
 
 void ServerConnection::handle(const Messages::LanguageClient::AutoCompleteSuggestions& message)
 void ServerConnection::handle(const Messages::LanguageClient::AutoCompleteSuggestions& message)
 {
 {
-    if (m_language_client)
-        m_language_client->provide_autocomplete_suggestions(message.suggestions());
+    if (!m_language_client) {
+        dbgln("Language Server connection has no attached language client");
+        return;
+    }
+    m_language_client->provide_autocomplete_suggestions(message.suggestions());
 }
 }
 
 
 void LanguageClient::open_file(const String& path, int fd)
 void LanguageClient::open_file(const String& path, int fd)

+ 10 - 2
Userland/DevTools/HackStudio/LanguageClient.h

@@ -30,6 +30,8 @@
 #include <AK/Forward.h>
 #include <AK/Forward.h>
 #include <AK/LexicalPath.h>
 #include <AK/LexicalPath.h>
 #include <AK/Types.h>
 #include <AK/Types.h>
+#include <AK/WeakPtr.h>
+#include <AK/Weakable.h>
 #include <LibIPC/ServerConnection.h>
 #include <LibIPC/ServerConnection.h>
 
 
 #include <DevTools/HackStudio/LanguageServers/LanguageClientEndpoint.h>
 #include <DevTools/HackStudio/LanguageServers/LanguageClientEndpoint.h>
@@ -64,6 +66,8 @@ public:
         set_my_client_id(response->client_id());
         set_my_client_id(response->client_id());
     }
     }
 
 
+    WeakPtr<LanguageClient> language_client() { return m_language_client; }
+
     template<typename ConcreteType>
     template<typename ConcreteType>
     static NonnullRefPtr<ServerConnection> get_or_create(const String& project_path)
     static NonnullRefPtr<ServerConnection> get_or_create(const String& project_path)
     {
     {
@@ -81,21 +85,24 @@ public:
 protected:
 protected:
     virtual void handle(const Messages::LanguageClient::AutoCompleteSuggestions&) override;
     virtual void handle(const Messages::LanguageClient::AutoCompleteSuggestions&) override;
 
 
-    LanguageClient* m_language_client { nullptr };
+    WeakPtr<LanguageClient> m_language_client;
 };
 };
 
 
-class LanguageClient {
+class LanguageClient : public Weakable<LanguageClient> {
 public:
 public:
     explicit LanguageClient(NonnullRefPtr<ServerConnection>&& connection)
     explicit LanguageClient(NonnullRefPtr<ServerConnection>&& connection)
         : m_connection(*connection)
         : m_connection(*connection)
         , m_server_connection(move(connection))
         , m_server_connection(move(connection))
     {
     {
+        m_previous_client = m_connection.language_client();
         m_connection.attach(*this);
         m_connection.attach(*this);
     }
     }
 
 
     virtual ~LanguageClient()
     virtual ~LanguageClient()
     {
     {
         m_connection.detach();
         m_connection.detach();
+        if (m_previous_client)
+            m_connection.attach(*m_previous_client);
     }
     }
 
 
     virtual void open_file(const String& path, int fd);
     virtual void open_file(const String& path, int fd);
@@ -111,6 +118,7 @@ public:
 private:
 private:
     ServerConnection& m_connection;
     ServerConnection& m_connection;
     NonnullRefPtr<ServerConnection> m_server_connection;
     NonnullRefPtr<ServerConnection> m_server_connection;
+    WeakPtr<LanguageClient> m_previous_client;
 };
 };
 
 
 template<typename ServerConnectionT>
 template<typename ServerConnectionT>