diff options
Diffstat (limited to 'crates/ra_hir_def/src')
-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 |
4 files changed, 129 insertions, 7 deletions
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; |