aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_hir/src/lang_item.rs56
-rw-r--r--crates/ra_hir_def/src/attr.rs24
-rw-r--r--crates/ra_hir_def/src/lib.rs4
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
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}
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
494impl_froms!( 495impl_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
507trait Intern { 509trait Intern {