LuaLanguageClient: Fix crash on exit

Change-Id: I2f70d0b1586bc2bfbb27ea1513313e5c6ca32754
Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
Marcus Tillmanns
2024-06-24 13:52:33 +02:00
parent 8910356ffc
commit 96815bb95e

View File

@@ -175,7 +175,7 @@ public:
std::optional<sol::protected_function> m_startFailedCallback; std::optional<sol::protected_function> m_startFailedCallback;
QMap<QString, sol::protected_function> m_messageCallbacks; QMap<QString, sol::protected_function> m_messageCallbacks;
QList<Client *> m_clients; LuaClientSettings *m_settings{nullptr};
public: public:
static BaseSettings::StartBehavior startBehaviorFromString(const QString &str) static BaseSettings::StartBehavior startBehaviorFromString(const QString &str)
@@ -190,6 +190,8 @@ public:
throw sol::error("Unknown start behavior: " + str.toStdString()); throw sol::error("Unknown start behavior: " + str.toStdString());
} }
void setSettings(LuaClientSettings *settings) { m_settings = settings; }
LuaClientWrapper(const sol::table &options) LuaClientWrapper(const sol::table &options)
{ {
m_cmdLineCallback = addValue<CommandLine>( m_cmdLineCallback = addValue<CommandLine>(
@@ -267,8 +269,6 @@ public:
auto luaClient = qobject_cast<LuaClient *>(c); auto luaClient = qobject_cast<LuaClient *>(c);
if (luaClient && luaClient->m_settingsId == m_settingsTypeId && m_onInstanceStart) { if (luaClient && luaClient->m_settingsId == m_settingsTypeId && m_onInstanceStart) {
QTC_CHECK(::Lua::LuaEngine::void_safe_call(*m_onInstanceStart, c)); QTC_CHECK(::Lua::LuaEngine::void_safe_call(*m_onInstanceStart, c));
m_clients.push_back(c);
updateMessageCallbacks(); updateMessageCallbacks();
} }
}); });
@@ -286,22 +286,11 @@ public:
if (!luaClient || luaClient->m_settingsId != m_settingsTypeId) if (!luaClient || luaClient->m_settingsId != m_settingsTypeId)
return; return;
if (m_clients.contains(c))
m_clients.removeOne(c);
if (unexpected && m_startFailedCallback) { if (unexpected && m_startFailedCallback) {
QTC_CHECK_EXPECTED(::Lua::LuaEngine::void_safe_call(*m_startFailedCallback)); QTC_CHECK_EXPECTED(::Lua::LuaEngine::void_safe_call(*m_startFailedCallback));
} }
} }
~LuaClientWrapper()
{
for (auto client : m_clients)
LanguageClientManager::shutdownClient(client);
// TODO: Unregister Client settings from LanguageClientManager
}
TransportType transportType() { return m_transportType; } TransportType transportType() { return m_transportType; }
void applySettings() void applySettings()
@@ -340,7 +329,9 @@ public:
void updateMessageCallbacks() void updateMessageCallbacks()
{ {
for (Client *c : m_clients) { for (Client *c : LanguageClientManager::clientsForSetting(m_settings)) {
if (!c)
continue;
for (const auto &[msg, func] : m_messageCallbacks.asKeyValueRange()) { for (const auto &[msg, func] : m_messageCallbacks.asKeyValueRange()) {
c->registerCustomMethod( c->registerCustomMethod(
msg, msg,
@@ -367,9 +358,11 @@ public:
if (!messageValue.isObject()) if (!messageValue.isObject())
throw sol::error("Message is not an object"); throw sol::error("Message is not an object");
const LanguageServerProtocol::JsonRpcMessage jsonrpcmessage(messageValue.toObject()); const LanguageServerProtocol::JsonRpcMessage jsonrpcmessage(messageValue.toObject());
for (Client *c : m_clients) for (Client *c : LanguageClientManager::clientsForSetting(m_settings)) {
if (c)
c->sendMessage(jsonrpcmessage); c->sendMessage(jsonrpcmessage);
} }
}
void updateOptions() void updateOptions()
{ {
@@ -536,6 +529,7 @@ static void registerLuaApi()
[](const sol::table &options) -> std::shared_ptr<LuaClientWrapper> { [](const sol::table &options) -> std::shared_ptr<LuaClientWrapper> {
auto luaClient = std::make_shared<LuaClientWrapper>(options); auto luaClient = std::make_shared<LuaClientWrapper>(options);
auto client = new LuaClientSettings(luaClient); auto client = new LuaClientSettings(luaClient);
luaClient->setSettings(client);
// The order is important! // The order is important!
// First restore the settings ... // First restore the settings ...