1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 02:07:36 +00:00

LanguageServers: Add ProjectLoaction, Declaration types and use in IPC

With this we can avoid passing (name, line, column) tuples in many
different places.
This commit is contained in:
Itamar 2021-02-27 09:31:05 +02:00 committed by Andreas Kling
parent daf18e7777
commit 4b483071fb
10 changed files with 93 additions and 33 deletions

View file

@ -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; }

View file

@ -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 }));
}
}

View file

@ -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

View file

@ -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 {

View file

@ -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) =|
}

View file

@ -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) =|
}

View file

@ -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)));