]> git.lizzy.rs Git - rust.git/commitdiff
Move attrs query to hir_def
authorAleksey Kladov <aleksey.kladov@gmail.com>
Sat, 23 Nov 2019 08:14:10 +0000 (11:14 +0300)
committerAleksey Kladov <aleksey.kladov@gmail.com>
Sat, 23 Nov 2019 08:14:40 +0000 (11:14 +0300)
crates/ra_hir/src/code_model.rs
crates/ra_hir/src/code_model/attrs.rs [deleted file]
crates/ra_hir/src/code_model/src.rs
crates/ra_hir/src/db.rs
crates/ra_hir/src/from_id.rs
crates/ra_hir/src/lib.rs
crates/ra_hir_def/src/attr.rs
crates/ra_hir_def/src/db.rs
crates/ra_hir_def/src/lib.rs
crates/ra_hir_def/src/nameres.rs

index 9f8c6c4a52b3b468c828ef2cca13eff6e4f973b0..496b4ee8a4efaae4981f71aefe734b1f842dbf34 100644 (file)
@@ -2,7 +2,6 @@
 
 pub(crate) mod src;
 pub(crate) mod docs;
-pub(crate) mod attrs;
 
 use std::sync::Arc;
 
@@ -13,8 +12,8 @@
     nameres::per_ns::PerNs,
     resolver::{HasResolver, TypeNs},
     type_ref::TypeRef,
