aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_lsp_server/src/main_loop
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_lsp_server/src/main_loop')
-rw-r--r--crates/ra_lsp_server/src/main_loop/handlers.rs76
-rw-r--r--crates/ra_lsp_server/src/main_loop/mod.rs20
2 files changed, 52 insertions, 44 deletions
diff --git a/crates/ra_lsp_server/src/main_loop/handlers.rs b/crates/ra_lsp_server/src/main_loop/handlers.rs
index c853ff653..5314a333e 100644
--- a/crates/ra_lsp_server/src/main_loop/handlers.rs
+++ b/crates/ra_lsp_server/src/main_loop/handlers.rs
@@ -6,9 +6,9 @@ use languageserver_types::{
6 DiagnosticSeverity, DocumentSymbol, Documentation, FoldingRange, FoldingRangeKind, 6 DiagnosticSeverity, DocumentSymbol, Documentation, FoldingRange, FoldingRangeKind,
7 FoldingRangeParams, InsertTextFormat, Location, MarkupContent, MarkupKind, Position, 7 FoldingRangeParams, InsertTextFormat, Location, MarkupContent, MarkupKind, Position,
8 PrepareRenameResponse, RenameParams, SymbolInformation, TextDocumentIdentifier, TextEdit, 8 PrepareRenameResponse, RenameParams, SymbolInformation, TextDocumentIdentifier, TextEdit,
9 WorkspaceEdit, 9 WorkspaceEdit, ParameterInformation, SignatureInformation,
10}; 10};
11use ra_analysis::{FileId, FoldKind, Query, RunnableKind}; 11use ra_analysis::{FileId, FoldKind, Query, RunnableKind, FilePosition};
12use ra_syntax::text_utils::contains_offset_nonstrict; 12use ra_syntax::text_utils::contains_offset_nonstrict;
13use rustc_hash::FxHashMap; 13use rustc_hash::FxHashMap;
14use serde_json::to_value; 14use serde_json::to_value;
@@ -83,10 +83,8 @@ pub fn handle_on_enter(
83 world: ServerWorld, 83 world: ServerWorld,
84 params: req::TextDocumentPositionParams, 84 params: req::TextDocumentPositionParams,
85) -> Result<Option<req::SourceChange>> { 85) -> Result<Option<req::SourceChange>> {
86 let file_id = params.text_document.try_conv_with(&world)?; 86 let position = params.try_conv_with(&world)?;
87 let line_index = world.analysis().file_line_index(file_id); 87 match world.analysis().on_enter(position) {
88 let offset = params.position.conv_with(&line_index);
89 match world.analysis().on_enter(file_id, offset) {
90 None => Ok(None), 88 None => Ok(None),
91 Some(edit) => Ok(Some(edit.try_conv_with(&world)?)), 89 Some(edit) => Ok(Some(edit.try_conv_with(&world)?)),
92 } 90 }
@@ -102,8 +100,11 @@ pub fn handle_on_type_formatting(
102 100
103 let file_id = params.text_document.try_conv_with(&world)?; 101 let file_id = params.text_document.try_conv_with(&world)?;
104 let line_index = world.analysis().file_line_index(file_id); 102 let line_index = world.analysis().file_line_index(file_id);
105 let offset = params.position.conv_with(&line_index); 103 let position = FilePosition {
106 let edits = match world.analysis().on_eq_typed(file_id, offset) { 104 file_id,
105 offset: params.position.conv_with(&line_index),
106 };
107 let edits = match world.analysis().on_eq_typed(position) {
107 None => return Ok(None), 108 None => return Ok(None),
108 Some(mut action) => action.source_file_edits.pop().unwrap().edits, 109 Some(mut action) => action.source_file_edits.pop().unwrap().edits,
109 }; 110 };
@@ -201,14 +202,9 @@ pub fn handle_goto_definition(
201 world: ServerWorld, 202 world: ServerWorld,
202 params: req::TextDocumentPositionParams, 203 params: req::TextDocumentPositionParams,
203) -> Result<Option<req::GotoDefinitionResponse>> { 204) -> Result<Option<req::GotoDefinitionResponse>> {
204 let file_id = params.text_document.try_conv_with(&world)?; 205 let position = params.try_conv_with(&world)?;
205 let line_index = world.analysis().file_line_index(file_id);
206 let offset = params.position.conv_with(&line_index);
207 let mut res = Vec::new(); 206 let mut res = Vec::new();
208 for (file_id, symbol) in world 207 for (file_id, symbol) in world.analysis().approximately_resolve_symbol(position)? {
209 .analysis()
210 .approximately_resolve_symbol(file_id, offset)?
211 {
212 let line_index = world.analysis().file_line_index(file_id); 208 let line_index = world.analysis().file_line_index(file_id);
213 let location = to_location(file_id, symbol.node_range, &world, &line_index)?; 209 let location = to_location(file_id, symbol.node_range, &world, &line_index)?;
214 res.push(location) 210 res.push(location)
@@ -218,11 +214,11 @@ pub fn handle_goto_definition(
218 214
219pub fn handle_parent_module( 215pub fn handle_parent_module(
220 world: ServerWorld, 216 world: ServerWorld,
221 params: TextDocumentIdentifier, 217 params: req::TextDocumentPositionParams,
222) -> Result<Vec<Location>> { 218) -> Result<Vec<Location>> {
223 let file_id = params.try_conv_with(&world)?; 219 let position = params.try_conv_with(&world)?;
224 let mut res = Vec::new(); 220 let mut res = Vec::new();
225 for (file_id, symbol) in world.analysis().parent_module(file_id)? { 221 for (file_id, symbol) in world.analysis().parent_module(position)? {
226 let line_index = world.analysis().file_line_index(file_id); 222 let line_index = world.analysis().file_line_index(file_id);
227 let location = to_location(file_id, symbol.node_range, &world, &line_index)?; 223 let location = to_location(file_id, symbol.node_range, &world, &line_index)?;
228 res.push(location); 224 res.push(location);
@@ -379,10 +375,13 @@ pub fn handle_completion(
379 world: ServerWorld, 375 world: ServerWorld,
380 params: req::CompletionParams, 376 params: req::CompletionParams,
381) -> Result<Option<req::CompletionResponse>> { 377) -> Result<Option<req::CompletionResponse>> {
382 let file_id = params.text_document.try_conv_with(&world)?; 378 let position = {
383 let line_index = world.analysis().file_line_index(file_id); 379 let file_id = params.text_document.try_conv_with(&world)?;
384 let offset = params.position.conv_with(&line_index); 380 let line_index = world.analysis().file_line_index(file_id);
385 let items = match world.analysis().completions(file_id, offset)? { 381 let offset = params.position.conv_with(&line_index);
382 FilePosition { file_id, offset }
383 };
384 let items = match world.analysis().completions(position)? {
386 None => return Ok(None), 385 None => return Ok(None),
387 Some(items) => items, 386 Some(items) => items,
388 }; 387 };
@@ -442,13 +441,9 @@ pub fn handle_signature_help(
442 world: ServerWorld, 441 world: ServerWorld,
443 params: req::TextDocumentPositionParams, 442 params: req::TextDocumentPositionParams,
444) -> Result<Option<req::SignatureHelp>> { 443) -> Result<Option<req::SignatureHelp>> {
445 use languageserver_types::{ParameterInformation, SignatureInformation}; 444 let position = params.try_conv_with(&world)?;
446 445
447 let file_id = params.text_document.try_conv_with(&world)?; 446 if let Some((descriptor, active_param)) = world.analysis().resolve_callable(position)? {
448 let line_index = world.analysis().file_line_index(file_id);
449 let offset = params.position.conv_with(&line_index);
450
451 if let Some((descriptor, active_param)) = world.analysis().resolve_callable(file_id, offset)? {
452 let parameters: Vec<ParameterInformation> = descriptor 447 let parameters: Vec<ParameterInformation> = descriptor
453 .params 448 .params
454 .iter() 449 .iter()
@@ -487,18 +482,17 @@ pub fn handle_prepare_rename(
487 world: ServerWorld, 482 world: ServerWorld,
488 params: req::TextDocumentPositionParams, 483 params: req::TextDocumentPositionParams,
489) -> Result<Option<PrepareRenameResponse>> { 484) -> Result<Option<PrepareRenameResponse>> {
490 let file_id = params.text_document.try_conv_with(&world)?; 485 let position = params.try_conv_with(&world)?;
491 let line_index = world.analysis().file_line_index(file_id);
492 let offset = params.position.conv_with(&line_index);
493 486
494 // We support renaming references like handle_rename does. 487 // We support renaming references like handle_rename does.
495 // In the future we may want to reject the renaming of things like keywords here too. 488 // In the future we may want to reject the renaming of things like keywords here too.
496 let refs = world.analysis().find_all_refs(file_id, offset)?; 489 let refs = world.analysis().find_all_refs(position)?;
497 if refs.is_empty() { 490 let r = match refs.first() {
498 return Ok(None); 491 Some(r) => r,
499 } 492 None => return Ok(None),
500 493 };
501 let r = refs.first().unwrap(); 494 let file_id = params.text_document.try_conv_with(&world)?;
495 let line_index = world.analysis().file_line_index(file_id);
502 let loc = to_location(r.0, r.1, &world, &line_index)?; 496 let loc = to_location(r.0, r.1, &world, &line_index)?;
503 497
504 Ok(Some(PrepareRenameResponse::Range(loc.range))) 498 Ok(Some(PrepareRenameResponse::Range(loc.range)))
@@ -517,7 +511,9 @@ pub fn handle_rename(world: ServerWorld, params: RenameParams) -> Result<Option<
517 .into()); 511 .into());
518 } 512 }
519 513
520 let refs = world.analysis().find_all_refs(file_id, offset)?; 514 let refs = world
515 .analysis()
516 .find_all_refs(FilePosition { file_id, offset })?;
521 if refs.is_empty() { 517 if refs.is_empty() {
522 return Ok(None); 518 return Ok(None);
523 } 519 }
@@ -548,7 +544,9 @@ pub fn handle_references(
548 let line_index = world.analysis().file_line_index(file_id); 544 let line_index = world.analysis().file_line_index(file_id);
549 let offset = params.position.conv_with(&line_index); 545 let offset = params.position.conv_with(&line_index);
550 546
551 let refs = world.analysis().find_all_refs(file_id, offset)?; 547 let refs = world
548 .analysis()
549 .find_all_refs(FilePosition { file_id, offset })?;
552 550
553 Ok(Some( 551 Ok(Some(
554 refs.into_iter() 552 refs.into_iter()
diff --git a/crates/ra_lsp_server/src/main_loop/mod.rs b/crates/ra_lsp_server/src/main_loop/mod.rs
index 1eb147539..229d1b0f7 100644
--- a/crates/ra_lsp_server/src/main_loop/mod.rs
+++ b/crates/ra_lsp_server/src/main_loop/mod.rs
@@ -376,11 +376,21 @@ impl<'a> PoolDispatcher<'a> {
376 Ok(lsp_error) => { 376 Ok(lsp_error) => {
377 RawResponse::err(id, lsp_error.code, lsp_error.message) 377 RawResponse::err(id, lsp_error.code, lsp_error.message)
378 } 378 }
379 Err(e) => RawResponse::err( 379 Err(e) => {
380 id, 380 if is_canceled(&e) {
381 ErrorCode::InternalError as i32, 381 RawResponse::err(
382 format!("{}\n{}", e, e.backtrace()), 382 id,
383 ), 383 ErrorCode::RequestCancelled as i32,
384 e.to_string(),
385 )
386 } else {
387 RawResponse::err(
388 id,
389 ErrorCode::InternalError as i32,
390 format!("{}\n{}", e, e.backtrace()),
391 )
392 }
393 }
384 }, 394 },
385 }; 395 };
386 let task = Task::Respond(resp); 396 let task = Task::Respond(resp);