diff options
Diffstat (limited to 'crates/ra_lsp_server')
-rw-r--r-- | crates/ra_lsp_server/src/conv.rs | 67 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/main_loop/handlers.rs | 27 |
2 files changed, 54 insertions, 40 deletions
diff --git a/crates/ra_lsp_server/src/conv.rs b/crates/ra_lsp_server/src/conv.rs index 32e67838e..fc01b1c0e 100644 --- a/crates/ra_lsp_server/src/conv.rs +++ b/crates/ra_lsp_server/src/conv.rs | |||
@@ -384,27 +384,32 @@ impl TryConvWith for &NavigationTarget { | |||
384 | } | 384 | } |
385 | } | 385 | } |
386 | 386 | ||
387 | pub fn to_location_link( | 387 | impl TryConvWith for (FileId, RangeInfo<NavigationTarget>) { |
388 | target: &RangeInfo<NavigationTarget>, | 388 | type Ctx = WorldSnapshot; |
389 | world: &WorldSnapshot, | 389 | type Output = LocationLink; |
390 | // line index for original range file | 390 | fn try_conv_with(self, world: &WorldSnapshot) -> Result<LocationLink> { |
391 | line_index: &LineIndex, | 391 | let (src_file_id, target) = self; |
392 | ) -> Result<LocationLink> { | 392 | |
393 | let target_uri = target.info.file_id().try_conv_with(world)?; | 393 | let target_uri = target.info.file_id().try_conv_with(world)?; |
394 | let tgt_line_index = world.analysis().file_line_index(target.info.file_id()); | 394 | let src_line_index = world.analysis().file_line_index(src_file_id); |
395 | 395 | let tgt_line_index = world.analysis().file_line_index(target.info.file_id()); | |
396 | let target_range = target.info.full_range().conv_with(&tgt_line_index); | 396 | |
397 | 397 | let target_range = target.info.full_range().conv_with(&tgt_line_index); | |
398 | let target_selection_range = | 398 | |
399 | target.info.focus_range().map(|it| it.conv_with(&tgt_line_index)).unwrap_or(target_range); | 399 | let target_selection_range = target |
400 | 400 | .info | |
401 | let res = LocationLink { | 401 | .focus_range() |
402 | origin_selection_range: Some(target.range.conv_with(line_index)), | 402 | .map(|it| it.conv_with(&tgt_line_index)) |
403 | target_uri, | 403 | .unwrap_or(target_range); |
404 | target_range, | 404 | |
405 | target_selection_range, | 405 | let res = LocationLink { |
406 | }; | 406 | origin_selection_range: Some(target.range.conv_with(&src_line_index)), |
407 | Ok(res) | 407 | target_uri, |
408 | target_range, | ||
409 | target_selection_range, | ||
410 | }; | ||
411 | Ok(res) | ||
412 | } | ||
408 | } | 413 | } |
409 | 414 | ||
410 | pub fn to_location( | 415 | pub fn to_location( |
@@ -452,3 +457,23 @@ where | |||
452 | self.iter.next().map(|item| item.conv_with(self.ctx)) | 457 | self.iter.next().map(|item| item.conv_with(self.ctx)) |
453 | } | 458 | } |
454 | } | 459 | } |
460 | |||
461 | pub trait TryConvWithToVec<'a>: Sized + 'a { | ||
462 | type Ctx; | ||
463 | type Output; | ||
464 | |||
465 | fn try_conv_with_to_vec(self, ctx: &'a Self::Ctx) -> Result<Vec<Self::Output>>; | ||
466 | } | ||
467 | |||
468 | impl<'a, I> TryConvWithToVec<'a> for I | ||
469 | where | ||
470 | I: Iterator + 'a, | ||
471 | I::Item: TryConvWith, | ||
472 | { | ||
473 | type Ctx = <I::Item as TryConvWith>::Ctx; | ||
474 | type Output = <I::Item as TryConvWith>::Output; | ||
475 | |||
476 | fn try_conv_with_to_vec(self, ctx: &'a Self::Ctx) -> Result<Vec<Self::Output>> { | ||
477 | self.map(|it| it.try_conv_with(ctx)).collect() | ||
478 | } | ||
479 | } | ||
diff --git a/crates/ra_lsp_server/src/main_loop/handlers.rs b/crates/ra_lsp_server/src/main_loop/handlers.rs index 62c8cbf71..8f07f5027 100644 --- a/crates/ra_lsp_server/src/main_loop/handlers.rs +++ b/crates/ra_lsp_server/src/main_loop/handlers.rs | |||
@@ -21,7 +21,7 @@ use url_serde::Ser; | |||
21 | 21 | ||
22 | use crate::{ | 22 | use crate::{ |
23 | cargo_target_spec::{runnable_args, CargoTargetSpec}, | 23 | cargo_target_spec::{runnable_args, CargoTargetSpec}, |
24 | conv::{to_location, to_location_link, Conv, ConvWith, MapConvWith, TryConvWith}, | 24 | conv::{to_location, Conv, ConvWith, MapConvWith, TryConvWith, TryConvWithToVec}, |
25 | req::{self, Decoration}, | 25 | req::{self, Decoration}, |
26 | world::WorldSnapshot, | 26 | world::WorldSnapshot, |
27 | LspError, Result, | 27 | LspError, Result, |
@@ -263,7 +263,6 @@ pub fn handle_goto_definition( | |||
263 | params: req::TextDocumentPositionParams, | 263 | params: req::TextDocumentPositionParams, |
264 | ) -> Result<Option<req::GotoDefinitionResponse>> { | 264 | ) -> Result<Option<req::GotoDefinitionResponse>> { |
265 | let position = params.try_conv_with(&world)?; | 265 | let position = params.try_conv_with(&world)?; |
266 | let line_index = world.analysis().file_line_index(position.file_id); | ||
267 | let nav_info = match world.analysis().goto_definition(position)? { | 266 | let nav_info = match world.analysis().goto_definition(position)? { |
268 | None => return Ok(None), | 267 | None => return Ok(None), |
269 | Some(it) => it, | 268 | Some(it) => it, |
@@ -272,9 +271,8 @@ pub fn handle_goto_definition( | |||
272 | let res = nav_info | 271 | let res = nav_info |
273 | .info | 272 | .info |
274 | .into_iter() | 273 | .into_iter() |
275 | .map(|nav| RangeInfo::new(nav_range, nav)) | 274 | .map(|nav| (position.file_id, RangeInfo::new(nav_range, nav))) |
276 | .map(|nav| to_location_link(&nav, &world, &line_index)) | 275 | .try_conv_with_to_vec(&world)?; |
277 | .collect::<Result<Vec<_>>>()?; | ||
278 | Ok(Some(res.into())) | 276 | Ok(Some(res.into())) |
279 | } | 277 | } |
280 | 278 | ||
@@ -283,7 +281,6 @@ pub fn handle_goto_implementation( | |||
283 | params: req::TextDocumentPositionParams, | 281 | params: req::TextDocumentPositionParams, |
284 | ) -> Result<Option<req::GotoImplementationResponse>> { | 282 | ) -> Result<Option<req::GotoImplementationResponse>> { |
285 | let position = params.try_conv_with(&world)?; | 283 | let position = params.try_conv_with(&world)?; |
286 | let line_index = world.analysis().file_line_index(position.file_id); | ||
287 | let nav_info = match world.analysis().goto_implementation(position)? { | 284 | let nav_info = match world.analysis().goto_implementation(position)? { |
288 | None => return Ok(None), | 285 | None => return Ok(None), |
289 | Some(it) => it, | 286 | Some(it) => it, |
@@ -292,9 +289,8 @@ pub fn handle_goto_implementation( | |||
292 | let res = nav_info | 289 | let res = nav_info |
293 | .info | 290 | .info |
294 | .into_iter() | 291 | .into_iter() |
295 | .map(|nav| RangeInfo::new(nav_range, nav)) | 292 | .map(|nav| (position.file_id, RangeInfo::new(nav_range, nav))) |
296 | .map(|nav| to_location_link(&nav, &world, &line_index)) | 293 | .try_conv_with_to_vec(&world)?; |
297 | .collect::<Result<Vec<_>>>()?; | ||
298 | Ok(Some(res.into())) | 294 | Ok(Some(res.into())) |
299 | } | 295 | } |
300 | 296 | ||
@@ -303,7 +299,6 @@ pub fn handle_goto_type_definition( | |||
303 | params: req::TextDocumentPositionParams, | 299 | params: req::TextDocumentPositionParams, |
304 | ) -> Result<Option<req::GotoTypeDefinitionResponse>> { | 300 | ) -> Result<Option<req::GotoTypeDefinitionResponse>> { |
305 | let position = params.try_conv_with(&world)?; | 301 | let position = params.try_conv_with(&world)?; |
306 | let line_index = world.analysis().file_line_index(position.file_id); | ||
307 | let nav_info = match world.analysis().goto_type_definition(position)? { | 302 | let nav_info = match world.analysis().goto_type_definition(position)? { |
308 | None => return Ok(None), | 303 | None => return Ok(None), |
309 | Some(it) => it, | 304 | Some(it) => it, |
@@ -312,9 +307,8 @@ pub fn handle_goto_type_definition( | |||
312 | let res = nav_info | 307 | let res = nav_info |
313 | .info | 308 | .info |
314 | .into_iter() | 309 | .into_iter() |
315 | .map(|nav| RangeInfo::new(nav_range, nav)) | 310 | .map(|nav| (position.file_id, RangeInfo::new(nav_range, nav))) |
316 | .map(|nav| to_location_link(&nav, &world, &line_index)) | 311 | .try_conv_with_to_vec(&world)?; |
317 | .collect::<Result<Vec<_>>>()?; | ||
318 | Ok(Some(res.into())) | 312 | Ok(Some(res.into())) |
319 | } | 313 | } |
320 | 314 | ||
@@ -323,12 +317,7 @@ pub fn handle_parent_module( | |||
323 | params: req::TextDocumentPositionParams, | 317 | params: req::TextDocumentPositionParams, |
324 | ) -> Result<Vec<Location>> { | 318 | ) -> Result<Vec<Location>> { |
325 | let position = params.try_conv_with(&world)?; | 319 | let position = params.try_conv_with(&world)?; |
326 | world | 320 | world.analysis().parent_module(position)?.iter().try_conv_with_to_vec(&world) |
327 | .analysis() | ||
328 | .parent_module(position)? | ||
329 | .into_iter() | ||
330 | .map(|nav| nav.try_conv_with(&world)) | ||
331 | .collect::<Result<Vec<_>>>() | ||
332 | } | 321 | } |
333 | 322 | ||
334 | pub fn handle_runnables( | 323 | pub fn handle_runnables( |