diff options
author | bors[bot] <bors[bot]@users.noreply.github.com> | 2019-01-03 18:31:41 +0000 |
---|---|---|
committer | bors[bot] <bors[bot]@users.noreply.github.com> | 2019-01-03 18:31:41 +0000 |
commit | 2fcc6bdafa1caffd4ddf98968ee967e9fb091cc0 (patch) | |
tree | 5a278ad534d2de9f308bbdfef323c3b20bf9a653 /crates/ra_hir | |
parent | 6c0bca5984a6b66d306f9a413b0433c15d450500 (diff) | |
parent | d61707b4e1f0bdfc7f62b1abf78fdc45c0128699 (diff) |
Merge #421
421: Index macros r=matklad a=matklad
So, this is pretty cool! We now index items which are the result of macro expansion! (of a single currently hard-coded macro). So, workspace symbols can now be used to navigate to `HirDatabase`, for example
Co-authored-by: Aleksey Kladov <[email protected]>
Diffstat (limited to 'crates/ra_hir')
-rw-r--r-- | crates/ra_hir/src/ids.rs | 7 | ||||
-rw-r--r-- | crates/ra_hir/src/module/nameres.rs | 8 | ||||
-rw-r--r-- | crates/ra_hir/src/source_binder.rs | 39 |
3 files changed, 49 insertions, 5 deletions
diff --git a/crates/ra_hir/src/ids.rs b/crates/ra_hir/src/ids.rs index a09dee8b1..4c7ebe3ea 100644 --- a/crates/ra_hir/src/ids.rs +++ b/crates/ra_hir/src/ids.rs | |||
@@ -48,6 +48,13 @@ impl HirFileId { | |||
48 | } | 48 | } |
49 | } | 49 | } |
50 | 50 | ||
51 | pub(crate) fn as_macro_call_id(self) -> Option<MacroCallId> { | ||
52 | match self.0 { | ||
53 | HirFileIdRepr::Macro(it) => Some(it), | ||
54 | _ => None, | ||
55 | } | ||
56 | } | ||
57 | |||
51 | pub(crate) fn hir_source_file(db: &impl HirDatabase, file_id: HirFileId) -> SourceFileNode { | 58 | pub(crate) fn hir_source_file(db: &impl HirDatabase, file_id: HirFileId) -> SourceFileNode { |
52 | match file_id.0 { | 59 | match file_id.0 { |
53 | HirFileIdRepr::File(file_id) => db.source_file(file_id), | 60 | HirFileIdRepr::File(file_id) => db.source_file(file_id), |
diff --git a/crates/ra_hir/src/module/nameres.rs b/crates/ra_hir/src/module/nameres.rs index 40aa33ffa..8d1209626 100644 --- a/crates/ra_hir/src/module/nameres.rs +++ b/crates/ra_hir/src/module/nameres.rs | |||
@@ -64,14 +64,14 @@ impl ModuleScope { | |||
64 | /// running name resolution. | 64 | /// running name resolution. |
65 | #[derive(Debug, Default, PartialEq, Eq)] | 65 | #[derive(Debug, Default, PartialEq, Eq)] |
66 | pub struct InputModuleItems { | 66 | pub struct InputModuleItems { |
67 | items: Vec<ModuleItem>, | 67 | pub(crate) items: Vec<ModuleItem>, |
68 | imports: Vec<Import>, | 68 | imports: Vec<Import>, |
69 | } | 69 | } |
70 | 70 | ||
71 | #[derive(Debug, PartialEq, Eq)] | 71 | #[derive(Debug, PartialEq, Eq)] |
72 | struct ModuleItem { | 72 | pub(crate) struct ModuleItem { |
73 | id: SourceItemId, | 73 | pub(crate) id: SourceItemId, |
74 | name: Name, | 74 | pub(crate) name: Name, |
75 | kind: SyntaxKind, | 75 | kind: SyntaxKind, |
76 | vis: Vis, | 76 | vis: Vis, |
77 | } | 77 | } |
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 | } | ||