diff options
author | Itamar <itamar8910@gmail.com> | 2021-02-27 09:31:05 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-02-27 16:37:35 +0100 |
commit | 4b483071fb5f00afa50ef05d0e5857d9ccd7c686 (patch) | |
tree | 97ba6cb5aa50ed2e0bc2b0aaad4fe8464e2e7a10 /Userland | |
parent | daf18e7777366d9b26a20d3e5788fa0cb66a7caa (diff) | |
download | serenity-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')
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) |