From cb3767f28a2f9e443b816b17d5d07b6a1cff90ab Mon Sep 17 00:00:00 2001 From: Martin Asquino Date: Mon, 4 Nov 2019 10:33:10 -0300 Subject: HirDatabase stored attributes --- crates/ra_hir/src/code_model.rs | 1 + crates/ra_hir/src/code_model/attrs.rs | 92 +++++++++++++++++++++++++++++++++++ crates/ra_hir/src/db.rs | 4 ++ crates/ra_hir/src/lib.rs | 1 + 4 files changed, 98 insertions(+) create mode 100644 crates/ra_hir/src/code_model/attrs.rs (limited to 'crates/ra_hir/src') diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index 181c5d47a..c29c2448e 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs @@ -2,6 +2,7 @@ pub(crate) mod src; pub(crate) mod docs; +pub(crate) mod attrs; use std::sync::Arc; diff --git a/crates/ra_hir/src/code_model/attrs.rs b/crates/ra_hir/src/code_model/attrs.rs new file mode 100644 index 000000000..f7db36b66 --- /dev/null +++ b/crates/ra_hir/src/code_model/attrs.rs @@ -0,0 +1,92 @@ +//! 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; +use hir_expand::hygiene::Hygiene; +use ra_syntax::ast; +use std::sync::Arc; + +#[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 Attrs { + fn attrs(&self, db: &impl HirDatabase) -> Option>; +} + +pub(crate) fn attributes_query( + db: &(impl DefDatabase + AstDatabase), + def: AttrDef, +) -> Option> { + match def { + AttrDef::Module(it) => { + let src = it.declaration_source(db)?; + let hygiene = Hygiene::new(db, src.file_id); + Attr::from_attrs_owner(&src.ast, &hygiene) + } + AttrDef::StructField(it) => match it.source(db).ast { + FieldSource::Named(named) => { + let src = it.source(db); + let hygiene = Hygiene::new(db, src.file_id); + Attr::from_attrs_owner(&named, &hygiene) + } + FieldSource::Pos(..) => None, + }, + 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(node: T, db: &D) -> Option> +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.ast, &hygiene) +} + +impl + Copy> Attrs for T { + fn attrs(&self, db: &impl HirDatabase) -> Option> { + db.attrs((*self).into()) + } +} diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs index eb66325f7..799cc0209 100644 --- a/crates/ra_hir/src/db.rs +++ b/crates/ra_hir/src/db.rs @@ -2,6 +2,7 @@ use std::sync::Arc; +use hir_def::attr::Attr; use ra_db::salsa; use ra_syntax::SmolStr; @@ -75,6 +76,9 @@ pub trait DefDatabase: HirDebugDatabase + DefDatabase2 { #[salsa::invoke(crate::code_model::docs::documentation_query)] fn documentation(&self, def: crate::DocDef) -> Option; + + #[salsa::invoke(crate::code_model::attrs::attributes_query)] + fn attrs(&self, def: crate::AttrDef) -> Option>; } #[salsa::query_group(HirDatabaseStorage)] diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs index 3ba99d92d..4003f0b7a 100644 --- a/crates/ra_hir/src/lib.rs +++ b/crates/ra_hir/src/lib.rs @@ -61,6 +61,7 @@ use crate::{ids::MacroFileKind, resolve::Resolver}; pub use crate::{ adt::VariantDef, code_model::{ + attrs::{AttrDef, Attrs}, docs::{DocDef, Docs, Documentation}, src::{HasBodySource, HasSource}, Adt, AssocItem, Const, ConstData, Container, Crate, CrateDependency, DefWithBody, Enum, -- cgit v1.2.3