diff options
author | Seivan Heidari <[email protected]> | 2019-12-23 14:35:31 +0000 |
---|---|---|
committer | Seivan Heidari <[email protected]> | 2019-12-23 14:35:31 +0000 |
commit | b21d9337d9200e2cfdc90b386591c72c302dc03e (patch) | |
tree | f81f5c08f821115cee26fa4d3ceaae88c7807fd5 /crates/ra_hir_expand/src/db.rs | |
parent | 18a0937585b836ec5ed054b9ae48e0156ab6d9ef (diff) | |
parent | ce07a2daa9e53aa86a769f8641b14c2878444fbc (diff) |
Merge branch 'master' into feature/themes
Diffstat (limited to 'crates/ra_hir_expand/src/db.rs')
-rw-r--r-- | crates/ra_hir_expand/src/db.rs | 66 |
1 files changed, 52 insertions, 14 deletions
diff --git a/crates/ra_hir_expand/src/db.rs b/crates/ra_hir_expand/src/db.rs index 8e46fa177..2e12e126f 100644 --- a/crates/ra_hir_expand/src/db.rs +++ b/crates/ra_hir_expand/src/db.rs | |||
@@ -6,17 +6,18 @@ use mbe::MacroRules; | |||
6 | use ra_db::{salsa, SourceDatabase}; | 6 | use ra_db::{salsa, SourceDatabase}; |
7 | use ra_parser::FragmentKind; | 7 | use ra_parser::FragmentKind; |
8 | use ra_prof::profile; | 8 | use ra_prof::profile; |
9 | use ra_syntax::{AstNode, Parse, SyntaxNode}; | 9 | use ra_syntax::{AstNode, Parse, SyntaxKind::*, SyntaxNode}; |
10 | 10 | ||
11 | use crate::{ | 11 | use crate::{ |
12 | ast_id_map::AstIdMap, BuiltinFnLikeExpander, HirFileId, HirFileIdRepr, MacroCallId, | 12 | ast_id_map::AstIdMap, BuiltinDeriveExpander, BuiltinFnLikeExpander, HirFileId, HirFileIdRepr, |
13 | MacroCallLoc, MacroDefId, MacroDefKind, MacroFile, MacroFileKind, | 13 | MacroCallId, MacroCallLoc, MacroDefId, MacroDefKind, MacroFile, |
14 | }; | 14 | }; |
15 | 15 | ||
16 | #[derive(Debug, Clone, Eq, PartialEq)] | 16 | #[derive(Debug, Clone, Eq, PartialEq)] |
17 | pub enum TokenExpander { | 17 | pub enum TokenExpander { |
18 | MacroRules(mbe::MacroRules), | 18 | MacroRules(mbe::MacroRules), |
19 | Builtin(BuiltinFnLikeExpander), | 19 | Builtin(BuiltinFnLikeExpander), |
20 | BuiltinDerive(BuiltinDeriveExpander), | ||
20 | } | 21 | } |
21 | 22 | ||
22 | impl TokenExpander { | 23 | impl TokenExpander { |
@@ -29,6 +30,7 @@ impl TokenExpander { | |||
29 | match self { | 30 | match self { |
30 | TokenExpander::MacroRules(it) => it.expand(tt), | 31 | TokenExpander::MacroRules(it) => it.expand(tt), |
31 | TokenExpander::Builtin(it) => it.expand(db, id, tt), | 32 | TokenExpander::Builtin(it) => it.expand(db, id, tt), |
33 | TokenExpander::BuiltinDerive(it) => it.expand(db, id, tt), | ||
32 | } | 34 | } |
33 | } | 35 | } |
34 | 36 | ||
@@ -36,13 +38,15 @@ impl TokenExpander { | |||
36 | match self { | 38 | match self { |
37 | TokenExpander::MacroRules(it) => it.map_id_down(id), | 39 | TokenExpander::MacroRules(it) => it.map_id_down(id), |
38 | TokenExpander::Builtin(..) => id, | 40 | TokenExpander::Builtin(..) => id, |
41 | TokenExpander::BuiltinDerive(..) => id, | ||
39 | } | 42 | } |
40 | } | 43 | } |
41 | 44 | ||
42 | pub fn map_id_up(&self, id: tt::TokenId) -> (tt::TokenId, mbe::Origin) { | 45 | pub fn map_id_up(&self, id: tt::TokenId) -> (tt::TokenId, mbe::Origin) { |
43 | match self { | 46 | match self { |
44 | TokenExpander::MacroRules(it) => it.map_id_up(id), | 47 | TokenExpander::MacroRules(it) => it.map_id_up(id), |
45 | TokenExpander::Builtin(..) => (id, mbe::Origin::Def), | 48 | TokenExpander::Builtin(..) => (id, mbe::Origin::Call), |
49 | TokenExpander::BuiltinDerive(..) => (id, mbe::Origin::Call), | ||
46 | } | 50 | } |
47 | } | 51 | } |
48 | } | 52 | } |
@@ -76,7 +80,7 @@ pub(crate) fn macro_def( | |||
76 | ) -> Option<Arc<(TokenExpander, mbe::TokenMap)>> { | 80 | ) -> Option<Arc<(TokenExpander, mbe::TokenMap)>> { |
77 | match id.kind { | 81 | match id.kind { |
78 | MacroDefKind::Declarative => { | 82 | MacroDefKind::Declarative => { |
79 | let macro_call = id.ast_id.to_node(db); | 83 | let macro_call = id.ast_id?.to_node(db); |
80 | let arg = macro_call.token_tree()?; | 84 | let arg = macro_call.token_tree()?; |
81 | let (tt, tmap) = mbe::ast_to_token_tree(&arg).or_else(|| { | 85 | let (tt, tmap) = mbe::ast_to_token_tree(&arg).or_else(|| { |
82 | log::warn!("fail on macro_def to token tree: {:#?}", arg); | 86 | log::warn!("fail on macro_def to token tree: {:#?}", arg); |
@@ -89,7 +93,10 @@ pub(crate) fn macro_def( | |||
89 | Some(Arc::new((TokenExpander::MacroRules(rules), tmap))) | 93 | Some(Arc::new((TokenExpander::MacroRules(rules), tmap))) |
90 | } | 94 | } |
91 | MacroDefKind::BuiltIn(expander) => { | 95 | MacroDefKind::BuiltIn(expander) => { |
92 | Some(Arc::new((TokenExpander::Builtin(expander.clone()), mbe::TokenMap::default()))) | 96 | Some(Arc::new((TokenExpander::Builtin(expander), mbe::TokenMap::default()))) |
97 | } | ||
98 | MacroDefKind::BuiltInDerive(expander) => { | ||
99 | Some(Arc::new((TokenExpander::BuiltinDerive(expander), mbe::TokenMap::default()))) | ||
93 | } | 100 | } |
94 | } | 101 | } |
95 | } | 102 | } |
@@ -99,9 +106,8 @@ pub(crate) fn macro_arg( | |||
99 | id: MacroCallId, | 106 | id: MacroCallId, |
100 | ) -> Option<Arc<(tt::Subtree, mbe::TokenMap)>> { | 107 | ) -> Option<Arc<(tt::Subtree, mbe::TokenMap)>> { |
101 | let loc = db.lookup_intern_macro(id); | 108 | let loc = db.lookup_intern_macro(id); |
102 | let macro_call = loc.ast_id.to_node(db); | 109 | let arg = loc.kind.arg(db)?; |
103 | let arg = macro_call.token_tree()?; | 110 | let (tt, tmap) = mbe::syntax_node_to_token_tree(&arg)?; |
104 | let (tt, tmap) = mbe::ast_to_token_tree(&arg)?; | ||
105 | Some(Arc::new((tt, tmap))) | 111 | Some(Arc::new((tt, tmap))) |
106 | } | 112 | } |
107 | 113 | ||
@@ -148,11 +154,43 @@ pub(crate) fn parse_macro( | |||
148 | }) | 154 | }) |
149 | .ok()?; | 155 | .ok()?; |
150 | 156 | ||
151 | let fragment_kind = match macro_file.macro_file_kind { | 157 | let fragment_kind = to_fragment_kind(db, macro_call_id); |
152 | MacroFileKind::Items => FragmentKind::Items, | 158 | |
153 | MacroFileKind::Expr => FragmentKind::Expr, | ||
154 | MacroFileKind::Statements => FragmentKind::Statements, | ||
155 | }; | ||
156 | let (parse, rev_token_map) = mbe::token_tree_to_syntax_node(&tt, fragment_kind).ok()?; | 159 | let (parse, rev_token_map) = mbe::token_tree_to_syntax_node(&tt, fragment_kind).ok()?; |
157 | Some((parse, Arc::new(rev_token_map))) | 160 | Some((parse, Arc::new(rev_token_map))) |
158 | } | 161 | } |
162 | |||
163 | /// Given a `MacroCallId`, return what `FragmentKind` it belongs to. | ||
164 | /// FIXME: Not completed | ||
165 | fn to_fragment_kind(db: &dyn AstDatabase, macro_call_id: MacroCallId) -> FragmentKind { | ||
166 | let syn = db.lookup_intern_macro(macro_call_id).kind.node(db).value; | ||
167 | |||
168 | let parent = match syn.parent() { | ||
169 | Some(it) => it, | ||
170 | None => { | ||
171 | // FIXME: | ||
172 | // If it is root, which means the parent HirFile | ||
173 | // MacroKindFile must be non-items | ||
174 | // return expr now. | ||
175 | return FragmentKind::Expr; | ||
176 | } | ||
177 | }; | ||
178 | |||
179 | match parent.kind() { | ||
180 | MACRO_ITEMS | SOURCE_FILE => FragmentKind::Items, | ||
181 | LET_STMT => { | ||
182 | // FIXME: Handle Pattern | ||
183 | FragmentKind::Expr | ||
184 | } | ||
185 | // FIXME: Expand to statements in appropriate positions; HIR lowering needs to handle that | ||
186 | EXPR_STMT | BLOCK => FragmentKind::Expr, | ||
187 | ARG_LIST => FragmentKind::Expr, | ||
188 | TRY_EXPR => FragmentKind::Expr, | ||
189 | TUPLE_EXPR => FragmentKind::Expr, | ||
190 | ITEM_LIST => FragmentKind::Items, | ||
191 | _ => { | ||
192 | // Unknown , Just guess it is `Items` | ||
193 | FragmentKind::Items | ||
194 | } | ||
195 | } | ||
196 | } | ||