aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/lang_item.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/lang_item.rs')
-rw-r--r--crates/ra_hir/src/lang_item.rs56
1 files changed, 25 insertions, 31 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
3use rustc_hash::FxHashMap;
4use std::sync::Arc; 3use std::sync::Arc;
5 4
6use ra_syntax::{ast::AttrsOwner, SmolStr}; 5use hir_def::{AdtId, AttrDefId, ModuleDefId};
6use ra_syntax::SmolStr;
7use rustc_hash::FxHashMap;
7 8
8use crate::{ 9use 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
154fn 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}