🔧 chore(lsp_server): gate providers to completion/definition

Initialize now advertises only completion (resolve) and definition.

Verified: test_provider (clang-linux-server/Release)
This commit is contained in:
csh 2025-12-24 11:33:40 +08:00
parent 09e65224fe
commit 02864dda89
3 changed files with 81 additions and 275 deletions

View File

@ -79,49 +79,9 @@ namespace lsp::provider
result.capabilities.textDocumentSync = BuildTextDocumentSyncOptions(); result.capabilities.textDocumentSync = BuildTextDocumentSyncOptions();
result.capabilities.completionProvider = BuildCompletionOptions(); result.capabilities.completionProvider = BuildCompletionOptions();
result.capabilities.definitionProvider = true; result.capabilities.definitionProvider = true;
result.capabilities.typeDefinitionProvider = true; // NOTE: Only advertise the minimal feature set for now:
result.capabilities.implementationProvider = true; // - completion (with resolve)
result.capabilities.hoverProvider = true; // - go-to-definition
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; return result;
} }

View File

@ -5,166 +5,100 @@ export module lsp.provider.manifest;
import lsp.core.dispacther; import lsp.core.dispacther;
import lsp.provider.base.registry; import lsp.provider.base.registry;
import lsp.provider.call_hierarchy.incoming_calls;
import lsp.provider.call_hierarchy.outgoing_calls;
import lsp.provider.cancel_request.cancel_request;
import lsp.provider.client.register_capability;
import lsp.provider.client.unregister_capability;
import lsp.provider.code_action.resolve;
import lsp.provider.code_lens.resolve;
import lsp.provider.completion_item.resolve; import lsp.provider.completion_item.resolve;
import lsp.provider.document_link.resolve;
import lsp.provider.exit.exit;
import lsp.provider.initialize.initialize; import lsp.provider.initialize.initialize;
import lsp.provider.initialized.initialized; import lsp.provider.initialized.initialized;
import lsp.provider.inlay_hint.resolve;
import lsp.provider.shutdown.shutdown; import lsp.provider.shutdown.shutdown;
import lsp.provider.telemetry.event;
import lsp.provider.text_document.code_action;
import lsp.provider.text_document.code_lens;
import lsp.provider.text_document.color_presentation;
import lsp.provider.text_document.completion;
import lsp.provider.text_document.definition; import lsp.provider.text_document.definition;
import lsp.provider.text_document.diagnostic;
import lsp.provider.text_document.did_change; import lsp.provider.text_document.did_change;
import lsp.provider.text_document.did_close; import lsp.provider.text_document.did_close;
import lsp.provider.text_document.did_open; import lsp.provider.text_document.did_open;
import lsp.provider.text_document.document_color; import lsp.provider.text_document.completion;
import lsp.provider.text_document.document_highlight;
import lsp.provider.text_document.document_link;
import lsp.provider.text_document.document_symbol;
import lsp.provider.text_document.folding_range;
import lsp.provider.text_document.formatting;
import lsp.provider.text_document.hover;
import lsp.provider.text_document.implementation;
import lsp.provider.text_document.inlay_hint;
import lsp.provider.text_document.inline_value;
import lsp.provider.text_document.linked_editing_range;
import lsp.provider.text_document.moniker;
import lsp.provider.text_document.on_type_formatting;
import lsp.provider.text_document.prepare_call_hierarchy;
import lsp.provider.text_document.prepare_rename;
import lsp.provider.text_document.prepare_type_hierarchy;
import lsp.provider.text_document.publish_diagnostics;
import lsp.provider.text_document.range_formatting;
import lsp.provider.text_document.references;
import lsp.provider.text_document.rename;
import lsp.provider.text_document.selection_range;
import lsp.provider.text_document.semantic_tokens;
import lsp.provider.text_document.signature_help;
import lsp.provider.text_document.type_definition;
import lsp.provider.trace.set_trace; import lsp.provider.trace.set_trace;
import lsp.provider.type_hierarchy.subtypes;
import lsp.provider.type_hierarchy.supertypes; // NOTE: keep other providers implemented but disabled.
import lsp.provider.window.log_message; // Uncomment when re-enabling additional capabilities.
import lsp.provider.window.show_document; // import lsp.provider.call_hierarchy.incoming_calls;
import lsp.provider.window.show_message; // import lsp.provider.call_hierarchy.outgoing_calls;
import lsp.provider.window.show_message_request; // import lsp.provider.cancel_request.cancel_request;
import lsp.provider.window.work_done_progress_create; // import lsp.provider.client.register_capability;
import lsp.provider.workspace.apply_edit; // import lsp.provider.client.unregister_capability;
import lsp.provider.workspace.code_lens_refresh; // import lsp.provider.code_action.resolve;
import lsp.provider.workspace.configuration; // import lsp.provider.code_lens.resolve;
import lsp.provider.workspace.diagnostic; // import lsp.provider.document_link.resolve;
import lsp.provider.workspace.did_change_configuration; // import lsp.provider.exit.exit;
import lsp.provider.workspace.did_change_watched_files; // import lsp.provider.inlay_hint.resolve;
import lsp.provider.workspace.did_change_workspace_folders; // import lsp.provider.telemetry.event;
import lsp.provider.workspace.did_create_files; // import lsp.provider.text_document.code_action;
import lsp.provider.workspace.did_delete_files; // import lsp.provider.text_document.code_lens;
import lsp.provider.workspace.did_rename_files; // import lsp.provider.text_document.color_presentation;
import lsp.provider.workspace.diagnostic_refresh; // import lsp.provider.text_document.diagnostic;
import lsp.provider.workspace.execute_command; // import lsp.provider.text_document.document_color;
import lsp.provider.workspace.inlay_hint_refresh; // import lsp.provider.text_document.document_highlight;
import lsp.provider.workspace.inline_value_refresh; // import lsp.provider.text_document.document_link;
import lsp.provider.workspace.semantic_tokens_refresh; // import lsp.provider.text_document.document_symbol;
import lsp.provider.workspace.symbol; // import lsp.provider.text_document.folding_range;
import lsp.provider.workspace.workspace_folders; // import lsp.provider.text_document.formatting;
import lsp.provider.workspace.will_create_files; // import lsp.provider.text_document.hover;
import lsp.provider.workspace.will_delete_files; // import lsp.provider.text_document.implementation;
import lsp.provider.workspace.will_rename_files; // import lsp.provider.text_document.inlay_hint;
import lsp.provider.workspace_symbol.resolve; // import lsp.provider.text_document.inline_value;
// import lsp.provider.text_document.linked_editing_range;
// import lsp.provider.text_document.moniker;
// import lsp.provider.text_document.on_type_formatting;
// import lsp.provider.text_document.prepare_call_hierarchy;
// import lsp.provider.text_document.prepare_rename;
// import lsp.provider.text_document.prepare_type_hierarchy;
// import lsp.provider.text_document.publish_diagnostics;
// import lsp.provider.text_document.range_formatting;
// import lsp.provider.text_document.references;
// import lsp.provider.text_document.rename;
// import lsp.provider.text_document.selection_range;
// import lsp.provider.text_document.semantic_tokens;
// import lsp.provider.text_document.signature_help;
// import lsp.provider.text_document.type_definition;
// import lsp.provider.type_hierarchy.subtypes;
// import lsp.provider.type_hierarchy.supertypes;
// import lsp.provider.window.log_message;
// import lsp.provider.window.show_document;
// import lsp.provider.window.show_message;
// import lsp.provider.window.show_message_request;
// import lsp.provider.window.work_done_progress_create;
// import lsp.provider.workspace.apply_edit;
// import lsp.provider.workspace.code_lens_refresh;
// import lsp.provider.workspace.configuration;
// import lsp.provider.workspace.diagnostic;
// import lsp.provider.workspace.did_change_configuration;
// import lsp.provider.workspace.did_change_watched_files;
// import lsp.provider.workspace.did_change_workspace_folders;
// import lsp.provider.workspace.did_create_files;
// import lsp.provider.workspace.did_delete_files;
// import lsp.provider.workspace.did_rename_files;
// import lsp.provider.workspace.diagnostic_refresh;
// import lsp.provider.workspace.execute_command;
// import lsp.provider.workspace.inlay_hint_refresh;
// import lsp.provider.workspace.inline_value_refresh;
// import lsp.provider.workspace.semantic_tokens_refresh;
// import lsp.provider.workspace.symbol;
// import lsp.provider.workspace.workspace_folders;
// import lsp.provider.workspace.will_create_files;
// import lsp.provider.workspace.will_delete_files;
// import lsp.provider.workspace.will_rename_files;
// import lsp.provider.workspace_symbol.resolve;
export namespace lsp::provider export namespace lsp::provider
{ {
using AllProviders = ProviderRegistry< using AllProviders = ProviderRegistry<
call_hierarchy::IncomingCalls,
call_hierarchy::OutgoingCalls,
CancelRequest,
client::RegisterCapability,
client::UnregisterCapability,
code_action::Resolve,
code_lens::Resolve,
completion_item::Resolve, completion_item::Resolve,
document_link::Resolve,
Exit,
Initialize, Initialize,
Initialized, Initialized,
inlay_hint::Resolve,
Shutdown, Shutdown,
telemetry::Event,
text_document::CodeAction,
text_document::CodeLens,
text_document::ColorPresentation,
text_document::Completion, text_document::Completion,
text_document::Definition, text_document::Definition,
text_document::Diagnostic,
text_document::DidChange, text_document::DidChange,
text_document::DidClose, text_document::DidClose,
text_document::DidOpen, text_document::DidOpen,
text_document::DocumentColor, SetTrace
text_document::DocumentHighlight,
text_document::DocumentLink,
text_document::DocumentSymbol,
text_document::FoldingRange,
text_document::Formatting,
text_document::Hover,
text_document::Implementation,
text_document::InlayHint,
text_document::InlineValue,
text_document::LinkedEditingRange,
text_document::Moniker,
text_document::OnTypeFormatting,
text_document::PrepareCallHierarchy,
text_document::PrepareRename,
text_document::PrepareTypeHierarchy,
text_document::PublishDiagnostics,
text_document::RangeFormatting,
text_document::References,
text_document::Rename,
text_document::SelectionRange,
text_document::SemanticTokensRange,
text_document::SemanticTokensFull,
text_document::SemanticTokensFullDelta,
text_document::SignatureHelp,
text_document::TypeDefinition,
SetTrace,
type_hierarchy::Subtypes,
type_hierarchy::Supertypes,
window::LogMessage,
window::ShowDocument,
window::ShowMessage,
window::ShowMessageRequest,
window::WorkDoneProgressCreate,
workspace::ApplyEdit,
workspace::CodeLensRefresh,
workspace::Configuration,
workspace::Diagnostic,
workspace::DidChangeConfiguration,
workspace::DidChangeWatchedFiles,
workspace::DidChangeWorkspaceFolders,
workspace::DidCreateFiles,
workspace::DidDeleteFiles,
workspace::DidRenameFiles,
workspace::DiagnosticRefresh,
workspace::ExecuteCommand,
workspace::InlayHintRefresh,
workspace::InlineValueRefresh,
workspace::SemanticTokensRefresh,
workspace::Symbol,
workspace::WorkspaceFolders,
workspace::WillCreateFiles,
workspace::WillDeleteFiles,
workspace::WillRenameFiles,
workspace_symbol::Resolve
>; >;
static_assert(AllProviders::kProviderCount > 0, "No providers registered."); static_assert(AllProviders::kProviderCount > 0, "No providers registered.");

View File

@ -420,100 +420,12 @@ namespace lsp::test::provider
} }
assertTrue(capabilities.find("definitionProvider") != capabilities.end(), "Initialize should enable definitionProvider"); assertTrue(capabilities.find("definitionProvider") != capabilities.end(), "Initialize should enable definitionProvider");
assertTrue(capabilities.find("typeDefinitionProvider") != capabilities.end(), "Initialize should enable typeDefinitionProvider"); assertFalse(capabilities.contains("hoverProvider"), "Initialize should not advertise hoverProvider");
assertTrue(capabilities.find("implementationProvider") != capabilities.end(), "Initialize should enable implementationProvider"); assertFalse(capabilities.contains("referencesProvider"), "Initialize should not advertise referencesProvider");
assertTrue(capabilities.find("hoverProvider") != capabilities.end(), "Initialize should enable hoverProvider"); assertFalse(capabilities.contains("renameProvider"), "Initialize should not advertise renameProvider");
assertTrue(capabilities.find("signatureHelpProvider") != capabilities.end(), "Initialize should enable signatureHelpProvider"); assertFalse(capabilities.contains("documentSymbolProvider"), "Initialize should not advertise documentSymbolProvider");
assertTrue(capabilities.find("codeActionProvider") != capabilities.end(), "Initialize should enable codeActionProvider"); assertFalse(capabilities.contains("workspaceSymbolProvider"), "Initialize should not advertise workspaceSymbolProvider");
auto call_hierarchy_it = capabilities.find("callHierarchyProvider"); assertFalse(capabilities.contains("workspace"), "Initialize should not advertise workspace capabilities");
assertTrue(call_hierarchy_it != capabilities.end(), "Initialize should enable callHierarchyProvider");
if (call_hierarchy_it != capabilities.end())
{
assertTrue(call_hierarchy_it->second.Is<protocol::boolean>() && call_hierarchy_it->second.Get<protocol::boolean>(),
"callHierarchyProvider should be enabled");
}
auto type_hierarchy_it = capabilities.find("typeHierarchyProvider");
assertTrue(type_hierarchy_it != capabilities.end(), "Initialize should enable typeHierarchyProvider");
if (type_hierarchy_it != capabilities.end())
{
assertTrue(type_hierarchy_it->second.Is<protocol::boolean>() && type_hierarchy_it->second.Get<protocol::boolean>(),
"typeHierarchyProvider should be enabled");
}
assertTrue(capabilities.find("referencesProvider") != capabilities.end(), "Initialize should enable referencesProvider");
assertTrue(capabilities.find("documentHighlightProvider") != capabilities.end(), "Initialize should enable documentHighlightProvider");
assertTrue(capabilities.find("documentSymbolProvider") != capabilities.end(), "Initialize should enable documentSymbolProvider");
assertTrue(capabilities.find("workspaceSymbolProvider") != capabilities.end(), "Initialize should enable workspaceSymbolProvider");
assertTrue(capabilities.find("semanticTokensProvider") != capabilities.end(), "Initialize should enable semanticTokensProvider");
auto document_link_it = capabilities.find("documentLinkProvider");
assertTrue(document_link_it != capabilities.end(), "Initialize should enable documentLinkProvider");
if (document_link_it != capabilities.end() && document_link_it->second.Is<protocol::LSPObject>())
{
const auto& document_link = document_link_it->second.Get<protocol::LSPObject>();
auto resolve_it = document_link.find("resolveProvider");
assertTrue(resolve_it != document_link.end(), "documentLinkProvider should include resolveProvider");
assertTrue(resolve_it->second.Is<protocol::boolean>() && resolve_it->second.Get<protocol::boolean>(),
"documentLinkProvider should enable resolveProvider");
}
assertTrue(capabilities.find("foldingRangeProvider") != capabilities.end(), "Initialize should enable foldingRangeProvider");
assertTrue(capabilities.find("selectionRangeProvider") != capabilities.end(), "Initialize should enable selectionRangeProvider");
auto inlay_hint_it = capabilities.find("inlayHintProvider");
assertTrue(inlay_hint_it != capabilities.end(), "Initialize should enable inlayHintProvider");
if (inlay_hint_it != capabilities.end() && inlay_hint_it->second.Is<protocol::LSPObject>())
{
const auto& inlay_hint = inlay_hint_it->second.Get<protocol::LSPObject>();
auto resolve_it = inlay_hint.find("resolveProvider");
assertTrue(resolve_it != inlay_hint.end(), "inlayHintProvider should include resolveProvider");
assertTrue(resolve_it->second.Is<protocol::boolean>() && resolve_it->second.Get<protocol::boolean>(),
"inlayHintProvider should enable resolveProvider");
}
auto code_lens_it = capabilities.find("codeLensProvider");
assertTrue(code_lens_it != capabilities.end(), "Initialize should enable codeLensProvider");
if (code_lens_it != capabilities.end() && code_lens_it->second.Is<protocol::LSPObject>())
{
const auto& code_lens = code_lens_it->second.Get<protocol::LSPObject>();
auto resolve_it = code_lens.find("resolveProvider");
assertTrue(resolve_it != code_lens.end(), "codeLensProvider should include resolveProvider");
assertTrue(resolve_it->second.Is<protocol::boolean>() && resolve_it->second.Get<protocol::boolean>(),
"codeLensProvider should enable resolveProvider");
}
auto rename_it = capabilities.find("renameProvider");
assertTrue(rename_it != capabilities.end(), "Initialize should enable renameProvider");
if (rename_it != capabilities.end() && rename_it->second.Is<protocol::LSPObject>())
{
const auto& rename = rename_it->second.Get<protocol::LSPObject>();
auto prepare_it = rename.find("prepareProvider");
assertTrue(prepare_it != rename.end(), "renameProvider should include prepareProvider");
assertTrue(prepare_it->second.Is<protocol::boolean>() && prepare_it->second.Get<protocol::boolean>(),
"renameProvider should enable prepareProvider");
}
auto workspace_it = capabilities.find("workspace");
assertTrue(workspace_it != capabilities.end(), "Initialize should include workspace capabilities");
if (workspace_it != capabilities.end() && workspace_it->second.Is<protocol::LSPObject>())
{
const auto& workspace = workspace_it->second.Get<protocol::LSPObject>();
auto file_ops_it = workspace.find("fileOperations");
assertTrue(file_ops_it != workspace.end(), "workspace should include fileOperations");
assertTrue(file_ops_it->second.Is<protocol::LSPObject>(), "fileOperations should be an object");
const auto& file_ops = file_ops_it->second.Get<protocol::LSPObject>();
auto did_create_it = file_ops.find("didCreate");
assertTrue(did_create_it != file_ops.end(), "fileOperations should include didCreate");
assertTrue(did_create_it->second.Is<protocol::boolean>() && did_create_it->second.Get<protocol::boolean>(),
"fileOperations.didCreate should be enabled");
auto did_delete_it = file_ops.find("didDelete");
assertTrue(did_delete_it != file_ops.end(), "fileOperations should include didDelete");
assertTrue(did_delete_it->second.Is<protocol::boolean>() && did_delete_it->second.Get<protocol::boolean>(),
"fileOperations.didDelete should be enabled");
auto did_rename_it = file_ops.find("didRename");
assertTrue(did_rename_it != file_ops.end(), "fileOperations should include didRename");
assertTrue(did_rename_it->second.Is<protocol::boolean>() && did_rename_it->second.Get<protocol::boolean>(),
"fileOperations.didRename should be enabled");
}
env.scheduler.WaitAll(); env.scheduler.WaitAll();
auto indexed = env.hub.symbols().QueryIndexedSymbols(protocol::SymbolKind::Module); auto indexed = env.hub.symbols().QueryIndexedSymbols(protocol::SymbolKind::Module);