diff options
author | Edwin Cheng <[email protected]> | 2021-03-27 05:44:54 +0000 |
---|---|---|
committer | Edwin Cheng <[email protected]> | 2021-03-27 05:44:54 +0000 |
commit | a193666361f6ea9725b927a35f5baf77da713c0a (patch) | |
tree | fa916fcc7e5031df796f42521fb74d775ebdec59 /crates/hir_expand/src | |
parent | c8066ebd1781a6f6f536abe3494477bd69df795a (diff) |
Basic Support Macro 2.0
Diffstat (limited to 'crates/hir_expand/src')
-rw-r--r-- | crates/hir_expand/src/db.rs | 60 | ||||
-rw-r--r-- | crates/hir_expand/src/hygiene.rs | 2 | ||||
-rw-r--r-- | crates/hir_expand/src/lib.rs | 2 |
3 files changed, 41 insertions, 23 deletions
diff --git a/crates/hir_expand/src/db.rs b/crates/hir_expand/src/db.rs index d672f6723..c0ab70b60 100644 --- a/crates/hir_expand/src/db.rs +++ b/crates/hir_expand/src/db.rs | |||
@@ -3,7 +3,7 @@ | |||
3 | use std::sync::Arc; | 3 | use std::sync::Arc; |
4 | 4 | ||
5 | use base_db::{salsa, SourceDatabase}; | 5 | use base_db::{salsa, SourceDatabase}; |
6 | use mbe::{ExpandError, ExpandResult, MacroRules}; | 6 | use mbe::{ExpandError, ExpandResult, MacroDef, MacroRules}; |
7 | use parser::FragmentKind; | 7 | use parser::FragmentKind; |
8 | use syntax::{ | 8 | use syntax::{ |
9 | algo::diff, | 9 | algo::diff, |
@@ -28,6 +28,7 @@ const TOKEN_LIMIT: usize = 524288; | |||
28 | #[derive(Debug, Clone, Eq, PartialEq)] | 28 | #[derive(Debug, Clone, Eq, PartialEq)] |
29 | pub enum TokenExpander { | 29 | pub enum TokenExpander { |
30 | MacroRules(mbe::MacroRules), | 30 | MacroRules(mbe::MacroRules), |
31 | MacroDef(mbe::MacroDef), | ||
31 | Builtin(BuiltinFnLikeExpander), | 32 | Builtin(BuiltinFnLikeExpander), |
32 | BuiltinDerive(BuiltinDeriveExpander), | 33 | BuiltinDerive(BuiltinDeriveExpander), |
33 | ProcMacro(ProcMacroExpander), | 34 | ProcMacro(ProcMacroExpander), |
@@ -42,6 +43,7 @@ impl TokenExpander { | |||
42 | ) -> mbe::ExpandResult<tt::Subtree> { | 43 | ) -> mbe::ExpandResult<tt::Subtree> { |
43 | match self { | 44 | match self { |
44 | TokenExpander::MacroRules(it) => it.expand(tt), | 45 | TokenExpander::MacroRules(it) => it.expand(tt), |
46 | TokenExpander::MacroDef(it) => it.expand(tt), | ||
45 | TokenExpander::Builtin(it) => it.expand(db, id, tt), | 47 | TokenExpander::Builtin(it) => it.expand(db, id, tt), |
46 | // FIXME switch these to ExpandResult as well | 48 | // FIXME switch these to ExpandResult as well |
47 | TokenExpander::BuiltinDerive(it) => it.expand(db, id, tt).into(), | 49 | TokenExpander::BuiltinDerive(it) => it.expand(db, id, tt).into(), |
@@ -57,6 +59,7 @@ impl TokenExpander { | |||
57 | pub fn map_id_down(&self, id: tt::TokenId) -> tt::TokenId { | 59 | pub fn map_id_down(&self, id: tt::TokenId) -> tt::TokenId { |
58 | match self { | 60 | match self { |
59 | TokenExpander::MacroRules(it) => it.map_id_down(id), | 61 | TokenExpander::MacroRules(it) => it.map_id_down(id), |
62 | TokenExpander::MacroDef(it) => it.map_id_down(id), | ||
60 | TokenExpander::Builtin(..) => id, | 63 | TokenExpander::Builtin(..) => id, |
61 | TokenExpander::BuiltinDerive(..) => id, | 64 | TokenExpander::BuiltinDerive(..) => id, |
62 | TokenExpander::ProcMacro(..) => id, | 65 | TokenExpander::ProcMacro(..) => id, |
@@ -66,6 +69,7 @@ impl TokenExpander { | |||
66 | pub fn map_id_up(&self, id: tt::TokenId) -> (tt::TokenId, mbe::Origin) { | 69 | pub fn map_id_up(&self, id: tt::TokenId) -> (tt::TokenId, mbe::Origin) { |
67 | match self { | 70 | match self { |
68 | TokenExpander::MacroRules(it) => it.map_id_up(id), | 71 | TokenExpander::MacroRules(it) => it.map_id_up(id), |
72 | TokenExpander::MacroDef(it) => it.map_id_up(id), | ||
69 | TokenExpander::Builtin(..) => (id, mbe::Origin::Call), | 73 | TokenExpander::Builtin(..) => (id, mbe::Origin::Call), |
70 | TokenExpander::BuiltinDerive(..) => (id, mbe::Origin::Call), | 74 | TokenExpander::BuiltinDerive(..) => (id, mbe::Origin::Call), |
71 | TokenExpander::ProcMacro(..) => (id, mbe::Origin::Call), | 75 | TokenExpander::ProcMacro(..) => (id, mbe::Origin::Call), |
@@ -136,26 +140,40 @@ fn ast_id_map(db: &dyn AstDatabase, file_id: HirFileId) -> Arc<AstIdMap> { | |||
136 | 140 | ||
137 | fn macro_def(db: &dyn AstDatabase, id: MacroDefId) -> Option<Arc<(TokenExpander, mbe::TokenMap)>> { | 141 | fn macro_def(db: &dyn AstDatabase, id: MacroDefId) -> Option<Arc<(TokenExpander, mbe::TokenMap)>> { |
138 | match id.kind { | 142 | match id.kind { |
139 | MacroDefKind::Declarative(ast_id) => { | 143 | MacroDefKind::Declarative(ast_id) => match ast_id.to_node(db) { |
140 | let macro_rules = match ast_id.to_node(db) { | 144 | syntax::ast::Macro::MacroRules(macro_rules) => { |
141 | syntax::ast::Macro::MacroRules(mac) => mac, | 145 | let arg = macro_rules.token_tree()?; |
142 | syntax::ast::Macro::MacroDef(_) => return None, | 146 | let (tt, tmap) = mbe::ast_to_token_tree(&arg).or_else(|| { |
143 | }; | 147 | log::warn!("fail on macro_rules to token tree: {:#?}", arg); |
144 | let arg = macro_rules.token_tree()?; | 148 | None |
145 | let (tt, tmap) = mbe::ast_to_token_tree(&arg).or_else(|| { | 149 | })?; |
146 | log::warn!("fail on macro_def to token tree: {:#?}", arg); | 150 | let rules = match MacroRules::parse(&tt) { |
147 | None | 151 | Ok(it) => it, |
148 | })?; | 152 | Err(err) => { |
149 | let rules = match MacroRules::parse(&tt) { | 153 | let name = macro_rules.name().map(|n| n.to_string()).unwrap_or_default(); |
150 | Ok(it) => it, | 154 | log::warn!("fail on macro_def parse ({}): {:?} {:#?}", name, err, tt); |
151 | Err(err) => { | 155 | return None; |
152 | let name = macro_rules.name().map(|n| n.to_string()).unwrap_or_default(); | 156 | } |
153 | log::warn!("fail on macro_def parse ({}): {:?} {:#?}", name, err, tt); | 157 | }; |
154 | return None; | 158 | Some(Arc::new((TokenExpander::MacroRules(rules), tmap))) |
155 | } | 159 | } |
156 | }; | 160 | syntax::ast::Macro::MacroDef(macro_def) => { |
157 | Some(Arc::new((TokenExpander::MacroRules(rules), tmap))) | 161 | let arg = macro_def.body()?; |
158 | } | 162 | let (tt, tmap) = mbe::ast_to_token_tree(&arg).or_else(|| { |
163 | log::warn!("fail on macro_def to token tree: {:#?}", arg); | ||
164 | None | ||
165 | })?; | ||
166 | let rules = match MacroDef::parse(&tt) { | ||
167 | Ok(it) => it, | ||
168 | Err(err) => { | ||
169 | let name = macro_def.name().map(|n| n.to_string()).unwrap_or_default(); | ||
170 | log::warn!("fail on macro_def parse ({}): {:?} {:#?}", name, err, tt); | ||
171 | return None; | ||
172 | } | ||
173 | }; | ||
174 | Some(Arc::new((TokenExpander::MacroDef(rules), tmap))) | ||
175 | } | ||
176 | }, | ||
159 | MacroDefKind::BuiltIn(expander, _) => { | 177 | MacroDefKind::BuiltIn(expander, _) => { |
160 | Some(Arc::new((TokenExpander::Builtin(expander), mbe::TokenMap::default()))) | 178 | Some(Arc::new((TokenExpander::Builtin(expander), mbe::TokenMap::default()))) |
161 | } | 179 | } |
diff --git a/crates/hir_expand/src/hygiene.rs b/crates/hir_expand/src/hygiene.rs index 0e0f7214a..779725629 100644 --- a/crates/hir_expand/src/hygiene.rs +++ b/crates/hir_expand/src/hygiene.rs | |||
@@ -148,7 +148,7 @@ fn make_hygiene_info( | |||
148 | let def_offset = loc.def.ast_id().left().and_then(|id| { | 148 | let def_offset = loc.def.ast_id().left().and_then(|id| { |
149 | let def_tt = match id.to_node(db) { | 149 | let def_tt = match id.to_node(db) { |
150 | ast::Macro::MacroRules(mac) => mac.token_tree()?.syntax().text_range().start(), | 150 | ast::Macro::MacroRules(mac) => mac.token_tree()?.syntax().text_range().start(), |
151 | ast::Macro::MacroDef(_) => return None, | 151 | ast::Macro::MacroDef(mac) => mac.body()?.syntax().text_range().start(), |
152 | }; | 152 | }; |
153 | Some(InFile::new(id.file_id, def_tt)) | 153 | Some(InFile::new(id.file_id, def_tt)) |
154 | }); | 154 | }); |
diff --git a/crates/hir_expand/src/lib.rs b/crates/hir_expand/src/lib.rs index b8045fda9..3e332ee47 100644 --- a/crates/hir_expand/src/lib.rs +++ b/crates/hir_expand/src/lib.rs | |||
@@ -151,7 +151,7 @@ impl HirFileId { | |||
151 | let def = loc.def.ast_id().left().and_then(|id| { | 151 | let def = loc.def.ast_id().left().and_then(|id| { |
152 | let def_tt = match id.to_node(db) { | 152 | let def_tt = match id.to_node(db) { |
153 | ast::Macro::MacroRules(mac) => mac.token_tree()?, | 153 | ast::Macro::MacroRules(mac) => mac.token_tree()?, |
154 | ast::Macro::MacroDef(_) => return None, | 154 | ast::Macro::MacroDef(mac) => mac.body()?, |
155 | }; | 155 | }; |
156 | Some(InFile::new(id.file_id, def_tt)) | 156 | Some(InFile::new(id.file_id, def_tt)) |
157 | }); | 157 | }); |