diff options
-rw-r--r-- | crates/ra_hir/src/lang_item.rs | 56 | ||||
-rw-r--r-- | crates/ra_hir_def/src/attr.rs | 24 | ||||
-rw-r--r-- | crates/ra_hir_def/src/lib.rs | 4 |
3 files changed, 45 insertions, 39 deletions
diff --git a/crates/ra_hir/src/lang_item.rs b/crates/ra_hir/src/lang_item.rs index 89fd85f59..55f0c3a13 100644 --- a/crates/ra_hir/src/lang_item.rs +++ b/crates/ra_hir/src/lang_item.rs | |||
@@ -1,13 +1,14 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! FIXME: write short doc here |
2 | 2 | ||
3 | use rustc_hash::FxHashMap; | ||
4 | use std::sync::Arc; | 3 | use std::sync::Arc; |
5 | 4 | ||
6 | use ra_syntax::{ast::AttrsOwner, SmolStr}; | 5 | use hir_def::{AdtId, AttrDefId, ModuleDefId}; |
6 | use ra_syntax::SmolStr; | ||
7 | use rustc_hash::FxHashMap; | ||
7 | 8 | ||
8 | use crate::{ | 9 | use crate::{ |
9 | db::{AstDatabase, DefDatabase, HirDatabase}, | 10 | db::{AstDatabase, DefDatabase, HirDatabase}, |
10 | Adt, Crate, Enum, Function, HasSource, ImplBlock, Module, ModuleDef, Static, Struct, Trait, | 11 | Crate, Enum, Function, ImplBlock, Module, Static, Struct, Trait, |
11 | }; | 12 | }; |
12 | 13 | ||
13 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 14 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
@@ -95,26 +96,27 @@ impl LangItems { | |||
95 | 96 | ||
96 | fn collect_lang_items(&mut self, db: &(impl DefDatabase + AstDatabase), module: Module) { | 97 | fn collect_lang_items(&mut self, db: &(impl DefDatabase + AstDatabase), module: Module) { |
97 | // Look for impl targets | 98 | // Look for impl targets |
98 | for impl_block in module.impl_blocks(db) { | 99 | let def_map = db.crate_def_map(module.id.krate); |
99 | let src = impl_block.source(db); | 100 | let module_data = &def_map[module.id.module_id]; |
100 | if let Some(lang_item_name) = lang_item_name(&src.value) { | 101 | for &impl_block in module_data.impls.iter() { |
101 | self.items | 102 | self.collect_lang_item(db, impl_block, LangItemTarget::ImplBlock) |
102 | .entry(lang_item_name) | ||
103 | .or_insert_with(|| LangItemTarget::ImplBlock(impl_block)); | ||
104 | } | ||
105 | } | 103 | } |
106 | 104 | ||
107 | for def in module.declarations(db) { | 105 | for def in module_data.scope.declarations() { |
108 | match def { | 106 | match def { |
109 | ModuleDef::Trait(trait_) => { | 107 | ModuleDefId::TraitId(trait_) => { |
110 | self.collect_lang_item(db, trait_, LangItemTarget::Trait) | 108 | self.collect_lang_item(db, trait_, LangItemTarget::Trait) |
111 | } | 109 | } |
112 | ModuleDef::Adt(Adt::Enum(e)) => self.collect_lang_item(db, e, LangItemTarget::Enum), | 110 | ModuleDefId::AdtId(AdtId::EnumId(e)) => { |
113 | ModuleDef::Adt(Adt::Struct(s)) => { | 111 | self.collect_lang_item(db, e, LangItemTarget::Enum) |
112 | } | ||
113 | ModuleDefId::AdtId(AdtId::StructId(s)) => { | ||
114 | self.collect_lang_item(db, s, LangItemTarget::Struct) | 114 | self.collect_lang_item(db, s, LangItemTarget::Struct) |
115 | } | 115 | } |
116 | ModuleDef::Function(f) => self.collect_lang_item(db, f, LangItemTarget::Function), | 116 | ModuleDefId::FunctionId(f) => { |
117 | ModuleDef::Static(s) => self.collect_lang_item(db, s, LangItemTarget::Static), | 117 | self.collect_lang_item(db, f, LangItemTarget::Function) |
118 | } | ||
119 | ModuleDefId::StaticId(s) => self.collect_lang_item(db, s, LangItemTarget::Static), | ||
118 | _ => {} | 120 | _ => {} |
119 | } | 121 | } |
120 | } | 122 | } |
@@ -135,26 +137,18 @@ impl LangItems { | |||
135 | } | 137 | } |
136 | } | 138 | } |
137 | 139 | ||
138 | fn collect_lang_item<T, N>( | 140 | fn collect_lang_item<T, D>( |
139 | &mut self, | 141 | &mut self, |
140 | db: &(impl DefDatabase + AstDatabase), | 142 | db: &(impl DefDatabase + AstDatabase), |
141 | item: T, | 143 | item: T, |
142 | constructor: fn(T) -> LangItemTarget, | 144 | constructor: fn(D) -> LangItemTarget, |
143 | ) where | 145 | ) where |
144 | T: Copy + HasSource<Ast = N>, | 146 | T: Into<AttrDefId> + Copy, |
145 | N: AttrsOwner, | 147 | D: From<T>, |
146 | { | 148 | { |
147 | let node = item.source(db).value; | 149 | let attrs = db.attrs(item.into()); |
148 | if let Some(lang_item_name) = lang_item_name(&node) { | 150 | if let Some(lang_item_name) = attrs.find_string_value("lang") { |
149 | self.items.entry(lang_item_name).or_insert_with(|| constructor(item)); | 151 | self.items.entry(lang_item_name).or_insert_with(|| constructor(D::from(item))); |
150 | } | 152 | } |
151 | } | 153 | } |
152 | } | 154 | } |
153 | |||
154 | fn lang_item_name<T: AttrsOwner>(node: &T) -> Option<SmolStr> { | ||
155 | node.attrs() | ||
156 | .filter_map(|a| a.as_simple_key_value()) | ||
157 | .filter(|(key, _)| key == "lang") | ||
158 | .map(|(_, val)| val) | ||
159 | .nth(0) | ||
160 | } | ||
diff --git a/crates/ra_hir_def/src/attr.rs b/crates/ra_hir_def/src/attr.rs index ce397f6b0..eee5e44bf 100644 --- a/crates/ra_hir_def/src/attr.rs +++ b/crates/ra_hir_def/src/attr.rs | |||
@@ -53,28 +53,38 @@ impl Attrs { | |||
53 | } | 53 | } |
54 | } | 54 | } |
55 | } | 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) => { | 56 | AttrDefId::EnumVariantId(it) => { |
62 | let src = it.parent.child_source(db); | 57 | let src = it.parent.child_source(db); |
63 | let hygiene = Hygiene::new(db, src.file_id); | 58 | let hygiene = Hygiene::new(db, src.file_id); |
64 | Attr::from_attrs_owner(&src.value[it.local_id], &hygiene) | 59 | Attr::from_attrs_owner(&src.value[it.local_id], &hygiene) |
65 | } | 60 | } |
61 | AttrDefId::AdtId(it) => match it { | ||
62 | AdtId::StructId(it) => attrs_from_ast(it.0.lookup_intern(db).ast_id, db), | ||
63 | AdtId::EnumId(it) => attrs_from_ast(it.lookup_intern(db).ast_id, db), | ||
64 | AdtId::UnionId(it) => attrs_from_ast(it.0.lookup_intern(db).ast_id, db), | ||
65 | }, | ||
66 | AttrDefId::StaticId(it) => attrs_from_ast(it.lookup_intern(db).ast_id, db), | 66 | AttrDefId::StaticId(it) => attrs_from_ast(it.lookup_intern(db).ast_id, db), |
67 | AttrDefId::TraitId(it) => attrs_from_ast(it.lookup_intern(db).ast_id, db), | ||
68 | AttrDefId::MacroDefId(it) => attrs_from_ast(it.ast_id, db), | ||
69 | AttrDefId::ImplId(it) => attrs_from_ast(it.lookup_intern(db).ast_id, db), | ||
67 | AttrDefId::ConstId(it) => attrs_from_loc(it.lookup(db), db), | 70 | AttrDefId::ConstId(it) => attrs_from_loc(it.lookup(db), db), |
68 | AttrDefId::FunctionId(it) => attrs_from_loc(it.lookup(db), db), | 71 | 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), | 72 | AttrDefId::TypeAliasId(it) => attrs_from_loc(it.lookup(db), db), |
71 | AttrDefId::MacroDefId(it) => attrs_from_ast(it.ast_id, db), | ||
72 | } | 73 | } |
73 | } | 74 | } |
74 | 75 | ||
75 | pub fn has_atom(&self, atom: &str) -> bool { | 76 | pub fn has_atom(&self, atom: &str) -> bool { |
76 | self.iter().any(|it| it.is_simple_atom(atom)) | 77 | self.iter().any(|it| it.is_simple_atom(atom)) |
77 | } | 78 | } |
79 | |||
80 | pub fn find_string_value(&self, key: &str) -> Option<SmolStr> { | ||
81 | self.iter().filter(|attr| attr.is_simple_atom(key)).find_map(|attr| { | ||
82 | match attr.input.as_ref()? { | ||
83 | AttrInput::Literal(it) => Some(it.clone()), | ||
84 | _ => None, | ||
85 | } | ||
86 | }) | ||
87 | } | ||
78 | } | 88 | } |
79 | 89 | ||
80 | #[derive(Debug, Clone, PartialEq, Eq)] | 90 | #[derive(Debug, Clone, PartialEq, Eq)] |
diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs index 1bcdf9b78..20d4deadb 100644 --- a/crates/ra_hir_def/src/lib.rs +++ b/crates/ra_hir_def/src/lib.rs | |||
@@ -489,6 +489,7 @@ pub enum AttrDefId { | |||
489 | TraitId(TraitId), | 489 | TraitId(TraitId), |
490 | TypeAliasId(TypeAliasId), | 490 | TypeAliasId(TypeAliasId), |
491 | MacroDefId(MacroDefId), | 491 | MacroDefId(MacroDefId), |
492 | ImplId(ImplId), | ||
492 | } | 493 | } |
493 | 494 | ||
494 | impl_froms!( | 495 | impl_froms!( |
@@ -501,7 +502,8 @@ impl_froms!( | |||
501 | FunctionId, | 502 | FunctionId, |
502 | TraitId, | 503 | TraitId, |
503 | TypeAliasId, | 504 | TypeAliasId, |
504 | MacroDefId | 505 | MacroDefId, |
506 | ImplId | ||
505 | ); | 507 | ); |
506 | 508 | ||
507 | trait Intern { | 509 | trait Intern { |