summaryrefslogtreecommitdiff
path: root/Userland
diff options
context:
space:
mode:
authorItamar <itamar8910@gmail.com>2021-02-27 09:31:05 +0200
committerAndreas Kling <kling@serenityos.org>2021-02-27 16:37:35 +0100
commit4b483071fb5f00afa50ef05d0e5857d9ccd7c686 (patch)
tree97ba6cb5aa50ed2e0bc2b0aaad4fe8464e2e7a10 /Userland
parentdaf18e7777366d9b26a20d3e5788fa0cb66a7caa (diff)
downloadserenity-4b483071fb5f00afa50ef05d0e5857d9ccd7c686.zip
LanguageServers: Add ProjectLoaction, Declaration types and use in IPC
With this we can avoid passing (name, line, column) tuples in many different places.
Diffstat (limited to 'Userland')
-rw-r--r--Userland/DevTools/HackStudio/AutoCompleteResponse.h47
-rw-r--r--Userland/DevTools/HackStudio/LanguageClient.cpp12
-rw-r--r--Userland/DevTools/HackStudio/LanguageServers/Cpp/AutoCompleteEngine.h8
-rw-r--r--Userland/DevTools/HackStudio/LanguageServers/Cpp/ClientConnection.cpp22
-rw-r--r--Userland/DevTools/HackStudio/LanguageServers/Cpp/ParserAutoComplete.cpp4
-rw-r--r--Userland/DevTools/HackStudio/LanguageServers/Cpp/ParserAutoComplete.h2
-rw-r--r--Userland/DevTools/HackStudio/LanguageServers/LanguageClient.ipc2
-rw-r--r--Userland/DevTools/HackStudio/LanguageServers/LanguageServer.ipc5
-rw-r--r--Userland/DevTools/HackStudio/LanguageServers/Shell/ClientConnection.cpp12
-rw-r--r--Userland/Libraries/LibGUI/AutocompleteProvider.h12
10 files changed, 93 insertions, 33 deletions
diff --git a/Userland/DevTools/HackStudio/AutoCompleteResponse.h b/Userland/DevTools/HackStudio/AutoCompleteResponse.h
index 70023bf7ec..6e16e5f4c3 100644
--- a/Userland/DevTools/HackStudio/AutoCompleteResponse.h
+++ b/Userland/DevTools/HackStudio/AutoCompleteResponse.h
@@ -64,4 +64,51 @@ inline bool decode(IPC::Decoder& decoder, GUI::AutocompleteProvider::Entry& resp
return ok;
}
+template<>
+inline bool encode(Encoder& encoder, const GUI::AutocompleteProvider::ProjectLocation& location)
+{
+ encoder << location.file;
+ encoder << (u64)location.line;
+ encoder << (u64)location.column;
+ return true;
+}
+
+template<>
+inline bool decode(Decoder& decoder, GUI::AutocompleteProvider::ProjectLocation& location)
+{
+ u64 line = 0;
+ u64 column = 0;
+ if (!decoder.decode(location.file))
+ return false;
+ if (!decoder.decode(line))
+ return false;
+ if (!decoder.decode(column))
+ return false;
+
+ location.line = line;
+ location.column = column;
+
+ return true;
+}
+
+template<>
+inline bool encode(Encoder& encoder, const GUI::AutocompleteProvider::Declaration& declaration)
+{
+ encoder << declaration.name;
+ if (!encode(encoder, declaration.position))
+ return false;
+ return true;
+}
+
+template<>
+inline bool decode(Decoder& decoder, GUI::AutocompleteProvider::Declaration& declaration)
+{
+ if (!decoder.decode(declaration.name))
+ return false;
+
+ if (!decode(decoder, declaration.position))
+ return false;
+ return true;
+}
+
}
diff --git a/Userland/DevTools/HackStudio/LanguageClient.cpp b/Userland/DevTools/HackStudio/LanguageClient.cpp
index 07a234bb19..7d701f46d2 100644
--- a/Userland/DevTools/HackStudio/LanguageClient.cpp
+++ b/Userland/DevTools/HackStudio/LanguageClient.cpp
@@ -40,13 +40,19 @@ void ServerConnection::handle(const Messages::LanguageClient::AutoCompleteSugges
}
m_language_client->provide_autocomplete_suggestions(message.suggestions());
}
+
void ServerConnection::handle(const Messages::LanguageClient::DeclarationLocation& message)
{
if (!m_language_client) {
dbgln("Language Server connection has no attached language client");
return;
}
- m_language_client->declaration_found(message.file_name(), message.line(), message.column());
+ m_language_client->declaration_found(message.location().file, message.location().line, message.location().column);
+}
+
+void ServerConnection::handle(const Messages::LanguageClient::DeclarationList& message)
+{
+ (void)message;
}
void ServerConnection::die()
@@ -90,7 +96,7 @@ void LanguageClient::request_autocomplete(const String& path, size_t cursor_line
if (!m_server_connection)
return;
set_active_client();
- m_server_connection->post_message(Messages::LanguageServer::AutoCompleteSuggestions(path, cursor_line, cursor_column));
+ m_server_connection->post_message(Messages::LanguageServer::AutoCompleteSuggestions(GUI::AutocompleteProvider::ProjectLocation { path, cursor_line, cursor_column }));
}
void LanguageClient::provide_autocomplete_suggestions(const Vector<GUI::AutocompleteProvider::Entry>& suggestions)
@@ -158,7 +164,7 @@ void LanguageClient::search_declaration(const String& path, size_t line, size_t
if (!m_server_connection)
return;
set_active_client();
- m_server_connection->post_message(Messages::LanguageServer::FindDeclaration(path, line, column));
+ m_server_connection->post_message(Messages::LanguageServer::FindDeclaration(GUI::AutocompleteProvider::ProjectLocation { path, line, column }));
}
void LanguageClient::declaration_found(const String& file, size_t line, size_t column)
diff --git a/Userland/DevTools/HackStudio/LanguageServers/Cpp/AutoCompleteEngine.h b/Userland/DevTools/HackStudio/LanguageServers/Cpp/AutoCompleteEngine.h
index 28268d20cc..d672068286 100644
--- a/Userland/DevTools/HackStudio/LanguageServers/Cpp/AutoCompleteEngine.h
+++ b/Userland/DevTools/HackStudio/LanguageServers/Cpp/AutoCompleteEngine.h
@@ -28,6 +28,7 @@
#include "FileDB.h"
#include <DevTools/HackStudio/AutoCompleteResponse.h>
+#include <LibGUI/AutocompleteProvider.h>
#include <LibGUI/TextPosition.h>
class AutoCompleteEngine {
@@ -41,12 +42,7 @@ public:
virtual void on_edit([[maybe_unused]] const String& file) {};
virtual void file_opened([[maybe_unused]] const String& file) {};
- struct ProjectPosition {
- String file;
- size_t line;
- size_t column;
- };
- virtual Optional<ProjectPosition> find_declaration_of(const String&, const GUI::TextPosition&) { return {}; };
+ virtual Optional<GUI::AutocompleteProvider::ProjectLocation> find_declaration_of(const String&, const GUI::TextPosition&) { return {}; };
protected:
const FileDB& filedb() const { return m_filedb; }
diff --git a/Userland/DevTools/HackStudio/LanguageServers/Cpp/ClientConnection.cpp b/Userland/DevTools/HackStudio/LanguageServers/Cpp/ClientConnection.cpp
index 9d11e92c4f..2fd805a1cc 100644
--- a/Userland/DevTools/HackStudio/LanguageServers/Cpp/ClientConnection.cpp
+++ b/Userland/DevTools/HackStudio/LanguageServers/Cpp/ClientConnection.cpp
@@ -100,17 +100,17 @@ void ClientConnection::handle(const Messages::LanguageServer::FileEditRemoveText
void ClientConnection::handle(const Messages::LanguageServer::AutoCompleteSuggestions& message)
{
#if CPP_LANGUAGE_SERVER_DEBUG
- dbgln("AutoCompleteSuggestions for: {} {}:{}", message.file_name(), message.cursor_line(), message.cursor_column());
+ dbgln("AutoCompleteSuggestions for: {} {}:{}", message.location().file, message.location().line, message.location().column);
#endif
- auto document = m_filedb.get(message.file_name());
+ auto document = m_filedb.get(message.location().file);
if (!document) {
- dbgln("file {} has not been opened", message.file_name());
+ dbgln("file {} has not been opened", message.location().file);
return;
}
- GUI::TextPosition autocomplete_position = { (size_t)message.cursor_line(), (size_t)max(message.cursor_column(), message.cursor_column() - 1) };
- Vector<GUI::AutocompleteProvider::Entry> suggestions = m_autocomplete_engine->get_suggestions(message.file_name(), autocomplete_position);
+ GUI::TextPosition autocomplete_position = { (size_t)message.location().line, (size_t)max(message.location().column, message.location().column - 1) };
+ Vector<GUI::AutocompleteProvider::Entry> suggestions = m_autocomplete_engine->get_suggestions(message.location().file, autocomplete_position);
post_message(Messages::LanguageClient::AutoCompleteSuggestions(move(suggestions)));
}
@@ -139,21 +139,21 @@ void ClientConnection::handle(const Messages::LanguageServer::SetAutoCompleteMod
void ClientConnection::handle(const Messages::LanguageServer::FindDeclaration& message)
{
- dbgln_if(CPP_LANGUAGE_SERVER_DEBUG, "FindDeclaration: {} {}:{}", message.file_name(), message.line(), message.column());
- auto document = m_filedb.get(message.file_name());
+ dbgln_if(CPP_LANGUAGE_SERVER_DEBUG, "FindDeclaration: {} {}:{}", message.location().file, message.location().line, message.location().column);
+ auto document = m_filedb.get(message.location().file);
if (!document) {
- dbgln("file {} has not been opened", message.file_name());
+ dbgln("file {} has not been opened", message.location().file);
return;
}
- GUI::TextPosition identifier_position = { (size_t)message.line(), (size_t)message.column() };
- auto location = m_autocomplete_engine->find_declaration_of(message.file_name(), identifier_position);
+ GUI::TextPosition identifier_position = { (size_t)message.location().line, (size_t)message.location().column };
+ auto location = m_autocomplete_engine->find_declaration_of(message.location().file, identifier_position);
if (!location.has_value()) {
dbgln("could not find declaration");
return;
}
dbgln_if(CPP_LANGUAGE_SERVER_DEBUG, "declaration location: {} {}:{}", location.value().file, location.value().line, location.value().column);
- post_message(Messages::LanguageClient::DeclarationLocation(location.value().file, location.value().line, location.value().column));
+ post_message(Messages::LanguageClient::DeclarationLocation(GUI::AutocompleteProvider::ProjectLocation { location.value().file, location.value().line, location.value().column }));
}
}
diff --git a/Userland/DevTools/HackStudio/LanguageServers/Cpp/ParserAutoComplete.cpp b/Userland/DevTools/HackStudio/LanguageServers/Cpp/ParserAutoComplete.cpp
index 76b911baca..eb69aba23a 100644
--- a/Userland/DevTools/HackStudio/LanguageServers/Cpp/ParserAutoComplete.cpp
+++ b/Userland/DevTools/HackStudio/LanguageServers/Cpp/ParserAutoComplete.cpp
@@ -317,7 +317,7 @@ void ParserAutoComplete::file_opened([[maybe_unused]] const String& file)
set_document_data(file, create_document_data_for(file));
}
-Optional<AutoCompleteEngine::ProjectPosition> ParserAutoComplete::find_declaration_of(const String& file_name, const GUI::TextPosition& identifier_position)
+Optional<GUI::AutocompleteProvider::ProjectLocation> ParserAutoComplete::find_declaration_of(const String& file_name, const GUI::TextPosition& identifier_position)
{
const auto& document = get_or_create_document_data(file_name);
auto node = document.parser.node_at(Cpp::Position { identifier_position.line(), identifier_position.column() });
@@ -329,7 +329,7 @@ Optional<AutoCompleteEngine::ProjectPosition> ParserAutoComplete::find_declarati
if (!decl)
return {};
- return ProjectPosition { decl->filename(), decl->start().line, decl->start().column };
+ return GUI::AutocompleteProvider::ProjectLocation { decl->filename(), decl->start().line, decl->start().column };
}
RefPtr<Declaration> ParserAutoComplete::find_declaration_of(const DocumentData& document_data, const ASTNode& node) const
diff --git a/Userland/DevTools/HackStudio/LanguageServers/Cpp/ParserAutoComplete.h b/Userland/DevTools/HackStudio/LanguageServers/Cpp/ParserAutoComplete.h
index 71ca10c163..3b83e41e3c 100644
--- a/Userland/DevTools/HackStudio/LanguageServers/Cpp/ParserAutoComplete.h
+++ b/Userland/DevTools/HackStudio/LanguageServers/Cpp/ParserAutoComplete.h
@@ -47,7 +47,7 @@ public:
virtual Vector<GUI::AutocompleteProvider::Entry> get_suggestions(const String& file, const GUI::TextPosition& autocomplete_position) override;
virtual void on_edit(const String& file) override;
virtual void file_opened([[maybe_unused]] const String& file) override;
- virtual Optional<ProjectPosition> find_declaration_of(const String& file_name, const GUI::TextPosition& identifier_position) override;
+ virtual Optional<GUI::AutocompleteProvider::ProjectLocation> find_declaration_of(const String& file_name, const GUI::TextPosition& identifier_position) override;
private:
struct DocumentData {
diff --git a/Userland/DevTools/HackStudio/LanguageServers/LanguageClient.ipc b/Userland/DevTools/HackStudio/LanguageServers/LanguageClient.ipc
index 9e85f8df9a..6e1d0a9c4c 100644
--- a/Userland/DevTools/HackStudio/LanguageServers/LanguageClient.ipc
+++ b/Userland/DevTools/HackStudio/LanguageServers/LanguageClient.ipc
@@ -1,5 +1,5 @@
endpoint LanguageClient = 8002
{
AutoCompleteSuggestions(Vector<GUI::AutocompleteProvider::Entry> suggestions) =|
- DeclarationLocation(String file_name, i32 line, i32 column) =|
+ DeclarationLocation(GUI::AutocompleteProvider::ProjectLocation location) =|
}
diff --git a/Userland/DevTools/HackStudio/LanguageServers/LanguageServer.ipc b/Userland/DevTools/HackStudio/LanguageServers/LanguageServer.ipc
index 379ba03c30..c8d804410a 100644
--- a/Userland/DevTools/HackStudio/LanguageServers/LanguageServer.ipc
+++ b/Userland/DevTools/HackStudio/LanguageServers/LanguageServer.ipc
@@ -7,8 +7,7 @@ endpoint LanguageServer = 8001
FileEditRemoveText(String file_name, i32 start_line, i32 start_column, i32 end_line, i32 end_column) =|
SetFileContent(String file_name, String content) =|
- AutoCompleteSuggestions(String file_name, i32 cursor_line, i32 cursor_column) =|
+ AutoCompleteSuggestions(GUI::AutocompleteProvider::ProjectLocation location) =|
SetAutoCompleteMode(String mode) =|
- FindDeclaration(String file_name, i32 line, i32 column) =|
-
+ FindDeclaration(GUI::AutocompleteProvider::ProjectLocation location) =|
}
diff --git a/Userland/DevTools/HackStudio/LanguageServers/Shell/ClientConnection.cpp b/Userland/DevTools/HackStudio/LanguageServers/Shell/ClientConnection.cpp
index ea0b69306d..41c05a8a70 100644
--- a/Userland/DevTools/HackStudio/LanguageServers/Shell/ClientConnection.cpp
+++ b/Userland/DevTools/HackStudio/LanguageServers/Shell/ClientConnection.cpp
@@ -135,23 +135,23 @@ void ClientConnection::handle(const Messages::LanguageServer::FileEditRemoveText
void ClientConnection::handle(const Messages::LanguageServer::AutoCompleteSuggestions& message)
{
#if SH_LANGUAGE_SERVER_DEBUG
- dbgln("AutoCompleteSuggestions for: {} {}:{}", message.file_name(), message.cursor_line(), message.cursor_column());
+ dbgln("AutoCompleteSuggestions for: {} {}:{}", message.location().file, message.location().line, message.location().column);
#endif
- auto document = document_for(message.file_name());
+ auto document = document_for(message.location().file);
if (!document) {
- dbgln("file {} has not been opened", message.file_name());
+ dbgln("file {} has not been opened", message.location().file);
return;
}
auto& lines = document->lines();
size_t offset = 0;
- if (message.cursor_line() > 0) {
- for (auto i = 0; i < message.cursor_line(); ++i)
+ if (message.location().line > 0) {
+ for (size_t i = 0; i < message.location().line; ++i)
offset += lines[i].length() + 1;
}
- offset += message.cursor_column();
+ offset += message.location().column;
auto suggestions = m_autocomplete.get_suggestions(document->text(), offset);
post_message(Messages::LanguageClient::AutoCompleteSuggestions(move(suggestions)));
diff --git a/Userland/Libraries/LibGUI/AutocompleteProvider.h b/Userland/Libraries/LibGUI/AutocompleteProvider.h
index 6dd51864ee..2794a3b37d 100644
--- a/Userland/Libraries/LibGUI/AutocompleteProvider.h
+++ b/Userland/Libraries/LibGUI/AutocompleteProvider.h
@@ -29,6 +29,7 @@
#include <LibGUI/Forward.h>
#include <LibGUI/TextEditor.h>
#include <LibGUI/Window.h>
+#include <LibIPC/Decoder.h>
namespace GUI {
@@ -55,6 +56,17 @@ public:
Language language { Language::Unspecified };
};
+ struct ProjectLocation {
+ String file;
+ size_t line { 0 };
+ size_t column { 0 };
+ };
+
+ struct Declaration {
+ String name;
+ ProjectLocation position;
+ };
+
virtual void provide_completions(Function<void(Vector<Entry>)>) = 0;
void attach(TextEditor& editor)