diff --git a/Userland/DevTools/HackStudio/AutoCompleteResponse.h b/Userland/DevTools/HackStudio/AutoCompleteResponse.h index 540022f98dd..26f2ed45ebd 100644 --- a/Userland/DevTools/HackStudio/AutoCompleteResponse.h +++ b/Userland/DevTools/HackStudio/AutoCompleteResponse.h @@ -110,7 +110,7 @@ inline bool decode(Decoder& decoder, GUI::AutocompleteProvider::Declaration& dec if (!decode(decoder, declaration.position)) return false; u32 type; - if (!decoder.decode( type)) + if (!decoder.decode(type)) return false; declaration.type = static_cast(type); diff --git a/Userland/DevTools/HackStudio/LanguageClient.h b/Userland/DevTools/HackStudio/LanguageClient.h index 8ec45ede126..938453b1f5f 100644 --- a/Userland/DevTools/HackStudio/LanguageClient.h +++ b/Userland/DevTools/HackStudio/LanguageClient.h @@ -91,6 +91,7 @@ public: protected: virtual void handle(const Messages::LanguageClient::AutoCompleteSuggestions&) override; virtual void handle(const Messages::LanguageClient::DeclarationLocation&) override; + virtual void handle(const Messages::LanguageClient::DeclarationsInDocument&) override; String m_project_path; WeakPtr m_language_client; diff --git a/Userland/DevTools/HackStudio/LanguageServers/Cpp/AutoCompleteEngine.cpp b/Userland/DevTools/HackStudio/LanguageServers/Cpp/AutoCompleteEngine.cpp index 6ee40241aac..e531869dded 100644 --- a/Userland/DevTools/HackStudio/LanguageServers/Cpp/AutoCompleteEngine.cpp +++ b/Userland/DevTools/HackStudio/LanguageServers/Cpp/AutoCompleteEngine.cpp @@ -26,11 +26,20 @@ #include "AutoCompleteEngine.h" -AutoCompleteEngine::AutoCompleteEngine(const FileDB& filedb) - : m_filedb(filedb) +namespace LanguageServers::Cpp { + +AutoCompleteEngine::AutoCompleteEngine(ClientConnection& connection, const FileDB& filedb) + : m_connection(connection) + , m_filedb(filedb) { } AutoCompleteEngine::~AutoCompleteEngine() { } +void AutoCompleteEngine::set_declarations_of_document(const String& filename, Vector&& declarations) +{ + VERIFY(set_declarations_of_document_callback); + set_declarations_of_document_callback(m_connection, filename, move(declarations)); +} +} diff --git a/Userland/DevTools/HackStudio/LanguageServers/Cpp/AutoCompleteEngine.h b/Userland/DevTools/HackStudio/LanguageServers/Cpp/AutoCompleteEngine.h index d6720682865..df61707c79d 100644 --- a/Userland/DevTools/HackStudio/LanguageServers/Cpp/AutoCompleteEngine.h +++ b/Userland/DevTools/HackStudio/LanguageServers/Cpp/AutoCompleteEngine.h @@ -31,9 +31,13 @@ #include #include +namespace LanguageServers::Cpp { + +class ClientConnection; + class AutoCompleteEngine { public: - AutoCompleteEngine(const FileDB& filedb); + AutoCompleteEngine(ClientConnection&, const FileDB& filedb); virtual ~AutoCompleteEngine(); virtual Vector get_suggestions(const String& file, const GUI::TextPosition& autocomplete_position) = 0; @@ -44,9 +48,15 @@ public: virtual Optional find_declaration_of(const String&, const GUI::TextPosition&) { return {}; }; +public: + Function)> set_declarations_of_document_callback; + protected: const FileDB& filedb() const { return m_filedb; } + void set_declarations_of_document(const String&, Vector&&); private: + ClientConnection& m_connection; const FileDB& m_filedb; }; +} diff --git a/Userland/DevTools/HackStudio/LanguageServers/Cpp/ClientConnection.cpp b/Userland/DevTools/HackStudio/LanguageServers/Cpp/ClientConnection.cpp index 2fd805a1cc3..99ad3d884ea 100644 --- a/Userland/DevTools/HackStudio/LanguageServers/Cpp/ClientConnection.cpp +++ b/Userland/DevTools/HackStudio/LanguageServers/Cpp/ClientConnection.cpp @@ -40,7 +40,8 @@ ClientConnection::ClientConnection(NonnullRefPtr socket, int : IPC::ClientConnection(*this, move(socket), client_id) { s_connections.set(client_id, *this); - m_autocomplete_engine = make(m_filedb); + m_autocomplete_engine = make(*this, m_filedb); + m_autocomplete_engine->set_declarations_of_document_callback = &ClientConnection::set_declarations_of_document_callback; } ClientConnection::~ClientConnection() @@ -132,9 +133,9 @@ void ClientConnection::handle(const Messages::LanguageServer::SetAutoCompleteMod dbgln("SetAutoCompleteMode: {}", message.mode()); #endif if (message.mode() == "Parser") - m_autocomplete_engine = make(m_filedb); + m_autocomplete_engine = make(*this, m_filedb); else - m_autocomplete_engine = make(m_filedb); + m_autocomplete_engine = make(*this, m_filedb); } void ClientConnection::handle(const Messages::LanguageServer::FindDeclaration& message) @@ -156,4 +157,9 @@ void ClientConnection::handle(const Messages::LanguageServer::FindDeclaration& m post_message(Messages::LanguageClient::DeclarationLocation(GUI::AutocompleteProvider::ProjectLocation { location.value().file, location.value().line, location.value().column })); } +void ClientConnection::set_declarations_of_document_callback(ClientConnection& instance, const String& filename, Vector&& declarations) +{ + instance.post_message(Messages::LanguageClient::DeclarationsInDocument(filename, move(declarations))); +} + } diff --git a/Userland/DevTools/HackStudio/LanguageServers/Cpp/ClientConnection.h b/Userland/DevTools/HackStudio/LanguageServers/Cpp/ClientConnection.h index 0103dde6cf2..c0accb7f1d4 100644 --- a/Userland/DevTools/HackStudio/LanguageServers/Cpp/ClientConnection.h +++ b/Userland/DevTools/HackStudio/LanguageServers/Cpp/ClientConnection.h @@ -59,6 +59,8 @@ private: virtual void handle(const Messages::LanguageServer::SetAutoCompleteMode&) override; virtual void handle(const Messages::LanguageServer::FindDeclaration&) override; + static void set_declarations_of_document_callback(ClientConnection&, const String&, Vector&&); + FileDB m_filedb; OwnPtr m_autocomplete_engine; }; diff --git a/Userland/DevTools/HackStudio/LanguageServers/Cpp/LexerAutoComplete.cpp b/Userland/DevTools/HackStudio/LanguageServers/Cpp/LexerAutoComplete.cpp index 14031432a68..95f6ea46860 100644 --- a/Userland/DevTools/HackStudio/LanguageServers/Cpp/LexerAutoComplete.cpp +++ b/Userland/DevTools/HackStudio/LanguageServers/Cpp/LexerAutoComplete.cpp @@ -31,8 +31,8 @@ namespace LanguageServers::Cpp { -LexerAutoComplete::LexerAutoComplete(const FileDB& filedb) - : AutoCompleteEngine(filedb) +LexerAutoComplete::LexerAutoComplete(ClientConnection& connection, const FileDB& filedb) + : AutoCompleteEngine(connection, filedb) { } diff --git a/Userland/DevTools/HackStudio/LanguageServers/Cpp/LexerAutoComplete.h b/Userland/DevTools/HackStudio/LanguageServers/Cpp/LexerAutoComplete.h index 58a836cce22..efbf246439c 100644 --- a/Userland/DevTools/HackStudio/LanguageServers/Cpp/LexerAutoComplete.h +++ b/Userland/DevTools/HackStudio/LanguageServers/Cpp/LexerAutoComplete.h @@ -39,7 +39,7 @@ using namespace ::Cpp; class LexerAutoComplete : public AutoCompleteEngine { public: - LexerAutoComplete(const FileDB& filedb); + LexerAutoComplete(ClientConnection&, const FileDB& filedb); virtual Vector get_suggestions(const String& file, const GUI::TextPosition& autocomplete_position) override; diff --git a/Userland/DevTools/HackStudio/LanguageServers/Cpp/ParserAutoComplete.cpp b/Userland/DevTools/HackStudio/LanguageServers/Cpp/ParserAutoComplete.cpp index eb69aba23af..aa4798d385b 100644 --- a/Userland/DevTools/HackStudio/LanguageServers/Cpp/ParserAutoComplete.cpp +++ b/Userland/DevTools/HackStudio/LanguageServers/Cpp/ParserAutoComplete.cpp @@ -27,6 +27,7 @@ #include "ParserAutoComplete.h" #include #include +#include #include #include #include @@ -35,8 +36,8 @@ namespace LanguageServers::Cpp { -ParserAutoComplete::ParserAutoComplete(const FileDB& filedb) - : AutoCompleteEngine(filedb) +ParserAutoComplete::ParserAutoComplete(ClientConnection& connection, const FileDB& filedb) + : AutoCompleteEngine(connection, filedb) { } @@ -71,6 +72,9 @@ OwnPtr ParserAutoComplete::create_document_dat #ifdef CPP_LANGUAGE_SERVER_DEBUG root->dump(0); #endif + + update_declared_symbols(*document_data); + return move(document_data); } @@ -79,8 +83,9 @@ void ParserAutoComplete::set_document_data(const String& file, OwnPtr ParserAutoComplete::find_declaration_of(const DocumentData& return {}; } +void ParserAutoComplete::update_declared_symbols(const DocumentData& document) +{ + Vector declarations; + for (auto& decl : document.parser.root_node()->declarations()) { + declarations.append({ decl.name(), { document.filename, decl.start().line, decl.start().column }, type_of_declaration(decl) }); + } + set_declarations_of_document(document.filename, move(declarations)); +} + +GUI::AutocompleteProvider::DeclarationType ParserAutoComplete::type_of_declaration(const Declaration& decl) +{ + if (decl.is_struct()) + return GUI::AutocompleteProvider::DeclarationType::Struct; + if (decl.is_class()) + return GUI::AutocompleteProvider::DeclarationType::Class; + if (decl.is_function()) + return GUI::AutocompleteProvider::DeclarationType::Function; + if (decl.is_variable_declaration()) + return GUI::AutocompleteProvider::DeclarationType::Variable; + return GUI::AutocompleteProvider::DeclarationType::Variable; +} + } diff --git a/Userland/DevTools/HackStudio/LanguageServers/Cpp/ParserAutoComplete.h b/Userland/DevTools/HackStudio/LanguageServers/Cpp/ParserAutoComplete.h index 3b83e41e3c6..d82373d701f 100644 --- a/Userland/DevTools/HackStudio/LanguageServers/Cpp/ParserAutoComplete.h +++ b/Userland/DevTools/HackStudio/LanguageServers/Cpp/ParserAutoComplete.h @@ -28,6 +28,7 @@ #include "AutoCompleteEngine.h" #include "FileDB.h" +#include #include #include #include @@ -42,7 +43,7 @@ using namespace ::Cpp; class ParserAutoComplete : public AutoCompleteEngine { public: - ParserAutoComplete(const FileDB& filedb); + ParserAutoComplete(ClientConnection&, const FileDB& filedb); virtual Vector get_suggestions(const String& file, const GUI::TextPosition& autocomplete_position) override; virtual void on_edit(const String& file) override; @@ -52,6 +53,7 @@ public: private: struct DocumentData { DocumentData(String&& text, const String& filename); + String filename; String text; Preprocessor preprocessor; Parser parser; @@ -80,6 +82,8 @@ private: OwnPtr create_document_data_for(const String& file); String document_path_from_include_path(const StringView& include_path) const; + void update_declared_symbols(const DocumentData&); + GUI::AutocompleteProvider::DeclarationType type_of_declaration(const Declaration&); HashMap> m_documents; }; diff --git a/Userland/DevTools/HackStudio/LanguageServers/LanguageClient.ipc b/Userland/DevTools/HackStudio/LanguageServers/LanguageClient.ipc index 6e1d0a9c4c4..889a37623e5 100644 --- a/Userland/DevTools/HackStudio/LanguageServers/LanguageClient.ipc +++ b/Userland/DevTools/HackStudio/LanguageServers/LanguageClient.ipc @@ -2,4 +2,5 @@ endpoint LanguageClient = 8002 { AutoCompleteSuggestions(Vector suggestions) =| DeclarationLocation(GUI::AutocompleteProvider::ProjectLocation location) =| + DeclarationsInDocument(String filename, Vector declarations) =| } diff --git a/Userland/Libraries/LibCpp/AST.h b/Userland/Libraries/LibCpp/AST.h index e01c1aeb9e5..26bcba7bd85 100644 --- a/Userland/Libraries/LibCpp/AST.h +++ b/Userland/Libraries/LibCpp/AST.h @@ -137,13 +137,19 @@ public: virtual bool is_variable_declaration() const { return false; } virtual bool is_parameter() const { return false; } virtual bool is_struct_or_class() const { return false; } + virtual bool is_struct() const { return false; } + virtual bool is_class() const { return false; } virtual bool is_function() const { return false; } + const StringView& name() const { return m_name; } + + StringView m_name; protected: Declaration(ASTNode* parent, Optional start, Optional end, const String& filename) : Statement(parent, start, end, filename) { } + }; class InvalidDeclaration : public Declaration { @@ -163,7 +169,6 @@ public: virtual const char* class_name() const override { return "FunctionDeclaration"; } virtual void dump(size_t indent) const override; virtual bool is_function() const override { return true; } - const StringView& name() const { return m_name; } RefPtr definition() { return m_definition; } FunctionDeclaration(ASTNode* parent, Optional start, Optional end, const String& filename) @@ -173,7 +178,6 @@ public: virtual NonnullRefPtrVector declarations() const override; - StringView m_name; RefPtr m_return_type; NonnullRefPtrVector m_parameters; RefPtr m_definition; @@ -184,7 +188,6 @@ public: virtual ~VariableOrParameterDeclaration() override = default; virtual bool is_variable_or_parameter_declaration() const override { return true; } - StringView m_name; RefPtr m_type; protected: @@ -492,6 +495,8 @@ public: virtual const char* class_name() const override { return "StructOrClassDeclaration"; } virtual void dump(size_t indent) const override; virtual bool is_struct_or_class() const override { return true; } + virtual bool is_struct() const override { return m_type == Type::Struct; } + virtual bool is_class() const override { return m_type == Type::Class; } enum class Type { Struct, @@ -505,7 +510,6 @@ public: } StructOrClassDeclaration::Type m_type; - StringView m_name; NonnullRefPtrVector m_members; };