Move reference imports filtering into to_proto layer

This commit is contained in:
Lukas Wirth 2022-09-13 14:47:26 +02:00
parent f64c95600c
commit cadb01c315
7 changed files with 45 additions and 50 deletions

View file

@ -9,6 +9,7 @@ use std::{mem, sync::Arc};
use base_db::{FileId, FileRange, SourceDatabase, SourceDatabaseExt}; use base_db::{FileId, FileRange, SourceDatabase, SourceDatabaseExt};
use hir::{DefWithBody, HasAttrs, HasSource, InFile, ModuleSource, Semantics, Visibility}; use hir::{DefWithBody, HasAttrs, HasSource, InFile, ModuleSource, Semantics, Visibility};
use once_cell::unsync::Lazy; use once_cell::unsync::Lazy;
use parser::SyntaxKind;
use stdx::hash::NoHashHashMap; use stdx::hash::NoHashHashMap;
use syntax::{ast, match_ast, AstNode, TextRange, TextSize}; use syntax::{ast, match_ast, AstNode, TextRange, TextSize};
@ -67,6 +68,7 @@ pub enum ReferenceCategory {
// Create // Create
Write, Write,
Read, Read,
Import,
// FIXME: Some day should be able to search in doc comments. Would probably // FIXME: Some day should be able to search in doc comments. Would probably
// need to switch from enum to bitflags then? // need to switch from enum to bitflags then?
// DocComment // DocComment
@ -577,7 +579,7 @@ impl<'a> FindUsages<'a> {
let reference = FileReference { let reference = FileReference {
range, range,
name: ast::NameLike::NameRef(name_ref.clone()), name: ast::NameLike::NameRef(name_ref.clone()),
category: None, category: is_name_ref_in_import(name_ref).then(|| ReferenceCategory::Import),
}; };
sink(file_id, reference) sink(file_id, reference)
} }
@ -756,7 +758,7 @@ impl ReferenceCategory {
fn new(def: &Definition, r: &ast::NameRef) -> Option<ReferenceCategory> { fn new(def: &Definition, r: &ast::NameRef) -> Option<ReferenceCategory> {
// Only Locals and Fields have accesses for now. // Only Locals and Fields have accesses for now.
if !matches!(def, Definition::Local(_) | Definition::Field(_)) { if !matches!(def, Definition::Local(_) | Definition::Field(_)) {
return None; return is_name_ref_in_import(r).then(|| ReferenceCategory::Import);
} }
let mode = r.syntax().ancestors().find_map(|node| { let mode = r.syntax().ancestors().find_map(|node| {
@ -783,3 +785,12 @@ impl ReferenceCategory {
mode.or(Some(ReferenceCategory::Read)) mode.or(Some(ReferenceCategory::Read))
} }
} }
fn is_name_ref_in_import(name_ref: &ast::NameRef) -> bool {
name_ref
.syntax()
.parent()
.and_then(ast::PathSegment::cast)
.and_then(|it| it.parent_path().top_path().syntax().parent())
.map_or(false, |it| it.kind() == SyntaxKind::USE_TREE)
}

View file

@ -158,7 +158,6 @@ pub(crate) fn resolve_annotation(db: &RootDatabase, mut annotation: Annotation)
&Semantics::new(db), &Semantics::new(db),
FilePosition { file_id, offset: annotation.range.start() }, FilePosition { file_id, offset: annotation.range.start() },
None, None,
false,
) )
.map(|result| { .map(|result| {
result result

View file

@ -377,6 +377,7 @@ mod tests {
match it { match it {
ReferenceCategory::Read => "read", ReferenceCategory::Read => "read",
ReferenceCategory::Write => "write", ReferenceCategory::Write => "write",
ReferenceCategory::Import => "import",
} }
.to_string() .to_string()
}), }),
@ -423,12 +424,12 @@ struct Foo;
check( check(
r#" r#"
use crate$0; use crate$0;
//^^^^^ //^^^^^ import
use self; use self;
//^^^^ //^^^^ import
mod __ { mod __ {
use super; use super;
//^^^^^ //^^^^^ import
} }
"#, "#,
); );
@ -436,7 +437,7 @@ mod __ {
r#" r#"
//- /main.rs crate:main deps:lib //- /main.rs crate:main deps:lib
use lib$0; use lib$0;
//^^^ //^^^ import
//- /lib.rs crate:lib //- /lib.rs crate:lib
"#, "#,
); );
@ -450,7 +451,7 @@ use lib$0;
mod foo; mod foo;
//- /foo.rs //- /foo.rs
use self$0; use self$0;
// ^^^^ // ^^^^ import
"#, "#,
); );
} }

View file

