feat: support concurrency

This commit is contained in:
csh
2025-07-03 18:52:04 +08:00
parent 07feb1c52c
commit 3cc1fccc81
57 changed files with 6743 additions and 6377 deletions
@@ -1,159 +1,159 @@
#include <spdlog/spdlog.h>
#include "./completion_provider.hpp"
#include "../../protocol/transform/facade.hpp"
namespace lsp::providers::text_document
{
std::string CompletionProvider::ProvideResponse(const protocol::RequestMessage& request)
{
spdlog::debug("CompletionProvider: Providing response for method {}", request.method);
try {
// 验证请求是否包含参数
if (!request.params.has_value()) {
spdlog::warn("{}: Missing params in request", GetProviderName());
return BuildErrorMessageResponse(protocol::ErrorCode::kInvalidParams, "Missing params");
}
// 从 variant 中提取参数
protocol::CompletionParams completion_params = transform::As<protocol::CompletionParams>(request.params.value());
protocol::CompletionList completion_list = BuildCompletionResponse(completion_params);
// 构建响应消息
protocol::ResponseMessage response;
response.id = request.id;
response.result = transform::LSPAny(completion_list);
std::string json;
auto ec = glz::write_json(response, json);
if (ec) {
spdlog::error("{}: Failed to serialize response: {}", GetProviderName(), glz::format_error(ec, json));
return BuildErrorMessageResponse(protocol::ErrorCode::kInternalError, "Failed to serialize response");
}
return json;
} catch (const transform::ConversionError& e) {
spdlog::error("{}: Failed to convert params: {}", GetProviderName(), e.what());
return BuildErrorMessageResponse(protocol::ErrorCode::kInvalidParams, "Invalid completion params");
} catch (const std::exception& e) {
spdlog::error("{}: Unexpected error: {}", GetProviderName(), e.what());
return BuildErrorMessageResponse(protocol::ErrorCode::kInternalError, "Internal error");
}
}
std::string CompletionProvider::GetMethod() const
{
return "textDocument/completion";
}
std::string CompletionProvider::GetProviderName() const
{
return "CompletionProvider";
}
protocol::CompletionList CompletionProvider::BuildCompletionResponse(const protocol::CompletionParams& params)
{
spdlog::trace("{}: Processing completion request for URI='{}', Position=({}, {})",
GetProviderName(),
params.textDocument.uri,
params.position.line,
params.position.character);
// 获取补全前缀
std::string prefix = ExtractPrefix(params.textDocument, params.position);
// 如果提供了 context,可以使用其中的信息
if (params.context.has_value())
{
spdlog::trace("{}: Trigger kind: {}", GetProviderName(), static_cast<int>(params.context->triggerKind));
if (params.context->triggerCharacter.has_value())
spdlog::trace("{}: Trigger character: '{}'", GetProviderName(), params.context->triggerCharacter.value());
}
// 收集所有补全项
std::vector<protocol::CompletionItem> allItems;
// 添加关键字补全
auto keywordItems = ProvideKeywordCompletions(prefix);
allItems.insert(allItems.end(), keywordItems.begin(), keywordItems.end());
// 添加上下文相关补全
auto contextualItems = ProvideContextualCompletions(params.textDocument, params.position, prefix);
allItems.insert(allItems.end(), contextualItems.begin(), contextualItems.end());
// 构建补全列表
protocol::CompletionList result;
result.isIncomplete = false; // 表示这是完整的补全列表
result.items = std::move(allItems);
spdlog::info("{}: Provided {} completion items", GetProviderName(), result.items.size());
return result;
}
std::string CompletionProvider::ExtractPrefix(const protocol::TextDocumentIdentifier& textDocument, const protocol::Position& position)
{
// TODO: 实现从文档内容和位置计算前缀
// 这需要访问文档管理器来获取文档内容
// 现在返回空字符串
spdlog::trace("{}: ExtractPrefix not implemented, returning empty string", GetProviderName());
return "";
}
std::vector<protocol::CompletionItem> CompletionProvider::ProvideKeywordCompletions(const std::string& prefix)
{
std::vector<protocol::CompletionItem> items;
// 从 tsl_keywords_ 获取补全项
auto tslItems = tsl_keywords_.GetCompletionItems(prefix);
for (const auto& tslItem : tslItems) {
protocol::CompletionItem item;
item.label = tslItem.label;
item.kind = protocol::CompletionItemKind::kKeyword;
item.detail = "TSL Keyword";
// 创建文档内容
protocol::MarkupContent documentation;
documentation.kind = protocol::MarkupKindLiterals::PlainText;
documentation.value = "TSL language keyword";
item.documentation = documentation;
item.insertText = tslItem.label;
items.push_back(item);
}
spdlog::debug("{}: Found {} keyword completions", GetProviderName(), items.size());
return items;
}
std::vector<protocol::CompletionItem> CompletionProvider::ProvideContextualCompletions(const protocol::TextDocumentIdentifier& textDocument, const protocol::Position& position, const std::string& prefix)
{
spdlog::debug("{}: Processing contextual completions for URI: {}", GetProviderName(), textDocument.uri);
std::vector<protocol::CompletionItem> items;
// TODO: 基于上下文提供补全
// 示例:添加一个变量补全
if (!prefix.empty() && prefix[0] == '$')
{
protocol::CompletionItem varItem;
varItem.label = "$myVariable";
varItem.kind = protocol::CompletionItemKind::kVariable;
varItem.detail = "Local variable";
varItem.insertText = "$myVariable";
protocol::MarkupContent doc;
doc.kind = protocol::MarkupKindLiterals::Markdown;
doc.value = "Example variable completion";
varItem.documentation = doc;
items.push_back(varItem);
}
spdlog::debug("{}: Found {} contextual completions", GetProviderName(), items.size());
return items;
}
}
#include <spdlog/spdlog.h>
#include "./completion_provider.hpp"
#include "../../protocol/transform/facade.hpp"
namespace lsp::providers::text_document
{
std::string CompletionProvider::ProvideResponse(const protocol::RequestMessage& request)
{
spdlog::debug("CompletionProvider: Providing response for method {}", request.method);
try {
// 验证请求是否包含参数
if (!request.params.has_value()) {
spdlog::warn("{}: Missing params in request", GetProviderName());
return BuildErrorResponseMessage(request, protocol::ErrorCode::kInvalidParams, "Missing params");
}
// 从 variant 中提取参数
protocol::CompletionParams completion_params = transform::As<protocol::CompletionParams>(request.params.value());
protocol::CompletionList completion_list = BuildCompletionResponse(completion_params);
// 构建响应消息
protocol::ResponseMessage response;
response.id = request.id;
response.result = transform::LSPAny(completion_list);
std::string json;
auto ec = glz::write_json(response, json);
if (ec) {
spdlog::error("{}: Failed to serialize response: {}", GetProviderName(), glz::format_error(ec, json));
return BuildErrorResponseMessage(request, protocol::ErrorCode::kInternalError, "Failed to serialize response");
}
return json;
} catch (const transform::ConversionError& e) {
spdlog::error("{}: Failed to convert params: {}", GetProviderName(), e.what());
return BuildErrorResponseMessage(request, protocol::ErrorCode::kInvalidParams, "Invalid completion params");
} catch (const std::exception& e) {
spdlog::error("{}: Unexpected error: {}", GetProviderName(), e.what());
return BuildErrorResponseMessage(request, protocol::ErrorCode::kInternalError, "Internal error");
}
}
std::string CompletionProvider::GetMethod() const
{
return "textDocument/completion";
}
std::string CompletionProvider::GetProviderName() const
{
return "CompletionProvider";
}
protocol::CompletionList CompletionProvider::BuildCompletionResponse(const protocol::CompletionParams& params)
{
spdlog::trace("{}: Processing completion request for URI='{}', Position=({}, {})",
GetProviderName(),
params.textDocument.uri,
params.position.line,
params.position.character);
// 获取补全前缀
std::string prefix = ExtractPrefix(params.textDocument, params.position);
// 如果提供了 context,可以使用其中的信息
if (params.context.has_value())
{
spdlog::trace("{}: Trigger kind: {}", GetProviderName(), static_cast<int>(params.context->triggerKind));
if (params.context->triggerCharacter.has_value())
spdlog::trace("{}: Trigger character: '{}'", GetProviderName(), params.context->triggerCharacter.value());
}
// 收集所有补全项
std::vector<protocol::CompletionItem> allItems;
// 添加关键字补全
auto keywordItems = ProvideKeywordCompletions(prefix);
allItems.insert(allItems.end(), keywordItems.begin(), keywordItems.end());
// 添加上下文相关补全
auto contextualItems = ProvideContextualCompletions(params.textDocument, params.position, prefix);
allItems.insert(allItems.end(), contextualItems.begin(), contextualItems.end());
// 构建补全列表
protocol::CompletionList result;
result.isIncomplete = false; // 表示这是完整的补全列表
result.items = std::move(allItems);
spdlog::info("{}: Provided {} completion items", GetProviderName(), result.items.size());
return result;
}
std::string CompletionProvider::ExtractPrefix(const protocol::TextDocumentIdentifier& textDocument, const protocol::Position& position)
{
// TODO: 实现从文档内容和位置计算前缀
// 这需要访问文档管理器来获取文档内容
// 现在返回空字符串
spdlog::trace("{}: ExtractPrefix not implemented, returning empty string", GetProviderName());
return "";
}
std::vector<protocol::CompletionItem> CompletionProvider::ProvideKeywordCompletions(const std::string& prefix)
{
std::vector<protocol::CompletionItem> items;
// 从 tsl_keywords_ 获取补全项
auto tslItems = tsl_keywords_.GetCompletionItems(prefix);
for (const auto& tslItem : tslItems) {
protocol::CompletionItem item;
item.label = tslItem.label;
item.kind = protocol::CompletionItemKind::kKeyword;
item.detail = "TSL Keyword";
// 创建文档内容
protocol::MarkupContent documentation;
documentation.kind = protocol::MarkupKindLiterals::PlainText;
documentation.value = "TSL language keyword";
item.documentation = documentation;
item.insertText = tslItem.label;
items.push_back(item);
}
spdlog::debug("{}: Found {} keyword completions", GetProviderName(), items.size());
return items;
}
std::vector<protocol::CompletionItem> CompletionProvider::ProvideContextualCompletions(const protocol::TextDocumentIdentifier& textDocument, const protocol::Position& position, const std::string& prefix)
{
spdlog::debug("{}: Processing contextual completions for URI: {}", GetProviderName(), textDocument.uri);
std::vector<protocol::CompletionItem> items;
// TODO: 基于上下文提供补全
// 示例:添加一个变量补全
if (!prefix.empty() && prefix[0] == '$')
{
protocol::CompletionItem varItem;
varItem.label = "$myVariable";
varItem.kind = protocol::CompletionItemKind::kVariable;
varItem.detail = "Local variable";
varItem.insertText = "$myVariable";
protocol::MarkupContent doc;
doc.kind = protocol::MarkupKindLiterals::Markdown;
doc.value = "Example variable completion";
varItem.documentation = doc;
items.push_back(varItem);
}
spdlog::debug("{}: Found {} contextual completions", GetProviderName(), items.size());
return items;
}
}
@@ -1,33 +1,33 @@
#pragma once
#include <string>
#include <vector>
#include "../base/provider_interface.hpp"
#include "../../protocol/protocol.hpp"
#include "../../language/tsl_keywords.hpp"
namespace lsp::providers::text_document
{
class CompletionProvider : public ILspProvider
{
public:
CompletionProvider() = default;
std::string ProvideResponse(const protocol::RequestMessage& request) override;
std::string GetMethod() const override;
std::string GetProviderName() const override;
private:
// 构建完整的补全响应
protocol::CompletionList BuildCompletionResponse(const protocol::CompletionParams& params);
// 获取补全前缀(从文档内容和位置计算)
std::string ExtractPrefix(const protocol::TextDocumentIdentifier& textDocument, const protocol::Position& position);
// 提供不同类型的补全
std::vector<protocol::CompletionItem> ProvideKeywordCompletions(const std::string& prefix);
std::vector<protocol::CompletionItem> ProvideContextualCompletions(const protocol::TextDocumentIdentifier& textDocument, const protocol::Position& position, const std::string& prefix);
private:
tsl::TslKeywords tsl_keywords_;
};
}
#pragma once
#include <string>
#include <vector>
#include "../base/provider_interface.hpp"
#include "../../protocol/protocol.hpp"
#include "../../language/tsl_keywords.hpp"
namespace lsp::providers::text_document
{
class CompletionProvider : public ILspProvider
{
public:
CompletionProvider() = default;
std::string ProvideResponse(const protocol::RequestMessage& request) override;
std::string GetMethod() const override;
std::string GetProviderName() const override;
private:
// 构建完整的补全响应
protocol::CompletionList BuildCompletionResponse(const protocol::CompletionParams& params);
// 获取补全前缀(从文档内容和位置计算)
std::string ExtractPrefix(const protocol::TextDocumentIdentifier& textDocument, const protocol::Position& position);
// 提供不同类型的补全
std::vector<protocol::CompletionItem> ProvideKeywordCompletions(const std::string& prefix);
std::vector<protocol::CompletionItem> ProvideContextualCompletions(const protocol::TextDocumentIdentifier& textDocument, const protocol::Position& position, const std::string& prefix);
private:
tsl::TslKeywords tsl_keywords_;
};
}
@@ -1,27 +1,27 @@
#include <spdlog/spdlog.h>
#include "./did_change_provider.hpp"
#include "./did_open_provider.hpp"
namespace lsp::providers::text_document
{
std::string DidChangeProvider::ProvideResponse(const protocol::RequestMessage& request)
{
spdlog::debug("DidChangeProvider: Providing response for method {}", request.method);
std::string json;
glz::obj empty_obj{}; // glaze的对象类型
auto ec = glz::write_json(empty_obj, json);
return ec ? BuildErrorMessageResponse(protocol::ErrorCode::kInternalError, "Internal error") : json;
}
std::string DidChangeProvider::GetMethod() const
{
return "textDocument/didChange";
}
std::string DidChangeProvider::GetProviderName() const
{
return "DidChangeProvider";
}
}
#include <spdlog/spdlog.h>
#include "./did_change_provider.hpp"
#include "./did_open_provider.hpp"
namespace lsp::providers::text_document
{
std::string DidChangeProvider::ProvideResponse(const protocol::RequestMessage& request)
{
spdlog::debug("DidChangeProvider: Providing response for method {}", request.method);
std::string json;
glz::obj empty_obj{}; // glaze的对象类型
auto ec = glz::write_json(empty_obj, json);
return ec ? BuildErrorResponseMessage(request, protocol::ErrorCode::kInternalError, "Internal error") : json;
}
std::string DidChangeProvider::GetMethod() const
{
return "textDocument/didChange";
}
std::string DidChangeProvider::GetProviderName() const
{
return "DidChangeProvider";
}
}
@@ -1,14 +1,14 @@
#pragma once
#include "../base/provider_interface.hpp"
namespace lsp::providers::text_document
{
class DidChangeProvider : public ILspProvider
{
public:
DidChangeProvider() = default;
std::string ProvideResponse(const protocol::RequestMessage& request) override;
std::string GetMethod() const override;
std::string GetProviderName() const override;
};
}
#pragma once
#include "../base/provider_interface.hpp"
namespace lsp::providers::text_document
{
class DidChangeProvider : public ILspProvider
{
public:
DidChangeProvider() = default;
std::string ProvideResponse(const protocol::RequestMessage& request) override;
std::string GetMethod() const override;
std::string GetProviderName() const override;
};
}
@@ -1,25 +1,25 @@
#include <spdlog/spdlog.h>
#include "./did_open_provider.hpp"
namespace lsp::providers::text_document
{
std::string DidOpenProvider::ProvideResponse(const protocol::RequestMessage& request)
{
spdlog::debug("DidOpenProvider: Providing response for method {}", request.method);
std::string json;
glz::obj empty_obj{}; // glaze的对象类型
auto ec = glz::write_json(empty_obj, json);
return ec ? BuildErrorMessageResponse(protocol::ErrorCode::kInternalError, "Internal error") : json;
}
std::string DidOpenProvider::GetMethod() const
{
return "textDocument/didOpen";
}
std::string DidOpenProvider::GetProviderName() const
{
return "DidOpenProvider";
}
}
#include <spdlog/spdlog.h>
#include "./did_open_provider.hpp"
namespace lsp::providers::text_document
{
std::string DidOpenProvider::ProvideResponse(const protocol::RequestMessage& request)
{
spdlog::debug("DidOpenProvider: Providing response for method {}", request.method);
std::string json;
glz::obj empty_obj{}; // glaze的对象类型
auto ec = glz::write_json(empty_obj, json);
return ec ? BuildErrorResponseMessage(request, protocol::ErrorCode::kInternalError, "Internal error") : json;
}
std::string DidOpenProvider::GetMethod() const
{
return "textDocument/didOpen";
}
std::string DidOpenProvider::GetProviderName() const
{
return "DidOpenProvider";
}
}
@@ -1,15 +1,15 @@
#pragma once
#include <unordered_map>
#include "../base/provider_interface.hpp"
namespace lsp::providers::text_document
{
class DidOpenProvider : public ILspProvider
{
public:
DidOpenProvider() = default;
std::string ProvideResponse(const protocol::RequestMessage& request) override;
std::string GetMethod() const override;
std::string GetProviderName() const override;
};
}
#pragma once
#include <unordered_map>
#include "../base/provider_interface.hpp"
namespace lsp::providers::text_document
{
class DidOpenProvider : public ILspProvider
{
public:
DidOpenProvider() = default;
std::string ProvideResponse(const protocol::RequestMessage& request) override;
std::string GetMethod() const override;
std::string GetProviderName() const override;
};
}