aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_lsp_server/src/main_loop/handlers.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_lsp_server/src/main_loop/handlers.rs')
-rw-r--r--crates/ra_lsp_server/src/main_loop/handlers.rs87
1 files changed, 41 insertions, 46 deletions
diff --git a/crates/ra_lsp_server/src/main_loop/handlers.rs b/crates/ra_lsp_server/src/main_loop/handlers.rs
index 20cb5f772..c853ff653 100644
--- a/crates/ra_lsp_server/src/main_loop/handlers.rs
+++ b/crates/ra_lsp_server/src/main_loop/handlers.rs
@@ -1,15 +1,16 @@
1use std::collections::HashMap; 1use std::collections::HashMap;
2 2
3use rustc_hash::FxHashMap; 3use gen_lsp_server::ErrorCode;
4use languageserver_types::{ 4use languageserver_types::{
5 CodeActionResponse, Command, CompletionItem, CompletionItemKind, Diagnostic, 5 CodeActionResponse, Command, CompletionItem, CompletionItemKind, Diagnostic,
6 DiagnosticSeverity, DocumentSymbol, FoldingRange, FoldingRangeKind, FoldingRangeParams, 6 DiagnosticSeverity, DocumentSymbol, Documentation, FoldingRange, FoldingRangeKind,
7 InsertTextFormat, Location, Position, SymbolInformation, TextDocumentIdentifier, TextEdit, 7 FoldingRangeParams, InsertTextFormat, Location, MarkupContent, MarkupKind, Position,
8 RenameParams, WorkspaceEdit, PrepareRenameResponse, Documentation, MarkupContent, MarkupKind 8 PrepareRenameResponse, RenameParams, SymbolInformation, TextDocumentIdentifier, TextEdit,
9 WorkspaceEdit,
9}; 10};
10use gen_lsp_server::ErrorCode;
11use ra_analysis::{FileId, FoldKind, Query, RunnableKind}; 11use ra_analysis::{FileId, FoldKind, Query, RunnableKind};
12use ra_syntax::text_utils::contains_offset_nonstrict; 12use ra_syntax::text_utils::contains_offset_nonstrict;
13use rustc_hash::FxHashMap;
13use serde_json::to_value; 14use serde_json::to_value;
14 15
15use crate::{ 16use crate::{
@@ -17,13 +18,10 @@ use crate::{
17 project_model::TargetKind, 18 project_model::TargetKind,
18 req::{self, Decoration}, 19 req::{self, Decoration},
19 server_world::ServerWorld, 20 server_world::ServerWorld,
20 Result, LspError 21 LspError, Result,
21}; 22};
22 23
23pub fn handle_syntax_tree( 24pub fn handle_syntax_tree(world: ServerWorld, params: req::SyntaxTreeParams) -> Result<String> {
24 world: ServerWorld,
25 params: req::SyntaxTreeParams,
26) -> Result<String> {
27 let id = params.text_document.try_conv_with(&world)?; 25 let id = params.text_document.try_conv_with(&world)?;
28 let res = world.analysis().syntax_tree(id); 26 let res = world.analysis().syntax_tree(id);
29 Ok(res) 27 Ok(res)
@@ -182,10 +180,7 @@ pub fn handle_workspace_symbol(
182 180
183 return Ok(Some(res)); 181 return Ok(Some(res));
184 182
185 fn exec_query( 183 fn exec_query(world: &ServerWorld, query: Query) -> Result<Vec<SymbolInformation>> {
186 world: &ServerWorld,
187 query: Query,
188 ) -> Result<Vec<SymbolInformation>> {
189 let mut res = Vec::new(); 184 let mut res = Vec::new();
190 for (file_id, symbol) in world.analysis().symbol_search(query)? { 185 for (file_id, symbol) in world.analysis().symbol_search(query)? {
191 let line_index = world.analysis().file_line_index(file_id); 186 let line_index = world.analysis().file_line_index(file_id);
@@ -290,7 +285,11 @@ pub fn handle_runnables(
290 }); 285 });
291 return Ok(res); 286 return Ok(res);
292 287
293 fn runnable_args(world: &ServerWorld, file_id: FileId, kind: &RunnableKind) -> Result<Vec<String>> { 288 fn runnable_args(
289 world: &ServerWorld,
290 file_id: FileId,
291 kind: &RunnableKind,
292 ) -> Result<Vec<String>> {
294 let spec = CargoTargetSpec::for_file(world, file_id)?; 293 let spec = CargoTargetSpec::for_file(world, file_id)?;
295 let mut res = Vec::new(); 294 let mut res = Vec::new();
296 match kind { 295 match kind {
@@ -327,18 +326,15 @@ pub fn handle_runnables(
327 }; 326 };
328 let file_id = world.analysis().crate_root(crate_id)?; 327 let file_id = world.analysis().crate_root(crate_id)?;
329 let path = world.path_map.get_path(file_id); 328 let path = world.path_map.get_path(file_id);
330 let res = world 329 let res = world.workspaces.iter().find_map(|ws| {
331 .workspaces 330 let tgt = ws.target_by_root(path)?;
332 .iter() 331 let res = CargoTargetSpec {
333 .find_map(|ws| { 332 package: tgt.package(ws).name(ws).to_string(),
334 let tgt = ws.target_by_root(path)?; 333 target: tgt.name(ws).to_string(),
335 let res = CargoTargetSpec { 334 target_kind: tgt.kind(ws),
336 package: tgt.package(ws).name(ws).to_string(), 335 };
337 target: tgt.name(ws).to_string(), 336 Some(res)
338 target_kind: tgt.kind(ws), 337 });
339 };
340 Some(res)
341 });
342 Ok(res) 338 Ok(res)
343 } 339 }
344 340
@@ -367,7 +363,6 @@ pub fn handle_runnables(
367 } 363 }
368 TargetKind::Other => (), 364 TargetKind::Other => (),
369 } 365 }
370
371 } 366 }
372 } 367 }
373} 368}
@@ -453,9 +448,7 @@ pub fn handle_signature_help(
453 let line_index = world.analysis().file_line_index(file_id); 448 let line_index = world.analysis().file_line_index(file_id);
454 let offset = params.position.conv_with(&line_index); 449 let offset = params.position.conv_with(&line_index);
455 450
456 if let Some((descriptor, active_param)) = 451 if let Some((descriptor, active_param)) = world.analysis().resolve_callable(file_id, offset)? {
457 world.analysis().resolve_callable(file_id, offset)?
458 {
459 let parameters: Vec<ParameterInformation> = descriptor 452 let parameters: Vec<ParameterInformation> = descriptor
460 .params 453 .params
461 .iter() 454 .iter()
@@ -468,7 +461,7 @@ pub fn handle_signature_help(
468 let documentation = if let Some(doc) = descriptor.doc { 461 let documentation = if let Some(doc) = descriptor.doc {
469 Some(Documentation::MarkupContent(MarkupContent { 462 Some(Documentation::MarkupContent(MarkupContent {
470 kind: MarkupKind::Markdown, 463 kind: MarkupKind::Markdown,
471 value: doc 464 value: doc,
472 })) 465 }))
473 } else { 466 } else {
474 None 467 None
@@ -511,16 +504,17 @@ pub fn handle_prepare_rename(
511 Ok(Some(PrepareRenameResponse::Range(loc.range))) 504 Ok(Some(PrepareRenameResponse::Range(loc.range)))
512} 505}
513 506
514pub fn handle_rename( 507pub fn handle_rename(world: ServerWorld, params: RenameParams) -> Result<Option<WorkspaceEdit>> {
515 world: ServerWorld,
516 params: RenameParams,
517) -> Result<Option<WorkspaceEdit>> {
518 let file_id = params.text_document.try_conv_with(&world)?; 508 let file_id = params.text_document.try_conv_with(&world)?;
519 let line_index = world.analysis().file_line_index(file_id); 509 let line_index = world.analysis().file_line_index(file_id);
520 let offset = params.position.conv_with(&line_index); 510 let offset = params.position.conv_with(&line_index);
521 511
522 if params.new_name.is_empty() { 512 if params.new_name.is_empty() {
523 return Err(LspError::new(ErrorCode::InvalidParams as i32, "New Name cannot be empty".into()).into()); 513 return Err(LspError::new(
514 ErrorCode::InvalidParams as i32,
515 "New Name cannot be empty".into(),
516 )
517 .into());
524 } 518 }
525 519
526 let refs = world.analysis().find_all_refs(file_id, offset)?; 520 let refs = world.analysis().find_all_refs(file_id, offset)?;
@@ -531,11 +525,10 @@ pub fn handle_rename(
531 let mut changes = HashMap::new(); 525 let mut changes = HashMap::new();
532 for r in refs { 526 for r in refs {
533 if let Ok(loc) = to_location(r.0, r.1, &world, &line_index) { 527 if let Ok(loc) = to_location(r.0, r.1, &world, &line_index) {
534 changes.entry(loc.uri).or_insert(Vec::new()).push( 528 changes.entry(loc.uri).or_insert(Vec::new()).push(TextEdit {
535 TextEdit { 529 range: loc.range,
536 range: loc.range, 530 new_text: params.new_name.clone(),
537 new_text: params.new_name.clone() 531 });
538 });
539 } 532 }
540 } 533 }
541 534
@@ -543,7 +536,7 @@ pub fn handle_rename(
543 changes: Some(changes), 536 changes: Some(changes),
544 537
545 // TODO: return this instead if client/server support it. See #144 538 // TODO: return this instead if client/server support it. See #144
546 document_changes : None, 539 document_changes: None,
547 })) 540 }))
548} 541}
549 542
@@ -557,9 +550,11 @@ pub fn handle_references(
557 550
558 let refs = world.analysis().find_all_refs(file_id, offset)?; 551 let refs = world.analysis().find_all_refs(file_id, offset)?;
559 552
560 Ok(Some(refs.into_iter() 553 Ok(Some(
561 .filter_map(|r| to_location(r.0, r.1, &world, &line_index).ok()) 554 refs.into_iter()
562 .collect())) 555 .filter_map(|r| to_location(r.0, r.1, &world, &line_index).ok())
556 .collect(),
557 ))
563} 558}
564 559
565pub fn handle_code_action( 560pub fn handle_code_action(