about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLukas Wirth <lukastw97@gmail.com>2023-12-19 08:30:48 +0100
committerLukas Wirth <lukastw97@gmail.com>2023-12-19 08:49:00 +0100
commit002e611d090ae8531afc80caf4f8d699f81f7595 (patch)
tree60eb2709aa6ed2f35ab3f57f9a81584a650ac1d8
parentae2c3223b0dfdfa9c0815760901ace12c08d7747 (diff)
fix: Deduplicate annotations
-rw-r--r--crates/hir-expand/src/files.rs2
-rw-r--r--crates/hir/src/semantics.rs5
-rw-r--r--crates/ide-assists/src/handlers/generate_enum_variant.rs2
-rw-r--r--crates/ide-db/src/rename.rs4
-rw-r--r--crates/ide/src/annotations.rs289
-rw-r--r--crates/ide/src/goto_implementation.rs15
-rw-r--r--crates/span/src/lib.rs2
7 files changed, 158 insertions, 161 deletions
diff --git a/crates/hir-expand/src/files.rs b/crates/hir-expand/src/files.rs
index 40553d3e964..d0a1bef11c3 100644
--- a/crates/hir-expand/src/files.rs
+++ b/crates/hir-expand/src/files.rs
@@ -342,7 +342,7 @@ impl InFile<TextRange> {
 }
 
 impl<N: AstNode> InFile<N> {
-    pub fn original_ast_node(self, db: &dyn db::ExpandDatabase) -> Option<InRealFile<N>> {
+    pub fn original_ast_node_rooted(self, db: &dyn db::ExpandDatabase) -> Option<InRealFile<N>> {
         // This kind of upmapping can only be achieved in attribute expanded files,
         // as we don't have node inputs otherwise and therefore can't find an `N` node in the input
         let file_id = match self.file_id.repr() {
diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs
index a03ff220745..95ed83a49ab 100644
--- a/crates/hir/src/semantics.rs
+++ b/crates/hir/src/semantics.rs
@@ -512,8 +512,7 @@ impl<'db> SemanticsImpl<'db> {
     }
 
     /// Descend the token into its macro call if it is part of one, returning the tokens in the
-    /// expansion that it is associated with. If `offset` points into the token's range, it will
-    /// be considered for the mapping in case of inline format args.
+    /// expansion that it is associated with.
     pub fn descend_into_macros(
         &self,
         mode: DescendPreference,
@@ -850,7 +849,7 @@ impl<'db> SemanticsImpl<'db> {
     /// Attempts to map the node out of macro expanded files.
     /// This only work for attribute expansions, as other ones do not have nodes as input.
     pub fn original_ast_node<N: AstNode>(&self, node: N) -> Option<N> {
-        self.wrap_node_infile(node).original_ast_node(self.db.upcast()).map(
+        self.wrap_node_infile(node).original_ast_node_rooted(self.db.upcast()).map(
             |InRealFile { file_id, value }| {
                 self.cache(find_root(value.syntax()), file_id.into());
                 value
diff --git a/crates/ide-assists/src/handlers/generate_enum_variant.rs b/crates/ide-assists/src/handlers/generate_enum_variant.rs
index 1a1e992e28a..2aaf9d0679d 100644
--- a/crates/ide-assists/src/handlers/generate_enum_variant.rs
+++ b/crates/ide-assists/src/handlers/generate_enum_variant.rs
@@ -114,7 +114,7 @@ fn add_variant_to_accumulator(
     parent: PathParent,
 ) -> Option<()> {
     let db = ctx.db();
-    let InRealFile { file_id, value: enum_node } = adt.source(db)?.original_ast_node(db)?;
+    let InRealFile { file_id, value: enum_node } = adt.source(db)?.original_ast_node_rooted(db)?;
 
     acc.add(
         AssistId("generate_enum_variant", AssistKind::Generate),
diff --git a/crates/ide-db/src/rename.rs b/crates/ide-db/src/rename.rs
index c6532640067..7f28965885a 100644
--- a/crates/ide-db/src/rename.rs
+++ b/crates/ide-db/src/rename.rs
@@ -516,7 +516,7 @@ fn source_edit_from_def(
     if let Definition::Local(local) = def {
         let mut file_id = None;
         for source in local.sources(sema.db) {
-            let source = match source.source.clone().original_ast_node(sema.db) {
+            let source = match source.source.clone().original_ast_node_rooted(sema.db) {
                 Some(source) => source,
                 None => match source
                     .source
@@ -560,7 +560,7 @@ fn source_edit_from_def(
                         }
                     } else {
                         // Foo { ref mut field } -> Foo { field: ref mut new_name }
-                        //      ^ insert `field: `
+                        //   original_ast_node_rootedd: `
                         //               ^^^^^ replace this with `new_name`
                         edit.insert(
                             pat.syntax().text_range().start(),
diff --git a/crates/ide/src/annotations.rs b/crates/ide/src/annotations.rs
index d7f82b4af3e..f49c5af0af1 100644
--- a/crates/ide/src/annotations.rs
+++ b/crates/ide/src/annotations.rs
@@ -3,8 +3,9 @@ use ide_db::{
     base_db::{FileId, FilePosition, FileRange},
     defs::Definition,
     helpers::visit_file_defs,
-    RootDatabase,
+    FxHashSet, RootDatabase,
 };
+use itertools::Itertools;
 use syntax::{ast::HasName, AstNode, TextRange};
 
 use crate::{
@@ -23,13 +24,13 @@ mod fn_references;
 // and running/debugging binaries.
 //
 // image::https://user-images.githubusercontent.com/48062697/113020672-b7c34f00-917a-11eb-8f6e-858735660a0e.png[]
-#[derive(Debug)]
+#[derive(Debug, Hash, PartialEq, Eq)]
 pub struct Annotation {
     pub range: TextRange,
     pub kind: AnnotationKind,
 }
 
-#[derive(Debug)]
+#[derive(Debug, Hash, PartialEq, Eq)]
 pub enum AnnotationKind {
     Runnable(Runnable),
     HasImpls { pos: FilePosition, data: Option<Vec<NavigationTarget>> },
@@ -56,7 +57,7 @@ pub(crate) fn annotations(
     config: &AnnotationConfig,
     file_id: FileId,
 ) -> Vec<Annotation> {
-    let mut annotations = Vec::default();
+    let mut annotations = FxHashSet::default();
 
     if config.annotate_runnables {
         for runnable in runnables(db, file_id) {
@@ -66,7 +67,7 @@ pub(crate) fn annotations(
 
             let range = runnable.nav.focus_or_full_range();
 
-            annotations.push(Annotation { range, kind: AnnotationKind::Runnable(runnable) });
+            annotations.insert(Annotation { range, kind: AnnotationKind::Runnable(runnable) });
         }
     }
 
@@ -99,13 +100,13 @@ pub(crate) fn annotations(
                             })
                             .for_each(|range| {
                                 let (annotation_range, target_position) = mk_ranges(range);
-                                annotations.push(Annotation {
+                                annotations.insert(Annotation {
                                     range: annotation_range,
                                     kind: AnnotationKind::HasReferences {
                                         pos: target_position,
                                         data: None,
                                     },
-                                })
+                                });
                             })
                     }
                     if config.annotate_references || config.annotate_impls {
@@ -131,14 +132,14 @@ pub(crate) fn annotations(
         };
         let (annotation_range, target_pos) = mk_ranges(range);
         if config.annotate_impls && !matches!(def, Definition::Const(_)) {
-            annotations.push(Annotation {
+            annotations.insert(Annotation {
                 range: annotation_range,
                 kind: AnnotationKind::HasImpls { pos: target_pos, data: None },
             });
         }
 
         if config.annotate_references {
-            annotations.push(Annotation {
+            annotations.insert(Annotation {
                 range: annotation_range,
                 kind: AnnotationKind::HasReferences { pos: target_pos, data: None },
             });
@@ -149,7 +150,7 @@ 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(db) {
+            if let Some(InRealFile { file_id, value }) = node.original_ast_node_rooted(db) {
                 if file_id == source_file_id {
                     return Some((
                         value.syntax().text_range(),
@@ -171,7 +172,7 @@ pub(crate) fn annotations(
         }));
     }
 
-    annotations
+    annotations.into_iter().sorted_by_key(|a| (a.range.start(), a.range.end())).collect()
 }
 
 pub(crate) fn resolve_annotation(db: &RootDatabase, mut annotation: Annotation) -> Annotation {
@@ -253,25 +254,6 @@ fn main() {
             expect![[r#"
                 [
                     Annotation {
-                        range: 53..57,
-                        kind: Runnable(
-                            Runnable {
-                                use_name_in_title: false,
-                                nav: NavigationTarget {
-                                    file_id: FileId(
-                                        0,
-                                    ),
-                                    full_range: 50..85,
-                                    focus_range: 53..57,
-                                    name: "main",
-                                    kind: Function,
-                                },
-                                kind: Bin,
-                                cfg: None,
-                            },
-                        ),
-                    },
-                    Annotation {
                         range: 6..10,
                         kind: HasReferences {
                             pos: FilePosition {
@@ -308,6 +290,25 @@ fn main() {
                     },
                     Annotation {
                         range: 53..57,
+                        kind: Runnable(
+                            Runnable {
+                                use_name_in_title: false,
+                                nav: NavigationTarget {
+                                    file_id: FileId(
+                                        0,
+                                    ),
+                                    full_range: 50..85,
+                                    focus_range: 53..57,
+                                    name: "main",
+                                    kind: Function,
+                                },
+                                kind: Bin,
+                                cfg: None,
+                            },
+                        ),
+                    },
+                    Annotation {
+                        range: 53..57,
                         kind: HasReferences {
                             pos: FilePosition {
                                 file_id: FileId(
@@ -338,27 +339,8 @@ fn main() {
             expect![[r#"
                 [
                     Annotation {
-                        range: 17..21,
-                        kind: Runnable(
-                            Runnable {
-                                use_name_in_title: false,
-                                nav: NavigationTarget {
-                                    file_id: FileId(
-                                        0,
-                                    ),
-                                    full_range: 14..48,
-                                    focus_range: 17..21,
-                                    name: "main",
-                                    kind: Function,
-                                },
-                                kind: Bin,
-                                cfg: None,
-                            },
-                        ),
-                    },
-                    Annotation {
                         range: 7..11,
-                        kind: HasImpls {
+                        kind: HasReferences {
                             pos: FilePosition {
                                 file_id: FileId(
                                     0,
@@ -366,13 +348,20 @@ fn main() {
                                 offset: 7,
                             },
                             data: Some(
-                                [],
+                                [
+                                    FileRange {
+                                        file_id: FileId(
+                                            0,
+                                        ),
+                                        range: 41..45,
+                                    },
+                                ],
                             ),
                         },
                     },
                     Annotation {
                         range: 7..11,
-                        kind: HasReferences {
+                        kind: HasImpls {
                             pos: FilePosition {
                                 file_id: FileId(
                                     0,
@@ -380,19 +369,31 @@ fn main() {
                                 offset: 7,
                             },
                             data: Some(
-                                [
-                                    FileRange {
-                                        file_id: FileId(
-                                            0,
-                                        ),
-                                        range: 41..45,
-                                    },
-                                ],
+                                [],
                             ),
                         },
                     },
                     Annotation {
                         range: 17..21,
+                        kind: Runnable(
+                            Runnable {
+                                use_name_in_title: false,
+                                nav: NavigationTarget {
+                                    file_id: FileId(
+                                        0,
+                                    ),
+                                    full_range: 14..48,
+                                    focus_range: 17..21,
+                                    name: "main",
+                                    kind: Function,
+                                },
+                                kind: Bin,
+                                cfg: None,
+                            },
+                        ),
+                    },
+                    Annotation {
+                        range: 17..21,
                         kind: HasReferences {
                             pos: FilePosition {
                                 file_id: FileId(
@@ -427,27 +428,8 @@ fn main() {
             expect![[r#"
                 [
                     Annotation {
-                        range: 69..73,
-                        kind: Runnable(
-                            Runnable {
-                                use_name_in_title: false,
-                                nav: NavigationTarget {
-                                    file_id: FileId(
-                                        0,
-                                    ),
-                                    full_range: 66..100,
-                                    focus_range: 69..73,
-                                    name: "main",
-                                    kind: Function,
-                                },
-                                kind: Bin,
-                                cfg: None,
-                            },
-                        ),
-                    },
-                    Annotation {
                         range: 7..11,
-                        kind: HasImpls {
+                        kind: HasReferences {
                             pos: FilePosition {
                                 file_id: FileId(
                                     0,
@@ -456,14 +438,17 @@ fn main() {
                             },
                             data: Some(
                                 [
-                                    NavigationTarget {
+                                    FileRange {
                                         file_id: FileId(
                                             0,
                                         ),
-                                        full_range: 36..64,
-                                        focus_range: 57..61,
-                                        name: "impl",
-                                        kind: Impl,
+                                        range: 57..61,
+                                    },
+                                    FileRange {
+                                        file_id: FileId(
+                                            0,
+                                        ),
+                                        range: 93..97,
                                     },
                                 ],
                             ),
@@ -471,7 +456,7 @@ fn main() {
                     },
                     Annotation {
                         range: 7..11,
-                        kind: HasReferences {
+                        kind: HasImpls {
                             pos: FilePosition {
                                 file_id: FileId(
                                     0,
@@ -480,17 +465,14 @@ fn main() {
                             },
                             data: Some(
                                 [
-                                    FileRange {
-                                        file_id: FileId(
-                                            0,
-                                        ),
-                                        range: 57..61,
-                                    },
-                                    FileRange {
+                                    NavigationTarget {
                                         file_id: FileId(
                                             0,
                                         ),
-                                        range: 93..97,
+                                        full_range: 36..64,
+                                        focus_range: 57..61,
+                                        name: "impl",
+                                        kind: Impl,
                                     },
                                 ],
                             ),
@@ -555,6 +537,25 @@ fn main() {
                             ),
                         },
                     },
+                    Annotation {
+                        range: 69..73,
+                        kind: Runnable(
+                            Runnable {
+                                use_name_in_title: false,
+                                nav: NavigationTarget {
+                                    file_id: FileId(
+                                        0,
+                                    ),
+                                    full_range: 66..100,
+                                    focus_range: 69..73,
+                                    name: "main",
+                                    kind: Function,
+                                },
+                                kind: Bin,
+                                cfg: None,
+                            },
+                        ),
+                    },
                 ]
             "#]],
         );
@@ -623,27 +624,8 @@ fn main() {
             expect![[r#"
                 [
                     Annotation {
-                        range: 61..65,
-                        kind: Runnable(
-                            Runnable {
-                                use_name_in_title: false,
-                                nav: NavigationTarget {
-                                    file_id: FileId(
-                                        0,
-                                    ),
-                                    full_range: 58..95,
-                                    focus_range: 61..65,
-                                    name: "main",
-                                    kind: Function,
-                                },
-                                kind: Bin,
-                                cfg: None,
-                            },
-                        ),
-                    },
-                    Annotation {
                         range: 7..11,
-                        kind: HasImpls {
+                        kind: HasReferences {
                             pos: FilePosition {
                                 file_id: FileId(
                                     0,
@@ -652,14 +634,17 @@ fn main() {
                             },
                             data: Some(
                                 [
-                                    NavigationTarget {
+                                    FileRange {
                                         file_id: FileId(
                                             0,
                                         ),
-                                        full_range: 14..56,
-                                        focus_range: 19..23,
-                                        name: "impl",
-                                        kind: Impl,
+                                        range: 19..23,
+                                    },
+                                    FileRange {
+                                        file_id: FileId(
+                                            0,
+                                        ),
+                                        range: 74..78,
                                     },
                                 ],
                             ),
@@ -667,7 +652,7 @@ fn main() {
                     },
                     Annotation {
                         range: 7..11,
-                        kind: HasReferences {
+                        kind: HasImpls {
                             pos: FilePosition {
                                 file_id: FileId(
                                     0,
@@ -676,17 +661,14 @@ fn main() {
                             },
                             data: Some(
                                 [
-                                    FileRange {
-                                        file_id: FileId(
-                                            0,
-                                        ),
-                                        range: 19..23,
-                                    },
-                                    FileRange {
+                                    NavigationTarget {
                                         file_id: FileId(
                                             0,
                                         ),
-                                        range: 74..78,
+                                        full_range: 14..56,
+                                        focus_range: 19..23,
+                                        name: "impl",
+                                        kind: Impl,
                                     },
                                 ],
                             ),
@@ -727,6 +709,25 @@ fn main() {
                             ),
                         },
                     },
+                    Annotation {
+                        range: 61..65,
+                        kind: Runnable(
+                            Runnable {
+                                use_name_in_title: false,
+                                nav: NavigationTarget {
+                                    file_id: FileId(
+                                        0,
+                                    ),
+                                    full_range: 58..95,
+                                    focus_range: 61..65,
+                                    name: "main",
+                                    kind: Function,
+                                },
+                                kind: Bin,
+                                cfg: None,
+                            },
+                        ),
+                    },
                 ]
             "#]],
         );
@@ -747,6 +748,20 @@ mod tests {
                 [
                     Annotation {
                         range: 3..7,
+                        kind: HasReferences {
+                            pos: FilePosition {
+                                file_id: FileId(
+                                    0,
+                                ),
+                                offset: 3,
+                            },
+                            data: Some(
+                                [],
+                            ),
+                        },
+                    },
+                    Annotation {
+                        range: 3..7,
                         kind: Runnable(
                             Runnable {
                                 use_name_in_title: false,
@@ -812,20 +827,6 @@ mod tests {
                             },
                         ),
                     },
-                    Annotation {
-                        range: 3..7,
-                        kind: HasReferences {
-                            pos: FilePosition {
-                                file_id: FileId(
-                                    0,
-                                ),
-                                offset: 3,
-                            },
-                            data: Some(
-                                [],
-                            ),
-                        },
-                    },
                 ]
             "#]],
         );
@@ -877,7 +878,7 @@ struct Foo;
                 [
                     Annotation {
                         range: 0..71,
-                        kind: HasImpls {
+                        kind: HasReferences {
                             pos: FilePosition {
                                 file_id: FileId(
                                     0,
@@ -891,7 +892,7 @@ struct Foo;
                     },
                     Annotation {
                         range: 0..71,
-                        kind: HasReferences {
+                        kind: HasImpls {
                             pos: FilePosition {
                                 file_id: FileId(
                                     0,
diff --git a/crates/ide/src/goto_implementation.rs b/crates/ide/src/goto_implementation.rs
index 6384db39d7c..c1a4a7b1fc7 100644
--- a/crates/ide/src/goto_implementation.rs
+++ b/crates/ide/src/goto_implementation.rs
@@ -4,7 +4,6 @@ use ide_db::{
     helpers::pick_best_token,
     RootDatabase,
 };
-use itertools::Itertools;
 use syntax::{ast, AstNode, SyntaxKind::*, T};
 
 use crate::{FilePosition, NavigationTarget, RangeInfo, TryToNav};
@@ -34,10 +33,10 @@ pub(crate) fn goto_implementation(
     })?;
     let range = original_token.text_range();
     let navs =
-        sema.descend_into_macros(DescendPreference::None, original_token)
-            .into_iter()
-            .filter_map(|token| token.parent().and_then(ast::NameLike::cast))
-            .filter_map(|node| match &node {
+        sema.descend_into_macros_single(DescendPreference::SameText, original_token)
+            .parent()
+            .and_then(ast::NameLike::cast)
+            .and_then(|node| match &node {
                 ast::NameLike::Name(name) => {
                     NameClass::classify(&sema, name).and_then(|class| match class {
                         NameClass::Definition(it) | NameClass::ConstReference(it) => Some(it),
@@ -52,8 +51,7 @@ pub(crate) fn goto_implementation(
                     }),
                 ast::NameLike::Lifetime(_) => None,
             })
-            .unique()
-            .filter_map(|def| {
+            .and_then(|def| {
                 let navs = match def {
                     Definition::Trait(trait_) => impls_for_trait(&sema, trait_),
                     Definition::Adt(adt) => impls_for_ty(&sema, adt.ty(sema.db)),
@@ -75,8 +73,7 @@ pub(crate) fn goto_implementation(
                 };
                 Some(navs)
             })
-            .flatten()
-            .collect();
+            .unwrap_or_default();
 
     Some(RangeInfo { range, info: navs })
 }
diff --git a/crates/span/src/lib.rs b/crates/span/src/lib.rs
index d9f20e18c4a..09af34ce7e0 100644
--- a/crates/span/src/lib.rs
+++ b/crates/span/src/lib.rs
@@ -12,7 +12,7 @@ pub use crate::map::{RealSpanMap, SpanMap};
 pub use syntax::{TextRange, TextSize};
 pub use vfs::FileId;
 
-#[derive(Clone, Copy, Debug)]
+#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
 pub struct FilePosition {
     pub file_id: FileId,
     pub offset: TextSize,