From 07f79b943c3041dd18137d72893af260b75ddcf9 Mon Sep 17 00:00:00 2001 From: Jay Kwak <82421531+jkwak-work@users.noreply.github.com> Date: Mon, 16 Jun 2025 11:42:45 -0700 Subject: Disable periadic diagnostic update on language-server on CI (#7445) The "textDocument/publishDiagnostics" Notification in the official Language Server Protocol, or LSP for short, is a notification that the server sends to the client such as VSCode or Visual Studio without the client having to ask for it. Its purpose is to provide a list of errors, warnings, or other informational "squiggles" for a specific file. Because the notification is an asynchronous push notification, it is receieved as an unexpected RPC message during the slang-test CI tests. When a notificatoin is unexpectedly sent to slang-test, the communication goes out-of-sync and the rest of language-server based tests intermittently fails. In order to address the problem, this PR adds a new command-line argument to change the behavior of the notification and it will be sent in a more deterministic manner where the notification can be sent only in one of three cases: didOpen, didChange, and didClose. Because these evets are only ways to cause a new notification, we can still expect to get the same diagnostic messages without missing any of them. For slang-test CI test, this new option will be used to make the notification more deterministic. --- source/slang/slang-language-server.cpp | 47 +++++++++++++++++++++++++++++++--- source/slang/slang-language-server.h | 3 +++ 2 files changed, 46 insertions(+), 4 deletions(-) (limited to 'source') diff --git a/source/slang/slang-language-server.cpp b/source/slang/slang-language-server.cpp index 59a9854f0..cd9818f65 100644 --- a/source/slang/slang-language-server.cpp +++ b/source/slang/slang-language-server.cpp @@ -252,7 +252,18 @@ SlangResult LanguageServerCore::didOpenTextDocument(const DidOpenTextDocumentPar SlangResult LanguageServer::didOpenTextDocument(const DidOpenTextDocumentParams& args) { - return m_core.didOpenTextDocument(args); + // When periodic diagnostic updates are disabled (e.g., for testing), + // the main server loop will not automatically publish diagnostics. + // In this case, we must manually trigger a diagnostic publication + // after any action that could affect the results, such as opening a document. + // The same logic applies to didChange and didClose handlers. + resetDiagnosticUpdateTime(); + auto result = m_core.didOpenTextDocument(args); + if (!m_core.m_options.periodicDiagnosticUpdate) + { + publishDiagnostics(); + } + return result; } static bool isBoolType(Type* t) @@ -2541,7 +2552,12 @@ void LanguageServer::processCommands() SlangResult LanguageServer::didCloseTextDocument(const DidCloseTextDocumentParams& args) { resetDiagnosticUpdateTime(); - return m_core.didCloseTextDocument(args); + auto result = m_core.didCloseTextDocument(args); + if (!m_core.m_options.periodicDiagnosticUpdate) + { + publishDiagnostics(); + } + return result; } SlangResult LanguageServerCore::didCloseTextDocument(const DidCloseTextDocumentParams& args) @@ -2554,7 +2570,12 @@ SlangResult LanguageServerCore::didCloseTextDocument(const DidCloseTextDocumentP SlangResult LanguageServer::didChangeTextDocument(const DidChangeTextDocumentParams& args) { resetDiagnosticUpdateTime(); - return m_core.didChangeTextDocument(args); + auto result = m_core.didChangeTextDocument(args); + if (!m_core.m_options.periodicDiagnosticUpdate) + { + publishDiagnostics(); + } + return result; } SlangResult LanguageServerCore::didChangeTextDocument(const DidChangeTextDocumentParams& args) @@ -2583,7 +2604,8 @@ void LanguageServer::update() { if (!m_core.m_workspace) return; - publishDiagnostics(); + if (m_core.m_options.periodicDiagnosticUpdate) + publishDiagnostics(); } void LanguageServer::updateConfigFromJSON(const JSONValue& jsonVal) @@ -2689,7 +2711,24 @@ SLANG_API void LanguageServerStartupOptions::parse(int argc, const char* const* for (int i = 1; i < argc; i++) { if (strcmp(argv[i], "-vs") == 0) + { isVisualStudio = true; + } + else if (strcmp(argv[i], "-periodic-diagnostic-update") == 0) + { + periodicDiagnosticUpdate = true; + if (i + 1 < argc) + { + const char* value = argv[i + 1]; + if (value[0] == 'f' || value[0] == 'F' || value[0] == 'n' || value[0] == 'N' || + value[0] == '0' || + ((value[0] == 'o' || value[0] == 'O') && (value[1] == 'f' || value[1] == 'F'))) + { + periodicDiagnosticUpdate = false; + } + i++; + } + } } } diff --git a/source/slang/slang-language-server.h b/source/slang/slang-language-server.h index 4b0abe3f2..e31e77acb 100644 --- a/source/slang/slang-language-server.h +++ b/source/slang/slang-language-server.h @@ -83,6 +83,9 @@ struct LanguageServerStartupOptions // Are we working with Visual Studio client? bool isVisualStudio = false; + // A flag to control periodic diagnostic update. Defaults to true. + bool periodicDiagnosticUpdate = true; + SLANG_API void parse(int argc, const char* const* argv); }; -- cgit v1.2.3