use navigation target in API

This commit is contained in:
Aleksey Kladov 2019-01-02 17:09:39 +03:00
parent d25c89f760
commit 830abe0c1b
4 changed files with 44 additions and 26 deletions

View file

@ -205,7 +205,7 @@ impl AnalysisImpl {
/// This returns `Vec` because a module may be included from several places. We /// This returns `Vec` because a module may be included from several places. We
/// don't handle this case yet though, so the Vec has length at most one. /// don't handle this case yet though, so the Vec has length at most one.
pub fn parent_module(&self, position: FilePosition) -> Cancelable<Vec<(FileId, FileSymbol)>> { pub fn parent_module(&self, position: FilePosition) -> Cancelable<Vec<NavigationTarget>> {
let descr = match source_binder::module_from_position(&*self.db, position)? { let descr = match source_binder::module_from_position(&*self.db, position)? {
None => return Ok(Vec::new()), None => return Ok(Vec::new()),
Some(it) => it, Some(it) => it,
@ -216,12 +216,12 @@ impl AnalysisImpl {
}; };
let decl = decl.borrowed(); let decl = decl.borrowed();
let decl_name = decl.name().unwrap(); let decl_name = decl.name().unwrap();
let sym = FileSymbol { let symbol = FileSymbol {
name: decl_name.text(), name: decl_name.text(),
node_range: decl_name.syntax().range(), node_range: decl_name.syntax().range(),
kind: MODULE, kind: MODULE,
}; };
Ok(vec![(file_id, sym)]) Ok(vec![NavigationTarget { file_id, symbol }])
} }
/// Returns `Vec` for the same reason as `parent_module` /// Returns `Vec` for the same reason as `parent_module`
pub fn crate_for(&self, file_id: FileId) -> Cancelable<Vec<CrateId>> { pub fn crate_for(&self, file_id: FileId) -> Cancelable<Vec<CrateId>> {

View file

@ -24,7 +24,7 @@ mod macros;
use std::{fmt, sync::Arc}; use std::{fmt, sync::Arc};
use rustc_hash::FxHashMap; use rustc_hash::FxHashMap;
use ra_syntax::{SourceFileNode, TextRange, TextUnit}; use ra_syntax::{SourceFileNode, TextRange, TextUnit, SmolStr, SyntaxKind};
use ra_text_edit::TextEdit; use ra_text_edit::TextEdit;
use rayon::prelude::*; use rayon::prelude::*;
use relative_path::RelativePathBuf; use relative_path::RelativePathBuf;
@ -251,6 +251,12 @@ pub struct NavigationTarget {
} }
impl NavigationTarget { impl NavigationTarget {
pub fn name(&self) -> SmolStr {
self.symbol.name.clone()
}
pub fn kind(&self) -> SyntaxKind {
self.symbol.kind
}
pub fn file_id(&self) -> FileId { pub fn file_id(&self) -> FileId {
self.file_id self.file_id
} }
@ -337,8 +343,14 @@ impl Analysis {
let file = self.imp.file_syntax(file_id); let file = self.imp.file_syntax(file_id);
ra_editor::folding_ranges(&file) ra_editor::folding_ranges(&file)
} }
pub fn symbol_search(&self, query: Query) -> Cancelable<Vec<(FileId, FileSymbol)>> { pub fn symbol_search(&self, query: Query) -> Cancelable<Vec<NavigationTarget>> {
self.imp.world_symbols(query) let res = self
.imp
.world_symbols(query)?
.into_iter()
.map(|(file_id, symbol)| NavigationTarget { file_id, symbol })
.collect();
Ok(res)
} }
pub fn approximately_resolve_symbol( pub fn approximately_resolve_symbol(
&self, &self,
@ -352,7 +364,7 @@ impl Analysis {
pub fn doc_text_for(&self, nav: NavigationTarget) -> Cancelable<Option<String>> { pub fn doc_text_for(&self, nav: NavigationTarget) -> Cancelable<Option<String>> {
self.imp.doc_text_for(nav) self.imp.doc_text_for(nav)
} }
pub fn parent_module(&self, position: FilePosition) -> Cancelable<Vec<(FileId, FileSymbol)>> { pub fn parent_module(&self, position: FilePosition) -> Cancelable<Vec<NavigationTarget>> {
self.imp.parent_module(position) self.imp.parent_module(position)
} }
pub fn module_path(&self, position: FilePosition) -> Cancelable<Option<String>> { pub fn module_path(&self, position: FilePosition) -> Cancelable<Option<String>> {

View file

@ -2,7 +2,7 @@ use languageserver_types::{
self, Location, Position, Range, SymbolKind, TextDocumentEdit, TextDocumentIdentifier, self, Location, Position, Range, SymbolKind, TextDocumentEdit, TextDocumentIdentifier,
TextDocumentItem, TextDocumentPositionParams, Url, VersionedTextDocumentIdentifier, InsertTextFormat, TextDocumentItem, TextDocumentPositionParams, Url, VersionedTextDocumentIdentifier, InsertTextFormat,
}; };
use ra_analysis::{FileId, FileSystemEdit, SourceChange, SourceFileEdit, FilePosition,FileRange, CompletionItem, CompletionItemKind, InsertText}; use ra_analysis::{FileId, FileSystemEdit, SourceChange, SourceFileEdit, FilePosition,FileRange, CompletionItem, CompletionItemKind, InsertText, NavigationTarget};
use ra_editor::{LineCol, LineIndex, translate_offset_with_edit}; use ra_editor::{LineCol, LineIndex, translate_offset_with_edit};
use ra_text_edit::{AtomTextEdit, TextEdit}; use ra_text_edit::{AtomTextEdit, TextEdit};
use ra_syntax::{SyntaxKind, TextRange, TextUnit}; use ra_syntax::{SyntaxKind, TextRange, TextUnit};
@ -322,6 +322,15 @@ impl TryConvWith for FileSystemEdit {
} }
} }
impl TryConvWith for &NavigationTarget {
type Ctx = ServerWorld;
type Output = Location;
fn try_conv_with(self, world: &ServerWorld) -> Result<Location> {
let line_index = world.analysis().file_line_index(self.file_id());
to_location(self.file_id(), self.range(), &world, &line_index)
}
}
pub fn to_location( pub fn to_location(
file_id: FileId, file_id: FileId,
range: TextRange, range: TextRange,

View file

@ -188,12 +188,11 @@ pub fn handle_workspace_symbol(
fn exec_query(world: &ServerWorld, query: Query) -> Result<Vec<SymbolInformation>> { fn exec_query(world: &ServerWorld, query: Query) -> Result<Vec<SymbolInformation>> {
let mut res = Vec::new(); let mut res = Vec::new();
for (file_id, symbol) in world.analysis().symbol_search(query)? { for nav in world.analysis().symbol_search(query)? {
let line_index = world.analysis().file_line_index(file_id);
let info = SymbolInformation { let info = SymbolInformation {
name: symbol.name.to_string(), name: nav.name().into(),
kind: symbol.kind.conv(), kind: nav.kind().conv(),
location: to_location(file_id, symbol.node_range, world, &line_index)?, location: nav.try_conv_with(world)?,
container_name: None, container_name: None,
deprecated: None, deprecated: None,
}; };
@ -212,12 +211,11 @@ pub fn handle_goto_definition(
None => return Ok(None), None => return Ok(None),
Some(it) => it, Some(it) => it,
}; };
let mut res = Vec::new(); let res = rr
for nav in rr.resolves_to { .resolves_to
let line_index = world.analysis().file_line_index(nav.file_id()); .into_iter()
let location = to_location(nav.file_id(), nav.range(), &world, &line_index)?; .map(|nav| nav.try_conv_with(&world))
res.push(location) .collect::<Result<Vec<_>>>()?;
}
Ok(Some(req::GotoDefinitionResponse::Array(res))) Ok(Some(req::GotoDefinitionResponse::Array(res)))
} }
@ -226,13 +224,12 @@ 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)?;
let mut res = Vec::new(); world
for (file_id, symbol) in world.analysis().parent_module(position)? { .analysis()
let line_index = world.analysis().file_line_index(file_id); .parent_module(position)?
let location = to_location(file_id, symbol.node_range, &world, &line_index)?; .into_iter()
res.push(location); .map(|nav| nav.try_conv_with(&world))
} .collect::<Result<Vec<_>>>()
Ok(res)
} }
pub fn handle_runnables( pub fn handle_runnables(