add try_conv_with_to_vec

This commit is contained in:
Aleksey Kladov 2019-07-08 13:39:16 +03:00
parent 5ce2b4819e
commit 227bc0b6d4
2 changed files with 51 additions and 37 deletions

View file

@ -384,27 +384,32 @@ impl TryConvWith for &NavigationTarget {
} }
} }
pub fn to_location_link( impl TryConvWith for (FileId, RangeInfo<NavigationTarget>) {
target: &RangeInfo<NavigationTarget>, type Ctx = WorldSnapshot;
world: &WorldSnapshot, type Output = LocationLink;
// line index for original range file fn try_conv_with(self, world: &WorldSnapshot) -> Result<LocationLink> {
line_index: &LineIndex, let (src_file_id, target) = self;
) -> Result<LocationLink> {
let target_uri = target.info.file_id().try_conv_with(world)?; let target_uri = target.info.file_id().try_conv_with(world)?;
let src_line_index = world.analysis().file_line_index(src_file_id);
let tgt_line_index = world.analysis().file_line_index(target.info.file_id()); let tgt_line_index = world.analysis().file_line_index(target.info.file_id());
let target_range = target.info.full_range().conv_with(&tgt_line_index); let target_range = target.info.full_range().conv_with(&tgt_line_index);
let target_selection_range = let target_selection_range = target
target.info.focus_range().map(|it| it.conv_with(&tgt_line_index)).unwrap_or(target_range); .info
.focus_range()
.map(|it| it.conv_with(&tgt_line_index))
.unwrap_or(target_range);
let res = LocationLink { let res = LocationLink {
origin_selection_range: Some(target.range.conv_with(line_index)), origin_selection_range: Some(target.range.conv_with(&src_line_index)),
target_uri, target_uri,
target_range, target_range,
target_selection_range, target_selection_range,
}; };
Ok(res) Ok(res)
}
} }
pub fn to_location( pub fn to_location(
@ -452,3 +457,23 @@ where
self.iter.next().map(|item| item.conv_with(self.ctx)) self.iter.next().map(|item| item.conv_with(self.ctx))
} }
} }
pub trait TryConvWithToVec<'a>: Sized + 'a {
type Ctx;
type Output;
fn try_conv_with_to_vec(self, ctx: &'a Self::Ctx) -> Result<Vec<Self::Output>>;
}
impl<'a, I> TryConvWithToVec<'a> for I
where
I: Iterator + 'a,
I::Item: TryConvWith,
{
type Ctx = <I::Item as TryConvWith>::Ctx;
type Output = <I::Item as TryConvWith>::Output;
fn try_conv_with_to_vec(self, ctx: &'a Self::Ctx) -> Result<Vec<Self::Output>> {
self.map(|it| it.try_conv_with(ctx)).collect()
}
}

View file

@ -21,7 +21,7 @@ use url_serde::Ser;
use crate::{ use crate::{
cargo_target_spec::{runnable_args, CargoTargetSpec}, cargo_target_spec::{runnable_args, CargoTargetSpec},
conv::{to_location, to_location_link, Conv, ConvWith, MapConvWith, TryConvWith}, conv::{to_location, Conv, ConvWith, MapConvWith, TryConvWith, TryConvWithToVec},
req::{self, Decoration}, req::{self, Decoration},
world::WorldSnapshot, world::WorldSnapshot,
LspError, Result, LspError, Result,
@ -263,7 +263,6 @@ pub fn handle_goto_definition(
params: req::TextDocumentPositionParams, params: req::TextDocumentPositionParams,
) -> Result<Option<req::GotoDefinitionResponse>> { ) -> Result<Option<req::GotoDefinitionResponse>> {
let position = params.try_conv_with(&world)?; let position = params.try_conv_with(&world)?;
let line_index = world.analysis().file_line_index(position.file_id);
let nav_info = match world.analysis().goto_definition(position)? { let nav_info = match world.analysis().goto_definition(position)? {
None => return Ok(None), None => return Ok(None),
Some(it) => it, Some(it) => it,
@ -272,9 +271,8 @@ pub fn handle_goto_definition(
let res = nav_info let res = nav_info
.info .info
.into_iter() .into_iter()
.map(|nav| RangeInfo::new(nav_range, nav)) .map(|nav| (position.file_id, RangeInfo::new(nav_range, nav)))
.map(|nav| to_location_link(&nav, &world, &line_index)) .try_conv_with_to_vec(&world)?;
.collect::<Result<Vec<_>>>()?;
Ok(Some(res.into())) Ok(Some(res.into()))
} }
@ -283,7 +281,6 @@ pub fn handle_goto_implementation(
params: req::TextDocumentPositionParams, params: req::TextDocumentPositionParams,
) -> Result<Option<req::GotoImplementationResponse>> { ) -> Result<Option<req::GotoImplementationResponse>> {
let position = params.try_conv_with(&world)?; let position = params.try_conv_with(&world)?;
let line_index = world.analysis().file_line_index(position.file_id);
let nav_info = match world.analysis().goto_implementation(position)? { let nav_info = match world.analysis().goto_implementation(position)? {
None => return Ok(None), None => return Ok(None),
Some(it) => it, Some(it) => it,
@ -292,9 +289,8 @@ pub fn handle_goto_implementation(
let res = nav_info let res = nav_info
.info .info
.into_iter() .into_iter()
.map(|nav| RangeInfo::new(nav_range, nav)) .map(|nav| (position.file_id, RangeInfo::new(nav_range, nav)))
.map(|nav| to_location_link(&nav, &world, &line_index)) .try_conv_with_to_vec(&world)?;
.collect::<Result<Vec<_>>>()?;
Ok(Some(res.into())) Ok(Some(res.into()))
} }
@ -303,7 +299,6 @@ pub fn handle_goto_type_definition(
params: req::TextDocumentPositionParams, params: req::TextDocumentPositionParams,
) -> Result<Option<req::GotoTypeDefinitionResponse>> { ) -> Result<Option<req::GotoTypeDefinitionResponse>> {
let position = params.try_conv_with(&world)?; let position = params.try_conv_with(&world)?;
let line_index = world.analysis().file_line_index(position.file_id);
let nav_info = match world.analysis().goto_type_definition(position)? { let nav_info = match world.analysis().goto_type_definition(position)? {
None => return Ok(None), None => return Ok(None),
Some(it) => it, Some(it) => it,
@ -312,9 +307,8 @@ pub fn handle_goto_type_definition(
let res = nav_info let res = nav_info
.info .info
.into_iter() .into_iter()
.map(|nav| RangeInfo::new(nav_range, nav)) .map(|nav| (position.file_id, RangeInfo::new(nav_range, nav)))
.map(|nav| to_location_link(&nav, &world, &line_index)) .try_conv_with_to_vec(&world)?;
.collect::<Result<Vec<_>>>()?;
Ok(Some(res.into())) Ok(Some(res.into()))
} }
@ -323,12 +317,7 @@ pub fn handle_parent_module(
params: req::TextDocumentPositionParams, params: req::TextDocumentPositionParams,
) -> Result<Vec<Location>> { ) -> Result<Vec<Location>> {
let position = params.try_conv_with(&world)?; let position = params.try_conv_with(&world)?;
world world.analysis().parent_module(position)?.iter().try_conv_with_to_vec(&world)
.analysis()
.parent_module(position)?
.into_iter()
.map(|nav| nav.try_conv_with(&world))
.collect::<Result<Vec<_>>>()
} }
pub fn handle_runnables( pub fn handle_runnables(