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/ra_ide_api/src') 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/ra_ide_api/src') 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/ra_ide_api/src') 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/ra_ide_api/src') 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/ra_ide_api/src') 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/ra_ide_api/src') 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_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 ++++++++++++++++++++++------- 5 files changed, 98 insertions(+), 94 deletions(-) (limited to 'crates/ra_ide_api/src') 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 ++-- 2 files changed, 8 insertions(+), 6 deletions(-) (limited to 'crates/ra_ide_api/src') 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))? } -- 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 ++++++++++++++++++++++++++++ 6 files changed, 103 insertions(+), 58 deletions(-) create mode 100644 crates/ra_ide_api/src/parent_module.rs (limited to 'crates/ra_ide_api/src') 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)"); + } +} -- 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/ra_ide_api/src') 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