Skip to content

feat: enable excluding refs search results in test - #16441

Merged
bors merged 4 commits into
rust-lang:masterfrom
Young-Flash:exclude_tests_refs
Jan 31, 2024
Merged

bors merged 4 commits into
rust-lang:masterfrom
Young-Flash:exclude_tests_refs

Conversation

@Young-Flash

@Young-Flash Young-Flash commented Jan 29, 2024

Copy link
Copy Markdown
Member

Change

Here I introduce a new ReferenceCategory::Test type to indicate whether the function where this reference is located is marked as #[test], and expose an config item (rust-analyzer.references.excludeTests) to client.

I also changed the signature of ReferenceCategory::new, adding a sema: &Semantics<'_, RootDatabase> param to do some hir analysis. Hope the current implementation is good to go.

Demo

"rust-analyzer.references.excludeTests": false

include

"rust-analyzer.references.excludeTests": true

exclude

Performance

I look a bit more about the latency in rust-analyzer server LSP log trace, compared the Find All References between v0.4.1825 and this PR over syntax::ast::AstNode::syntax() and ide_assists::tests::check_assist(), taking an average of 5 operations response time (every operation is perform after restart rust-analyzer server so it's not the cache reslut). I found this PR does't bring noticable regression.

item excludeTests? v0.4.1825 this PR ref results
syntax::ast::AstNode::syntax false 13329.4 ms 13464.2 ms 2419 results in 257 files
syntax::ast::AstNode::syntax true - 13449.0 ms 2396 results in 256 files
ide_assists::tests::check_assist false 333.2 ms 348.2 ms 1684 results in 110 files
ide_assists::tests::check_assist true - 335.6 ms 113 results in 110 files

close #14530

@rustbot rustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Jan 29, 2024
Comment thread crates/ide-db/src/search.rs
@Young-Flash

Copy link
Copy Markdown
Member Author

I look a bit more about the latency in rust-analyzer server LSP log trace, compared the Find All References between v0.4.1825 and this PR over syntax::ast::AstNode::syntax() and ide_assists::tests::check_assist(), taking an average of 5 operations response time (every operation is perform after restart rust-analyzer server so it's not the cache reslut). I found this PR does't bring noticable regression.

item excludeTests? v0.4.1825 this PR ref results
syntax::ast::AstNode::syntax false 13329.4 ms 13464.2 ms 2419 results in 257 files
syntax::ast::AstNode::syntax true - 13449.0 ms 2396 results in 256 files
ide_assists::tests::check_assist false 333.2 ms 348.2 ms 1684 results in 110 files
ide_assists::tests::check_assist true - 335.6 ms 113 results in 110 files

@Veykril

Veykril commented Jan 31, 2024

Copy link
Copy Markdown
Member

@bors r+

@bors

bors commented Jan 31, 2024

Copy link
Copy Markdown
Contributor

📌 Commit 2b71aca has been approved by Veykril

It is now in the queue for this repository.

@bors

bors commented Jan 31, 2024

Copy link
Copy Markdown
Contributor

⌛ Testing commit 2b71aca with merge e4146af...

@bors

bors commented Jan 31, 2024

Copy link
Copy Markdown
Contributor

☀️ Test successful - checks-actions
Approved by: Veykril
Pushing e4146af to master...

@bors
bors merged commit e4146af into rust-lang:master Jan 31, 2024
@Young-Flash
Young-Flash deleted the exclude_tests_refs branch January 31, 2024 08:05
@PSeitz PSeitz mentioned this pull request Mar 6, 2024

@matklad matklad left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great to see this! Supporting this feature is exactly why the search API was designed as it was, with reference categories and such!

let position = from_proto::file_position(&snap, params.text_document_position)?;

let exclude_imports = snap.config.find_all_refs_exclude_imports();
let exclude_tests = snap.config.find_all_refs_exclude_tests();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

exclude_tests should be pushed down as a parameter to find_all_refs.

that way, a potentially more optimal implementation would be able to avoid even analyzing the test, which would be faster than filtering out results after the fact.

I think the second parameter we are passing here, which is currently None, is something like a SearchScope. It exists exactly to narrow down search results, and I think could be extended to exclude tests.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good point, I had create an issue for this

(sorry for the slow response, kind of busy recently)

// FIXME: Some day should be able to search in doc comments. Would probably
// need to switch from enum to bitflags then?
// DocComment
Test,

@matklad matklad Apr 13, 2024

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Something can be a test and a read at the same time. So, the time has come to use a bitset here! This is precisely the situation the old comment just above this line talks about

@glasser

glasser commented Nov 26, 2024

Copy link
Copy Markdown

I just discovered this and I'm really excited, as I've wanted this in VSCode for years!

It looks like this filters out things inside #[test] functions, but not inside blocks marked with #[cfg(test)]. Is this intentional? I really just want to find references in my actual production code, skipping both tests and test-support code.

@Young-Flash

Copy link
Copy Markdown
Member Author

it is not intentional, just forgot #[cfg(test)]

@glasser

glasser commented Nov 27, 2024

Copy link
Copy Markdown

Ah cool. Should I file an issue about this?

@Young-Flash

Young-Flash commented Nov 28, 2024

Copy link
Copy Markdown
Member Author

yeah, you can also try to implement it

fn is_name_ref_in_test(sema: &Semantics<'_, RootDatabase>, name_ref: &ast::NameRef) -> bool {
name_ref.syntax().ancestors().any(|node| match ast::Fn::cast(node) {
Some(it) => sema.to_def(&it).map_or(false, |func| func.is_test(sema.db)),
None => false,
})
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-review Status: Awaiting review from the assignee but also interested parties.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Find all references, exclusing test configuration

6 participants