Unnamed repository; edit this file 'description' to name the repository.
Generate annotations for macro defined items if their name is in the input
Lukas Wirth 10 months ago
parent bff3e1e · commit d78cade
-rw-r--r--crates/ide/src/annotations.rs82
-rw-r--r--crates/ide/src/navigation_target.rs2
2 files changed, 76 insertions, 8 deletions
diff --git a/crates/ide/src/annotations.rs b/crates/ide/src/annotations.rs
index 3d71da985b..05196ac98c 100644
--- a/crates/ide/src/annotations.rs
+++ b/crates/ide/src/annotations.rs
@@ -10,6 +10,7 @@ use crate::{
NavigationTarget, RunnableKind,
annotations::fn_references::find_all_methods,
goto_implementation::goto_implementation,
+ navigation_target,
references::find_all_refs,
runnables::{Runnable, runnables},
};
@@ -148,15 +149,32 @@ pub(crate) fn annotations(
node: InFile<T>,
source_file_id: FileId,
) -> Option<(TextRange, Option<TextRange>)> {
- if let Some(InRealFile { file_id, value }) = node.original_ast_node_rooted(db) {
- if file_id.file_id(db) == source_file_id {
- return Some((
- value.syntax().text_range(),
- value.name().map(|name| name.syntax().text_range()),
- ));
+ if let Some(name) = node.value.name().map(|name| name.syntax().text_range()) {
+ // if we have a name, try mapping that out of the macro expansion as we can put the
+ // annotation on that name token
+ // See `test_no_annotations_macro_struct_def` vs `test_annotations_macro_struct_def_call_site`
+ let res = navigation_target::orig_range_with_focus_r(
+ db,
+ node.file_id,
+ node.value.syntax().text_range(),
+ Some(name),
+ );
+ if res.call_site.0.file_id == source_file_id {
+ if let Some(name_range) = res.call_site.1 {
+ return Some((res.call_site.0.range, Some(name_range)));
+ }
}
+ };
+ // otherwise try upmapping the entire node out of attributes
+ let InRealFile { file_id, value } = node.original_ast_node_rooted(db)?;
+ if file_id.file_id(db) == source_file_id {
+ Some((
+ value.syntax().text_range(),
+ value.name().map(|name| name.syntax().text_range()),
+ ))
+ } else {
+ None
}
- None
}
});
@@ -914,6 +932,56 @@ m!();
}
#[test]
+ fn test_annotations_macro_struct_def_call_site() {
+ check(
+ r#"
+//- /lib.rs
+macro_rules! m {
+ ($name:ident) => {
+ struct $name {}
+ };
+}
+
+m! {
+ Name
+};
+"#,
+ expect![[r#"
+ [
+ Annotation {
+ range: 83..87,
+ kind: HasImpls {
+ pos: FilePositionWrapper {
+ file_id: FileId(
+ 0,
+ ),
+ offset: 83,
+ },
+ data: Some(
+ [],
+ ),
+ },
+ },
+ Annotation {
+ range: 83..87,
+ kind: HasReferences {
+ pos: FilePositionWrapper {
+ file_id: FileId(
+ 0,
+ ),
+ offset: 83,
+ },
+ data: Some(
+ [],
+ ),
+ },
+ },
+ ]
+ "#]],
+ );
+ }
+
+ #[test]
fn test_annotations_appear_above_whole_item_when_configured_to_do_so() {
check_with_config(
r#"
diff --git a/crates/ide/src/navigation_target.rs b/crates/ide/src/navigation_target.rs
index 9334b73fc7..4c7c597e68 100644
--- a/crates/ide/src/navigation_target.rs
+++ b/crates/ide/src/navigation_target.rs
@@ -867,7 +867,7 @@ pub(crate) fn orig_range_with_focus_r(
}
// def site name
- // FIXME: This can be de improved
+ // FIXME: This can be improved
Some((focus_range, _ctxt)) => {
match value_range {
// but overall node is in macro input