Skip to content

Commit

Permalink
Merge #4516
Browse files Browse the repository at this point in the history
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]>
  • Loading branch information
bors[bot] and kjeremy authored May 22, 2020
2 parents 90332ca + acc5e8d commit 5aa3a4c
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 26 deletions.
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 15 additions & 2 deletions crates/rust-analyzer/src/bin/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,12 +74,25 @@ fn run_server() -> Result<()> {
log::info!("lifecycle: server started");

let (connection, io_threads) = Connection::stdio();
let server_capabilities = serde_json::to_value(rust_analyzer::server_capabilities()).unwrap();

let initialize_params = connection.initialize(server_capabilities)?;
let (initialize_id, initialize_params) = connection.initialize_start()?;
let initialize_params =
from_json::<lsp_types::InitializeParams>("InitializeParams", initialize_params)?;

let server_capabilities = rust_analyzer::server_capabilities(&initialize_params.capabilities);

let initialize_result = lsp_types::InitializeResult {
capabilities: server_capabilities,
server_info: Some(lsp_types::ServerInfo {
name: String::from("rust-analyzer"),
version: Some(String::from(env!("REV"))),
}),
};

let initialize_result = serde_json::to_value(initialize_result).unwrap();

connection.initialize_finish(initialize_id, initialize_result)?;

if let Some(client_info) = initialize_params.client_info {
log::info!("Client '{}' {}", client_info.name, client_info.version.unwrap_or_default());
}
Expand Down
60 changes: 38 additions & 22 deletions crates/rust-analyzer/src/caps.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,22 @@
use std::env;

use lsp_types::{
CallHierarchyServerCapability, CodeActionOptions, CodeActionProviderCapability,
CodeLensOptions, CompletionOptions, DocumentOnTypeFormattingOptions,
FoldingRangeProviderCapability, ImplementationProviderCapability, RenameOptions,
RenameProviderCapability, SaveOptions, SelectionRangeProviderCapability,
SemanticTokensDocumentProvider, SemanticTokensLegend, SemanticTokensOptions,
ServerCapabilities, SignatureHelpOptions, TextDocumentSyncCapability, TextDocumentSyncKind,
TextDocumentSyncOptions, TypeDefinitionProviderCapability, WorkDoneProgressOptions,
CallHierarchyServerCapability, ClientCapabilities, CodeActionOptions,
CodeActionProviderCapability, CodeLensOptions, CompletionOptions,
DocumentOnTypeFormattingOptions, FoldingRangeProviderCapability,
ImplementationProviderCapability, RenameOptions, RenameProviderCapability, SaveOptions,
SelectionRangeProviderCapability, SemanticTokensDocumentProvider, SemanticTokensLegend,
SemanticTokensOptions, ServerCapabilities, SignatureHelpOptions, TextDocumentSyncCapability,
TextDocumentSyncKind, TextDocumentSyncOptions, TypeDefinitionProviderCapability,
WorkDoneProgressOptions,
};
use serde_json::json;

use crate::semantic_tokens;

pub fn server_capabilities() -> ServerCapabilities {
pub fn server_capabilities(client_caps: &ClientCapabilities) -> ServerCapabilities {
let code_action_provider = code_action_capabilities(client_caps);

ServerCapabilities {
text_document_sync: Some(TextDocumentSyncCapability::Options(TextDocumentSyncOptions {
open_close: Some(true),
Expand Down Expand Up @@ -46,20 +49,7 @@ pub fn server_capabilities() -> ServerCapabilities {
document_highlight_provider: Some(true),
document_symbol_provider: Some(true),
workspace_symbol_provider: Some(true),
code_action_provider: Some(CodeActionProviderCapability::Options(CodeActionOptions {
// Advertise support for all built-in CodeActionKinds
code_action_kinds: Some(vec![
lsp_types::code_action_kind::EMPTY.to_string(),
lsp_types::code_action_kind::QUICKFIX.to_string(),
lsp_types::code_action_kind::REFACTOR.to_string(),
lsp_types::code_action_kind::REFACTOR_EXTRACT.to_string(),
lsp_types::code_action_kind::REFACTOR_INLINE.to_string(),
lsp_types::code_action_kind::REFACTOR_REWRITE.to_string(),
lsp_types::code_action_kind::SOURCE.to_string(),
lsp_types::code_action_kind::SOURCE_ORGANIZE_IMPORTS.to_string(),
]),
work_done_progress_options: Default::default(),
})),
code_action_provider: Some(code_action_provider),
code_lens_provider: Some(CodeLensOptions { resolve_provider: Some(true) }),
document_formatting_provider: Some(true),
document_range_formatting_provider: None,
Expand Down Expand Up @@ -98,3 +88,29 @@ pub fn server_capabilities() -> ServerCapabilities {
})),
}
}

fn code_action_capabilities(client_caps: &ClientCapabilities) -> CodeActionProviderCapability {
client_caps
.text_document
.as_ref()
.and_then(|it| it.code_action.as_ref())
.and_then(|it| it.code_action_literal_support.as_ref())
.map_or(CodeActionProviderCapability::Simple(true), |_| {
CodeActionProviderCapability::Options(CodeActionOptions {
// Advertise support for all built-in CodeActionKinds.
// Ideally we would base this off of the client capabilities
// but the client is supposed to fall back gracefully for unknown values.
code_action_kinds: Some(vec![
lsp_types::code_action_kind::EMPTY.to_string(),
lsp_types::code_action_kind::QUICKFIX.to_string(),
lsp_types::code_action_kind::REFACTOR.to_string(),
lsp_types::code_action_kind::REFACTOR_EXTRACT.to_string(),
lsp_types::code_action_kind::REFACTOR_INLINE.to_string(),
lsp_types::code_action_kind::REFACTOR_REWRITE.to_string(),
lsp_types::code_action_kind::SOURCE.to_string(),
lsp_types::code_action_kind::SOURCE_ORGANIZE_IMPORTS.to_string(),
]),
work_done_progress_options: Default::default(),
})
})
}

0 comments on commit 5aa3a4c

Please sign in to comment.