1504: Simplify LSP handlers r=matklad a=kjeremy

Takes advantage of protocol inheritance via composition and simplifies some responses via the `From`/`Into` traits.

Co-authored-by: Jeremy Kolb <kjeremy@gmail.com>
This commit is contained in:
bors[bot] 2019-07-08 09:55:23 +00:00
commit 5ce2b4819e
5 changed files with 34 additions and 42 deletions

8
Cargo.lock generated
View file

@ -541,7 +541,7 @@ dependencies = [
"crossbeam-channel 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-channel 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"flexi_logger 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)", "flexi_logger 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"lsp-types 0.58.1 (registry+https://github.com/rust-lang/crates.io-index)", "lsp-types 0.59.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.94 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.94 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
@ -774,7 +774,7 @@ dependencies = [
[[package]] [[package]]
name = "lsp-types" name = "lsp-types"
version = "0.58.1" version = "0.59.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1200,7 +1200,7 @@ dependencies = [
"flexi_logger 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)", "flexi_logger 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)",
"gen_lsp_server 0.2.0", "gen_lsp_server 0.2.0",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"lsp-types 0.58.1 (registry+https://github.com/rust-lang/crates.io-index)", "lsp-types 0.59.0 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ra_arena 0.1.0", "ra_arena 0.1.0",
"ra_ide_api 0.1.0", "ra_ide_api 0.1.0",
@ -2201,7 +2201,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ae91b68aebc4ddb91978b11a1b02ddd8602a05ec19002801c5666000e05e0f83" "checksum linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ae91b68aebc4ddb91978b11a1b02ddd8602a05ec19002801c5666000e05e0f83"
"checksum lock_api 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ed946d4529956a20f2d63ebe1b69996d5a2137c91913fe3ebbeff957f5bca7ff" "checksum lock_api 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ed946d4529956a20f2d63ebe1b69996d5a2137c91913fe3ebbeff957f5bca7ff"
"checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6" "checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6"
"checksum lsp-types 0.58.1 (registry+https://github.com/rust-lang/crates.io-index)" = "42c7edac51b6739544453fd33c7ae5e910d1ec4f2d9904cf1990f8f6581e26f5" "checksum lsp-types 0.59.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8961cde7f6f856771910edf37ff0729e59e02d2a8592a94c27495b746320e6ed"
"checksum maplit 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "08cbb6b4fef96b6d77bfc40ec491b1690c779e77b05cd9f07f787ed376fd4c43" "checksum maplit 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "08cbb6b4fef96b6d77bfc40ec491b1690c779e77b05cd9f07f787ed376fd4c43"
"checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" "checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
"checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e" "checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e"

View file

@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0"
description = "Generic LSP server scaffold." description = "Generic LSP server scaffold."
[dependencies] [dependencies]
lsp-types = "0.58.0" lsp-types = "0.59.0"
log = "0.4.3" log = "0.4.3"
serde_json = "1.0.34" serde_json = "1.0.34"
serde = { version = "1.0.83", features = ["derive"] } serde = { version = "1.0.83", features = ["derive"] }

View file

@ -13,7 +13,7 @@ crossbeam-channel = "0.3.5"
flexi_logger = "0.13.0" flexi_logger = "0.13.0"
log = "0.4.3" log = "0.4.3"
url_serde = "0.2.0" url_serde = "0.2.0"
lsp-types = { version = "0.58.0", features = ["proposed"] } lsp-types = { version = "0.59.0", features = ["proposed"] }
rustc-hash = "1.0" rustc-hash = "1.0"
parking_lot = "0.8.0" parking_lot = "0.8.0"

View file

@ -2,11 +2,11 @@ use std::{fmt::Write as _, io::Write as _};
use gen_lsp_server::ErrorCode; use gen_lsp_server::ErrorCode;
use lsp_types::{ use lsp_types::{
CodeAction, CodeActionResponse, CodeLens, Command, Diagnostic, DiagnosticSeverity, CodeAction, CodeActionResponse, CodeLens, Command, CompletionItem, Diagnostic,
DocumentFormattingParams, DocumentHighlight, DocumentSymbol, FoldingRange, FoldingRangeKind, DiagnosticSeverity, DocumentFormattingParams, DocumentHighlight, DocumentSymbol, FoldingRange,
FoldingRangeParams, Hover, HoverContents, Location, MarkupContent, MarkupKind, Position, FoldingRangeKind, FoldingRangeParams, Hover, HoverContents, Location, MarkupContent,
PrepareRenameResponse, Range, RenameParams, SymbolInformation, TextDocumentIdentifier, MarkupKind, Position, PrepareRenameResponse, Range, RenameParams, SymbolInformation,
TextEdit, WorkspaceEdit, TextDocumentIdentifier, TextEdit, WorkspaceEdit,
}; };
use ra_ide_api::{ use ra_ide_api::{
AssistId, Cancelable, FileId, FilePosition, FileRange, FoldKind, Query, RangeInfo, AssistId, Cancelable, FileId, FilePosition, FileRange, FoldKind, Query, RangeInfo,
@ -153,14 +153,12 @@ pub fn handle_on_type_formatting(
params: req::DocumentOnTypeFormattingParams, params: req::DocumentOnTypeFormattingParams,
) -> Result<Option<Vec<TextEdit>>> { ) -> Result<Option<Vec<TextEdit>>> {
let _p = profile("handle_on_type_formatting"); let _p = profile("handle_on_type_formatting");
let file_id = params.text_document.try_conv_with(&world)?; let mut position = params.text_document_position.try_conv_with(&world)?;
let line_index = world.analysis().file_line_index(file_id); let line_index = world.analysis().file_line_index(position.file_id);
let position = FilePosition {
file_id, // in `ra_ide_api`, the `on_type` invariant is that
/// in `ra_ide_api`, the `on_type` invariant is that // `text.char_at(position) == typed_char`.
/// `text.char_at(position) == typed_char`. position.offset = position.offset - TextUnit::of_char('.');
offset: params.position.conv_with(&line_index) - TextUnit::of_char('.'),
};
let edit = match params.ch.as_str() { let edit = match params.ch.as_str() {
"=" => world.analysis().on_eq_typed(position), "=" => world.analysis().on_eq_typed(position),
@ -214,7 +212,7 @@ pub fn handle_document_symbol(
} }
} }
Ok(Some(req::DocumentSymbolResponse::Nested(res))) Ok(Some(res.into()))
} }
pub fn handle_workspace_symbol( pub fn handle_workspace_symbol(
@ -277,7 +275,7 @@ pub fn handle_goto_definition(
.map(|nav| RangeInfo::new(nav_range, nav)) .map(|nav| RangeInfo::new(nav_range, nav))
.map(|nav| to_location_link(&nav, &world, &line_index)) .map(|nav| to_location_link(&nav, &world, &line_index))
.collect::<Result<Vec<_>>>()?; .collect::<Result<Vec<_>>>()?;
Ok(Some(req::GotoDefinitionResponse::Link(res))) Ok(Some(res.into()))
} }
pub fn handle_goto_implementation( pub fn handle_goto_implementation(
@ -297,7 +295,7 @@ pub fn handle_goto_implementation(
.map(|nav| RangeInfo::new(nav_range, nav)) .map(|nav| RangeInfo::new(nav_range, nav))
.map(|nav| to_location_link(&nav, &world, &line_index)) .map(|nav| to_location_link(&nav, &world, &line_index))
.collect::<Result<Vec<_>>>()?; .collect::<Result<Vec<_>>>()?;
Ok(Some(req::GotoDefinitionResponse::Link(res))) Ok(Some(res.into()))
} }
pub fn handle_goto_type_definition( pub fn handle_goto_type_definition(
@ -317,7 +315,7 @@ pub fn handle_goto_type_definition(
.map(|nav| RangeInfo::new(nav_range, nav)) .map(|nav| RangeInfo::new(nav_range, nav))
.map(|nav| to_location_link(&nav, &world, &line_index)) .map(|nav| to_location_link(&nav, &world, &line_index))
.collect::<Result<Vec<_>>>()?; .collect::<Result<Vec<_>>>()?;
Ok(Some(req::GotoDefinitionResponse::Link(res))) Ok(Some(res.into()))
} }
pub fn handle_parent_module( pub fn handle_parent_module(
@ -407,12 +405,7 @@ pub fn handle_completion(
params: req::CompletionParams, params: req::CompletionParams,
) -> Result<Option<req::CompletionResponse>> { ) -> Result<Option<req::CompletionResponse>> {
let _p = profile("handle_completion"); let _p = profile("handle_completion");
let position = { let position = params.text_document_position.try_conv_with(&world)?;
let file_id = params.text_document.try_conv_with(&world)?;
let line_index = world.analysis().file_line_index(file_id);
let offset = params.position.conv_with(&line_index);
FilePosition { file_id, offset }
};
let completion_triggered_after_single_colon = { let completion_triggered_after_single_colon = {
let mut res = false; let mut res = false;
if let Some(ctx) = params.context { if let Some(ctx) = params.context {
@ -440,9 +433,10 @@ pub fn handle_completion(
Some(items) => items, Some(items) => items,
}; };
let line_index = world.analysis().file_line_index(position.file_id); let line_index = world.analysis().file_line_index(position.file_id);
let items = items.into_iter().map(|item| item.conv_with(&line_index)).collect(); let items: Vec<CompletionItem> =
items.into_iter().map(|item| item.conv_with(&line_index)).collect();
Ok(Some(req::CompletionResponse::Array(items))) Ok(Some(items.into()))
} }
pub fn handle_folding_range( pub fn handle_folding_range(
@ -543,9 +537,7 @@ pub fn handle_prepare_rename(
} }
pub fn handle_rename(world: WorldSnapshot, params: RenameParams) -> Result<Option<WorkspaceEdit>> { pub fn handle_rename(world: WorldSnapshot, params: RenameParams) -> Result<Option<WorkspaceEdit>> {
let file_id = params.text_document.try_conv_with(&world)?; let position = params.text_document_position.try_conv_with(&world)?;
let line_index = world.analysis().file_line_index(file_id);
let offset = params.position.conv_with(&line_index);
if params.new_name.is_empty() { if params.new_name.is_empty() {
return Err(LspError::new( return Err(LspError::new(
@ -555,8 +547,7 @@ pub fn handle_rename(world: WorldSnapshot, params: RenameParams) -> Result<Optio
.into()); .into());
} }
let optional_change = let optional_change = world.analysis().rename(position, &*params.new_name)?;
world.analysis().rename(FilePosition { file_id, offset }, &*params.new_name)?;
let change = match optional_change { let change = match optional_change {
None => return Ok(None), None => return Ok(None),
Some(it) => it, Some(it) => it,
@ -571,11 +562,10 @@ pub fn handle_references(
world: WorldSnapshot, world: WorldSnapshot,
params: req::ReferenceParams, params: req::ReferenceParams,
) -> Result<Option<Vec<Location>>> { ) -> Result<Option<Vec<Location>>> {
let file_id = params.text_document.try_conv_with(&world)?; let position = params.text_document_position.try_conv_with(&world)?;
let line_index = world.analysis().file_line_index(file_id); let line_index = world.analysis().file_line_index(position.file_id);
let offset = params.position.conv_with(&line_index);
let refs = match world.analysis().find_all_refs(FilePosition { file_id, offset })? { let refs = match world.analysis().find_all_refs(position)? {
None => return Ok(None), None => return Ok(None),
Some(refs) => refs, Some(refs) => refs,
}; };

View file

@ -37,9 +37,11 @@ use std::collections::Spam;
eprintln!("loading took {:?}", project_start.elapsed()); eprintln!("loading took {:?}", project_start.elapsed());
let completion_start = Instant::now(); let completion_start = Instant::now();
let res = server.send_request::<Completion>(CompletionParams { let res = server.send_request::<Completion>(CompletionParams {
text_document: server.doc_id("src/lib.rs"), text_document_position: TextDocumentPositionParams::new(
server.doc_id("src/lib.rs"),
Position::new(0, 23),
),
context: None, context: None,
position: Position::new(0, 23),
}); });
assert!(format!("{}", res).contains("HashMap")); assert!(format!("{}", res).contains("HashMap"));
eprintln!("completion took {:?}", completion_start.elapsed()); eprintln!("completion took {:?}", completion_start.elapsed());