From f848aa97ab9d9789f72828d28619dd4227c352b9 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 11 Jan 2019 12:53:16 +0300 Subject: group feature modules --- crates/ra_ide_api/src/lib.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'crates') diff --git a/crates/ra_ide_api/src/lib.rs b/crates/ra_ide_api/src/lib.rs index 65d21d899..f2439bfd7 100644 --- a/crates/ra_ide_api/src/lib.rs +++ b/crates/ra_ide_api/src/lib.rs @@ -18,14 +18,14 @@ macro_rules! ctry { }; } -mod completion; mod db; -mod goto_definition; mod imp; pub mod mock_analysis; -mod runnables; mod symbol_index; +mod completion; +mod runnables; +mod goto_definition; mod extend_selection; mod hover; mod call_info; -- cgit v1.2.3 From 2aa125251ebd74c0e2a119b351caec27a9e1da46 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 11 Jan 2019 13:01:35 +0300 Subject: move nav to a separate file --- crates/ra_ide_api/src/lib.rs | 75 +------------------------- crates/ra_ide_api/src/navigation_target.rs | 86 ++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+), 73 deletions(-) create mode 100644 crates/ra_ide_api/src/navigation_target.rs (limited to 'crates') diff --git a/crates/ra_ide_api/src/lib.rs b/crates/ra_ide_api/src/lib.rs index f2439bfd7..2e1768951 100644 --- a/crates/ra_ide_api/src/lib.rs +++ b/crates/ra_ide_api/src/lib.rs @@ -22,6 +22,7 @@ mod db; mod imp; pub mod mock_analysis; mod symbol_index; +mod navigation_target; mod completion; mod runnables; @@ -33,8 +34,7 @@ mod syntax_highlighting; use std::{fmt, sync::Arc}; -use hir::{Def, ModuleSource, Name}; -use ra_syntax::{SmolStr, SourceFile, TreePtr, SyntaxKind, SyntaxNode, TextRange, TextUnit, AstNode}; +use ra_syntax::{SmolStr, SourceFile, TreePtr, SyntaxKind, TextRange, TextUnit}; use ra_text_edit::TextEdit; use ra_db::{SyntaxDatabase, FilesDatabase, LocalSyntaxPtr, BaseDatabase}; use rayon::prelude::*; @@ -259,77 +259,6 @@ pub struct NavigationTarget { } impl NavigationTarget { - fn from_symbol(symbol: FileSymbol) -> NavigationTarget { - NavigationTarget { - file_id: symbol.file_id, - name: symbol.name.clone(), - kind: symbol.ptr.kind(), - range: symbol.ptr.range(), - ptr: Some(symbol.ptr.clone()), - } - } - - fn from_syntax(name: Option, file_id: FileId, node: &SyntaxNode) -> NavigationTarget { - NavigationTarget { - file_id, - name: name.map(|n| n.to_string().into()).unwrap_or("".into()), - kind: node.kind(), - range: node.range(), - ptr: Some(LocalSyntaxPtr::new(node)), - } - } - // TODO once Def::Item is gone, this should be able to always return a NavigationTarget - fn from_def(db: &db::RootDatabase, def: Def) -> Cancelable> { - Ok(match def { - Def::Struct(s) => { - let (file_id, node) = s.source(db)?; - Some(NavigationTarget::from_syntax( - s.name(db)?, - file_id.original_file(db), - node.syntax(), - )) - } - Def::Enum(e) => { - let (file_id, node) = e.source(db)?; - Some(NavigationTarget::from_syntax( - e.name(db)?, - file_id.original_file(db), - node.syntax(), - )) - } - Def::EnumVariant(ev) => { - let (file_id, node) = ev.source(db)?; - Some(NavigationTarget::from_syntax( - ev.name(db)?, - file_id.original_file(db), - node.syntax(), - )) - } - Def::Function(f) => { - let (file_id, node) = f.source(db)?; - let name = f.signature(db).name().clone(); - Some(NavigationTarget::from_syntax( - Some(name), - file_id.original_file(db), - node.syntax(), - )) - } - Def::Module(m) => { - let (file_id, source) = m.definition_source(db)?; - let name = m.name(db)?; - match source { - ModuleSource::SourceFile(node) => { - Some(NavigationTarget::from_syntax(name, file_id, node.syntax())) - } - ModuleSource::Module(node) => { - Some(NavigationTarget::from_syntax(name, file_id, node.syntax())) - } - } - } - Def::Item => None, - }) - } - pub fn name(&self) -> &SmolStr { &self.name } diff --git a/crates/ra_ide_api/src/navigation_target.rs b/crates/ra_ide_api/src/navigation_target.rs new file mode 100644 index 000000000..bacb7329f --- /dev/null +++ b/crates/ra_ide_api/src/navigation_target.rs @@ -0,0 +1,86 @@ +use ra_db::{FileId, LocalSyntaxPtr, Cancelable}; +use ra_syntax::{SyntaxNode, AstNode}; +use hir::{Name, Def, ModuleSource}; + +use crate::{ + NavigationTarget, + FileSymbol, + db::RootDatabase, +}; + +impl NavigationTarget { + pub(crate) fn from_symbol(symbol: FileSymbol) -> NavigationTarget { + NavigationTarget { + file_id: symbol.file_id, + name: symbol.name.clone(), + kind: symbol.ptr.kind(), + range: symbol.ptr.range(), + ptr: Some(symbol.ptr.clone()), + } + } + + pub(crate) fn from_syntax( + name: Option, + file_id: FileId, + node: &SyntaxNode, + ) -> NavigationTarget { + NavigationTarget { + file_id, + name: name.map(|n| n.to_string().into()).unwrap_or("".into()), + kind: node.kind(), + range: node.range(), + ptr: Some(LocalSyntaxPtr::new(node)), + } + } + // TODO once Def::Item is gone, this should be able to always return a NavigationTarget + pub(crate) fn from_def(db: &RootDatabase, def: Def) -> Cancelable> { + Ok(match def { + Def::Struct(s) => { + let (file_id, node) = s.source(db)?; + Some(NavigationTarget::from_syntax( + s.name(db)?, + file_id.original_file(db), + node.syntax(), + )) + } + Def::Enum(e) => { + let (file_id, node) = e.source(db)?; + Some(NavigationTarget::from_syntax( + e.name(db)?, + file_id.original_file(db), + node.syntax(), + )) + } + Def::EnumVariant(ev) => { + let (file_id, node) = ev.source(db)?; + Some(NavigationTarget::from_syntax( + ev.name(db)?, + file_id.original_file(db), + node.syntax(), + )) + } + Def::Function(f) => { + let (file_id, node) = f.source(db)?; + let name = f.signature(db).name().clone(); + Some(NavigationTarget::from_syntax( + Some(name), + file_id.original_file(db), + node.syntax(), + )) + } + Def::Module(m) => { + let (file_id, source) = m.definition_source(db)?; + let name = m.name(db)?; + match source { + ModuleSource::SourceFile(node) => { + Some(NavigationTarget::from_syntax(name, file_id, node.syntax())) + } + ModuleSource::Module(node) => { + Some(NavigationTarget::from_syntax(name, file_id, node.syntax())) + } + } + } + Def::Item => None, + }) + } +} -- cgit v1.2.3 From df6bbc6e420e869c4a3a6effb21170c952727d04 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 11 Jan 2019 13:05:45 +0300 Subject: Make from_syntax private --- crates/ra_ide_api/src/lib.rs | 2 +- crates/ra_ide_api/src/navigation_target.rs | 23 ++++++++++------------- 2 files changed, 11 insertions(+), 14 deletions(-) (limited to 'crates') diff --git a/crates/ra_ide_api/src/lib.rs b/crates/ra_ide_api/src/lib.rs index 2e1768951..9c5a82187 100644 --- a/crates/ra_ide_api/src/lib.rs +++ b/crates/ra_ide_api/src/lib.rs @@ -243,7 +243,7 @@ impl Query { } } -/// `NavigationTarget` represents and element in the editor's UI whihc you can +/// `NavigationTarget` represents and element in the editor's UI which you can /// click on to navigate to a particular piece of code. /// /// Typically, a `NavigationTarget` corresponds to some element in the source diff --git a/crates/ra_ide_api/src/navigation_target.rs b/crates/ra_ide_api/src/navigation_target.rs index bacb7329f..eaf46fd01 100644 --- a/crates/ra_ide_api/src/navigation_target.rs +++ b/crates/ra_ide_api/src/navigation_target.rs @@ -19,19 +19,6 @@ impl NavigationTarget { } } - pub(crate) fn from_syntax( - name: Option, - file_id: FileId, - node: &SyntaxNode, - ) -> NavigationTarget { - NavigationTarget { - file_id, - name: name.map(|n| n.to_string().into()).unwrap_or("".into()), - kind: node.kind(), - range: node.range(), - ptr: Some(LocalSyntaxPtr::new(node)), - } - } // TODO once Def::Item is gone, this should be able to always return a NavigationTarget pub(crate) fn from_def(db: &RootDatabase, def: Def) -> Cancelable> { Ok(match def { @@ -83,4 +70,14 @@ impl NavigationTarget { Def::Item => None, }) } + + fn from_syntax(name: Option, file_id: FileId, node: &SyntaxNode) -> NavigationTarget { + NavigationTarget { + file_id, + name: name.map(|n| n.to_string().into()).unwrap_or("".into()), + kind: node.kind(), + range: node.range(), + ptr: Some(LocalSyntaxPtr::new(node)), + } + } } -- cgit v1.2.3 From 7b143779653ac6dfe094f7cf0c9967e1c0a81318 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 11 Jan 2019 13:28:59 +0300 Subject: refactor nav target --- crates/ra_ide_api/src/navigation_target.rs | 49 ++++++++++++++++++------------ 1 file changed, 29 insertions(+), 20 deletions(-) (limited to 'crates') diff --git a/crates/ra_ide_api/src/navigation_target.rs b/crates/ra_ide_api/src/navigation_target.rs index eaf46fd01..cff11eeab 100644 --- a/crates/ra_ide_api/src/navigation_target.rs +++ b/crates/ra_ide_api/src/navigation_target.rs @@ -1,6 +1,9 @@ use ra_db::{FileId, LocalSyntaxPtr, Cancelable}; -use ra_syntax::{SyntaxNode, AstNode}; -use hir::{Name, Def, ModuleSource}; +use ra_syntax::{ + SyntaxNode, AstNode, SmolStr, + ast +}; +use hir::{Def, ModuleSource}; use crate::{ NavigationTarget, @@ -24,46 +27,44 @@ impl NavigationTarget { Ok(match def { Def::Struct(s) => { let (file_id, node) = s.source(db)?; - Some(NavigationTarget::from_syntax( - s.name(db)?, + Some(NavigationTarget::from_named( file_id.original_file(db), - node.syntax(), + &*node, )) } Def::Enum(e) => { let (file_id, node) = e.source(db)?; - Some(NavigationTarget::from_syntax( - e.name(db)?, + Some(NavigationTarget::from_named( file_id.original_file(db), - node.syntax(), + &*node, )) } Def::EnumVariant(ev) => { let (file_id, node) = ev.source(db)?; - Some(NavigationTarget::from_syntax( - ev.name(db)?, + Some(NavigationTarget::from_named( file_id.original_file(db), - node.syntax(), + &*node, )) } Def::Function(f) => { let (file_id, node) = f.source(db)?; - let name = f.signature(db).name().clone(); - Some(NavigationTarget::from_syntax( - Some(name), + Some(NavigationTarget::from_named( file_id.original_file(db), - node.syntax(), + &*node, )) } Def::Module(m) => { let (file_id, source) = m.definition_source(db)?; - let name = m.name(db)?; + let name = m + .name(db)? + .map(|it| it.to_string().into()) + .unwrap_or_else(|| SmolStr::new("")); match source { ModuleSource::SourceFile(node) => { - Some(NavigationTarget::from_syntax(name, file_id, node.syntax())) + Some(NavigationTarget::from_syntax(file_id, name, node.syntax())) } ModuleSource::Module(node) => { - Some(NavigationTarget::from_syntax(name, file_id, node.syntax())) + Some(NavigationTarget::from_syntax(file_id, name, node.syntax())) } } } @@ -71,10 +72,18 @@ impl NavigationTarget { }) } - fn from_syntax(name: Option, file_id: FileId, node: &SyntaxNode) -> NavigationTarget { + fn from_named(file_id: FileId, node: &impl ast::NameOwner) -> NavigationTarget { + let name = node + .name() + .map(|it| it.text().clone()) + .unwrap_or_else(|| SmolStr::new("")); + NavigationTarget::from_syntax(file_id, name, node.syntax()) + } + + fn from_syntax(file_id: FileId, name: SmolStr, node: &SyntaxNode) -> NavigationTarget { NavigationTarget { file_id, - name: name.map(|n| n.to_string().into()).unwrap_or("".into()), + name, kind: node.kind(), range: node.range(), ptr: Some(LocalSyntaxPtr::new(node)), -- cgit v1.2.3 From a5dd04078e6be1e3a874a2c9017d824f5a067315 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 11 Jan 2019 13:29:53 +0300 Subject: reshuffle nones --- crates/ra_ide_api/src/navigation_target.rs | 31 ++++++++++-------------------- 1 file changed, 10 insertions(+), 21 deletions(-) (limited to 'crates') diff --git a/crates/ra_ide_api/src/navigation_target.rs b/crates/ra_ide_api/src/navigation_target.rs index cff11eeab..b2a53e9aa 100644 --- a/crates/ra_ide_api/src/navigation_target.rs +++ b/crates/ra_ide_api/src/navigation_target.rs @@ -24,34 +24,22 @@ impl NavigationTarget { // TODO once Def::Item is gone, this should be able to always return a NavigationTarget pub(crate) fn from_def(db: &RootDatabase, def: Def) -> Cancelable> { - Ok(match def { + let res = match def { Def::Struct(s) => { let (file_id, node) = s.source(db)?; - Some(NavigationTarget::from_named( - file_id.original_file(db), - &*node, - )) + NavigationTarget::from_named(file_id.original_file(db), &*node) } Def::Enum(e) => { let (file_id, node) = e.source(db)?; - Some(NavigationTarget::from_named( - file_id.original_file(db), - &*node, - )) + NavigationTarget::from_named(file_id.original_file(db), &*node) } Def::EnumVariant(ev) => { let (file_id, node) = ev.source(db)?; - Some(NavigationTarget::from_named( - file_id.original_file(db), - &*node, - )) + NavigationTarget::from_named(file_id.original_file(db), &*node) } Def::Function(f) => { let (file_id, node) = f.source(db)?; - Some(NavigationTarget::from_named( - file_id.original_file(db), - &*node, - )) + NavigationTarget::from_named(file_id.original_file(db), &*node) } Def::Module(m) => { let (file_id, source) = m.definition_source(db)?; @@ -61,15 +49,16 @@ impl NavigationTarget { .unwrap_or_else(|| SmolStr::new("")); match source { ModuleSource::SourceFile(node) => { - Some(NavigationTarget::from_syntax(file_id, name, node.syntax())) + NavigationTarget::from_syntax(file_id, name, node.syntax()) } ModuleSource::Module(node) => { - Some(NavigationTarget::from_syntax(file_id, name, node.syntax())) + NavigationTarget::from_syntax(file_id, name, node.syntax()) } } } - Def::Item => None, - }) + Def::Item => return Ok(None), + }; + Ok(Some(res)) } fn from_named(file_id: FileId, node: &impl ast::NameOwner) -> NavigationTarget { -- cgit v1.2.3 From 1d3d05d5d70943d8b1356a7e2c8d8b63a1ec470d Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 11 Jan 2019 13:31:21 +0300 Subject: simplify --- crates/ra_ide_api/src/navigation_target.rs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'crates') diff --git a/crates/ra_ide_api/src/navigation_target.rs b/crates/ra_ide_api/src/navigation_target.rs index b2a53e9aa..09a723d68 100644 --- a/crates/ra_ide_api/src/navigation_target.rs +++ b/crates/ra_ide_api/src/navigation_target.rs @@ -46,7 +46,7 @@ impl NavigationTarget { let name = m .name(db)? .map(|it| it.to_string().into()) - .unwrap_or_else(|| SmolStr::new("")); + .unwrap_or_default(); match source { ModuleSource::SourceFile(node) => { NavigationTarget::from_syntax(file_id, name, node.syntax()) @@ -62,10 +62,7 @@ impl NavigationTarget { } fn from_named(file_id: FileId, node: &impl ast::NameOwner) -> NavigationTarget { - let name = node - .name() - .map(|it| it.text().clone()) - .unwrap_or_else(|| SmolStr::new("")); + let name = node.name().map(|it| it.text().clone()).unwrap_or_default(); NavigationTarget::from_syntax(file_id, name, node.syntax()) } -- cgit v1.2.3 From f9ed8d4d23cd210f24ca303c72b436bfbe84741f Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 11 Jan 2019 14:00:54 +0300 Subject: envapsulate navigation target better --- crates/ra_hir/src/code_model_api.rs | 2 + crates/ra_hir/src/code_model_impl/function.rs | 2 +- crates/ra_hir/src/lib.rs | 2 +- crates/ra_ide_api/src/goto_definition.rs | 23 +----- crates/ra_ide_api/src/hover.rs | 4 +- crates/ra_ide_api/src/imp.rs | 15 +--- crates/ra_ide_api/src/lib.rs | 38 +-------- crates/ra_ide_api/src/navigation_target.rs | 112 ++++++++++++++++++++------ 8 files changed, 102 insertions(+), 96 deletions(-) (limited to 'crates') diff --git a/crates/ra_hir/src/code_model_api.rs b/crates/ra_hir/src/code_model_api.rs index e69f546ff..8ec6b9b2b 100644 --- a/crates/ra_hir/src/code_model_api.rs +++ b/crates/ra_hir/src/code_model_api.rs @@ -274,6 +274,8 @@ pub struct Function { pub(crate) def_id: DefId, } +pub use crate::code_model_impl::function::ScopeEntryWithSyntax; + /// The declared signature of a function. #[derive(Debug, Clone, PartialEq, Eq)] pub struct FnSignature { diff --git a/crates/ra_hir/src/code_model_impl/function.rs b/crates/ra_hir/src/code_model_impl/function.rs index 1bd4cc802..009175bab 100644 --- a/crates/ra_hir/src/code_model_impl/function.rs +++ b/crates/ra_hir/src/code_model_impl/function.rs @@ -15,7 +15,7 @@ use crate::{ impl_block::ImplBlock, }; -pub use self::scope::{FnScopes, ScopesWithSyntaxMapping}; +pub use self::scope::{FnScopes, ScopesWithSyntaxMapping, ScopeEntryWithSyntax}; impl Function { pub(crate) fn new(def_id: DefId) -> Function { diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs index 1aca2f067..fe8be5700 100644 --- a/crates/ra_hir/src/lib.rs +++ b/crates/ra_hir/src/lib.rs @@ -59,5 +59,5 @@ pub use self::code_model_api::{ Def, Module, ModuleSource, Problem, Struct, Enum, EnumVariant, - Function, FnSignature, + Function, FnSignature, ScopeEntryWithSyntax, }; diff --git a/crates/ra_ide_api/src/goto_definition.rs b/crates/ra_ide_api/src/goto_definition.rs index eaddd5083..4706dc733 100644 --- a/crates/ra_ide_api/src/goto_definition.rs +++ b/crates/ra_ide_api/src/goto_definition.rs @@ -1,6 +1,6 @@ use ra_db::{FileId, Cancelable, SyntaxDatabase}; use ra_syntax::{ - TextRange, AstNode, ast, SyntaxKind::{NAME, MODULE}, + AstNode, ast, algo::find_node_at_offset, }; @@ -32,13 +32,7 @@ pub(crate) fn reference_definition( let scope = fn_descr.scopes(db)?; // First try to resolve the symbol locally if let Some(entry) = scope.resolve_local_name(name_ref) { - let nav = NavigationTarget { - file_id, - name: entry.name().to_string().into(), - range: entry.ptr().range(), - kind: NAME, - ptr: None, - }; + let nav = NavigationTarget::from_scope_entry(file_id, &entry); return Ok(vec![nav]); }; } @@ -79,18 +73,7 @@ fn name_definition( if let Some(child_module) = hir::source_binder::module_from_declaration(db, file_id, module)? { - let (file_id, _) = child_module.definition_source(db)?; - let name = match child_module.name(db)? { - Some(name) => name.to_string().into(), - None => "".into(), - }; - let nav = NavigationTarget { - file_id, - name, - range: TextRange::offset_len(0.into(), 0.into()), - kind: MODULE, - ptr: None, - }; + let nav = NavigationTarget::from_module(db, child_module)?; return Ok(Some(vec![nav])); } } diff --git a/crates/ra_ide_api/src/hover.rs b/crates/ra_ide_api/src/hover.rs index 41309e756..9b06a0e58 100644 --- a/crates/ra_ide_api/src/hover.rs +++ b/crates/ra_ide_api/src/hover.rs @@ -88,11 +88,11 @@ fn doc_text_for(db: &RootDatabase, nav: NavigationTarget) -> Cancelable Option> { - let source_file = db.source_file(self.file_id); + let source_file = db.source_file(self.file_id()); let source_file = source_file.syntax(); let node = source_file .descendants() - .find(|node| node.kind() == self.kind && node.range() == self.range)? + .find(|node| node.kind() == self.kind() && node.range() == self.range())? .to_owned(); Some(node) } diff --git a/crates/ra_ide_api/src/imp.rs b/crates/ra_ide_api/src/imp.rs index 7c60ab7d6..12bfe1761 100644 --- a/crates/ra_ide_api/src/imp.rs +++ b/crates/ra_ide_api/src/imp.rs @@ -11,7 +11,6 @@ use ra_syntax::{ TextRange, AstNode, SourceFile, ast::{self, NameOwner}, algo::find_node_at_offset, - SyntaxKind::*, }; use crate::{ @@ -109,18 +108,8 @@ impl db::RootDatabase { None => return Ok(Vec::new()), Some(it) => it, }; - let (file_id, ast_module) = match module.declaration_source(self)? { - None => return Ok(Vec::new()), - Some(it) => it, - }; - let name = ast_module.name().unwrap(); - Ok(vec![NavigationTarget { - file_id, - name: name.text().clone(), - range: name.syntax().range(), - kind: MODULE, - ptr: None, - }]) + let nav = NavigationTarget::from_module(self, module)?; + Ok(vec![nav]) } /// Returns `Vec` for the same reason as `parent_module` pub(crate) fn crate_for(&self, file_id: FileId) -> Cancelable> { diff --git a/crates/ra_ide_api/src/lib.rs b/crates/ra_ide_api/src/lib.rs index 9c5a82187..2873bab36 100644 --- a/crates/ra_ide_api/src/lib.rs +++ b/crates/ra_ide_api/src/lib.rs @@ -34,9 +34,9 @@ mod syntax_highlighting; use std::{fmt, sync::Arc}; -use ra_syntax::{SmolStr, SourceFile, TreePtr, SyntaxKind, TextRange, TextUnit}; +use ra_syntax::{SourceFile, TreePtr, TextRange, TextUnit}; use ra_text_edit::TextEdit; -use ra_db::{SyntaxDatabase, FilesDatabase, LocalSyntaxPtr, BaseDatabase}; +use ra_db::{SyntaxDatabase, FilesDatabase, BaseDatabase}; use rayon::prelude::*; use relative_path::RelativePathBuf; use rustc_hash::FxHashMap; @@ -50,6 +50,7 @@ use crate::{ pub use crate::{ completion::{CompletionItem, CompletionItemKind, InsertText}, runnables::{Runnable, RunnableKind}, + navigation_target::NavigationTarget, }; pub use ra_ide_api_light::{ Fold, FoldKind, HighlightedRange, Severity, StructureNode, @@ -243,39 +244,6 @@ impl Query { } } -/// `NavigationTarget` represents and element in the editor's UI which you can -/// click on to navigate to a particular piece of code. -/// -/// Typically, a `NavigationTarget` corresponds to some element in the source -/// code, like a function or a struct, but this is not strictly required. -#[derive(Debug, Clone)] -pub struct NavigationTarget { - file_id: FileId, - name: SmolStr, - kind: SyntaxKind, - range: TextRange, - // Should be DefId ideally - ptr: Option, -} - -impl NavigationTarget { - pub fn name(&self) -> &SmolStr { - &self.name - } - - pub fn kind(&self) -> SyntaxKind { - self.kind - } - - pub fn file_id(&self) -> FileId { - self.file_id - } - - pub fn range(&self) -> TextRange { - self.range - } -} - #[derive(Debug)] pub struct RangeInfo { pub range: TextRange, diff --git a/crates/ra_ide_api/src/navigation_target.rs b/crates/ra_ide_api/src/navigation_target.rs index 09a723d68..943e62eb8 100644 --- a/crates/ra_ide_api/src/navigation_target.rs +++ b/crates/ra_ide_api/src/navigation_target.rs @@ -1,27 +1,98 @@ use ra_db::{FileId, LocalSyntaxPtr, Cancelable}; use ra_syntax::{ - SyntaxNode, AstNode, SmolStr, - ast + SyntaxNode, AstNode, SmolStr, TextRange, ast, + SyntaxKind::{self, NAME}, }; use hir::{Def, ModuleSource}; -use crate::{ - NavigationTarget, - FileSymbol, - db::RootDatabase, -}; +use crate::{FileSymbol, db::RootDatabase}; + +/// `NavigationTarget` represents and element in the editor's UI which you can +/// click on to navigate to a particular piece of code. +/// +/// Typically, a `NavigationTarget` corresponds to some element in the source +/// code, like a function or a struct, but this is not strictly required. +#[derive(Debug, Clone)] +pub struct NavigationTarget { + file_id: FileId, + name: SmolStr, + kind: SyntaxKind, + range: TextRange, + focus_range: Option, + // Should be DefId ideally + ptr: Option, +} impl NavigationTarget { + pub fn name(&self) -> &SmolStr { + &self.name + } + + pub fn kind(&self) -> SyntaxKind { + self.kind + } + + pub fn file_id(&self) -> FileId { + self.file_id + } + + pub fn range(&self) -> TextRange { + self.range + } + + /// A "most interesting" range withing the `range`. + /// + /// Typically, `range` is the whole syntax node, including doc comments, and + /// `focus_range` is the range of the identifier. + pub fn focus_range(&self) -> Option { + self.focus_range + } + pub(crate) fn from_symbol(symbol: FileSymbol) -> NavigationTarget { NavigationTarget { file_id: symbol.file_id, name: symbol.name.clone(), kind: symbol.ptr.kind(), range: symbol.ptr.range(), + focus_range: None, ptr: Some(symbol.ptr.clone()), } } + pub(crate) fn from_scope_entry( + file_id: FileId, + entry: &hir::ScopeEntryWithSyntax, + ) -> NavigationTarget { + NavigationTarget { + file_id, + name: entry.name().to_string().into(), + range: entry.ptr().range(), + focus_range: None, + kind: NAME, + ptr: None, + } + } + + pub(crate) fn from_module( + db: &RootDatabase, + module: hir::Module, + ) -> Cancelable { + let (file_id, source) = module.definition_source(db)?; + let name = module + .name(db)? + .map(|it| it.to_string().into()) + .unwrap_or_default(); + let res = match source { + ModuleSource::SourceFile(node) => { + NavigationTarget::from_syntax(file_id, name, None, node.syntax()) + } + ModuleSource::Module(node) => { + NavigationTarget::from_syntax(file_id, name, None, node.syntax()) + } + }; + Ok(res) + } + // TODO once Def::Item is gone, this should be able to always return a NavigationTarget pub(crate) fn from_def(db: &RootDatabase, def: Def) -> Cancelable> { let res = match def { @@ -41,21 +112,7 @@ impl NavigationTarget { let (file_id, node) = f.source(db)?; NavigationTarget::from_named(file_id.original_file(db), &*node) } - Def::Module(m) => { - let (file_id, source) = m.definition_source(db)?; - let name = m - .name(db)? - .map(|it| it.to_string().into()) - .unwrap_or_default(); - match source { - ModuleSource::SourceFile(node) => { - NavigationTarget::from_syntax(file_id, name, node.syntax()) - } - ModuleSource::Module(node) => { - NavigationTarget::from_syntax(file_id, name, node.syntax()) - } - } - } + Def::Module(m) => NavigationTarget::from_module(db, m)?, Def::Item => return Ok(None), }; Ok(Some(res)) @@ -63,15 +120,22 @@ impl NavigationTarget { fn from_named(file_id: FileId, node: &impl ast::NameOwner) -> NavigationTarget { let name = node.name().map(|it| it.text().clone()).unwrap_or_default(); - NavigationTarget::from_syntax(file_id, name, node.syntax()) + let focus_range = node.name().map(|it| it.syntax().range()); + NavigationTarget::from_syntax(file_id, name, focus_range, node.syntax()) } - fn from_syntax(file_id: FileId, name: SmolStr, node: &SyntaxNode) -> NavigationTarget { + fn from_syntax( + file_id: FileId, + name: SmolStr, + focus_range: Option, + node: &SyntaxNode, + ) -> NavigationTarget { NavigationTarget { file_id, name, kind: node.kind(), range: node.range(), + focus_range, ptr: Some(LocalSyntaxPtr::new(node)), } } -- cgit v1.2.3 From 3aaf20bd6ec75a572b13d020520d4df563a2891c Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 11 Jan 2019 14:14:09 +0300 Subject: return ref ranges from gotodef --- crates/ra_ide_api/src/goto_definition.rs | 10 ++++++---- crates/ra_ide_api/src/lib.rs | 4 ++-- crates/ra_lsp_server/src/conv.rs | 11 ++++++++++- crates/ra_lsp_server/src/main_loop/handlers.rs | 9 ++++++--- 4 files changed, 24 insertions(+), 10 deletions(-) (limited to 'crates') diff --git a/crates/ra_ide_api/src/goto_definition.rs b/crates/ra_ide_api/src/goto_definition.rs index 4706dc733..3fb29950b 100644 --- a/crates/ra_ide_api/src/goto_definition.rs +++ b/crates/ra_ide_api/src/goto_definition.rs @@ -4,19 +4,21 @@ use ra_syntax::{ algo::find_node_at_offset, }; -use crate::{FilePosition, NavigationTarget, db::RootDatabase}; +use crate::{FilePosition, NavigationTarget, db::RootDatabase, RangeInfo}; pub(crate) fn goto_definition( db: &RootDatabase, position: FilePosition, -) -> Cancelable>> { +) -> Cancelable>>> { let file = db.source_file(position.file_id); let syntax = file.syntax(); if let Some(name_ref) = find_node_at_offset::(syntax, position.offset) { - return Ok(Some(reference_definition(db, position.file_id, name_ref)?)); + let navs = reference_definition(db, position.file_id, name_ref)?; + return Ok(Some(RangeInfo::new(name_ref.syntax().range(), navs))); } if let Some(name) = find_node_at_offset::(syntax, position.offset) { - return name_definition(db, position.file_id, name); + let navs = ctry!(name_definition(db, position.file_id, name)?); + return Ok(Some(RangeInfo::new(name.syntax().range(), navs))); } Ok(None) } diff --git a/crates/ra_ide_api/src/lib.rs b/crates/ra_ide_api/src/lib.rs index 2873bab36..2b02dab2a 100644 --- a/crates/ra_ide_api/src/lib.rs +++ b/crates/ra_ide_api/src/lib.rs @@ -251,7 +251,7 @@ pub struct RangeInfo { } impl RangeInfo { - fn new(range: TextRange, info: T) -> RangeInfo { + pub fn new(range: TextRange, info: T) -> RangeInfo { RangeInfo { range, info } } } @@ -391,7 +391,7 @@ impl Analysis { pub fn goto_definition( &self, position: FilePosition, - ) -> Cancelable>> { + ) -> Cancelable>>> { self.db .catch_canceled(|db| goto_definition::goto_definition(db, position))? } diff --git a/crates/ra_lsp_server/src/conv.rs b/crates/ra_lsp_server/src/conv.rs index 35c679a4a..0b9b18cbf 100644 --- a/crates/ra_lsp_server/src/conv.rs +++ b/crates/ra_lsp_server/src/conv.rs @@ -6,7 +6,7 @@ use languageserver_types::{ }; use ra_ide_api::{ CompletionItem, CompletionItemKind, FileId, FilePosition, FileRange, FileSystemEdit, - InsertText, NavigationTarget, SourceChange, SourceFileEdit, + InsertText, NavigationTarget, SourceChange, SourceFileEdit, RangeInfo, LineCol, LineIndex, translate_offset_with_edit }; use ra_syntax::{SyntaxKind, TextRange, TextUnit}; @@ -349,6 +349,15 @@ impl TryConvWith for &NavigationTarget { } } +impl TryConvWith for &RangeInfo { + type Ctx = ServerWorld; + type Output = Location; + fn try_conv_with(self, world: &ServerWorld) -> Result { + let line_index = world.analysis().file_line_index(self.info.file_id()); + to_location(self.info.file_id(), self.info.range(), &world, &line_index) + } +} + pub fn to_location( file_id: FileId, range: TextRange, diff --git a/crates/ra_lsp_server/src/main_loop/handlers.rs b/crates/ra_lsp_server/src/main_loop/handlers.rs index 5f4b27149..e3bf55ae7 100644 --- a/crates/ra_lsp_server/src/main_loop/handlers.rs +++ b/crates/ra_lsp_server/src/main_loop/handlers.rs @@ -9,7 +9,7 @@ use languageserver_types::{ SignatureInformation, SymbolInformation, TextDocumentIdentifier, TextEdit, WorkspaceEdit, }; use ra_ide_api::{ - FileId, FilePosition, FileRange, FoldKind, Query, RunnableKind, Severity, + FileId, FilePosition, FileRange, FoldKind, Query, RunnableKind, Severity, SourceChange, RangeInfo, }; use ra_syntax::{TextUnit, AstNode}; use rustc_hash::FxHashMap; @@ -208,12 +208,15 @@ pub fn handle_goto_definition( params: req::TextDocumentPositionParams, ) -> Result> { let position = params.try_conv_with(&world)?; - let navs = match world.analysis().goto_definition(position)? { + let nav_info = match world.analysis().goto_definition(position)? { None => return Ok(None), Some(it) => it, }; - let res = navs + let nav_range = nav_info.range; + let res = nav_info + .info .into_iter() + .map(|nav| RangeInfo::new(nav_range, nav)) .map(|nav| nav.try_conv_with(&world)) .collect::>>()?; Ok(Some(req::GotoDefinitionResponse::Array(res))) -- cgit v1.2.3 From 8a5f74a24f726a839f3a0e154cfadec23040e14c Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 11 Jan 2019 16:01:48 +0300 Subject: use location link in goto def --- crates/ra_lsp_server/src/conv.rs | 28 ++++++++++++++++++-------- crates/ra_lsp_server/src/main_loop/handlers.rs | 9 +++++---- 2 files changed, 25 insertions(+), 12 deletions(-) (limited to 'crates') diff --git a/crates/ra_lsp_server/src/conv.rs b/crates/ra_lsp_server/src/conv.rs index 0b9b18cbf..aad698da1 100644 --- a/crates/ra_lsp_server/src/conv.rs +++ b/crates/ra_lsp_server/src/conv.rs @@ -1,5 +1,5 @@ use languageserver_types::{ - self, CreateFile, DocumentChangeOperation, DocumentChanges, InsertTextFormat, Location, + self, CreateFile, DocumentChangeOperation, DocumentChanges, InsertTextFormat, Location, LocationLink, Position, Range, RenameFile, ResourceOp, SymbolKind, TextDocumentEdit, TextDocumentIdentifier, TextDocumentItem, TextDocumentPositionParams, Url, VersionedTextDocumentIdentifier, WorkspaceEdit, @@ -349,13 +349,25 @@ impl TryConvWith for &NavigationTarget { } } -impl TryConvWith for &RangeInfo { - type Ctx = ServerWorld; - type Output = Location; - fn try_conv_with(self, world: &ServerWorld) -> Result { - let line_index = world.analysis().file_line_index(self.info.file_id()); - to_location(self.info.file_id(), self.info.range(), &world, &line_index) - } +pub fn to_location_link( + target: &RangeInfo, + world: &ServerWorld, + // line index for original range file + line_index: &LineIndex, +) -> Result { + let url = target.info.file_id().try_conv_with(world)?; + let tgt_line_index = world.analysis().file_line_index(target.info.file_id()); + + let res = LocationLink { + origin_selection_range: Some(target.range.conv_with(line_index)), + target_uri: url.to_string(), + target_range: target.info.range().conv_with(&tgt_line_index), + target_selection_range: target + .info + .focus_range() + .map(|it| it.conv_with(&tgt_line_index)), + }; + Ok(res) } pub fn to_location( diff --git a/crates/ra_lsp_server/src/main_loop/handlers.rs b/crates/ra_lsp_server/src/main_loop/handlers.rs index e3bf55ae7..aad9d6568 100644 --- a/crates/ra_lsp_server/src/main_loop/handlers.rs +++ b/crates/ra_lsp_server/src/main_loop/handlers.rs @@ -9,7 +9,7 @@ use languageserver_types::{ SignatureInformation, SymbolInformation, TextDocumentIdentifier, TextEdit, WorkspaceEdit, }; use ra_ide_api::{ - FileId, FilePosition, FileRange, FoldKind, Query, RunnableKind, Severity, SourceChange, RangeInfo, + FileId, FilePosition, FileRange, FoldKind, Query, RunnableKind, Severity, RangeInfo, }; use ra_syntax::{TextUnit, AstNode}; use rustc_hash::FxHashMap; @@ -17,7 +17,7 @@ use serde_json::to_value; use std::io::Write; use crate::{ - conv::{to_location, Conv, ConvWith, MapConvWith, TryConvWith}, + conv::{to_location, to_location_link, Conv, ConvWith, MapConvWith, TryConvWith}, project_model::TargetKind, req::{self, Decoration}, server_world::ServerWorld, @@ -208,6 +208,7 @@ pub fn handle_goto_definition( params: req::TextDocumentPositionParams, ) -> Result> { 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)? { None => return Ok(None), Some(it) => it, @@ -217,9 +218,9 @@ pub fn handle_goto_definition( .info .into_iter() .map(|nav| RangeInfo::new(nav_range, nav)) - .map(|nav| nav.try_conv_with(&world)) + .map(|nav| to_location_link(&nav, &world, &line_index)) .collect::>>()?; - Ok(Some(req::GotoDefinitionResponse::Array(res))) + Ok(Some(req::GotoDefinitionResponse::Link(res))) } pub fn handle_parent_module( -- cgit v1.2.3 From dda916bc4d51383fcf84f736bd12c7a77c445fb0 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 11 Jan 2019 18:17:20 +0300 Subject: fix tests --- crates/ra_ide_api/src/goto_definition.rs | 54 +++++++++++------------------- crates/ra_ide_api/src/hover.rs | 2 +- crates/ra_ide_api/src/imp.rs | 15 +-------- crates/ra_ide_api/src/lib.rs | 3 +- crates/ra_ide_api/src/navigation_target.rs | 35 +++++++++++++++---- crates/ra_ide_api/src/parent_module.rs | 52 ++++++++++++++++++++++++++++ crates/ra_ide_api/tests/test/main.rs | 40 ++-------------------- crates/ra_lsp_server/src/conv.rs | 5 +-- 8 files changed, 108 insertions(+), 98 deletions(-) create mode 100644 crates/ra_ide_api/src/parent_module.rs (limited to 'crates') diff --git a/crates/ra_ide_api/src/goto_definition.rs b/crates/ra_ide_api/src/goto_definition.rs index 3fb29950b..8d2ff561a 100644 --- a/crates/ra_ide_api/src/goto_definition.rs +++ b/crates/ra_ide_api/src/goto_definition.rs @@ -85,31 +85,32 @@ fn name_definition( #[cfg(test)] mod tests { - use test_utils::assert_eq_dbg; use crate::mock_analysis::analysis_and_position; + fn check_goto(fixuture: &str, expected: &str) { + let (analysis, pos) = analysis_and_position(fixuture); + + let mut navs = analysis.goto_definition(pos).unwrap().unwrap().info; + assert_eq!(navs.len(), 1); + let nav = navs.pop().unwrap(); + nav.assert_match(expected); + } + #[test] fn goto_definition_works_in_items() { - let (analysis, pos) = analysis_and_position( + check_goto( " //- /lib.rs struct Foo; enum E { X(Foo<|>) } ", - ); - - let symbols = analysis.goto_definition(pos).unwrap().unwrap(); - assert_eq_dbg( - r#"[NavigationTarget { file_id: FileId(1), name: "Foo", - kind: STRUCT_DEF, range: [0; 11), - ptr: Some(LocalSyntaxPtr { range: [0; 11), kind: STRUCT_DEF }) }]"#, - &symbols, + "Foo STRUCT_DEF FileId(1) [0; 11) [7; 10)", ); } #[test] fn goto_definition_resolves_correct_name() { - let (analysis, pos) = analysis_and_position( + check_goto( " //- /lib.rs use a::Foo; @@ -121,47 +122,30 @@ mod tests { //- /b.rs struct Foo; ", - ); - - let symbols = analysis.goto_definition(pos).unwrap().unwrap(); - assert_eq_dbg( - r#"[NavigationTarget { file_id: FileId(2), name: "Foo", - kind: STRUCT_DEF, range: [0; 11), - ptr: Some(LocalSyntaxPtr { range: [0; 11), kind: STRUCT_DEF }) }]"#, - &symbols, + "Foo STRUCT_DEF FileId(2) [0; 11) [7; 10)", ); } #[test] fn goto_definition_works_for_module_declaration() { - let (analysis, pos) = analysis_and_position( + check_goto( " //- /lib.rs mod <|>foo; //- /foo.rs // empty - ", - ); - - let symbols = analysis.goto_definition(pos).unwrap().unwrap(); - assert_eq_dbg( - r#"[NavigationTarget { file_id: FileId(2), name: "foo", kind: MODULE, range: [0; 0), ptr: None }]"#, - &symbols, + ", + "foo SOURCE_FILE FileId(2) [0; 10)", ); - let (analysis, pos) = analysis_and_position( + check_goto( " //- /lib.rs mod <|>foo; //- /foo/mod.rs // empty - ", - ); - - let symbols = analysis.goto_definition(pos).unwrap().unwrap(); - assert_eq_dbg( - r#"[NavigationTarget { file_id: FileId(2), name: "foo", kind: MODULE, range: [0; 0), ptr: None }]"#, - &symbols, + ", + "foo SOURCE_FILE FileId(2) [0; 10)", ); } } diff --git a/crates/ra_ide_api/src/hover.rs b/crates/ra_ide_api/src/hover.rs index 9b06a0e58..f544ffa6d 100644 --- a/crates/ra_ide_api/src/hover.rs +++ b/crates/ra_ide_api/src/hover.rs @@ -92,7 +92,7 @@ impl NavigationTarget { let source_file = source_file.syntax(); let node = source_file .descendants() - .find(|node| node.kind() == self.kind() && node.range() == self.range())? + .find(|node| node.kind() == self.kind() && node.range() == self.full_range())? .to_owned(); Some(node) } diff --git a/crates/ra_ide_api/src/imp.rs b/crates/ra_ide_api/src/imp.rs index 12bfe1761..ba4aa0fd5 100644 --- a/crates/ra_ide_api/src/imp.rs +++ b/crates/ra_ide_api/src/imp.rs @@ -15,7 +15,7 @@ use ra_syntax::{ use crate::{ AnalysisChange, - Cancelable, NavigationTarget, + Cancelable, CrateId, db, Diagnostic, FileId, FilePosition, FileRange, FileSystemEdit, Query, RootChange, SourceChange, SourceFileEdit, symbol_index::{LibrarySymbolsQuery, FileSymbol}, @@ -98,19 +98,6 @@ impl db::RootDatabase { } impl db::RootDatabase { - /// 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. - pub(crate) fn parent_module( - &self, - position: FilePosition, - ) -> Cancelable> { - let module = match source_binder::module_from_position(self, position)? { - None => return Ok(Vec::new()), - Some(it) => it, - }; - let nav = NavigationTarget::from_module(self, module)?; - Ok(vec![nav]) - } /// Returns `Vec` for the same reason as `parent_module` pub(crate) fn crate_for(&self, file_id: FileId) -> Cancelable> { let module = match source_binder::module_from_file_id(self, file_id)? { diff --git a/crates/ra_ide_api/src/lib.rs b/crates/ra_ide_api/src/lib.rs index 2b02dab2a..6155d903a 100644 --- a/crates/ra_ide_api/src/lib.rs +++ b/crates/ra_ide_api/src/lib.rs @@ -31,6 +31,7 @@ mod extend_selection; mod hover; mod call_info; mod syntax_highlighting; +mod parent_module; use std::{fmt, sync::Arc}; @@ -414,7 +415,7 @@ impl Analysis { /// Returns a `mod name;` declaration which created the current module. pub fn parent_module(&self, position: FilePosition) -> Cancelable> { - self.with_db(|db| db.parent_module(position))? + self.with_db(|db| parent_module::parent_module(db, position))? } /// Returns crates this file belongs too. diff --git a/crates/ra_ide_api/src/navigation_target.rs b/crates/ra_ide_api/src/navigation_target.rs index 943e62eb8..8b29c3a97 100644 --- a/crates/ra_ide_api/src/navigation_target.rs +++ b/crates/ra_ide_api/src/navigation_target.rs @@ -17,7 +17,7 @@ pub struct NavigationTarget { file_id: FileId, name: SmolStr, kind: SyntaxKind, - range: TextRange, + full_range: TextRange, focus_range: Option, // Should be DefId ideally ptr: Option, @@ -36,11 +36,11 @@ impl NavigationTarget { self.file_id } - pub fn range(&self) -> TextRange { - self.range + pub fn full_range(&self) -> TextRange { + self.full_range } - /// A "most interesting" range withing the `range`. + /// A "most interesting" range withing the `range_full`. /// /// Typically, `range` is the whole syntax node, including doc comments, and /// `focus_range` is the range of the identifier. @@ -53,7 +53,7 @@ impl NavigationTarget { file_id: symbol.file_id, name: symbol.name.clone(), kind: symbol.ptr.kind(), - range: symbol.ptr.range(), + full_range: symbol.ptr.range(), focus_range: None, ptr: Some(symbol.ptr.clone()), } @@ -66,7 +66,7 @@ impl NavigationTarget { NavigationTarget { file_id, name: entry.name().to_string().into(), - range: entry.ptr().range(), + full_range: entry.ptr().range(), focus_range: None, kind: NAME, ptr: None, @@ -118,6 +118,27 @@ impl NavigationTarget { Ok(Some(res)) } + #[cfg(test)] + pub(crate) fn assert_match(&self, expected: &str) { + let actual = self.debug_render(); + test_utils::assert_eq_text!(expected.trim(), actual.trim(),); + } + + #[cfg(test)] + pub(crate) fn debug_render(&self) -> String { + let mut buf = format!( + "{} {:?} {:?} {:?}", + self.name(), + self.kind(), + self.file_id(), + self.full_range() + ); + if let Some(focus_range) = self.focus_range() { + buf.push_str(&format!(" {:?}", focus_range)) + } + buf + } + fn from_named(file_id: FileId, node: &impl ast::NameOwner) -> NavigationTarget { let name = node.name().map(|it| it.text().clone()).unwrap_or_default(); let focus_range = node.name().map(|it| it.syntax().range()); @@ -134,7 +155,7 @@ impl NavigationTarget { file_id, name, kind: node.kind(), - range: node.range(), + full_range: node.range(), focus_range, ptr: Some(LocalSyntaxPtr::new(node)), } diff --git a/crates/ra_ide_api/src/parent_module.rs b/crates/ra_ide_api/src/parent_module.rs new file mode 100644 index 000000000..d345839a3 --- /dev/null +++ b/crates/ra_ide_api/src/parent_module.rs @@ -0,0 +1,52 @@ +use ra_db::{Cancelable, FilePosition}; + +use crate::{NavigationTarget, db::RootDatabase}; + +/// 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. +pub(crate) fn parent_module( + db: &RootDatabase, + position: FilePosition, +) -> Cancelable> { + let module = match hir::source_binder::module_from_position(db, position)? { + None => return Ok(Vec::new()), + Some(it) => it, + }; + let nav = NavigationTarget::from_module(db, module)?; + Ok(vec![nav]) +} + +#[cfg(test)] +mod tests { + use crate::mock_analysis::analysis_and_position; + + #[test] + fn test_resolve_parent_module() { + let (analysis, pos) = analysis_and_position( + " + //- /lib.rs + mod foo; + //- /foo.rs + <|>// empty + ", + ); + let nav = analysis.parent_module(pos).unwrap().pop().unwrap(); + nav.assert_match("foo SOURCE_FILE FileId(2) [0; 10)"); + } + + #[test] + fn test_resolve_parent_module_for_inline() { + let (analysis, pos) = analysis_and_position( + " + //- /lib.rs + mod foo { + mod bar { + mod baz { <|> } + } + } + ", + ); + let nav = analysis.parent_module(pos).unwrap().pop().unwrap(); + nav.assert_match("baz MODULE FileId(1) [32; 44)"); + } +} diff --git a/crates/ra_ide_api/tests/test/main.rs b/crates/ra_ide_api/tests/test/main.rs index d1dc07e5b..7dc1dba73 100644 --- a/crates/ra_ide_api/tests/test/main.rs +++ b/crates/ra_ide_api/tests/test/main.rs @@ -4,7 +4,7 @@ use ra_syntax::TextRange; use test_utils::{assert_eq_dbg, assert_eq_text}; use ra_ide_api::{ - mock_analysis::{analysis_and_position, single_file, single_file_with_position, MockAnalysis}, + mock_analysis::{single_file, single_file_with_position, MockAnalysis}, AnalysisChange, CrateGraph, FileId, Query }; @@ -34,42 +34,6 @@ fn test_unresolved_module_diagnostic_no_diag_for_inline_mode() { assert_eq_dbg(r#"[]"#, &diagnostics); } -#[test] -fn test_resolve_parent_module() { - let (analysis, pos) = analysis_and_position( - " - //- /lib.rs - mod foo; - //- /foo.rs - <|>// empty - ", - ); - let symbols = analysis.parent_module(pos).unwrap(); - assert_eq_dbg( - r#"[NavigationTarget { file_id: FileId(1), name: "foo", kind: MODULE, range: [4; 7), ptr: None }]"#, - &symbols, - ); -} - -#[test] -fn test_resolve_parent_module_for_inline() { - let (analysis, pos) = analysis_and_position( - " - //- /lib.rs - mod foo { - mod bar { - mod baz { <|> } - } - } - ", - ); - let symbols = analysis.parent_module(pos).unwrap(); - assert_eq_dbg( - r#"[NavigationTarget { file_id: FileId(1), name: "baz", kind: MODULE, range: [36; 39), ptr: None }]"#, - &symbols, - ); -} - #[test] fn test_resolve_crate_root() { let mock = MockAnalysis::with_files( @@ -245,5 +209,5 @@ pub trait HirDatabase: SyntaxDatabase {} let mut symbols = analysis.symbol_search(Query::new("Hir".into())).unwrap(); let s = symbols.pop().unwrap(); assert_eq!(s.name(), "HirDatabase"); - assert_eq!(s.range(), TextRange::from_to(33.into(), 44.into())); + assert_eq!(s.full_range(), TextRange::from_to(33.into(), 44.into())); } diff --git a/crates/ra_lsp_server/src/conv.rs b/crates/ra_lsp_server/src/conv.rs index aad698da1..76fa98cbe 100644 --- a/crates/ra_lsp_server/src/conv.rs +++ b/crates/ra_lsp_server/src/conv.rs @@ -345,7 +345,8 @@ impl TryConvWith for &NavigationTarget { type Output = Location; fn try_conv_with(self, world: &ServerWorld) -> Result { let line_index = world.analysis().file_line_index(self.file_id()); - to_location(self.file_id(), self.range(), &world, &line_index) + let range = self.focus_range().unwrap_or(self.full_range()); + to_location(self.file_id(), range, &world, &line_index) } } @@ -361,7 +362,7 @@ pub fn to_location_link( let res = LocationLink { origin_selection_range: Some(target.range.conv_with(line_index)), target_uri: url.to_string(), - target_range: target.info.range().conv_with(&tgt_line_index), + target_range: target.info.full_range().conv_with(&tgt_line_index), target_selection_range: target .info .focus_range() -- cgit v1.2.3 From f23a13bfa7bae7e34070bfd14d22b70a82315022 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 11 Jan 2019 18:35:04 +0300 Subject: kill NavTarget ptr --- crates/ra_ide_api/src/navigation_target.rs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'crates') diff --git a/crates/ra_ide_api/src/navigation_target.rs b/crates/ra_ide_api/src/navigation_target.rs index 8b29c3a97..b955bbe42 100644 --- a/crates/ra_ide_api/src/navigation_target.rs +++ b/crates/ra_ide_api/src/navigation_target.rs @@ -1,4 +1,4 @@ -use ra_db::{FileId, LocalSyntaxPtr, Cancelable}; +use ra_db::{FileId, Cancelable}; use ra_syntax::{ SyntaxNode, AstNode, SmolStr, TextRange, ast, SyntaxKind::{self, NAME}, @@ -19,8 +19,6 @@ pub struct NavigationTarget { kind: SyntaxKind, full_range: TextRange, focus_range: Option, - // Should be DefId ideally - ptr: Option, } impl NavigationTarget { @@ -55,7 +53,6 @@ impl NavigationTarget { kind: symbol.ptr.kind(), full_range: symbol.ptr.range(), focus_range: None, - ptr: Some(symbol.ptr.clone()), } } @@ -69,7 +66,6 @@ impl NavigationTarget { full_range: entry.ptr().range(), focus_range: None, kind: NAME, - ptr: None, } } @@ -157,7 +153,7 @@ impl NavigationTarget { kind: node.kind(), full_range: node.range(), focus_range, - ptr: Some(LocalSyntaxPtr::new(node)), + // ptr: Some(LocalSyntaxPtr::new(node)), } } } -- cgit v1.2.3