aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_lsp_server/src/conv.rs67
-rw-r--r--crates/ra_lsp_server/src/main_loop/handlers.rs27
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
387pub fn to_location_link( 387impl 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
410pub fn to_location( 415pub 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
461pub 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
468impl<'a, I> TryConvWithToVec<'a> for I
469where
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
22use crate::{ 22use 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
334pub fn handle_runnables( 323pub fn handle_runnables(