From 9d90a6794c6aad0cde4ae77e12e1733aa45221a0 Mon Sep 17 00:00:00 2001 From: HolonProduction Date: Fri, 9 Jan 2026 13:58:13 +0100 Subject: [PATCH] LSP: Reuse stale parsers in request --- .../gdscript_language_protocol.cpp | 23 ++++++++++--------- .../gdscript_language_protocol.h | 8 +++---- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/modules/gdscript/language_server/gdscript_language_protocol.cpp b/modules/gdscript/language_server/gdscript_language_protocol.cpp index 7662252c62..2d01c49cf2 100644 --- a/modules/gdscript/language_server/gdscript_language_protocol.cpp +++ b/modules/gdscript/language_server/gdscript_language_protocol.cpp @@ -107,6 +107,7 @@ Error GDScriptLanguageProtocol::LSPeer::handle_data() { // Response String output = GDScriptLanguageProtocol::get_singleton()->process_message(msg); + clear_stale_parsers(); if (!output.is_empty()) { res_queue.push_back(output.utf8()); } @@ -397,13 +398,18 @@ ExtendGDScriptParser *GDScriptLanguageProtocol::LSPeer::parse_script(const Strin GDScriptLanguageProtocol::get_singleton()->get_workspace()->publish_diagnostics(p_path); } else { // Don't keep cached for further requests since we can't invalidate the cache properly. - parse_results.erase(p_path); - stale_parsers[p_path] = parser; + stale_parsers.insert(p_path); } return parser; } +void GDScriptLanguageProtocol::LSPeer::clear_stale_parsers() { + while (!stale_parsers.is_empty()) { + remove_cached_parser(*stale_parsers.begin()); + } +} + void GDScriptLanguageProtocol::LSPeer::remove_cached_parser(const String &p_path) { HashMap::Iterator cached = parse_results.find(p_path); if (cached) { @@ -411,11 +417,7 @@ void GDScriptLanguageProtocol::LSPeer::remove_cached_parser(const String &p_path parse_results.remove(cached); } - HashMap::Iterator stale = stale_parsers.find(p_path); - if (stale) { - memdelete(stale->value); - stale_parsers.remove(stale); - } + stale_parsers.erase(p_path); } ExtendGDScriptParser *GDScriptLanguageProtocol::get_parse_result(const String &p_path) { @@ -531,11 +533,10 @@ void GDScriptLanguageProtocol::resolve_related_symbols(const LSP::TextDocumentPo GDScriptLanguageProtocol::LSPeer::~LSPeer() { while (!parse_results.is_empty()) { - remove_cached_parser(parse_results.begin()->key); - } - while (!stale_parsers.is_empty()) { - remove_cached_parser(stale_parsers.begin()->key); + String path = parse_results.begin()->key; + remove_cached_parser(path); } + stale_parsers.clear(); } // clang-format off diff --git a/modules/gdscript/language_server/gdscript_language_protocol.h b/modules/gdscript/language_server/gdscript_language_protocol.h index bff630e177..c0f30cb9c3 100644 --- a/modules/gdscript/language_server/gdscript_language_protocol.h +++ b/modules/gdscript/language_server/gdscript_language_protocol.h @@ -78,10 +78,10 @@ private: ~LSPeer(); private: - // We can't cache parsers for scripts not managed by the editor since we have - // no way to invalidate the cache. We still need to keep track of those parsers - // to clean them up properly. - HashMap stale_parsers; + void clear_stale_parsers(); + // Paths of parsers which we can't cache longterm. + // Can be cleared up using `clear_stale_parsers()`. + HashSet stale_parsers; }; enum LSPErrorCode {