@ -425,11 +425,8 @@ impl Analysis {
&self, &self,
position: FilePosition, position: FilePosition,
search_scope: Option<SearchScope>, search_scope: Option<SearchScope>,
exclude_imports: bool,
) -> Cancellable<Option<Vec<ReferenceSearchResult>>> { ) -> Cancellable<Option<Vec<ReferenceSearchResult>>> {
self.with_db(|db| { self.with_db(|db| references::find_all_refs(&Semantics::new(db), position, search_scope))
references::find_all_refs(&Semantics::new(db), position, search_scope, exclude_imports)
})
} }
/// Finds all methods and free functions for the file. Does not return tests! /// Finds all methods and free functions for the file. Does not return tests!

View file

@ -54,7 +54,6 @@ pub(crate) fn find_all_refs(
sema: &Semantics<'_, RootDatabase>, sema: &Semantics<'_, RootDatabase>,
position: FilePosition, position: FilePosition,
search_scope: Option<SearchScope>, search_scope: Option<SearchScope>,
exclude_imports: bool,
) -> Option<Vec<ReferenceSearchResult>> { ) -> Option<Vec<ReferenceSearchResult>> {
let _p = profile::span("find_all_refs"); let _p = profile::span("find_all_refs");
let syntax = sema.parse(position.file_id).syntax().clone(); let syntax = sema.parse(position.file_id).syntax().clone();
@ -80,10 +79,6 @@ pub(crate) fn find_all_refs(
retain_adt_literal_usages(&mut usages, def, sema); retain_adt_literal_usages(&mut usages, def, sema);
} }
if exclude_imports {
filter_import_references(&mut usages);
}
let references = usages let references = usages
.into_iter() .into_iter()
.map(|(file_id, refs)| { .map(|(file_id, refs)| {
@ -117,17 +112,6 @@ pub(crate) fn find_all_refs(
} }
} }
fn filter_import_references(usages: &mut UsageSearchResult) {
for (_file_id, refs) in &mut usages.references {
refs.retain(|it| match it.name.as_name_ref() {
Some(name_ref) => {
!name_ref.syntax().ancestors().any(|it_ref| matches!(it_ref.kind(), USE))
}
None => true,
});
}
}
pub(crate) fn find_defs<'a>( pub(crate) fn find_defs<'a>(
sema: &'a Semantics<'_, RootDatabase>, sema: &'a Semantics<'_, RootDatabase>,
syntax: &SyntaxNode, syntax: &SyntaxNode,
@ -758,7 +742,7 @@ pub struct Foo {
expect![[r#" expect![[r#"
foo Module FileId(0) 0..8 4..7 foo Module FileId(0) 0..8 4..7
FileId(0) 14..17 FileId(0) 14..17 Import
"#]], "#]],
); );
} }
@ -776,7 +760,7 @@ use self$0;
expect![[r#" expect![[r#"
foo Module FileId(0) 0..8 4..7 foo Module FileId(0) 0..8 4..7
FileId(1) 4..8 FileId(1) 4..8 Import
"#]], "#]],
); );
} }
@ -791,7 +775,7 @@ use self$0;
expect![[r#" expect![[r#"
Module FileId(0) 0..10 Module FileId(0) 0..10
FileId(0) 4..8 FileId(0) 4..8 Import
"#]], "#]],
); );
} }
@ -819,7 +803,7 @@ pub(super) struct Foo$0 {
expect![[r#" expect![[r#"
Foo Struct FileId(2) 0..41 18..21 Foo Struct FileId(2) 0..41 18..21
FileId(1) 20..23 FileId(1) 20..23 Import
FileId(1) 47..50 FileId(1) 47..50
"#]], "#]],
); );
@ -982,7 +966,7 @@ fn g() { f(); }
expect![[r#" expect![[r#"
f Function FileId(0) 22..31 25..26 f Function FileId(0) 22..31 25..26
FileId(1) 11..12 FileId(1) 11..12 Import
FileId(1) 24..25 FileId(1) 24..25
"#]], "#]],
); );
@ -1110,7 +1094,7 @@ impl Foo {
fn check_with_scope(ra_fixture: &str, search_scope: Option<SearchScope>, expect: Expect) { fn check_with_scope(ra_fixture: &str, search_scope: Option<SearchScope>, expect: Expect) {
let (analysis, pos) = fixture::position(ra_fixture); let (analysis, pos) = fixture::position(ra_fixture);
let refs = analysis.find_all_refs(pos, search_scope, false).unwrap().unwrap(); let refs = analysis.find_all_refs(pos, search_scope).unwrap().unwrap();
let mut actual = String::new(); let mut actual = String::new();
for refs in refs { for refs in refs {
@ -1440,9 +1424,9 @@ pub use level1::Foo;
expect![[r#" expect![[r#"
Foo Struct FileId(0) 0..15 11..14 Foo Struct FileId(0) 0..15 11..14
FileId(1) 16..19 FileId(1) 16..19 Import
FileId(2) 16..19 FileId(2) 16..19 Import
FileId(3) 16..19 FileId(3) 16..19 Import
"#]], "#]],
); );
} }
@ -1470,7 +1454,7 @@ lib::foo!();
expect![[r#" expect![[r#"
foo Macro FileId(1) 0..61 29..32 foo Macro FileId(1) 0..61 29..32
FileId(0) 46..49 FileId(0) 46..49 Import
FileId(2) 0..3 FileId(2) 0..3
FileId(3) 5..8 FileId(3) 5..8
"#]], "#]],
@ -1633,7 +1617,7 @@ struct Foo;
expect![[r#" expect![[r#"
derive_identity Derive FileId(2) 1..107 45..60 derive_identity Derive FileId(2) 1..107 45..60
FileId(0) 17..31 FileId(0) 17..31 Import
FileId(0) 56..70 FileId(0) 56..70
"#]], "#]],
); );

View file

@ -10,8 +10,8 @@ use std::{
use anyhow::Context; use anyhow::Context;
use ide::{ use ide::{
AnnotationConfig, AssistKind, AssistResolveStrategy, FileId, FilePosition, FileRange, AnnotationConfig, AssistKind, AssistResolveStrategy, FileId, FilePosition, FileRange,
HoverAction, HoverGotoTypeData, Query, RangeInfo, Runnable, RunnableKind, SingleResolve, HoverAction, HoverGotoTypeData, Query, RangeInfo, ReferenceCategory, Runnable, RunnableKind,
SourceChange, TextEdit, SingleResolve, SourceChange, TextEdit,
}; };
use ide_db::SymbolKind; use ide_db::SymbolKind;
use lsp_server::ErrorCode; use lsp_server::ErrorCode;
@ -1014,7 +1014,7 @@ pub(crate) fn handle_references(
let exclude_imports = snap.config.find_all_refs_exclude_imports(); let exclude_imports = snap.config.find_all_refs_exclude_imports();
let refs = match snap.analysis.find_all_refs(position, None, exclude_imports)? { let refs = match snap.analysis.find_all_refs(position, None)? {
None => return Ok(None), None => return Ok(None),
Some(refs) => refs, Some(refs) => refs,
}; };
@ -1034,7 +1034,11 @@ pub(crate) fn handle_references(
refs.references refs.references
.into_iter() .into_iter()
.flat_map(|(file_id, refs)| { .flat_map(|(file_id, refs)| {
refs.into_iter().map(move |(range, _)| FileRange { file_id, range }) refs.into_iter()
.filter(|&(_, category)| {
!exclude_imports || category != Some(ReferenceCategory::Import)
})
.map(move |(range, _)| FileRange { file_id, range })
}) })
.chain(decl) .chain(decl)
}) })
@ -1285,7 +1289,7 @@ pub(crate) fn handle_document_highlight(
.into_iter() .into_iter()
.map(|ide::HighlightedRange { range, category }| lsp_types::DocumentHighlight { .map(|ide::HighlightedRange { range, category }| lsp_types::DocumentHighlight {
range: to_proto::range(&line_index, range), range: to_proto::range(&line_index, range),
kind: category.map(to_proto::document_highlight_kind), kind: category.and_then(to_proto::document_highlight_kind),
}) })
.collect(); .collect();
Ok(Some(res)) Ok(Some(res))
@ -1654,9 +1658,7 @@ fn show_ref_command_link(
position: &FilePosition, position: &FilePosition,
) -> Option<lsp_ext::CommandLinkGroup> { ) -> Option<lsp_ext::CommandLinkGroup> {
if snap.config.hover_actions().references && snap.config.client_commands().show_reference { if snap.config.hover_actions().references && snap.config.client_commands().show_reference {
if let Some(ref_search_res) = if let Some(ref_search_res) = snap.analysis.find_all_refs(*position, None).unwrap_or(None) {
snap.analysis.find_all_refs(*position, None, false).unwrap_or(None)
{
let uri = to_proto::url(snap, position.file_id); let uri = to_proto::url(snap, position.file_id);
let line_index = snap.file_line_index(position.file_id).ok()?; let line_index = snap.file_line_index(position.file_id).ok()?;
let position = to_proto::position(&line_index, position.offset); let position = to_proto::position(&line_index, position.offset);

View file

@ -83,10 +83,11 @@ pub(crate) fn structure_node_kind(kind: StructureNodeKind) -> lsp_types::SymbolK
pub(crate) fn document_highlight_kind( pub(crate) fn document_highlight_kind(
category: ReferenceCategory, category: ReferenceCategory,
) -> lsp_types::DocumentHighlightKind { ) -> Option<lsp_types::DocumentHighlightKind> {
match category { match category {
ReferenceCategory::Read => lsp_types::DocumentHighlightKind::READ, ReferenceCategory::Read => Some(lsp_types::DocumentHighlightKind::READ),
ReferenceCategory::Write => lsp_types::DocumentHighlightKind::WRITE, ReferenceCategory::Write => Some(lsp_types::DocumentHighlightKind::WRITE),
ReferenceCategory::Import => None,
} }
} }