feat(lsp_server): implement missing providers and json coverage

Implement workspace configuration/folders and apply WorkspaceEdit.changes.

Strengthen provider JSON coverage (all methods require params, no errors).

Verified: Release test_provider
This commit is contained in:
csh
2025-12-24 10:42:13 +08:00
parent f6943e69ef
commit 09e65224fe
93 changed files with 14203 additions and 856 deletions
@@ -1,7 +1,5 @@
module;
#include <format>
export module lsp.provider.initialize.initialize;
import spdlog;
@@ -29,7 +27,11 @@ export namespace lsp::provider
protocol::InitializeResult BuildInitializeResult();
protocol::TextDocumentSyncOptions BuildTextDocumentSyncOptions();
protocol::CompletionOptions BuildCompletionOptions();
protocol::SignatureHelpOptions BuildSignatureHelpOptions();
protocol::SemanticTokensOptions BuildSemanticTokenOptions();
protocol::CodeActionOptions BuildCodeActionOptions();
protocol::DocumentOnTypeFormattingOptions BuildOnTypeFormattingOptions();
protocol::ExecuteCommandOptions BuildExecuteCommandOptions();
void ProcessWorkspaceFolder(const std::vector<protocol::WorkspaceFolder>& workspace_folders, ExecutionContext& context);
};
@@ -51,7 +53,10 @@ namespace lsp::provider
manager_hub.Initialize();
if (params.workspaceFolders)
{
manager_hub.SetWorkspaceFolders(params.workspaceFolders.value());
ProcessWorkspaceFolder(params.workspaceFolders.value(), context);
}
protocol::ResponseMessage response;
response.id = request.id;
@@ -73,7 +78,51 @@ namespace lsp::provider
result.serverInfo.version = __DATE__;
result.capabilities.textDocumentSync = BuildTextDocumentSyncOptions();
result.capabilities.completionProvider = BuildCompletionOptions();
// result.capabilities.semanticTokensProvider = BuildSemanticTokenOptions();
result.capabilities.definitionProvider = true;
result.capabilities.typeDefinitionProvider = true;
result.capabilities.implementationProvider = true;
result.capabilities.hoverProvider = true;
result.capabilities.signatureHelpProvider = BuildSignatureHelpOptions();
result.capabilities.codeActionProvider = BuildCodeActionOptions();
result.capabilities.codeLensProvider = protocol::CodeLensOptions{ .resolveProvider = true };
result.capabilities.documentLinkProvider = protocol::DocumentLinkOptions{ .resolveProvider = true };
result.capabilities.colorProvider = true;
result.capabilities.referencesProvider = true;
result.capabilities.documentHighlightProvider = true;
result.capabilities.renameProvider = protocol::RenameOptions{ .prepareProvider = true };
result.capabilities.documentSymbolProvider = true;
result.capabilities.workspaceSymbolProvider = protocol::WorkspaceSymbolOptions{ .resolveProvider = true };
result.capabilities.semanticTokensProvider = BuildSemanticTokenOptions();
result.capabilities.callHierarchyProvider = true;
result.capabilities.typeHierarchyProvider = true;
result.capabilities.inlayHintProvider = protocol::InlayHintOptions{ .resolveProvider = true };
result.capabilities.foldingRangeProvider = true;
result.capabilities.selectionRangeProvider = true;
result.capabilities.linkedEditingRangeProvider = true;
result.capabilities.monikerProvider = true;
result.capabilities.inlineValueProvider = true;
result.capabilities.documentFormattingProvider = true;
result.capabilities.documentRangeFormattingProvider = true;
result.capabilities.documentOnTypeFormattingProvider = BuildOnTypeFormattingOptions();
result.capabilities.executeCommandProvider = BuildExecuteCommandOptions();
protocol::DiagnosticOptions diagnostic;
diagnostic.identifier = "syntax";
diagnostic.interFileDependencies = false;
diagnostic.workspaceDiagnostics = true;
result.capabilities.diagnosticProvider = std::move(diagnostic);
protocol::ServerCapabilities::Workspace workspace;
protocol::ServerCapabilities::Workspace::FileOperations file_operations;
file_operations.didCreate = true;
file_operations.willCreate = true;
file_operations.didDelete = true;
file_operations.willDelete = true;
file_operations.didRename = true;
file_operations.willRename = true;
workspace.fileOperations = std::move(file_operations);
result.capabilities.workspace = std::move(workspace);
return result;
}
@@ -94,42 +143,65 @@ namespace lsp::provider
return options;
}
protocol::SignatureHelpOptions Initialize::BuildSignatureHelpOptions()
{
protocol::SignatureHelpOptions options;
options.triggerCharacters = { std::vector<std::string>{ "(", "," } };
options.retriggerCharacters = { std::vector<std::string>{ "(", "," } };
return options;
}
protocol::CodeActionOptions Initialize::BuildCodeActionOptions()
{
protocol::CodeActionOptions options;
options.codeActionKinds = std::vector<protocol::CodeActionKind>{
protocol::CodeActionKindLiterals::QuickFix,
protocol::CodeActionKindLiterals::SourceFixAll,
};
options.resolveProvider = true;
return options;
}
protocol::DocumentOnTypeFormattingOptions Initialize::BuildOnTypeFormattingOptions()
{
protocol::DocumentOnTypeFormattingOptions options;
options.firstTriggerCharacter = ";";
options.moreTriggerCharacter = std::vector<protocol::string>{ "\n" };
return options;
}
protocol::ExecuteCommandOptions Initialize::BuildExecuteCommandOptions()
{
protocol::ExecuteCommandOptions options;
options.commands = std::vector<protocol::string>{
"tsl.noop",
"tsl.loadWorkspace",
"tsl.indexFiles",
};
return options;
}
protocol::SemanticTokensOptions Initialize::BuildSemanticTokenOptions()
{
protocol::SemanticTokensOptions options;
options.legend.tokenTypes.emplace_back(protocol::SemanticTokenTypesLiterals::Namespace);
options.legend.tokenTypes.emplace_back(protocol::SemanticTokenTypesLiterals::Type);
options.legend.tokenTypes.emplace_back(protocol::SemanticTokenTypesLiterals::Class);
options.legend.tokenTypes.emplace_back(protocol::SemanticTokenTypesLiterals::Enum);
options.legend.tokenTypes.emplace_back(protocol::SemanticTokenTypesLiterals::Interface);
options.legend.tokenTypes.emplace_back(protocol::SemanticTokenTypesLiterals::Struct);
options.legend.tokenTypes.emplace_back(protocol::SemanticTokenTypesLiterals::TypeParameter);
options.legend.tokenTypes.emplace_back(protocol::SemanticTokenTypesLiterals::Parameter);
options.legend.tokenTypes.emplace_back(protocol::SemanticTokenTypesLiterals::Variable);
options.legend.tokenTypes.emplace_back(protocol::SemanticTokenTypesLiterals::Property);
options.legend.tokenTypes.emplace_back(protocol::SemanticTokenTypesLiterals::EnumMember);
options.legend.tokenTypes.emplace_back(protocol::SemanticTokenTypesLiterals::Event);
options.legend.tokenTypes.emplace_back(protocol::SemanticTokenTypesLiterals::Function);
options.legend.tokenTypes.emplace_back(protocol::SemanticTokenTypesLiterals::Method);
options.legend.tokenTypes.emplace_back(protocol::SemanticTokenTypesLiterals::Macro);
options.legend.tokenTypes.emplace_back(protocol::SemanticTokenTypesLiterals::Function);
options.legend.tokenTypes.emplace_back(protocol::SemanticTokenTypesLiterals::Property);
options.legend.tokenTypes.emplace_back(protocol::SemanticTokenTypesLiterals::Variable);
options.legend.tokenTypes.emplace_back(protocol::SemanticTokenTypesLiterals::Parameter);
options.legend.tokenTypes.emplace_back(protocol::SemanticTokenTypesLiterals::Keyword);
options.legend.tokenTypes.emplace_back(protocol::SemanticTokenTypesLiterals::Modifier);
options.legend.tokenTypes.emplace_back(protocol::SemanticTokenTypesLiterals::Comment);
options.legend.tokenTypes.emplace_back(protocol::SemanticTokenTypesLiterals::String);
options.legend.tokenTypes.emplace_back(protocol::SemanticTokenTypesLiterals::Number);
options.legend.tokenTypes.emplace_back(protocol::SemanticTokenTypesLiterals::Regexp);
options.legend.tokenTypes.emplace_back(protocol::SemanticTokenTypesLiterals::Operator);
options.legend.tokenTypes.emplace_back(protocol::SemanticTokenTypesLiterals::Decorator);
options.legend.tokenModifiers.emplace_back(protocol::SemanticTokenModifiersLiterals::Declaration);
options.legend.tokenModifiers.emplace_back(protocol::SemanticTokenModifiersLiterals::Definition);
options.legend.tokenModifiers.emplace_back(protocol::SemanticTokenModifiersLiterals::Readonly);
options.legend.tokenModifiers.emplace_back(protocol::SemanticTokenModifiersLiterals::Static);
options.legend.tokenModifiers.emplace_back(protocol::SemanticTokenModifiersLiterals::Deprecated);
options.legend.tokenModifiers.emplace_back(protocol::SemanticTokenModifiersLiterals::Abstract);
options.legend.tokenModifiers.emplace_back(protocol::SemanticTokenModifiersLiterals::Async);
options.legend.tokenModifiers.emplace_back(protocol::SemanticTokenModifiersLiterals::Readonly);
options.legend.tokenModifiers.emplace_back(protocol::SemanticTokenModifiersLiterals::Modification);
options.legend.tokenModifiers.emplace_back(protocol::SemanticTokenModifiersLiterals::Documentation);
options.legend.tokenModifiers.emplace_back(protocol::SemanticTokenModifiersLiterals::DefaultLibrary);
options.range = true;
options.full = protocol::SemanticTokensOptions::Full{ .delta = true };
return options;