From 1895716c885eba9aae710f80f4c29eb2b424c6f0 Mon Sep 17 00:00:00 2001 From: vsrs Date: Wed, 2 Sep 2020 17:27:57 +0300 Subject: Do not show references CodeLens for tests. --- crates/ide/src/fn_references.rs | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 crates/ide/src/fn_references.rs (limited to 'crates/ide/src/fn_references.rs') diff --git a/crates/ide/src/fn_references.rs b/crates/ide/src/fn_references.rs new file mode 100644 index 000000000..ca91b98cf --- /dev/null +++ b/crates/ide/src/fn_references.rs @@ -0,0 +1,21 @@ +use hir::Semantics; +use ide_db::RootDatabase; +use syntax::{ast, ast::NameOwner, AstNode, SyntaxNode}; + +use crate::{runnables::has_test_related_attribute, FileId, FileRange}; + +pub(crate) fn find_all_methods(db: &RootDatabase, file_id: FileId) -> Vec { + let sema = Semantics::new(db); + let source_file = sema.parse(file_id); + source_file.syntax().descendants().filter_map(|it| method_range(it, file_id)).collect() +} + +pub(crate) fn method_range(item: SyntaxNode, file_id: FileId) -> Option { + ast::Fn::cast(item).and_then(|fn_def|{ + if has_test_related_attribute(&fn_def) { + None + } else { + fn_def.name().map(|name| FileRange{ file_id, range: name.syntax().text_range() }) + } + }) +} -- cgit v1.2.3 From cd5eeb904e6f5096bb1f8b76fba7e568cdbbdc8c Mon Sep 17 00:00:00 2001 From: vsrs Date: Wed, 2 Sep 2020 18:21:20 +0300 Subject: Add tests --- crates/ide/src/fn_references.rs | 80 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 77 insertions(+), 3 deletions(-) (limited to 'crates/ide/src/fn_references.rs') diff --git a/crates/ide/src/fn_references.rs b/crates/ide/src/fn_references.rs index ca91b98cf..1989a562b 100644 --- a/crates/ide/src/fn_references.rs +++ b/crates/ide/src/fn_references.rs @@ -1,3 +1,6 @@ +//! This module implements a methods and free functions search in the specified file. +//! We have to skip tests, so cannot reuse file_structure module. + use hir::Semantics; use ide_db::RootDatabase; use syntax::{ast, ast::NameOwner, AstNode, SyntaxNode}; @@ -10,12 +13,83 @@ pub(crate) fn find_all_methods(db: &RootDatabase, file_id: FileId) -> Vec Option { - ast::Fn::cast(item).and_then(|fn_def|{ +fn method_range(item: SyntaxNode, file_id: FileId) -> Option { + ast::Fn::cast(item).and_then(|fn_def| { if has_test_related_attribute(&fn_def) { None } else { - fn_def.name().map(|name| FileRange{ file_id, range: name.syntax().text_range() }) + fn_def.name().map(|name| FileRange { file_id, range: name.syntax().text_range() }) } }) } + +#[cfg(test)] +mod tests { + use crate::mock_analysis::analysis_and_position; + use crate::{FileRange, TextSize}; + use std::ops::RangeInclusive; + + #[test] + fn test_find_all_methods() { + let (analysis, pos) = analysis_and_position( + r#" + //- /lib.rs + fn private_fn() {<|>} + + pub fn pub_fn() {} + + pub fn generic_fn(arg: T) {} + "#, + ); + + let refs = analysis.find_all_methods(pos.file_id).unwrap(); + check_result(&refs, &[3..=13, 27..=33, 47..=57]); + } + + #[test] + fn test_find_trait_methods() { + let (analysis, pos) = analysis_and_position( + r#" + //- /lib.rs + trait Foo { + fn bar() {<|>} + fn baz() {} + } + "#, + ); + + let refs = analysis.find_all_methods(pos.file_id).unwrap(); + check_result(&refs, &[19..=22, 35..=38]); + } + + #[test] + fn test_skip_tests() { + let (analysis, pos) = analysis_and_position( + r#" + //- /lib.rs + #[test] + fn foo() {<|>} + + pub fn pub_fn() {} + + mod tests { + #[test] + fn bar() {} + } + "#, + ); + + let refs = analysis.find_all_methods(pos.file_id).unwrap(); + check_result(&refs, &[28..=34]); + } + + fn check_result(refs: &[FileRange], expected: &[RangeInclusive]) { + assert_eq!(refs.len(), expected.len()); + + for (i, item) in refs.iter().enumerate() { + let range = &expected[i]; + assert_eq!(TextSize::from(*range.start()), item.range.start()); + assert_eq!(TextSize::from(*range.end()), item.range.end()); + } + } +} -- cgit v1.2.3