aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_lsp_server
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_lsp_server')
-rw-r--r--crates/ra_lsp_server/src/conv.rs13
-rw-r--r--crates/ra_lsp_server/src/main_loop/handlers.rs76
2 files changed, 48 insertions, 41 deletions
diff --git a/crates/ra_lsp_server/src/conv.rs b/crates/ra_lsp_server/src/conv.rs
index 84ffac2da..fa04f4b00 100644
--- a/crates/ra_lsp_server/src/conv.rs
+++ b/crates/ra_lsp_server/src/conv.rs
@@ -2,7 +2,7 @@ use languageserver_types::{
2 Location, Position, Range, SymbolKind, TextDocumentEdit, TextDocumentIdentifier, 2 Location, Position, Range, SymbolKind, TextDocumentEdit, TextDocumentIdentifier,
3 TextDocumentItem, TextDocumentPositionParams, TextEdit, Url, VersionedTextDocumentIdentifier, 3 TextDocumentItem, TextDocumentPositionParams, TextEdit, Url, VersionedTextDocumentIdentifier,
4}; 4};
5use ra_analysis::{FileId, FileSystemEdit, SourceChange, SourceFileEdit}; 5use ra_analysis::{FileId, FileSystemEdit, SourceChange, SourceFileEdit, FilePosition};
6use ra_editor::{AtomEdit, Edit, LineCol, LineIndex}; 6use ra_editor::{AtomEdit, Edit, LineCol, LineIndex};
7use ra_syntax::{SyntaxKind, TextRange, TextUnit}; 7use ra_syntax::{SyntaxKind, TextRange, TextUnit};
8 8
@@ -165,6 +165,17 @@ impl<'a> TryConvWith for &'a TextDocumentIdentifier {
165 } 165 }
166} 166}
167 167
168impl<'a> TryConvWith for &'a TextDocumentPositionParams {
169 type Ctx = ServerWorld;
170 type Output = FilePosition;
171 fn try_conv_with(self, world: &ServerWorld) -> Result<FilePosition> {
172 let file_id = self.text_document.try_conv_with(world)?;
173 let line_index = world.analysis().file_line_index(file_id);
174 let offset = self.position.conv_with(&line_index);
175 Ok(FilePosition { file_id, offset })
176 }
177}
178
168impl<T: TryConvWith> TryConvWith for Vec<T> { 179impl<T: TryConvWith> TryConvWith for Vec<T> {
169 type Ctx = <T as TryConvWith>::Ctx; 180 type Ctx = <T as TryConvWith>::Ctx;
170 type Output = Vec<<T as TryConvWith>::Output>; 181 type Output = Vec<<T as TryConvWith>::Output>;
diff --git a/crates/ra_lsp_server/src/main_loop/handlers.rs b/crates/ra_lsp_server/src/main_loop/handlers.rs
index 2219a0036..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)
@@ -220,11 +216,9 @@ pub fn handle_parent_module(
220 world: ServerWorld, 216 world: ServerWorld,
221 params: req::TextDocumentPositionParams, 217 params: req::TextDocumentPositionParams,
222) -> Result<Vec<Location>> { 218) -> Result<Vec<Location>> {
223 let file_id = params.text_document.try_conv_with(&world)?; 219 let position = params.try_conv_with(&world)?;
224 let line_index = world.analysis().file_line_index(file_id);
225 let offset = params.position.conv_with(&line_index);
226 let mut res = Vec::new(); 220 let mut res = Vec::new();
227 for (file_id, symbol) in world.analysis().parent_module(file_id, offset)? { 221 for (file_id, symbol) in world.analysis().parent_module(position)? {
228 let line_index = world.analysis().file_line_index(file_id); 222 let line_index = world.analysis().file_line_index(file_id);
229 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)?;
230 res.push(location); 224 res.push(location);
@@ -381,10 +375,13 @@ pub fn handle_completion(
381 world: ServerWorld, 375 world: ServerWorld,
382 params: req::CompletionParams, 376 params: req::CompletionParams,
383) -> Result<Option<req::CompletionResponse>> { 377) -> Result<Option<req::CompletionResponse>> {
384 let file_id = params.text_document.try_conv_with(&world)?; 378 let position = {
385 let line_index = world.analysis().file_line_index(file_id); 379 let file_id = params.text_document.try_conv_with(&world)?;
386 let offset = params.position.conv_with(&line_index); 380 let line_index = world.analysis().file_line_index(file_id);
387 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)? {
388 None => return Ok(None), 385 None => return Ok(None),
389 Some(items) => items, 386 Some(items) => items,
390 }; 387 };
@@ -444,13 +441,9 @@ pub fn handle_signature_help(
444 world: ServerWorld, 441 world: ServerWorld,
445 params: req::TextDocumentPositionParams, 442 params: req::TextDocumentPositionParams,
446) -> Result<Option<req::SignatureHelp>> { 443) -> Result<Option<req::SignatureHelp>> {
447 use languageserver_types::{ParameterInformation, SignatureInformation}; 444 let position = params.try_conv_with(&world)?;
448 445
449 let file_id = params.text_document.try_conv_with(&world)?; 446 if let Some((descriptor, active_param)) = world.analysis().resolve_callable(position)? {
450 let line_index = world.analysis().file_line_index(file_id);
451 let offset = params.position.conv_with(&line_index);
452
453 if let Some((descriptor, active_param)) = world.analysis().resolve_callable(file_id, offset)? {
454 let parameters: Vec<ParameterInformation> = descriptor 447 let parameters: Vec<ParameterInformation> = descriptor
455 .params 448 .params
456 .iter() 449 .iter()
@@ -489,18 +482,17 @@ pub fn handle_prepare_rename(
489 world: ServerWorld, 482 world: ServerWorld,
490 params: req::TextDocumentPositionParams, 483 params: req::TextDocumentPositionParams,
491) -> Result<Option<PrepareRenameResponse>> { 484) -> Result<Option<PrepareRenameResponse>> {
492 let file_id = params.text_document.try_conv_with(&world)?; 485 let position = params.try_conv_with(&world)?;
493 let line_index = world.analysis().file_line_index(file_id);
494 let offset = params.position.conv_with(&line_index);
495 486
496 // We support renaming references like handle_rename does. 487 // We support renaming references like handle_rename does.
497 // 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.
498 let refs = world.analysis().find_all_refs(file_id, offset)?; 489 let refs = world.analysis().find_all_refs(position)?;
499 if refs.is_empty() { 490 let r = match refs.first() {
500 return Ok(None); 491 Some(r) => r,
501 } 492 None => return Ok(None),
502 493 };
503 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);
504 let loc = to_location(r.0, r.1, &world, &line_index)?; 496 let loc = to_location(r.0, r.1, &world, &line_index)?;
505 497
506 Ok(Some(PrepareRenameResponse::Range(loc.range))) 498 Ok(Some(PrepareRenameResponse::Range(loc.range)))
@@ -519,7 +511,9 @@ pub fn handle_rename(world: ServerWorld, params: RenameParams) -> Result<Option<
519 .into()); 511 .into());
520 } 512 }
521 513
522 let refs = world.analysis().find_all_refs(file_id, offset)?; 514 let refs = world
515 .analysis()
516 .find_all_refs(FilePosition { file_id, offset })?;
523 if refs.is_empty() { 517 if refs.is_empty() {
524 return Ok(None); 518 return Ok(None);
525 } 519 }
@@ -550,7 +544,9 @@ pub fn handle_references(
550 let line_index = world.analysis().file_line_index(file_id); 544 let line_index = world.analysis().file_line_index(file_id);
551 let offset = params.position.conv_with(&line_index); 545 let offset = params.position.conv_with(&line_index);
552 546
553 let refs = world.analysis().find_all_refs(file_id, offset)?; 547 let refs = world
548 .analysis()
549 .find_all_refs(FilePosition { file_id, offset })?;
554 550
555 Ok(Some( 551 Ok(Some(
556 refs.into_iter() 552 refs.into_iter()