-    ContainerId, CrateModuleId, HasModule, ImplId, LocalEnumVariantId, LocalStructFieldId, Lookup,
-    ModuleId, UnionId,
+    AdtId, ContainerId, CrateModuleId, EnumVariantId, HasModule, ImplId, LocalEnumVariantId,
+    LocalStructFieldId, Lookup, ModuleId, StructFieldId, UnionId,
 };
 use hir_expand::{
     diagnostics::DiagnosticSink,
@@ -110,7 +109,7 @@ pub enum ModuleDef {
     BuiltinType
 );
 
-pub use hir_def::ModuleSource;
+pub use hir_def::{attr::Attrs, ModuleSource};
 
 impl Module {
     pub(crate) fn new(krate: Crate, crate_module_id: CrateModuleId) -> Module {
@@ -991,3 +990,52 @@ fn from(def: PerNs) -> Self {
             .unwrap_or(ScopeDef::Unknown)
     }
 }
+
+#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
+pub enum AttrDef {
+    Module(Module),
+    StructField(StructField),
+    Adt(Adt),
+    Function(Function),
+    EnumVariant(EnumVariant),
+    Static(Static),
+    Const(Const),
+    Trait(Trait),
+    TypeAlias(TypeAlias),
+    MacroDef(MacroDef),
+}
+
+impl_froms!(
+    AttrDef: Module,
+    StructField,
+    Adt(Struct, Enum, Union),
+    EnumVariant,
+    Static,
+    Const,
+    Function,
+    Trait,
+    TypeAlias,
+    MacroDef
+);
+
+pub trait HasAttrs {
+    fn attrs(self, db: &impl DefDatabase) -> Attrs;
+}
+
+impl<T: Into<AttrDef>> HasAttrs for T {
+    fn attrs(self, db: &impl DefDatabase) -> Attrs {
+        let def = self.into();
+        match def {
+            AttrDef::Module(it) => db.attrs(it.id.into()),
+            AttrDef::StructField(it) => db.attrs(StructFieldId::from(it).into()),
+            AttrDef::Adt(it) => db.attrs(AdtId::from(it).into()),
+            AttrDef::Function(it) => db.attrs(it.id.into()),
+            AttrDef::EnumVariant(it) => db.attrs(EnumVariantId::from(it).into()),
+            AttrDef::Static(it) => db.attrs(it.id.into()),
+            AttrDef::Const(it) => db.attrs(it.id.into()),
+            AttrDef::Trait(it) => db.attrs(it.id.into()),
+            AttrDef::TypeAlias(it) => db.attrs(it.id.into()),
+            AttrDef::MacroDef(it) => db.attrs(it.id.into()),
+        }
+    }
+}
diff --git a/crates/ra_hir/src/code_model/attrs.rs b/crates/ra_hir/src/code_model/attrs.rs
deleted file mode 100644 (file)
index 96da8c8..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-//! FIXME: write short doc here
-
-use crate::{
-    db::{AstDatabase, DefDatabase, HirDatabase},
-    Adt, Const, Enum, EnumVariant, FieldSource, Function, HasSource, MacroDef, Module, Static,
-    Struct, StructField, Trait, TypeAlias, Union,
-};
-use hir_def::attr::{Attr, Attrs};
-use hir_expand::hygiene::Hygiene;
-use ra_syntax::ast;
-
-#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
-pub enum AttrDef {
-    Module(Module),
-    StructField(StructField),
-    Adt(Adt),
-    Function(Function),
-    EnumVariant(EnumVariant),
-    Static(Static),
-    Const(Const),
-    Trait(Trait),
-    TypeAlias(TypeAlias),
-    MacroDef(MacroDef),
-}
-
-impl_froms!(
-    AttrDef: Module,
-    StructField,
-    Adt(Struct, Enum, Union),
-    EnumVariant,
-    Static,
-    Const,
-    Function,
-    Trait,
-    TypeAlias,
-    MacroDef
-);
-
-pub trait HasAttrs {
-    fn attrs(&self, db: &impl HirDatabase) -> Attrs;
-}
-
-pub(crate) fn attributes_query(db: &(impl DefDatabase + AstDatabase), def: AttrDef) -> Attrs {
-    match def {
-        AttrDef::Module(it) => {
-            let src = match it.declaration_source(db) {
-                Some(it) => it,
-                None => return Attrs::default(),
-            };
-            let hygiene = Hygiene::new(db, src.file_id);
-            Attr::from_attrs_owner(&src.value, &hygiene)
-        }
-        AttrDef::StructField(it) => match it.source(db).value {
-            FieldSource::Named(named) => {
-                let src = it.source(db);
-                let hygiene = Hygiene::new(db, src.file_id);
-                Attr::from_attrs_owner(&named, &hygiene)
-            }
-            FieldSource::Pos(..) => Attrs::default(),
-        },
-        AttrDef::Adt(it) => match it {
-            Adt::Struct(it) => attrs_from_ast(it, db),
-            Adt::Enum(it) => attrs_from_ast(it, db),
-            Adt::Union(it) => attrs_from_ast(it, db),
-        },
-        AttrDef::EnumVariant(it) => attrs_from_ast(it, db),
-        AttrDef::Static(it) => attrs_from_ast(it, db),
-        AttrDef::Const(it) => attrs_from_ast(it, db),
-        AttrDef::Function(it) => attrs_from_ast(it, db),
-        AttrDef::Trait(it) => attrs_from_ast(it, db),
-        AttrDef::TypeAlias(it) => attrs_from_ast(it, db),
-        AttrDef::MacroDef(it) => attrs_from_ast(it, db),
-    }
-}
-
-fn attrs_from_ast<T, D>(node: T, db: &D) -> Attrs
-where
-    T: HasSource,
-    T::Ast: ast::AttrsOwner,
-    D: DefDatabase + AstDatabase,
-{
-    let src = node.source(db);
-    let hygiene = Hygiene::new(db, src.file_id);
-    Attr::from_attrs_owner(&src.value, &hygiene)
-}
-
-impl<T: Into<AttrDef> + Copy> HasAttrs for T {
-    fn attrs(&self, db: &impl HirDatabase) -> Attrs {
-        db.attrs((*self).into())
-    }
-}
index a45c062bf4c2bca6258ff154ed53cab506124db5..09bacf5790aa91c329fc326ba177e90d7114cb5e 100644 (file)
@@ -1,13 +1,14 @@
 //! FIXME: write short doc here
 
 use hir_def::{HasChildSource, HasSource as _, Lookup, VariantId};
+use hir_expand::either::Either;
 use ra_syntax::ast::{self, AstNode};
 
 use crate::{
     db::{AstDatabase, DefDatabase, HirDatabase},
     ids::AstItemDef,
-    Const, Either, Enum, EnumVariant, FieldSource, Function, HasBody, HirFileId, MacroDef, Module,
-    ModuleSource, Static, Struct, StructField, Trait, TypeAlias, Union,
+    Const, Enum, EnumVariant, FieldSource, Function, HasBody, MacroDef, Module, ModuleSource,
+    Static, Struct, StructField, Trait, TypeAlias, Union,
 };
 
 pub use hir_expand::Source;
@@ -23,11 +24,11 @@ impl Module {
     /// Returns a node which defines this module. That is, a file or a `mod foo {}` with items.
     pub fn definition_source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ModuleSource> {
         let def_map = db.crate_def_map(self.id.krate);
-        let decl_id = def_map[self.id.module_id].declaration;
-        let file_id = def_map[self.id.module_id].definition;
-        let value = ModuleSource::new(db, file_id, decl_id);
-        let file_id = file_id.map(HirFileId::from).unwrap_or_else(|| decl_id.unwrap().file_id());
-        Source { file_id, value }
+        let src = def_map[self.id.module_id].definition_source(db);
+        src.map(|it| match it {
+            Either::A(it) => ModuleSource::SourceFile(it),
+            Either::B(it) => ModuleSource::Module(it),
+        })
     }
 
     /// Returns a node which declares this module, either a `mod foo;` or a `mod foo {}`.
@@ -37,9 +38,7 @@ pub fn declaration_source(
         db: &(impl DefDatabase + AstDatabase),
     ) -> Option<Source<ast::Module>> {
         let def_map = db.crate_def_map(self.id.krate);
-        let decl = def_map[self.id.module_id].declaration?;
-        let value = decl.to_node(db);
-        Some(Source { file_id: decl.file_id(), value })
+        def_map[self.id.module_id].declaration_source(db)
     }
 }
 
index 85d46b485f47e246456fe163faf6aaa1557b4007..c3f698ea039d58ef2597c4598423d5fffb362404 100644 (file)
@@ -2,7 +2,6 @@
 
 use std::sync::Arc;
 
-use hir_def::attr::Attrs;
 use ra_db::salsa;
 use ra_syntax::SmolStr;
 
@@ -46,9 +45,6 @@ pub trait DefDatabase: HirDebugDatabase + DefDatabase2 {
 
     #[salsa::invoke(crate::code_model::docs::documentation_query)]
     fn documentation(&self, def: crate::DocDef) -> Option<crate::Documentation>;
-
-    #[salsa::invoke(crate::code_model::attrs::attributes_query)]
-    fn attrs(&self, def: crate::AttrDef) -> Attrs;
 }
 
 #[salsa::query_group(HirDatabaseStorage)]
index 8900fc1f240de56bd6822a74b54cf569cce8a7c9..5d7af00ab9833766906929ae1f7b130a81d0aed2 100644 (file)
@@ -5,13 +5,13 @@
 
 use hir_def::{
     AdtId, AssocItemId, ConstId, DefWithBodyId, EnumId, EnumVariantId, FunctionId, GenericDefId,
-    ModuleDefId, StaticId, StructId, TypeAliasId, UnionId, VariantId,
+    ModuleDefId, StaticId, StructFieldId, StructId, TypeAliasId, UnionId, VariantId,
 };
 
 use crate::{
     ty::{CallableDef, TypableDef},
     Adt, AssocItem, Const, Crate, DefWithBody, EnumVariant, Function, GenericDef, ModuleDef,
-    Static, TypeAlias, VariantDef,
+    Static, StructField, TypeAlias, VariantDef,
 };
 
 impl From<ra_db::CrateId> for Crate {
@@ -234,3 +234,9 @@ fn from(def: VariantDef) -> Self {
         }
     }
 }
+
+impl From<StructField> for StructFieldId {
+    fn from(def: StructField) -> Self {
+        StructFieldId { parent: def.parent.into(), local_id: def.id }
+    }
+}
index e164c9b3275fc17a1f889954db25335d528bf319..152590cd1719737f882c20461ac87150f8852c35 100644 (file)
@@ -51,13 +51,12 @@ fn from(it: $sv) -> $e {
 
 pub use crate::{
     code_model::{
-        attrs::{AttrDef, HasAttrs},
         docs::{DocDef, Docs, Documentation},
         src::{HasBodySource, HasSource},
-        Adt, AssocItem, Const, Container, Crate, CrateDependency, DefWithBody, Enum, EnumVariant,
-        FieldSource, Function, GenericDef, GenericParam, HasBody, ImplBlock, Local, MacroDef,
-        Module, ModuleDef, ModuleSource, ScopeDef, Static, Struct, StructField, Trait, TypeAlias,
-        Union, VariantDef,
+        Adt, AssocItem, AttrDef, Const, Container, Crate, CrateDependency, DefWithBody, Enum,
+        EnumVariant, FieldSource, Function, GenericDef, GenericParam, HasAttrs, HasBody, ImplBlock,
+        Local, MacroDef, Module, ModuleDef, ModuleSource, ScopeDef, Static, Struct, StructField,
+        Trait, TypeAlias, Union, VariantDef,
     },
     expr::ExprScopes,
     from_source::FromSource,
index 7a9d0fdf4404ac00c2a45b2c1a9360c39071b2e7..ce397f6b06c8480a4f4163244622746604cd1cf1 100644 (file)
@@ -2,7 +2,7 @@
 
 use std::{ops, sync::Arc};
 
-use hir_expand::hygiene::Hygiene;
+use hir_expand::{either::Either, hygiene::Hygiene, AstId};
 use mbe::ast_to_token_tree;
 use ra_cfg::CfgOptions;
 use ra_syntax::{
@@ -11,7 +11,9 @@
 };
 use tt::Subtree;
 
-use crate::path::Path;
+use crate::{
+    db::DefDatabase2, path::Path, AdtId, AstItemDef, AttrDefId, HasChildSource, HasSource, Lookup,
+};
 
 #[derive(Default, Debug, Clone, PartialEq, Eq)]
 pub struct Attrs {
@@ -30,6 +32,46 @@ fn deref(&self) -> &[Attr] {
 }
 
 impl Attrs {
+    pub(crate) fn attrs_query(db: &impl DefDatabase2, def: AttrDefId) -> Attrs {
+        match def {
+            AttrDefId::ModuleId(module) => {
+                let def_map = db.crate_def_map(module.krate);
+                let src = match def_map[module.module_id].declaration_source(db) {
+                    Some(it) => it,
+                    None => return Attrs::default(),
+                };
+                let hygiene = Hygiene::new(db, src.file_id);
+                Attr::from_attrs_owner(&src.value, &hygiene)
+            }
+            AttrDefId::StructFieldId(it) => {
+                let src = it.parent.child_source(db);
+                match &src.value[it.local_id] {
+                    Either::A(_tuple) => Attrs::default(),
+                    Either::B(record) => {
+                        let hygiene = Hygiene::new(db, src.file_id);
+                        Attr::from_attrs_owner(record, &hygiene)
+                    }
+                }
+            }
+            AttrDefId::AdtId(it) => match it {
+                AdtId::StructId(it) => attrs_from_ast(it.0.lookup_intern(db).ast_id, db),
+                AdtId::EnumId(it) => attrs_from_ast(it.lookup_intern(db).ast_id, db),
+                AdtId::UnionId(it) => attrs_from_ast(it.0.lookup_intern(db).ast_id, db),
+            },
+            AttrDefId::EnumVariantId(it) => {
+                let src = it.parent.child_source(db);
+                let hygiene = Hygiene::new(db, src.file_id);
+                Attr::from_attrs_owner(&src.value[it.local_id], &hygiene)
+            }
+            AttrDefId::StaticId(it) => attrs_from_ast(it.lookup_intern(db).ast_id, db),
+            AttrDefId::ConstId(it) => attrs_from_loc(it.lookup(db), db),
+            AttrDefId::FunctionId(it) => attrs_from_loc(it.lookup(db), db),
+            AttrDefId::TraitId(it) => attrs_from_ast(it.lookup_intern(db).ast_id, db),
+            AttrDefId::TypeAliasId(it) => attrs_from_loc(it.lookup(db), db),
+            AttrDefId::MacroDefId(it) => attrs_from_ast(it.ast_id, db),
+        }
+    }
+
     pub fn has_atom(&self, atom: &str) -> bool {
         self.iter().any(|it| it.is_simple_atom(atom))
     }
@@ -106,3 +148,23 @@ pub fn is_cfg_enabled(&self, cfg_options: &CfgOptions) -> Option<bool> {
         cfg_options.is_cfg_enabled(self.as_cfg()?)
     }
 }
+
+fn attrs_from_ast<D, N>(src: AstId<N>, db: &D) -> Attrs
+where
+    N: ast::AttrsOwner,
+    D: DefDatabase2,
+{
+    let hygiene = Hygiene::new(db, src.file_id());
+    Attr::from_attrs_owner(&src.to_node(db), &hygiene)
+}
+
+fn attrs_from_loc<T, D>(node: T, db: &D) -> Attrs
+where
+    T: HasSource,
+    T::Value: ast::AttrsOwner,
+    D: DefDatabase2,
+{
+    let src = node.source(db);
+    let hygiene = Hygiene::new(db, src.file_id);
+    Attr::from_attrs_owner(&src.value, &hygiene)
+}
index 2c660ab88bd73207d26e29dba6f968de86186a58..e91e741bb9b896b0dde0f69addd0042e1fa5fa36 100644 (file)
@@ -7,6 +7,7 @@
 
 use crate::{
     adt::{EnumData, StructData},
+    attr::Attrs,
     body::{scope::ExprScopes, Body, BodySourceMap},
     data::{ConstData, FunctionData, ImplData, TraitData, TypeAliasData},
     generics::GenericParams,
@@ -14,7 +15,7 @@
         raw::{ImportSourceMap, RawItems},
         CrateDefMap,
     },
-    ConstId, DefWithBodyId, EnumId, FunctionId, GenericDefId, ImplId, ItemLoc, StaticId,
+    AttrDefId, ConstId, DefWithBodyId, EnumId, FunctionId, GenericDefId, ImplId, ItemLoc, StaticId,
     StructOrUnionId, TraitId, TypeAliasId,
 };
 
@@ -87,4 +88,7 @@ fn raw_items_with_source_map(
 
     #[salsa::invoke(GenericParams::generic_params_query)]
     fn generic_params(&self, def: GenericDefId) -> Arc<GenericParams>;
+
+    #[salsa::invoke(Attrs::attrs_query)]
+    fn attrs(&self, def: AttrDefId) -> Attrs;
 }
index 2edf743abba781b15717f440ca85d929ae21af64..1bcdf9b7891fc6d22dabed3a4c6ba3343e3e00ce 100644 (file)
@@ -32,7 +32,7 @@
 
 use std::hash::{Hash, Hasher};
 
-use hir_expand::{ast_id_map::FileAstId, db::AstDatabase, AstId, HirFileId, Source};
+use hir_expand::{ast_id_map::FileAstId, db::AstDatabase, AstId, HirFileId, MacroDefId, Source};
 use ra_arena::{impl_arena_id, map::ArenaMap, RawId};
 use ra_db::{salsa, CrateId, FileId};
 use ra_syntax::{ast, AstNode, SyntaxNode};
@@ -280,8 +280,8 @@ pub enum VariantId {
 
 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 pub struct StructFieldId {
-    parent: VariantId,
-    local_id: LocalStructFieldId,
+    pub parent: VariantId,
+    pub local_id: LocalStructFieldId,
 }
 
 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@@ -477,6 +477,33 @@ pub enum GenericDefId {
     ConstId
 );
 
+#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
+pub enum AttrDefId {
+    ModuleId(ModuleId),
+    StructFieldId(StructFieldId),
+    AdtId(AdtId),
+    FunctionId(FunctionId),
+    EnumVariantId(EnumVariantId),
+    StaticId(StaticId),
+    ConstId(ConstId),
+    TraitId(TraitId),
+    TypeAliasId(TypeAliasId),
+    MacroDefId(MacroDefId),
+}
+
+impl_froms!(
+    AttrDefId: ModuleId,
+    StructFieldId,
+    AdtId(StructId, EnumId, UnionId),
+    EnumVariantId,
+    StaticId,
+    ConstId,
+    FunctionId,
+    TraitId,
+    TypeAliasId,
+    MacroDefId
+);
+
 trait Intern {
     type ID;
     fn intern(self, db: &impl db::DefDatabase2) -> Self::ID;
index c01e020ef12e00b6d8789019c778edf9938162ce..6723465a591d78cad6b73fd171c770cc59d49b87 100644 (file)
 
 use std::sync::Arc;
 
-use hir_expand::{ast_id_map::FileAstId, diagnostics::DiagnosticSink, name::Name, MacroDefId};
+use hir_expand::{
+    ast_id_map::FileAstId, diagnostics::DiagnosticSink, either::Either, name::Name, MacroDefId,
+    Source,
+};
 use once_cell::sync::Lazy;
 use ra_arena::Arena;
 use ra_db::{CrateId, Edition, FileId};
@@ -116,12 +119,15 @@ pub struct ModuleData {
     pub parent: Option<CrateModuleId>,
     pub children: FxHashMap<Name, CrateModuleId>,
     pub scope: ModuleScope,
+
+    //  FIXME: these can't be both null, we need a three-state enum here.
     /// None for root
     pub declaration: Option<AstId<ast::Module>>,
     /// None for inline modules.
     ///
     /// Note that non-inline modules, by definition, live inside non-macro file.
     pub definition: Option<FileId>,
+
     pub impls: Vec<ImplId>,
 }
 
@@ -285,6 +291,29 @@ pub fn modules_for_file(&self, file_id: FileId) -> impl Iterator<Item = CrateMod
     }
 }
 
+impl ModuleData {
+    /// Returns a node which defines this module. That is, a file or a `mod foo {}` with items.
+    pub fn definition_source(
+        &self,
+        db: &impl DefDatabase2,
+    ) -> Source<Either<ast::SourceFile, ast::Module>> {
+        if let Some(file_id) = self.definition {
+            let sf = db.parse(file_id).tree();
+            return Source::new(file_id.into(), Either::A(sf));
+        }
+        let decl = self.declaration.unwrap();
+        Source::new(decl.file_id(), Either::B(decl.to_node(db)))
+    }
+
+    /// Returns a node which declares this module, either a `mod foo;` or a `mod foo {}`.
+    /// `None` for the crate root.
+    pub fn declaration_source(&self, db: &impl DefDatabase2) -> Option<Source<ast::Module>> {
+        let decl = self.declaration?;
+        let value = decl.to_node(db);
+        Some(Source { file_id: decl.file_id(), value })
+    }
+}
+
 mod diagnostics {
     use hir_expand::diagnostics::DiagnosticSink;
     use ra_db::RelativePathBuf;