aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2020-05-22 14:12:57 +0100
committerGitHub <[email protected]>2020-05-22 14:12:57 +0100
commit5aa3a4c04fa69a44285f26646369dec8d010d063 (patch)
treebf6e3487e322704a5c042ace5f184d4a9a9161b1
parent90332ca21901e1101154462053b50e5d2743a21c (diff)
parentacc5e8d64b9b3d75798407d4ea4a6ba39d96eb60 (diff)
Merge #4516
4516: LSP: Two stage initialization r=kjeremy a=kjeremy Fills in server information. Derives CodeAction capabilities from the client. If code action literals are unsupported we fall back to the "simple support" which just sends back commands (this is already supported in our config). The difference being that we did not adjust our server capabilities so that if the client was checking for `CodeActionProvider: "true"` in the response that would have failed. Part of #144 Fixes #4130 (the specific case called out in that issue) Co-authored-by: kjeremy <[email protected]>
-rw-r--r--Cargo.lock4
-rw-r--r--crates/rust-analyzer/src/bin/main.rs17
-rw-r--r--crates/rust-analyzer/src/caps.rs60
3 files changed, 55 insertions, 26 deletions
diff --git a/Cargo.lock b/Cargo.lock
index c06236692..5ce35c5b1 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -658,9 +658,9 @@ dependencies = [
658 658
659[[package]] 659[[package]]
660name = "lsp-server" 660name = "lsp-server"
661version = "0.3.1" 661version = "0.3.2"
662source = "registry+https://github.com/rust-lang/crates.io-index" 662source = "registry+https://github.com/rust-lang/crates.io-index"
663checksum = "5383e043329615624bbf45e1ba27bd75c176762b2592855c659bc28ac580a06b" 663checksum = "dccec31bfd027ac0dd288a78e19005fd89624d9099456e284b5241316a6c3072"
664dependencies = [ 664dependencies = [
665 "crossbeam-channel", 665 "crossbeam-channel",
666 "log", 666 "log",
diff --git a/crates/rust-analyzer/src/bin/main.rs b/crates/rust-analyzer/src/bin/main.rs
index 09908458d..e82fd57de 100644
--- a/crates/rust-analyzer/src/bin/main.rs
+++ b/crates/rust-analyzer/src/bin/main.rs
@@ -74,12 +74,25 @@ fn run_server() -> Result<()> {
74 log::info!("lifecycle: server started"); 74 log::info!("lifecycle: server started");
75 75
76 let (connection, io_threads) = Connection::stdio(); 76 let (connection, io_threads) = Connection::stdio();
77 let server_capabilities = serde_json::to_value(rust_analyzer::server_capabilities()).unwrap();
78 77
79 let initialize_params = connection.initialize(server_capabilities)?; 78 let (initialize_id, initialize_params) = connection.initialize_start()?;
80 let initialize_params = 79 let initialize_params =
81 from_json::<lsp_types::InitializeParams>("InitializeParams", initialize_params)?; 80 from_json::<lsp_types::InitializeParams>("InitializeParams", initialize_params)?;
82 81
82 let server_capabilities = rust_analyzer::server_capabilities(&initialize_params.capabilities);
83
84 let initialize_result = lsp_types::InitializeResult {
85 capabilities: server_capabilities,
86 server_info: Some(lsp_types::ServerInfo {
87 name: String::from("rust-analyzer"),
88 version: Some(String::from(env!("REV"))),
89 }),
90 };
91
92 let initialize_result = serde_json::to_value(initialize_result).unwrap();
93
94 connection.initialize_finish(initialize_id, initialize_result)?;
95
83 if let Some(client_info) = initialize_params.client_info { 96 if let Some(client_info) = initialize_params.client_info {
84 log::info!("Client '{}' {}", client_info.name, client_info.version.unwrap_or_default()); 97 log::info!("Client '{}' {}", client_info.name, client_info.version.unwrap_or_default());
85 } 98 }
diff --git a/crates/rust-analyzer/src/caps.rs b/crates/rust-analyzer/src/caps.rs
index 13af75469..780fc9317 100644
--- a/crates/rust-analyzer/src/caps.rs
+++ b/crates/rust-analyzer/src/caps.rs
@@ -2,19 +2,22 @@
2use std::env; 2use std::env;
3 3
4use lsp_types::{ 4use lsp_types::{
5 CallHierarchyServerCapability, CodeActionOptions, CodeActionProviderCapability, 5 CallHierarchyServerCapability, ClientCapabilities, CodeActionOptions,
6 CodeLensOptions, CompletionOptions, DocumentOnTypeFormattingOptions, 6 CodeActionProviderCapability, CodeLensOptions, CompletionOptions,
7 FoldingRangeProviderCapability, ImplementationProviderCapability, RenameOptions, 7 DocumentOnTypeFormattingOptions, FoldingRangeProviderCapability,
8 RenameProviderCapability, SaveOptions, SelectionRangeProviderCapability, 8 ImplementationProviderCapability, RenameOptions, RenameProviderCapability, SaveOptions,
9 SemanticTokensDocumentProvider, SemanticTokensLegend, SemanticTokensOptions, 9 SelectionRangeProviderCapability, SemanticTokensDocumentProvider, SemanticTokensLegend,
10 ServerCapabilities, SignatureHelpOptions, TextDocumentSyncCapability, TextDocumentSyncKind, 10 SemanticTokensOptions, ServerCapabilities, SignatureHelpOptions, TextDocumentSyncCapability,
11 TextDocumentSyncOptions, TypeDefinitionProviderCapability, WorkDoneProgressOptions, 11 TextDocumentSyncKind, TextDocumentSyncOptions, TypeDefinitionProviderCapability,
12 WorkDoneProgressOptions,
12}; 13};
13use serde_json::json; 14use serde_json::json;
14 15
15use crate::semantic_tokens; 16use crate::semantic_tokens;
16 17
17pub fn server_capabilities() -> ServerCapabilities { 18pub fn server_capabilities(client_caps: &ClientCapabilities) -> ServerCapabilities {
19 let code_action_provider = code_action_capabilities(client_caps);
20
18 ServerCapabilities { 21 ServerCapabilities {
19 text_document_sync: Some(TextDocumentSyncCapability::Options(TextDocumentSyncOptions { 22 text_document_sync: Some(TextDocumentSyncCapability::Options(TextDocumentSyncOptions {
20 open_close: Some(true), 23 open_close: Some(true),
@@ -46,20 +49,7 @@ pub fn server_capabilities() -> ServerCapabilities {
46 document_highlight_provider: Some(true), 49 document_highlight_provider: Some(true),
47 document_symbol_provider: Some(true), 50 document_symbol_provider: Some(true),
48 workspace_symbol_provider: Some(true), 51 workspace_symbol_provider: Some(true),
49 code_action_provider: Some(CodeActionProviderCapability::Options(CodeActionOptions { 52 code_action_provider: Some(code_action_provider),
50 // Advertise support for all built-in CodeActionKinds
51 code_action_kinds: Some(vec![
52 lsp_types::code_action_kind::EMPTY.to_string(),
53 lsp_types::code_action_kind::QUICKFIX.to_string(),
54 lsp_types::code_action_kind::REFACTOR.to_string(),
55 lsp_types::code_action_kind::REFACTOR_EXTRACT.to_string(),
56 lsp_types::code_action_kind::REFACTOR_INLINE.to_string(),
57 lsp_types::code_action_kind::REFACTOR_REWRITE.to_string(),
58 lsp_types::code_action_kind::SOURCE.to_string(),
59 lsp_types::code_action_kind::SOURCE_ORGANIZE_IMPORTS.to_string(),
60 ]),
61 work_done_progress_options: Default::default(),
62 })),
63 code_lens_provider: Some(CodeLensOptions { resolve_provider: Some(true) }), 53 code_lens_provider: Some(CodeLensOptions { resolve_provider: Some(true) }),
64 document_formatting_provider: Some(true), 54 document_formatting_provider: Some(true),
65 document_range_formatting_provider: None, 55 document_range_formatting_provider: None,
@@ -98,3 +88,29 @@ pub fn server_capabilities() -> ServerCapabilities {
98 })), 88 })),
99 } 89 }
100} 90}
91
92fn code_action_capabilities(client_caps: &ClientCapabilities) -> CodeActionProviderCapability {
93 client_caps
94 .text_document
95 .as_ref()
96 .and_then(|it| it.code_action.as_ref())
97 .and_then(|it| it.code_action_literal_support.as_ref())
98 .map_or(CodeActionProviderCapability::Simple(true), |_| {
99 CodeActionProviderCapability::Options(CodeActionOptions {
100 // Advertise support for all built-in CodeActionKinds.
101 // Ideally we would base this off of the client capabilities
102 // but the client is supposed to fall back gracefully for unknown values.
103 code_action_kinds: Some(vec![
104 lsp_types::code_action_kind::EMPTY.to_string(),
105 lsp_types::code_action_kind::QUICKFIX.to_string(),
106 lsp_types::code_action_kind::REFACTOR.to_string(),
107 lsp_types::code_action_kind::REFACTOR_EXTRACT.to_string(),
108 lsp_types::code_action_kind::REFACTOR_INLINE.to_string(),
109 lsp_types::code_action_kind::REFACTOR_REWRITE.to_string(),
110 lsp_types::code_action_kind::SOURCE.to_string(),
111 lsp_types::code_action_kind::SOURCE_ORGANIZE_IMPORTS.to_string(),
112 ]),
113 work_done_progress_options: Default::default(),
114 })
115 })
116}