From 5c19a48b952f07f39e00e8487aa52227a9924c28 Mon Sep 17 00:00:00 2001 From: Itamar Date: Fri, 7 May 2021 15:20:05 +0300 Subject: [PATCH] CppLanguageServer: Cache declarations from headers in every document Previously, to get the globally available declarations in a document (including declarations from headers), we would have to recursively walk the #include tree and get the declarations of each included document. To improve upon this, we now store a HashTable of globally available declaration from included header files in each document, and populate it when we first process the document. Before this, invoking simple autocomplete actions in code documents that had a very large #include tree (e.g when was included) hang the CppLanguageServer process and used 100% CPU until the process ran out of memory. Now, the autocomplete request in that situation returns immediately :^) --- .../Cpp/ParserAutoComplete.cpp | 28 +++++++++---------- .../LanguageServers/Cpp/ParserAutoComplete.h | 5 +++- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/Userland/DevTools/HackStudio/LanguageServers/Cpp/ParserAutoComplete.cpp b/Userland/DevTools/HackStudio/LanguageServers/Cpp/ParserAutoComplete.cpp index 2a8b598092..e3c195a4db 100644 --- a/Userland/DevTools/HackStudio/LanguageServers/Cpp/ParserAutoComplete.cpp +++ b/Userland/DevTools/HackStudio/LanguageServers/Cpp/ParserAutoComplete.cpp @@ -44,12 +44,7 @@ OwnPtr ParserAutoComplete::create_document_dat auto document = filedb().get_or_create_from_filesystem(file); if (!document) return {}; - auto content = document->text(); - auto document_data = create_document_data(document->text(), file); - - update_declared_symbols(*document_data); - - return document_data; + return create_document_data(document->text(), file); } void ParserAutoComplete::set_document_data(const String& file, OwnPtr&& data) @@ -260,13 +255,8 @@ Vector ParserAutoComplete::properties_of_type( NonnullRefPtrVector ParserAutoComplete::get_global_declarations_including_headers(const DocumentData& document) const { NonnullRefPtrVector declarations; - for (auto& include : document.preprocessor().included_paths()) { - document_path_from_include_path(include); - auto included_document = get_document_data(document_path_from_include_path(include)); - if (!included_document) - continue; - declarations.append(get_global_declarations_including_headers(*included_document)); - } + for (auto& decl : document.m_declarations_from_headers) + declarations.append(*decl); declarations.append(get_global_declarations(*document.parser().root_node())); @@ -434,8 +424,16 @@ RefPtr ParserAutoComplete::find_declaration_of(const DocumentData& return {}; } -void ParserAutoComplete::update_declared_symbols(const DocumentData& document) +void ParserAutoComplete::update_declared_symbols(DocumentData& document) { + for (auto& include : document.preprocessor().included_paths()) { + auto included_document = get_or_create_document_data(document_path_from_include_path(include)); + if (!included_document) + continue; + for (auto&& decl : get_global_declarations_including_headers(*included_document)) + document.m_declarations_from_headers.set(move(decl)); + } + Vector declarations; for (auto& decl : get_global_declarations(*document.parser().root_node())) { @@ -494,6 +492,8 @@ OwnPtr ParserAutoComplete::create_document_dat if constexpr (CPP_LANGUAGE_SERVER_DEBUG) root->dump(0); + update_declared_symbols(*document_data); + return document_data; } diff --git a/Userland/DevTools/HackStudio/LanguageServers/Cpp/ParserAutoComplete.h b/Userland/DevTools/HackStudio/LanguageServers/Cpp/ParserAutoComplete.h index 5d8c4487db..39db9c8656 100644 --- a/Userland/DevTools/HackStudio/LanguageServers/Cpp/ParserAutoComplete.h +++ b/Userland/DevTools/HackStudio/LanguageServers/Cpp/ParserAutoComplete.h @@ -59,6 +59,9 @@ private: String m_text; OwnPtr m_preprocessor; OwnPtr m_parser; + + // FIXME: This HashTable must be re-computed if a declaration from a header file is modified + HashTable> m_declarations_from_headers; }; Vector autocomplete_property(const DocumentData&, const MemberExpression&, const String partial_text) const; @@ -85,7 +88,7 @@ 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&); + void update_declared_symbols(DocumentData&); GUI::AutocompleteProvider::DeclarationType type_of_declaration(const Declaration&); String scope_of_declaration(const Declaration&); Optional find_preprocessor_definition(const DocumentData&, const GUI::TextPosition&);