mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-03 07:04:49 +00:00
Fix annotations not resolving when lens location is set to whole item
This commit is contained in:
parent
b16b0413dc
commit
3cd57c425a
5 changed files with 199 additions and 130 deletions
103
crates/ide/src/annotations/fn_references.rs
Normal file
103
crates/ide/src/annotations/fn_references.rs
Normal file
|
@ -0,0 +1,103 @@
|
|||
//! 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_assists::utils::test_related_attribute;
|
||||
use ide_db::RootDatabase;
|
||||
use syntax::{ast, ast::HasName, AstNode, SyntaxNode, TextRange};
|
||||
|
||||
use crate::FileId;
|
||||
|
||||
pub(super) fn find_all_methods(
|
||||
db: &RootDatabase,
|
||||
file_id: FileId,
|
||||
) -> Vec<(TextRange, Option<TextRange>)> {
|
||||
let sema = Semantics::new(db);
|
||||
let source_file = sema.parse(file_id);
|
||||
source_file.syntax().descendants().filter_map(|it| method_range(it)).collect()
|
||||
}
|
||||
|
||||
fn method_range(item: SyntaxNode) -> Option<(TextRange, Option<TextRange>)> {
|
||||
ast::Fn::cast(item).and_then(|fn_def| {
|
||||
if test_related_attribute(&fn_def).is_some() {
|
||||
None
|
||||
} else {
|
||||
Some((
|
||||
fn_def.syntax().text_range(),
|
||||
fn_def.name().map(|name| name.syntax().text_range()),
|
||||
))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use syntax::TextRange;
|
||||
|
||||
use crate::fixture;
|
||||
use crate::TextSize;
|
||||
use std::ops::RangeInclusive;
|
||||
|
||||
#[test]
|
||||
fn test_find_all_methods() {
|
||||
let (analysis, pos) = fixture::position(
|
||||
r#"
|
||||
fn private_fn() {$0}
|
||||
|
||||
pub fn pub_fn() {}
|
||||
|
||||
pub fn generic_fn<T>(arg: T) {}
|
||||
"#,
|
||||
);
|
||||
|
||||
let refs = super::find_all_methods(&analysis.db, pos.file_id);
|
||||
check_result(&refs, &[3..=13, 27..=33, 47..=57]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_find_trait_methods() {
|
||||
let (analysis, pos) = fixture::position(
|
||||
r#"
|
||||
trait Foo {
|
||||
fn bar() {$0}
|
||||
fn baz() {}
|
||||
}
|
||||
"#,
|
||||
);
|
||||
|
||||
let refs = super::find_all_methods(&analysis.db, pos.file_id);
|
||||
check_result(&refs, &[19..=22, 35..=38]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_skip_tests() {
|
||||
let (analysis, pos) = fixture::position(
|
||||
r#"
|
||||
//- /lib.rs
|
||||
#[test]
|
||||
fn foo() {$0}
|
||||
|
||||
pub fn pub_fn() {}
|
||||
|
||||
mod tests {
|
||||
#[test]
|
||||
fn bar() {}
|
||||
}
|
||||
"#,
|
||||
);
|
||||
|
||||
let refs = super::find_all_methods(&analysis.db, pos.file_id);
|
||||
check_result(&refs, &[28..=34]);
|
||||
}
|
||||
|
||||
fn check_result(refs: &[(TextRange, Option<TextRange>)], expected: &[RangeInclusive<u32>]) {
|
||||
assert_eq!(refs.len(), expected.len());
|
||||
|
||||
for (i, &(full, focus)) in refs.iter().enumerate() {
|
||||
let range = &expected[i];
|
||||
let item = focus.unwrap_or(full);
|
||||
assert_eq!(TextSize::from(*range.start()), item.start());
|
||||
assert_eq!(TextSize::from(*range.end()), item.end());
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue