about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--crates/ide/src/annotations.rs150
-rw-r--r--crates/ide/src/runnables.rs75
-rw-r--r--crates/ide_db/src/defs.rs26
-rw-r--r--crates/ide_db/src/helpers.rs11
4 files changed, 132 insertions, 130 deletions
diff --git a/crates/ide/src/annotations.rs b/crates/ide/src/annotations.rs
index 47db002ef90..a7c12c16361 100644
--- a/crates/ide/src/annotations.rs
+++ b/crates/ide/src/annotations.rs
@@ -1,7 +1,7 @@
-use either::Either;
 use hir::{HasSource, InFile, Semantics};
 use ide_db::{
     base_db::{FileId, FilePosition, FileRange},
+    defs::Definition,
     helpers::visit_file_defs,
     RootDatabase,
 };
@@ -62,91 +62,83 @@ pub(crate) fn annotations(
         }
     }
 
-    visit_file_defs(&Semantics::new(db), file_id, &mut |def| match def {
-        Either::Left(def) => {
-            let range = match def {
-                hir::ModuleDef::Const(konst) if config.annotate_references => {
-                    konst.source(db).and_then(|node| name_range(&node, file_id))
-                }
-                hir::ModuleDef::Trait(trait_)
-                    if config.annotate_references || config.annotate_impls =>
-                {
-                    trait_.source(db).and_then(|node| name_range(&node, file_id))
-                }
-                hir::ModuleDef::Adt(adt) => match adt {
-                    hir::Adt::Enum(enum_) => {
-                        if config.annotate_enum_variant_references {
-                            enum_
-                                .variants(db)
-                                .into_iter()
-                                .map(|variant| {
-                                    variant.source(db).and_then(|node| name_range(&node, file_id))
-                                })
-                                .filter_map(std::convert::identity)
-                                .for_each(|range| {
-                                    annotations.push(Annotation {
-                                        range,
-                                        kind: AnnotationKind::HasReferences {
-                                            position: FilePosition {
-                                                file_id,
-                                                offset: range.start(),
-                                            },
-                                            data: None,
-                                        },
-                                    })
+    visit_file_defs(&Semantics::new(db), file_id, &mut |def| {
+        let range = match def {
+            Definition::Const(konst) if config.annotate_references => {
+                konst.source(db).and_then(|node| name_range(&node, file_id))
+            }
+            Definition::Trait(trait_) if config.annotate_references || config.annotate_impls => {
+                trait_.source(db).and_then(|node| name_range(&node, file_id))
+            }
+            Definition::Adt(adt) => match adt {
+                hir::Adt::Enum(enum_) => {
+                    if config.annotate_enum_variant_references {
+                        enum_
+                            .variants(db)
+                            .into_iter()
+                            .map(|variant| {
+                                variant.source(db).and_then(|node| name_range(&node, file_id))
+                            })
+                            .filter_map(std::convert::identity)
+                            .for_each(|range| {
+                                annotations.push(Annotation {
+                                    range,
+                                    kind: AnnotationKind::HasReferences {
+                                        position: FilePosition { file_id, offset: range.start() },
+                                        data: None,
+                                    },
                                 })
-                        }
-                        if config.annotate_references || config.annotate_impls {
-                            enum_.source(db).and_then(|node| name_range(&node, file_id))
-                        } else {
-                            None
-                        }
+                            })
+                    }
+                    if config.annotate_references || config.annotate_impls {
+                        enum_.source(db).and_then(|node| name_range(&node, file_id))
+                    } else {
+                        None
                     }
-                    _ => {
-                        if config.annotate_references || config.annotate_impls {
-                            adt.source(db).and_then(|node| name_range(&node, file_id))
-                        } else {
-                            None
-                        }
+                }
+                _ => {
+                    if config.annotate_references || config.annotate_impls {
+                        adt.source(db).and_then(|node| name_range(&node, file_id))
+                    } else {
+                        None
                     }
+                }
+            },
+            _ => None,
+        };
+
+        let (range, offset) = match range {
+            Some(range) => (range, range.start()),
+            None => return,
+        };
+
+        if config.annotate_impls && !matches!(def, Definition::Const(_)) {
+            annotations.push(Annotation {
+                range,
+                kind: AnnotationKind::HasImpls {
+                    position: FilePosition { file_id, offset },
+                    data: None,
                 },
-                _ => None,
-            };
-
-            let (range, offset) = match range {
-                Some(range) => (range, range.start()),
-                None => return,
-            };
-
-            if config.annotate_impls && !matches!(def, hir::ModuleDef::Const(_)) {
-                annotations.push(Annotation {
-                    range,
-                    kind: AnnotationKind::HasImpls {
-                        position: FilePosition { file_id, offset },
-                        data: None,
-                    },
-                });
-            }
-            if config.annotate_references {
-                annotations.push(Annotation {
-                    range,
-                    kind: AnnotationKind::HasReferences {
-                        position: FilePosition { file_id, offset },
-                        data: None,
-                    },
-                });
-            }
+            });
+        }
+        if config.annotate_references {
+            annotations.push(Annotation {
+                range,
+                kind: AnnotationKind::HasReferences {
+                    position: FilePosition { file_id, offset },
+                    data: None,
+                },
+            });
+        }
 
-            fn name_range<T: HasName>(node: &InFile<T>, file_id: FileId) -> Option<TextRange> {
-                if node.file_id == file_id.into() {
-                    node.value.name().map(|it| it.syntax().text_range())
-                } else {
-                    // Node is outside the file we are adding annotations to (e.g. macros).
-                    None
-                }
+        fn name_range<T: HasName>(node: &InFile<T>, file_id: FileId) -> Option<TextRange> {
+            if node.file_id == file_id.into() {
+                node.value.name().map(|it| it.syntax().text_range())
+            } else {
+                // Node is outside the file we are adding annotations to (e.g. macros).
+                None
             }
         }
-        Either::Right(_) => (),
     });
 
     if config.annotate_method_references {
diff --git a/crates/ide/src/runnables.rs b/crates/ide/src/runnables.rs
index 3c04208281c..09344917633 100644
--- a/crates/ide/src/runnables.rs
+++ b/crates/ide/src/runnables.rs
@@ -2,11 +2,11 @@ use std::fmt;
 
 use ast::HasName;
 use cfg::CfgExpr;
-use either::Either;
 use hir::{AsAssocItem, HasAttrs, HasSource, HirDisplay, InFile, Semantics};
 use ide_assists::utils::test_related_attribute;
 use ide_db::{
     base_db::{FilePosition, FileRange},
+    defs::Definition,
     helpers::visit_file_defs,
     search::SearchScope,
     RootDatabase, SymbolKind,
@@ -138,8 +138,8 @@ pub(crate) fn runnables(db: &RootDatabase, file_id: FileId) -> Vec<Runnable> {
         }) {
             if let Some(def) = def {
                 let file_id = match def {
-                    hir::ModuleDef::Module(it) => it.declaration_source(db).map(|src| src.file_id),
-                    hir::ModuleDef::Function(it) => it.source(db).map(|src| src.file_id),
+                    Definition::Module(it) => it.declaration_source(db).map(|src| src.file_id),
+                    Definition::Function(it) => it.source(db).map(|src| src.file_id),
                     _ => None,
                 };
                 if let Some(file_id) = file_id.filter(|file| file.call_node(db).is_some()) {
@@ -150,32 +150,25 @@ pub(crate) fn runnables(db: &RootDatabase, file_id: FileId) -> Vec<Runnable> {
             res.push(runnable);
         }
     };
-    visit_file_defs(&sema, file_id, &mut |def| match def {
-        Either::Left(def) => {
-            let runnable = match def {
-                hir::ModuleDef::Module(it) => runnable_mod(&sema, it),
-                hir::ModuleDef::Function(it) => runnable_fn(&sema, it),
-                _ => None,
-            };
-            add_opt(runnable.or_else(|| module_def_doctest(sema.db, def)), Some(def));
-        }
-        Either::Right(impl_) => {
-            add_opt(runnable_impl(&sema, &impl_), None);
-            impl_
-                .items(db)
-                .into_iter()
-                .map(|assoc| {
-                    (
-                        match assoc {
-                            hir::AssocItem::Function(it) => runnable_fn(&sema, it)
-                                .or_else(|| module_def_doctest(sema.db, it.into())),
-                            hir::AssocItem::Const(it) => module_def_doctest(sema.db, it.into()),
-                            hir::AssocItem::TypeAlias(it) => module_def_doctest(sema.db, it.into()),
-                        },
-                        assoc,
-                    )
-                })
-                .for_each(|(r, assoc)| add_opt(r, Some(assoc.into())));
+    visit_file_defs(&sema, file_id, &mut |def| {
+        let runnable = match def {
+            Definition::Module(it) => runnable_mod(&sema, it),
+            Definition::Function(it) => runnable_fn(&sema, it),
+            Definition::SelfType(impl_) => runnable_impl(&sema, &impl_),
+            _ => None,
+        };
+        add_opt(runnable.or_else(|| module_def_doctest(sema.db, def)), Some(def));
+        if let Definition::SelfType(impl_) = def {
+            impl_.items(db).into_iter().for_each(|assoc| {
+                let runnable = match assoc {
+                    hir::AssocItem::Function(it) => {
+                        runnable_fn(&sema, it).or_else(|| module_def_doctest(sema.db, it.into()))
+                    }
+                    hir::AssocItem::Const(it) => module_def_doctest(sema.db, it.into()),
+                    hir::AssocItem::TypeAlias(it) => module_def_doctest(sema.db, it.into()),
+                };
+                add_opt(runnable, Some(assoc.into()))
+            });
         }
     });
 
@@ -392,17 +385,19 @@ fn runnable_mod_outline_definition(
     }
 }
 
-fn module_def_doctest(db: &RootDatabase, def: hir::ModuleDef) -> Option<Runnable> {
+fn module_def_doctest(db: &RootDatabase, def: Definition) -> Option<Runnable> {
     let attrs = match def {
-        hir::ModuleDef::Module(it) => it.attrs(db),
-        hir::ModuleDef::Function(it) => it.attrs(db),
-        hir::ModuleDef::Adt(it) => it.attrs(db),
-        hir::ModuleDef::Variant(it) => it.attrs(db),
-        hir::ModuleDef::Const(it) => it.attrs(db),
-        hir::ModuleDef::Static(it) => it.attrs(db),
-        hir::ModuleDef::Trait(it) => it.attrs(db),
-        hir::ModuleDef::TypeAlias(it) => it.attrs(db),
-        hir::ModuleDef::BuiltinType(_) => return None,
+        Definition::Module(it) => it.attrs(db),
+        Definition::Function(it) => it.attrs(db),
+        Definition::Adt(it) => it.attrs(db),
+        Definition::Variant(it) => it.attrs(db),
+        Definition::Const(it) => it.attrs(db),
+        Definition::Static(it) => it.attrs(db),
+        Definition::Trait(it) => it.attrs(db),
+        Definition::TypeAlias(it) => it.attrs(db),
+        Definition::Macro(it) => it.attrs(db),
+        Definition::SelfType(it) => it.attrs(db),
+        _ => return None,
     };
     if !has_runnable_doc_test(&attrs) {
         return None;
@@ -440,7 +435,7 @@ fn module_def_doctest(db: &RootDatabase, def: hir::ModuleDef) -> Option<Runnable
     let test_id = path.map_or_else(|| TestId::Name(def_name.to_string()), TestId::Path);
 
     let mut nav = match def {
-        hir::ModuleDef::Module(def) => NavigationTarget::from_module_to_decl(db, def),
+        Definition::Module(def) => NavigationTarget::from_module_to_decl(db, def),
         def => def.try_to_nav(db)?,
     };
     nav.focus_range = None;
diff --git a/crates/ide_db/src/defs.rs b/crates/ide_db/src/defs.rs
index 5fdbb600814..1d7f4392dd0 100644
--- a/crates/ide_db/src/defs.rs
+++ b/crates/ide_db/src/defs.rs
@@ -516,6 +516,18 @@ impl NameRefClass {
     }
 }
 
+impl_from!(
+    Field, Module, Function, Adt, Variant, Const, Static, Trait, TypeAlias, BuiltinType, Local,
+    GenericParam, Label
+    for Definition
+);
+
+impl From<Impl> for Definition {
+    fn from(impl_: Impl) -> Self {
+        Definition::SelfType(impl_)
+    }
+}
+
 impl AsAssocItem for Definition {
     fn as_assoc_item(self, db: &dyn hir::db::HirDatabase) -> Option<AssocItem> {
         match self {
@@ -527,11 +539,15 @@ impl AsAssocItem for Definition {
     }
 }
 
-impl_from!(
-    Field, Module, Function, Adt, Variant, Const, Static, Trait, TypeAlias, BuiltinType, Local,
-    GenericParam, Label
-    for Definition
-);
+impl From<AssocItem> for Definition {
+    fn from(assoc_item: AssocItem) -> Self {
+        match assoc_item {
+            AssocItem::Function(it) => Definition::Function(it),
+            AssocItem::Const(it) => Definition::Const(it),
+            AssocItem::TypeAlias(it) => Definition::TypeAlias(it),
+        }
+    }
+}
 
 impl From<PathResolution> for Definition {
     fn from(path_resolution: PathResolution) -> Self {
diff --git a/crates/ide_db/src/helpers.rs b/crates/ide_db/src/helpers.rs
index 5c5dbdfb5fe..aae1fba6e93 100644
--- a/crates/ide_db/src/helpers.rs
+++ b/crates/ide_db/src/helpers.rs
@@ -10,7 +10,6 @@ pub mod rust_doc;
 use std::{collections::VecDeque, iter};
 
 use base_db::FileId;
-use either::Either;
 use hir::{ItemInNs, MacroDef, ModuleDef, Name, PathResolution, Semantics};
 use itertools::Itertools;
 use syntax::{
@@ -19,7 +18,7 @@ use syntax::{
     T,
 };
 
-use crate::RootDatabase;
+use crate::{defs::Definition, RootDatabase};
 
 pub use self::famous_defs::FamousDefs;
 
@@ -122,7 +121,7 @@ pub fn mod_path_to_ast(path: &hir::ModPath) -> ast::Path {
 pub fn visit_file_defs(
     sema: &Semantics<RootDatabase>,
     file_id: FileId,
-    cb: &mut dyn FnMut(Either<hir::ModuleDef, hir::Impl>),
+    cb: &mut dyn FnMut(Definition),
 ) {
     let db = sema.db;
     let module = match sema.to_module_def(file_id) {
@@ -134,12 +133,12 @@ pub fn visit_file_defs(
         if let ModuleDef::Module(submodule) = def {
             if let hir::ModuleSource::Module(_) = submodule.definition_source(db).value {
                 defs.extend(submodule.declarations(db));
-                submodule.impl_defs(db).into_iter().for_each(|impl_| cb(Either::Right(impl_)));
+                submodule.impl_defs(db).into_iter().for_each(|impl_| cb(impl_.into()));
             }
         }
-        cb(Either::Left(def));
+        cb(def.into());
     }
-    module.impl_defs(db).into_iter().for_each(|impl_| cb(Either::Right(impl_)));
+    module.impl_defs(db).into_iter().for_each(|impl_| cb(impl_.into()));
 }
 
 #[derive(Clone, Copy, Debug, PartialEq, Eq)]