diff options
author | Aleksey Kladov <[email protected]> | 2019-11-23 08:14:10 +0000 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2019-11-23 08:14:40 +0000 |
commit | 552ba868afc8f72202ac834d07bbeb330aca007d (patch) | |
tree | cd57fc21ce442e84bdc41241a70ece9995d826af /crates | |
parent | 81bfbd26bef1a63ccbeba33430e6b07a53c8e7d9 (diff) |
Move attrs query to hir_def
Diffstat (limited to 'crates')
-rw-r--r-- | crates/ra_hir/src/code_model.rs | 56 | ||||
-rw-r--r-- | crates/ra_hir/src/code_model/attrs.rs | 91 | ||||
-rw-r--r-- | crates/ra_hir/src/code_model/src.rs | 19 | ||||
-rw-r--r-- | crates/ra_hir/src/db.rs | 4 | ||||
-rw-r--r-- | crates/ra_hir/src/from_id.rs | 10 | ||||
-rw-r--r-- | crates/ra_hir/src/lib.rs | 9 | ||||
-rw-r--r-- | crates/ra_hir_def/src/attr.rs | 66 | ||||
-rw-r--r-- | crates/ra_hir_def/src/db.rs | 6 | ||||
-rw-r--r-- | crates/ra_hir_def/src/lib.rs | 33 | ||||
-rw-r--r-- | crates/ra_hir_def/src/nameres.rs | 31 |
10 files changed, 202 insertions, 123 deletions
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index 9f8c6c4a5..496b4ee8a 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs | |||
@@ -2,7 +2,6 @@ | |||
2 | 2 | ||
3 | pub(crate) mod src; | 3 | pub(crate) mod src; |
4 | pub(crate) mod docs; | 4 | pub(crate) mod docs; |
5 | pub(crate) mod attrs; | ||
6 | 5 | ||
7 | use std::sync::Arc; | 6 | use std::sync::Arc; |
8 | 7 | ||
@@ -13,8 +12,8 @@ use hir_def::{ | |||
13 | nameres::per_ns::PerNs, | 12 | nameres::per_ns::PerNs, |
14 | resolver::{HasResolver, TypeNs}, | 13 | resolver::{HasResolver, TypeNs}, |
15 | type_ref::TypeRef, | 14 | type_ref::TypeRef, |
16 | ContainerId, CrateModuleId, HasModule, ImplId, LocalEnumVariantId, LocalStructFieldId, Lookup, | 15 | AdtId, ContainerId, CrateModuleId, EnumVariantId, HasModule, ImplId, LocalEnumVariantId, |
17 | ModuleId, UnionId, | 16 | LocalStructFieldId, Lookup, ModuleId, StructFieldId, UnionId, |
18 | }; | 17 | }; |
19 | use hir_expand::{ | 18 | use hir_expand::{ |
20 | diagnostics::DiagnosticSink, | 19 | diagnostics::DiagnosticSink, |
@@ -110,7 +109,7 @@ impl_froms!( | |||
110 | BuiltinType | 109 | BuiltinType |
111 | ); | 110 | ); |
112 | 111 | ||
113 | pub use hir_def::ModuleSource; | 112 | pub use hir_def::{attr::Attrs, ModuleSource}; |
114 | 113 | ||
115 | impl Module { | 114 | impl Module { |
116 | pub(crate) fn new(krate: Crate, crate_module_id: CrateModuleId) -> Module { | 115 | pub(crate) fn new(krate: Crate, crate_module_id: CrateModuleId) -> Module { |
@@ -991,3 +990,52 @@ impl From<PerNs> for ScopeDef { | |||
991 | .unwrap_or(ScopeDef::Unknown) | 990 | .unwrap_or(ScopeDef::Unknown) |
992 | } | 991 | } |
993 | } | 992 | } |
993 | |||
994 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] | ||
995 | pub enum AttrDef { | ||
996 | Module(Module), | ||
997 | StructField(StructField), | ||
998 | Adt(Adt), | ||
999 | Function(Function), | ||
1000 | EnumVariant(EnumVariant), | ||
1001 | Static(Static), | ||
1002 | Const(Const), | ||
1003 | Trait(Trait), | ||
1004 | TypeAlias(TypeAlias), | ||
1005 | MacroDef(MacroDef), | ||
1006 | } | ||
1007 | |||
1008 | impl_froms!( | ||
1009 | AttrDef: Module, | ||
1010 | StructField, | ||
1011 | Adt(Struct, Enum, Union), | ||
1012 | EnumVariant, | ||
1013 | Static, | ||
1014 | Const, | ||
1015 | Function, | ||
1016 | Trait, | ||
1017 | TypeAlias, | ||
1018 | MacroDef | ||
1019 | ); | ||
1020 | |||
1021 | pub trait HasAttrs { | ||
1022 | fn attrs(self, db: &impl DefDatabase) -> Attrs; | ||
1023 | } | ||
1024 | |||
1025 | impl<T: Into<AttrDef>> HasAttrs for T { | ||
1026 | fn attrs(self, db: &impl DefDatabase) -> Attrs { | ||
1027 | let def = self.into(); | ||
1028 | match def { | ||
1029 | AttrDef::Module(it) => db.attrs(it.id.into()), | ||
1030 | AttrDef::StructField(it) => db.attrs(StructFieldId::from(it).into()), | ||
1031 | AttrDef::Adt(it) => db.attrs(AdtId::from(it).into()), | ||
1032 | AttrDef::Function(it) => db.attrs(it.id.into()), | ||
1033 | AttrDef::EnumVariant(it) => db.attrs(EnumVariantId::from(it).into()), | ||
1034 | AttrDef::Static(it) => db.attrs(it.id.into()), | ||
1035 | AttrDef::Const(it) => db.attrs(it.id.into()), | ||
1036 | AttrDef::Trait(it) => db.attrs(it.id.into()), | ||
1037 | AttrDef::TypeAlias(it) => db.attrs(it.id.into()), | ||
1038 | AttrDef::MacroDef(it) => db.attrs(it.id.into()), | ||
1039 | } | ||
1040 | } | ||
1041 | } | ||
diff --git a/crates/ra_hir/src/code_model/attrs.rs b/crates/ra_hir/src/code_model/attrs.rs deleted file mode 100644 index 96da8c88c..000000000 --- a/crates/ra_hir/src/code_model/attrs.rs +++ /dev/null | |||
@@ -1,91 +0,0 @@ | |||
1 | //! FIXME: write short doc here | ||
2 | |||
3 | use crate::{ | ||
4 | db::{AstDatabase, DefDatabase, HirDatabase}, | ||
5 | Adt, Const, Enum, EnumVariant, FieldSource, Function, HasSource, MacroDef, Module, Static, | ||
6 | Struct, StructField, Trait, TypeAlias, Union, | ||
7 | }; | ||
8 | use hir_def::attr::{Attr, Attrs}; | ||
9 | use hir_expand::hygiene::Hygiene; | ||
10 | use ra_syntax::ast; | ||
11 | |||
12 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] | ||
13 | pub enum AttrDef { | ||
14 | Module(Module), | ||
15 | StructField(StructField), | ||
16 | Adt(Adt), | ||
17 | Function(Function), | ||
18 | EnumVariant(EnumVariant), | ||
19 | Static(Static), | ||
20 | Const(Const), | ||
21 | Trait(Trait), | ||
22 | TypeAlias(TypeAlias), | ||
23 | MacroDef(MacroDef), | ||
24 | } | ||
25 | |||
26 | impl_froms!( | ||
27 | AttrDef: Module, | ||
28 | StructField, | ||
29 | Adt(Struct, Enum, Union), | ||
30 | EnumVariant, | ||
31 | Static, | ||
32 | Const, | ||
33 | Function, | ||
34 | Trait, | ||
35 | TypeAlias, | ||
36 | MacroDef | ||
37 | ); | ||
38 | |||
39 | pub trait HasAttrs { | ||
40 | fn attrs(&self, db: &impl HirDatabase) -> Attrs; | ||
41 | } | ||
42 | |||
43 | pub(crate) fn attributes_query(db: &(impl DefDatabase + AstDatabase), def: AttrDef) -> Attrs { | ||
44 | match def { | ||
45 | AttrDef::Module(it) => { | ||
46 | let src = match it.declaration_source(db) { | ||
47 | Some(it) => it, | ||
48 | None => return Attrs::default(), | ||
49 | }; | ||
50 | let hygiene = Hygiene::new(db, src.file_id); | ||
51 | Attr::from_attrs_owner(&src.value, &hygiene) | ||
52 | } | ||
53 | AttrDef::StructField(it) => match it.source(db).value { | ||
54 | FieldSource::Named(named) => { | ||
55 | let src = it.source(db); | ||
56 | let hygiene = Hygiene::new(db, src.file_id); | ||
57 | Attr::from_attrs_owner(&named, &hygiene) | ||
58 | } | ||
59 | FieldSource::Pos(..) => Attrs::default(), | ||
60 | }, | ||
61 | AttrDef::Adt(it) => match it { | ||
62 | Adt::Struct(it) => attrs_from_ast(it, db), | ||
63 | Adt::Enum(it) => attrs_from_ast(it, db), | ||
64 | Adt::Union(it) => attrs_from_ast(it, db), | ||
65 | }, | ||
66 | AttrDef::EnumVariant(it) => attrs_from_ast(it, db), | ||
67 | AttrDef::Static(it) => attrs_from_ast(it, db), | ||
68 | AttrDef::Const(it) => attrs_from_ast(it, db), | ||
69 | AttrDef::Function(it) => attrs_from_ast(it, db), | ||
70 | AttrDef::Trait(it) => attrs_from_ast(it, db), | ||
71 | AttrDef::TypeAlias(it) => attrs_from_ast(it, db), | ||
72 | AttrDef::MacroDef(it) => attrs_from_ast(it, db), | ||
73 | } | ||
74 | } | ||
75 | |||
76 | fn attrs_from_ast<T, D>(node: T, db: &D) -> Attrs | ||
77 | where | ||
78 | T: HasSource, | ||
79 | T::Ast: ast::AttrsOwner, | ||
80 | D: DefDatabase + AstDatabase, | ||
81 | { | ||
82 | let src = node.source(db); | ||
83 | let hygiene = Hygiene::new(db, src.file_id); | ||
84 | Attr::from_attrs_owner(&src.value, &hygiene) | ||
85 | } | ||
86 | |||
87 | impl<T: Into<AttrDef> + Copy> HasAttrs for T { | ||
88 | fn attrs(&self, db: &impl HirDatabase) -> Attrs { | ||
89 | db.attrs((*self).into()) | ||
90 | } | ||
91 | } | ||
diff --git a/crates/ra_hir/src/code_model/src.rs b/crates/ra_hir/src/code_model/src.rs index a45c062bf..09bacf579 100644 --- a/crates/ra_hir/src/code_model/src.rs +++ b/crates/ra_hir/src/code_model/src.rs | |||
@@ -1,13 +1,14 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! FIXME: write short doc here |
2 | 2 | ||
3 | use hir_def::{HasChildSource, HasSource as _, Lookup, VariantId}; | 3 | use hir_def::{HasChildSource, HasSource as _, Lookup, VariantId}; |
4 | use hir_expand::either::Either; | ||
4 | use ra_syntax::ast::{self, AstNode}; | 5 | use ra_syntax::ast::{self, AstNode}; |
5 | 6 | ||
6 | use crate::{ | 7 | use crate::{ |
7 | db::{AstDatabase, DefDatabase, HirDatabase}, | 8 | db::{AstDatabase, DefDatabase, HirDatabase}, |
8 | ids::AstItemDef, | 9 | ids::AstItemDef, |
9 | Const, Either, Enum, EnumVariant, FieldSource, Function, HasBody, HirFileId, MacroDef, Module, | 10 | Const, Enum, EnumVariant, FieldSource, Function, HasBody, MacroDef, Module, ModuleSource, |
10 | ModuleSource, Static, Struct, StructField, Trait, TypeAlias, Union, | 11 | Static, Struct, StructField, Trait, TypeAlias, Union, |
11 | }; | 12 | }; |
12 | 13 | ||
13 | pub use hir_expand::Source; | 14 | pub use hir_expand::Source; |
@@ -23,11 +24,11 @@ impl Module { | |||
23 | /// Returns a node which defines this module. That is, a file or a `mod foo {}` with items. | 24 | /// Returns a node which defines this module. That is, a file or a `mod foo {}` with items. |
24 | pub fn definition_source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ModuleSource> { | 25 | pub fn definition_source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ModuleSource> { |
25 | let def_map = db.crate_def_map(self.id.krate); | 26 | let def_map = db.crate_def_map(self.id.krate); |
26 | let decl_id = def_map[self.id.module_id].declaration; | 27 | let src = def_map[self.id.module_id].definition_source(db); |
27 | let file_id = def_map[self.id.module_id].definition; | 28 | src.map(|it| match it { |
28 | let value = ModuleSource::new(db, file_id, decl_id); | 29 | Either::A(it) => ModuleSource::SourceFile(it), |
29 | let file_id = file_id.map(HirFileId::from).unwrap_or_else(|| decl_id.unwrap().file_id()); | 30 | Either::B(it) => ModuleSource::Module(it), |
30 | Source { file_id, value } | 31 | }) |
31 | } | 32 | } |
32 | 33 | ||
33 | /// Returns a node which declares this module, either a `mod foo;` or a `mod foo {}`. | 34 | /// Returns a node which declares this module, either a `mod foo;` or a `mod foo {}`. |
@@ -37,9 +38,7 @@ impl Module { | |||
37 | db: &(impl DefDatabase + AstDatabase), | 38 | db: &(impl DefDatabase + AstDatabase), |
38 | ) -> Option<Source<ast::Module>> { | 39 | ) -> Option<Source<ast::Module>> { |
39 | let def_map = db.crate_def_map(self.id.krate); | 40 | let def_map = db.crate_def_map(self.id.krate); |
40 | let decl = def_map[self.id.module_id].declaration?; | 41 | def_map[self.id.module_id].declaration_source(db) |
41 | let value = decl.to_node(db); | ||
42 | Some(Source { file_id: decl.file_id(), value }) | ||
43 | } | 42 | } |
44 | } | 43 | } |
45 | 44 | ||
diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs index 85d46b485..c3f698ea0 100644 --- a/crates/ra_hir/src/db.rs +++ b/crates/ra_hir/src/db.rs | |||
@@ -2,7 +2,6 @@ | |||
2 | 2 | ||
3 | use std::sync::Arc; | 3 | use std::sync::Arc; |
4 | 4 | ||
5 | use hir_def::attr::Attrs; | ||
6 | use ra_db::salsa; | 5 | use ra_db::salsa; |
7 | use ra_syntax::SmolStr; | 6 | use ra_syntax::SmolStr; |
8 | 7 | ||
@@ -46,9 +45,6 @@ pub trait DefDatabase: HirDebugDatabase + DefDatabase2 { | |||
46 | 45 | ||
47 | #[salsa::invoke(crate::code_model::docs::documentation_query)] | 46 | #[salsa::invoke(crate::code_model::docs::documentation_query)] |
48 | fn documentation(&self, def: crate::DocDef) -> Option<crate::Documentation>; | 47 | fn documentation(&self, def: crate::DocDef) -> Option<crate::Documentation>; |
49 | |||
50 | #[salsa::invoke(crate::code_model::attrs::attributes_query)] | ||
51 | fn attrs(&self, def: crate::AttrDef) -> Attrs; | ||
52 | } | 48 | } |
53 | 49 | ||
54 | #[salsa::query_group(HirDatabaseStorage)] | 50 | #[salsa::query_group(HirDatabaseStorage)] |
diff --git a/crates/ra_hir/src/from_id.rs b/crates/ra_hir/src/from_id.rs index 8900fc1f2..5d7af00ab 100644 --- a/crates/ra_hir/src/from_id.rs +++ b/crates/ra_hir/src/from_id.rs | |||
@@ -5,13 +5,13 @@ | |||
5 | 5 | ||
6 | use hir_def::{ | 6 | use hir_def::{ |
7 | AdtId, AssocItemId, ConstId, DefWithBodyId, EnumId, EnumVariantId, FunctionId, GenericDefId, | 7 | AdtId, AssocItemId, ConstId, DefWithBodyId, EnumId, EnumVariantId, FunctionId, GenericDefId, |
8 | ModuleDefId, StaticId, StructId, TypeAliasId, UnionId, VariantId, | 8 | ModuleDefId, StaticId, StructFieldId, StructId, TypeAliasId, UnionId, VariantId, |
9 | }; | 9 | }; |
10 | 10 | ||
11 | use crate::{ | 11 | use crate::{ |
12 | ty::{CallableDef, TypableDef}, | 12 | ty::{CallableDef, TypableDef}, |
13 | Adt, AssocItem, Const, Crate, DefWithBody, EnumVariant, Function, GenericDef, ModuleDef, | 13 | Adt, AssocItem, Const, Crate, DefWithBody, EnumVariant, Function, GenericDef, ModuleDef, |
14 | Static, TypeAlias, VariantDef, | 14 | Static, StructField, TypeAlias, VariantDef, |
15 | }; | 15 | }; |
16 | 16 | ||
17 | impl From<ra_db::CrateId> for Crate { | 17 | impl From<ra_db::CrateId> for Crate { |
@@ -234,3 +234,9 @@ impl From<VariantDef> for VariantId { | |||
234 | } | 234 | } |
235 | } | 235 | } |
236 | } | 236 | } |
237 | |||
238 | impl From<StructField> for StructFieldId { | ||
239 | fn from(def: StructField) -> Self { | ||
240 | StructFieldId { parent: def.parent.into(), local_id: def.id } | ||
241 | } | ||
242 | } | ||
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs index e164c9b32..152590cd1 100644 --- a/crates/ra_hir/src/lib.rs +++ b/crates/ra_hir/src/lib.rs | |||
@@ -51,13 +51,12 @@ mod marks; | |||
51 | 51 | ||
52 | pub use crate::{ | 52 | pub use crate::{ |
53 | code_model::{ | 53 | code_model::{ |
54 | attrs::{AttrDef, HasAttrs}, | ||
55 | docs::{DocDef, Docs, Documentation}, | 54 | docs::{DocDef, Docs, Documentation}, |
56 | src::{HasBodySource, HasSource}, | 55 | src::{HasBodySource, HasSource}, |
57 | Adt, AssocItem, Const, Container, Crate, CrateDependency, DefWithBody, Enum, EnumVariant, | 56 | Adt, AssocItem, AttrDef, Const, Container, Crate, CrateDependency, DefWithBody, Enum, |
58 | FieldSource, Function, GenericDef, GenericParam, HasBody, ImplBlock, Local, MacroDef, | 57 | EnumVariant, FieldSource, Function, GenericDef, GenericParam, HasAttrs, HasBody, ImplBlock, |
59 | Module, ModuleDef, ModuleSource, ScopeDef, Static, Struct, StructField, Trait, TypeAlias, | 58 | Local, MacroDef, Module, ModuleDef, ModuleSource, ScopeDef, Static, Struct, StructField, |
60 | Union, VariantDef, | 59 | Trait, TypeAlias, Union, VariantDef, |
61 | }, | 60 | }, |
62 | expr::ExprScopes, | 61 | expr::ExprScopes, |
63 | from_source::FromSource, | 62 | from_source::FromSource, |
diff --git a/crates/ra_hir_def/src/attr.rs b/crates/ra_hir_def/src/attr.rs index 7a9d0fdf4..ce397f6b0 100644 --- a/crates/ra_hir_def/src/attr.rs +++ b/crates/ra_hir_def/src/attr.rs | |||
@@ -2,7 +2,7 @@ | |||
2 | 2 | ||
3 | use std::{ops, sync::Arc}; | 3 | use std::{ops, sync::Arc}; |
4 | 4 | ||
5 | use hir_expand::hygiene::Hygiene; | 5 | use hir_expand::{either::Either, hygiene::Hygiene, AstId}; |
6 | use mbe::ast_to_token_tree; | 6 | use mbe::ast_to_token_tree; |
7 | use ra_cfg::CfgOptions; | 7 | use ra_cfg::CfgOptions; |
8 | use ra_syntax::{ | 8 | use ra_syntax::{ |
@@ -11,7 +11,9 @@ use ra_syntax::{ | |||
11 | }; | 11 | }; |
12 | use tt::Subtree; | 12 | use tt::Subtree; |
13 | 13 | ||
14 | use crate::path::Path; | 14 | use crate::{ |
15 | db::DefDatabase2, path::Path, AdtId, AstItemDef, AttrDefId, HasChildSource, HasSource, Lookup, | ||
16 | }; | ||
15 | 17 | ||
16 | #[derive(Default, Debug, Clone, PartialEq, Eq)] | 18 | #[derive(Default, Debug, Clone, PartialEq, Eq)] |
17 | pub struct Attrs { | 19 | pub struct Attrs { |
@@ -30,6 +32,46 @@ impl ops::Deref for Attrs { | |||
30 | } | 32 | } |
31 | 33 | ||
32 | impl Attrs { | 34 | impl Attrs { |
35 | pub(crate) fn attrs_query(db: &impl DefDatabase2, def: AttrDefId) -> Attrs { | ||
36 | match def { | ||
37 | AttrDefId::ModuleId(module) => { | ||
38 | let def_map = db.crate_def_map(module.krate); | ||
39 | let src = match def_map[module.module_id].declaration_source(db) { | ||
40 | Some(it) => it, | ||
41 | None => return Attrs::default(), | ||
42 | }; | ||
43 | let hygiene = Hygiene::new(db, src.file_id); | ||
44 | Attr::from_attrs_owner(&src.value, &hygiene) | ||
45 | } | ||
46 | AttrDefId::StructFieldId(it) => { | ||
47 | let src = it.parent.child_source(db); | ||
48 | match &src.value[it.local_id] { | ||
49 | Either::A(_tuple) => Attrs::default(), | ||
50 | Either::B(record) => { | ||
51 | let hygiene = Hygiene::new(db, src.file_id); | ||
52 | Attr::from_attrs_owner(record, &hygiene) | ||
53 | } | ||
54 | } | ||
55 | } | ||
56 | AttrDefId::AdtId(it) => match it { | ||
57 | AdtId::StructId(it) => attrs_from_ast(it.0.lookup_intern(db).ast_id, db), | ||
58 | AdtId::EnumId(it) => attrs_from_ast(it.lookup_intern(db).ast_id, db), | ||
59 | AdtId::UnionId(it) => attrs_from_ast(it.0.lookup_intern(db).ast_id, db), | ||
60 | }, | ||
61 | AttrDefId::EnumVariantId(it) => { | ||
62 | let src = it.parent.child_source(db); | ||
63 | let hygiene = Hygiene::new(db, src.file_id); | ||
64 | Attr::from_attrs_owner(&src.value[it.local_id], &hygiene) | ||
65 | } | ||
66 | AttrDefId::StaticId(it) => attrs_from_ast(it.lookup_intern(db).ast_id, db), | ||
67 | AttrDefId::ConstId(it) => attrs_from_loc(it.lookup(db), db), | ||
68 | AttrDefId::FunctionId(it) => attrs_from_loc(it.lookup(db), db), | ||
69 | AttrDefId::TraitId(it) => attrs_from_ast(it.lookup_intern(db).ast_id, db), | ||
70 | AttrDefId::TypeAliasId(it) => attrs_from_loc(it.lookup(db), db), | ||
71 | AttrDefId::MacroDefId(it) => attrs_from_ast(it.ast_id, db), | ||
72 | } | ||
73 | } | ||
74 | |||
33 | pub fn has_atom(&self, atom: &str) -> bool { | 75 | pub fn has_atom(&self, atom: &str) -> bool { |
34 | self.iter().any(|it| it.is_simple_atom(atom)) | 76 | self.iter().any(|it| it.is_simple_atom(atom)) |
35 | } | 77 | } |
@@ -106,3 +148,23 @@ impl Attr { | |||
106 | cfg_options.is_cfg_enabled(self.as_cfg()?) | 148 | cfg_options.is_cfg_enabled(self.as_cfg()?) |
107 | } | 149 | } |
108 | } | 150 | } |
151 | |||
152 | fn attrs_from_ast<D, N>(src: AstId<N>, db: &D) -> Attrs | ||
153 | where | ||
154 | N: ast::AttrsOwner, | ||
155 | D: DefDatabase2, | ||
156 | { | ||
157 | let hygiene = Hygiene::new(db, src.file_id()); | ||
158 | Attr::from_attrs_owner(&src.to_node(db), &hygiene) | ||
159 | } | ||
160 | |||
161 | fn attrs_from_loc<T, D>(node: T, db: &D) -> Attrs | ||
162 | where | ||
163 | T: HasSource, | ||
164 | T::Value: ast::AttrsOwner, | ||
165 | D: DefDatabase2, | ||
166 | { | ||
167 | let src = node.source(db); | ||
168 | let hygiene = Hygiene::new(db, src.file_id); | ||
169 | Attr::from_attrs_owner(&src.value, &hygiene) | ||
170 | } | ||
diff --git a/crates/ra_hir_def/src/db.rs b/crates/ra_hir_def/src/db.rs index 2c660ab88..e91e741bb 100644 --- a/crates/ra_hir_def/src/db.rs +++ b/crates/ra_hir_def/src/db.rs | |||
@@ -7,6 +7,7 @@ use ra_syntax::ast; | |||
7 | 7 | ||
8 | use crate::{ | 8 | use crate::{ |
9 | adt::{EnumData, StructData}, | 9 | adt::{EnumData, StructData}, |
10 | attr::Attrs, | ||
10 | body::{scope::ExprScopes, Body, BodySourceMap}, | 11 | body::{scope::ExprScopes, Body, BodySourceMap}, |
11 | data::{ConstData, FunctionData, ImplData, TraitData, TypeAliasData}, | 12 | data::{ConstData, FunctionData, ImplData, TraitData, TypeAliasData}, |
12 | generics::GenericParams, | 13 | generics::GenericParams, |
@@ -14,7 +15,7 @@ use crate::{ | |||
14 | raw::{ImportSourceMap, RawItems}, | 15 | raw::{ImportSourceMap, RawItems}, |
15 | CrateDefMap, | 16 | CrateDefMap, |
16 | }, | 17 | }, |
17 | ConstId, DefWithBodyId, EnumId, FunctionId, GenericDefId, ImplId, ItemLoc, StaticId, | 18 | AttrDefId, ConstId, DefWithBodyId, EnumId, FunctionId, GenericDefId, ImplId, ItemLoc, StaticId, |
18 | StructOrUnionId, TraitId, TypeAliasId, | 19 | StructOrUnionId, TraitId, TypeAliasId, |
19 | }; | 20 | }; |
20 | 21 | ||
@@ -87,4 +88,7 @@ pub trait DefDatabase2: InternDatabase + AstDatabase { | |||
87 | 88 | ||
88 | #[salsa::invoke(GenericParams::generic_params_query)] | 89 | #[salsa::invoke(GenericParams::generic_params_query)] |
89 | fn generic_params(&self, def: GenericDefId) -> Arc<GenericParams>; | 90 | fn generic_params(&self, def: GenericDefId) -> Arc<GenericParams>; |
91 | |||
92 | #[salsa::invoke(Attrs::attrs_query)] | ||
93 | fn attrs(&self, def: AttrDefId) -> Attrs; | ||
90 | } | 94 | } |
diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs index 2edf743ab..1bcdf9b78 100644 --- a/crates/ra_hir_def/src/lib.rs +++ b/crates/ra_hir_def/src/lib.rs | |||
@@ -32,7 +32,7 @@ pub mod nameres; | |||
32 | 32 | ||
33 | use std::hash::{Hash, Hasher}; | 33 | use std::hash::{Hash, Hasher}; |
34 | 34 | ||
35 | use hir_expand::{ast_id_map::FileAstId, db::AstDatabase, AstId, HirFileId, Source}; | 35 | use hir_expand::{ast_id_map::FileAstId, db::AstDatabase, AstId, HirFileId, MacroDefId, Source}; |
36 | use ra_arena::{impl_arena_id, map::ArenaMap, RawId}; | 36 | use ra_arena::{impl_arena_id, map::ArenaMap, RawId}; |
37 | use ra_db::{salsa, CrateId, FileId}; | 37 | use ra_db::{salsa, CrateId, FileId}; |
38 | use ra_syntax::{ast, AstNode, SyntaxNode}; | 38 | use ra_syntax::{ast, AstNode, SyntaxNode}; |
@@ -280,8 +280,8 @@ pub enum VariantId { | |||
280 | 280 | ||
281 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 281 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
282 | pub struct StructFieldId { | 282 | pub struct StructFieldId { |
283 | parent: VariantId, | 283 | pub parent: VariantId, |
284 | local_id: LocalStructFieldId, | 284 | pub local_id: LocalStructFieldId, |
285 | } | 285 | } |
286 | 286 | ||
287 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 287 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
@@ -477,6 +477,33 @@ impl_froms!( | |||
477 | ConstId | 477 | ConstId |
478 | ); | 478 | ); |
479 | 479 | ||
480 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] | ||
481 | pub enum AttrDefId { | ||
482 | ModuleId(ModuleId), | ||
483 | StructFieldId(StructFieldId), | ||
484 | AdtId(AdtId), | ||
485 | FunctionId(FunctionId), | ||
486 | EnumVariantId(EnumVariantId), | ||
487 | StaticId(StaticId), | ||
488 | ConstId(ConstId), | ||
489 | TraitId(TraitId), | ||
490 | TypeAliasId(TypeAliasId), | ||
491 | MacroDefId(MacroDefId), | ||
492 | } | ||
493 | |||
494 | impl_froms!( | ||
495 | AttrDefId: ModuleId, | ||
496 | StructFieldId, | ||
497 | AdtId(StructId, EnumId, UnionId), | ||
498 | EnumVariantId, | ||
499 | StaticId, | ||
500 | ConstId, | ||
501 | FunctionId, | ||
502 | TraitId, | ||
503 | TypeAliasId, | ||
504 | MacroDefId | ||
505 | ); | ||
506 | |||
480 | trait Intern { | 507 | trait Intern { |
481 | type ID; | 508 | type ID; |
482 | fn intern(self, db: &impl db::DefDatabase2) -> Self::ID; | 509 | fn intern(self, db: &impl db::DefDatabase2) -> Self::ID; |
diff --git a/crates/ra_hir_def/src/nameres.rs b/crates/ra_hir_def/src/nameres.rs index c01e020ef..6723465a5 100644 --- a/crates/ra_hir_def/src/nameres.rs +++ b/crates/ra_hir_def/src/nameres.rs | |||
@@ -58,7 +58,10 @@ mod tests; | |||
58 | 58 | ||
59 | use std::sync::Arc; | 59 | use std::sync::Arc; |
60 | 60 | ||
61 | use hir_expand::{ast_id_map::FileAstId, diagnostics::DiagnosticSink, name::Name, MacroDefId}; | 61 | use hir_expand::{ |
62 | ast_id_map::FileAstId, diagnostics::DiagnosticSink, either::Either, name::Name, MacroDefId, | ||
63 | Source, | ||
64 | }; | ||
62 | use once_cell::sync::Lazy; | 65 | use once_cell::sync::Lazy; |
63 | use ra_arena::Arena; | 66 | use ra_arena::Arena; |
64 | use ra_db::{CrateId, Edition, FileId}; | 67 | use ra_db::{CrateId, Edition, FileId}; |
@@ -116,12 +119,15 @@ pub struct ModuleData { | |||
116 | pub parent: Option<CrateModuleId>, | 119 | pub parent: Option<CrateModuleId>, |
117 | pub children: FxHashMap<Name, CrateModuleId>, | 120 | pub children: FxHashMap<Name, CrateModuleId>, |
118 | pub scope: ModuleScope, | 121 | pub scope: ModuleScope, |
122 | |||
123 | // FIXME: these can't be both null, we need a three-state enum here. | ||
119 | /// None for root | 124 | /// None for root |
120 | pub declaration: Option<AstId<ast::Module>>, | 125 | pub declaration: Option<AstId<ast::Module>>, |
121 | /// None for inline modules. | 126 | /// None for inline modules. |
122 | /// | 127 | /// |
123 | /// Note that non-inline modules, by definition, live inside non-macro file. | 128 | /// Note that non-inline modules, by definition, live inside non-macro file. |
124 | pub definition: Option<FileId>, | 129 | pub definition: Option<FileId>, |
130 | |||
125 | pub impls: Vec<ImplId>, | 131 | pub impls: Vec<ImplId>, |
126 | } | 132 | } |
127 | 133 | ||
@@ -285,6 +291,29 @@ impl CrateDefMap { | |||
285 | } | 291 | } |
286 | } | 292 | } |
287 | 293 | ||
294 | impl ModuleData { | ||
295 | /// Returns a node which defines this module. That is, a file or a `mod foo {}` with items. | ||
296 | pub fn definition_source( | ||
297 | &self, | ||
298 | db: &impl DefDatabase2, | ||
299 | ) -> Source<Either<ast::SourceFile, ast::Module>> { | ||
300 | if let Some(file_id) = self.definition { | ||
301 | let sf = db.parse(file_id).tree(); | ||
302 | return Source::new(file_id.into(), Either::A(sf)); | ||
303 | } | ||
304 | let decl = self.declaration.unwrap(); | ||
305 | Source::new(decl.file_id(), Either::B(decl.to_node(db))) | ||
306 | } | ||
307 | |||
308 | /// Returns a node which declares this module, either a `mod foo;` or a `mod foo {}`. | ||
309 | /// `None` for the crate root. | ||
310 | pub fn declaration_source(&self, db: &impl DefDatabase2) -> Option<Source<ast::Module>> { | ||
311 | let decl = self.declaration?; | ||
312 | let value = decl.to_node(db); | ||
313 | Some(Source { file_id: decl.file_id(), value }) | ||
314 | } | ||
315 | } | ||
316 | |||
288 | mod diagnostics { | 317 | mod diagnostics { |
289 | use hir_expand::diagnostics::DiagnosticSink; | 318 | use hir_expand::diagnostics::DiagnosticSink; |
290 | use ra_db::RelativePathBuf; | 319 | use ra_db::RelativePathBuf; |