diff options
Diffstat (limited to 'crates/ra_hir/src/source_binder.rs')
-rw-r--r-- | crates/ra_hir/src/source_binder.rs | 39 |
1 files changed, 38 insertions, 1 deletions
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index 24490d119..85bd84469 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs | |||
@@ -8,8 +8,8 @@ | |||
8 | use ra_db::{FileId, FilePosition, Cancelable}; | 8 | use ra_db::{FileId, FilePosition, Cancelable}; |
9 | use ra_editor::find_node_at_offset; | 9 | use ra_editor::find_node_at_offset; |
10 | use ra_syntax::{ | 10 | use ra_syntax::{ |
11 | SmolStr, TextRange, SyntaxNodeRef, | ||
11 | ast::{self, AstNode, NameOwner}, | 12 | ast::{self, AstNode, NameOwner}, |
12 | SyntaxNodeRef, | ||
13 | }; | 13 | }; |
14 | 14 | ||
15 | use crate::{ | 15 | use crate::{ |
@@ -126,3 +126,40 @@ pub fn function_from_child_node( | |||
126 | let fn_def = ctry!(node.ancestors().find_map(ast::FnDef::cast)); | 126 | let fn_def = ctry!(node.ancestors().find_map(ast::FnDef::cast)); |
127 | function_from_source(db, file_id, fn_def) | 127 | function_from_source(db, file_id, fn_def) |
128 | } | 128 | } |
129 | |||
130 | pub fn macro_symbols( | ||
131 | db: &impl HirDatabase, | ||
132 | file_id: FileId, | ||
133 | ) -> Cancelable<Vec<(SmolStr, TextRange)>> { | ||
134 | let module = match module_from_file_id(db, file_id)? { | ||
135 | Some(it) => it, | ||
136 | None => return Ok(Vec::new()), | ||
137 | }; | ||
138 | let items = db.input_module_items(module.source_root_id, module.module_id)?; | ||
139 | let mut res = Vec::new(); | ||
140 | |||
141 | for macro_call_id in items | ||
142 | .items | ||
143 | .iter() | ||
144 | .filter_map(|it| it.id.file_id.as_macro_call_id()) | ||
145 | { | ||
146 | if let Some(exp) = db.expand_macro_invocation(macro_call_id) { | ||
147 | let loc = macro_call_id.loc(db); | ||
148 | let syntax = db.file_item(loc.source_item_id); | ||
149 | let syntax = syntax.borrowed(); | ||
150 | let macro_call = ast::MacroCall::cast(syntax).unwrap(); | ||
151 | let off = macro_call.token_tree().unwrap().syntax().range().start(); | ||
152 | let file = exp.file(); | ||
153 | for trait_def in file.syntax().descendants().filter_map(ast::TraitDef::cast) { | ||
154 | if let Some(name) = trait_def.name() { | ||
155 | let dst_range = name.syntax().range(); | ||
156 | if let Some(src_range) = exp.map_range_back(dst_range) { | ||
157 | res.push((name.text(), src_range + off)) | ||
158 | } | ||
159 | } | ||
160 | } | ||
161 | } | ||
162 | } | ||
163 | |||
164 | Ok(res) | ||
165 | } | ||