aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/query_definitions.rs
diff options
context:
space:
mode:
authorbors[bot] <bors[bot]@users.noreply.github.com>2019-01-02 13:05:54 +0000
committerbors[bot] <bors[bot]@users.noreply.github.com>2019-01-02 13:05:54 +0000
commitafa972e78d2d81598c02b742ab84d70c88208300 (patch)
tree2ec32a586d0ee00e0d35a489efeaf31c91d14a15 /crates/ra_hir/src/query_definitions.rs
parente4ffd7b31780b1f2ac6dcb731566b583bf562647 (diff)
parent1076e82856f353763de8426d378fcd1e371cbed4 (diff)
Merge #403
403: initial support for macros r=matklad a=matklad I'll write a more comprehensive description when this is closer to being done. Basically this investigates one question: "how do we represent code which is a result of a macro call". This is an interesting question: currently everything is `FileId` based, but macro expansion does not have a file! Co-authored-by: Aleksey Kladov <[email protected]>
Diffstat (limited to 'crates/ra_hir/src/query_definitions.rs')
-rw-r--r--crates/ra_hir/src/query_definitions.rs73
1 files changed, 45 insertions, 28 deletions
diff --git a/crates/ra_hir/src/query_definitions.rs b/crates/ra_hir/src/query_definitions.rs
index 721bd4195..a5d99beda 100644
--- a/crates/ra_hir/src/query_definitions.rs
+++ b/crates/ra_hir/src/query_definitions.rs
@@ -8,10 +8,11 @@ use ra_syntax::{
8 AstNode, SyntaxNode, 8 AstNode, SyntaxNode,
9 ast::{self, NameOwner, ModuleItemOwner} 9 ast::{self, NameOwner, ModuleItemOwner}
10}; 10};
11use ra_db::{SourceRootId, FileId, Cancelable,}; 11use ra_db::{SourceRootId, Cancelable,};
12 12
13use crate::{ 13use crate::{
14 SourceFileItems, SourceItemId, DefKind, Function, DefId, Name, AsName, 14 SourceFileItems, SourceItemId, DefKind, Function, DefId, Name, AsName, HirFileId,
15 MacroCallLoc,
15 db::HirDatabase, 16 db::HirDatabase,
16 function::FnScopes, 17 function::FnScopes,
17 module::{ 18 module::{
@@ -47,25 +48,17 @@ pub(super) fn enum_data(db: &impl HirDatabase, def_id: DefId) -> Cancelable<Arc<
47 Ok(Arc::new(EnumData::new(enum_def.borrowed()))) 48 Ok(Arc::new(EnumData::new(enum_def.borrowed())))
48} 49}
49 50
50pub(super) fn file_items(db: &impl HirDatabase, file_id: FileId) -> Arc<SourceFileItems> { 51pub(super) fn file_items(db: &impl HirDatabase, file_id: HirFileId) -> Arc<SourceFileItems> {
51 let mut res = SourceFileItems::new(file_id); 52 let source_file = db.hir_source_file(file_id);
52 let source_file = db.source_file(file_id);
53 let source_file = source_file.borrowed(); 53 let source_file = source_file.borrowed();
54 source_file 54 let res = SourceFileItems::new(file_id, source_file);
55 .syntax()
56 .descendants()
57 .filter_map(ast::ModuleItem::cast)
58 .map(|it| it.syntax().owned())
59 .for_each(|it| {
60 res.alloc(it);
61 });
62 Arc::new(res) 55 Arc::new(res)
63} 56}
64 57
65pub(super) fn file_item(db: &impl HirDatabase, source_item_id: SourceItemId) -> SyntaxNode { 58pub(super) fn file_item(db: &impl HirDatabase, source_item_id: SourceItemId) -> SyntaxNode {
66 match source_item_id.item_id { 59 match source_item_id.item_id {
67 Some(id) => db.file_items(source_item_id.file_id)[id].clone(), 60 Some(id) => db.file_items(source_item_id.file_id)[id].clone(),
68 None => db.source_file(source_item_id.file_id).syntax().owned(), 61 None => db.hir_source_file(source_item_id.file_id).syntax().owned(),
69 } 62 }
70} 63}
71 64
@@ -87,7 +80,7 @@ pub(crate) fn submodules(
87 80
88 fn collect_submodules<'a>( 81 fn collect_submodules<'a>(
89 db: &impl HirDatabase, 82 db: &impl HirDatabase,
90 file_id: FileId, 83 file_id: HirFileId,
91 root: impl ast::ModuleItemOwner<'a>, 84 root: impl ast::ModuleItemOwner<'a>,
92 ) -> Vec<Submodule> { 85 ) -> Vec<Submodule> {
93 modules(root) 86 modules(root)
@@ -119,24 +112,48 @@ pub(crate) fn modules<'a>(
119 112
120pub(super) fn input_module_items( 113pub(super) fn input_module_items(
121 db: &impl HirDatabase, 114 db: &impl HirDatabase,
122 source_root: SourceRootId, 115 source_root_id: SourceRootId,
123 module_id: ModuleId, 116 module_id: ModuleId,
124) -> Cancelable<Arc<InputModuleItems>> { 117) -> Cancelable<Arc<InputModuleItems>> {
125 let module_tree = db.module_tree(source_root)?; 118 let module_tree = db.module_tree(source_root_id)?;
126 let source = module_id.source(&module_tree); 119 let source = module_id.source(&module_tree);
127 let file_items = db.file_items(source.file_id()); 120 let file_id = source.file_id();
128 let res = match source.resolve(db) { 121 let file_items = db.file_items(file_id);
129 ModuleSourceNode::SourceFile(it) => { 122 let fill = |acc: &mut InputModuleItems, items: &mut Iterator<Item = ast::ItemOrMacro>| {
130 let items = it.borrowed().items(); 123 for item in items {
131 InputModuleItems::new(&file_items, items) 124 match item {
125 ast::ItemOrMacro::Item(it) => {
126 acc.add_item(file_id, &file_items, it);
127 }
128 ast::ItemOrMacro::Macro(macro_call) => {
129 let item_id = file_items.id_of_unchecked(macro_call.syntax());
130 let loc = MacroCallLoc {
131 source_root_id,
132 module_id,
133 source_item_id: SourceItemId {
134 file_id,
135 item_id: Some(item_id),
136 },
137 };
138 let id = loc.id(db);
139 let file_id = HirFileId::from(id);
140 let file_items = db.file_items(file_id);
141 //FIXME: expand recursively
142 for item in db.hir_source_file(file_id).borrowed().items() {
143 acc.add_item(file_id, &file_items, item);
144 }
145 }
146 }
132 } 147 }
148 };
149
150 let mut res = InputModuleItems::default();
151 match source.resolve(db) {
152 ModuleSourceNode::SourceFile(it) => fill(&mut res, &mut it.borrowed().items_with_macros()),
133 ModuleSourceNode::Module(it) => { 153 ModuleSourceNode::Module(it) => {
134 let items = it 154 if let Some(item_list) = it.borrowed().item_list() {
135 .borrowed() 155 fill(&mut res, &mut item_list.items_with_macros())
136 .item_list() 156 }
137 .into_iter()
138 .flat_map(|it| it.items());
139 InputModuleItems::new(&file_items, items)
140 } 157 }
141 }; 158 };
142 Ok(Arc::new(res)) 159 Ok(Arc::new(res))