LSP: Reuse stale parsers in request

This commit is contained in:
HolonProduction
2026-01-09 13:58:13 +01:00
parent 4089843d13
commit 9d90a6794c
2 changed files with 16 additions and 15 deletions

View File

@@ -107,6 +107,7 @@ Error GDScriptLanguageProtocol::LSPeer::handle_data() {
// Response // Response
String output = GDScriptLanguageProtocol::get_singleton()->process_message(msg); String output = GDScriptLanguageProtocol::get_singleton()->process_message(msg);
clear_stale_parsers();
if (!output.is_empty()) { if (!output.is_empty()) {
res_queue.push_back(output.utf8()); 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); GDScriptLanguageProtocol::get_singleton()->get_workspace()->publish_diagnostics(p_path);
} else { } else {
// Don't keep cached for further requests since we can't invalidate the cache properly. // Don't keep cached for further requests since we can't invalidate the cache properly.
parse_results.erase(p_path); stale_parsers.insert(p_path);
stale_parsers[p_path] = parser;
} }
return parser; 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) { void GDScriptLanguageProtocol::LSPeer::remove_cached_parser(const String &p_path) {
HashMap<String, ExtendGDScriptParser *>::Iterator cached = parse_results.find(p_path); HashMap<String, ExtendGDScriptParser *>::Iterator cached = parse_results.find(p_path);
if (cached) { if (cached) {
@@ -411,11 +417,7 @@ void GDScriptLanguageProtocol::LSPeer::remove_cached_parser(const String &p_path
parse_results.remove(cached); parse_results.remove(cached);
} }
HashMap<String, ExtendGDScriptParser *>::Iterator stale = stale_parsers.find(p_path); stale_parsers.erase(p_path);
if (stale) {
memdelete(stale->value);
stale_parsers.remove(stale);
}
} }
ExtendGDScriptParser *GDScriptLanguageProtocol::get_parse_result(const String &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() { GDScriptLanguageProtocol::LSPeer::~LSPeer() {
while (!parse_results.is_empty()) { while (!parse_results.is_empty()) {
remove_cached_parser(parse_results.begin()->key); String path = parse_results.begin()->key;
} remove_cached_parser(path);
while (!stale_parsers.is_empty()) {
remove_cached_parser(stale_parsers.begin()->key);
} }
stale_parsers.clear();
} }
// clang-format off // clang-format off

View File

@@ -78,10 +78,10 @@ private:
~LSPeer(); ~LSPeer();
private: private:
// We can't cache parsers for scripts not managed by the editor since we have void clear_stale_parsers();
// no way to invalidate the cache. We still need to keep track of those parsers // Paths of parsers which we can't cache longterm.
// to clean them up properly. // Can be cleared up using `clear_stale_parsers()`.
HashMap<String, ExtendGDScriptParser *> stale_parsers; HashSet<String> stale_parsers;
}; };
enum LSPErrorCode { enum LSPErrorCode {