aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_expand
diff options
context:
space:
mode:
authorEdwin Cheng <[email protected]>2021-03-27 05:44:54 +0000
committerEdwin Cheng <[email protected]>2021-03-27 05:44:54 +0000
commita193666361f6ea9725b927a35f5baf77da713c0a (patch)
treefa916fcc7e5031df796f42521fb74d775ebdec59 /crates/hir_expand
parentc8066ebd1781a6f6f536abe3494477bd69df795a (diff)
Basic Support Macro 2.0
Diffstat (limited to 'crates/hir_expand')
-rw-r--r--crates/hir_expand/src/db.rs60
-rw-r--r--crates/hir_expand/src/hygiene.rs2
-rw-r--r--crates/hir_expand/src/lib.rs2
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 @@
3use std::sync::Arc; 3use std::sync::Arc;
4 4
5use base_db::{salsa, SourceDatabase}; 5use base_db::{salsa, SourceDatabase};
6use mbe::{ExpandError, ExpandResult, MacroRules}; 6use mbe::{ExpandError, ExpandResult, MacroDef, MacroRules};
7use parser::FragmentKind; 7use parser::FragmentKind;
8use syntax::{ 8use 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)]
29pub enum TokenExpander { 29pub 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
137fn macro_def(db: &dyn AstDatabase, id: MacroDefId) -> Option<Arc<(TokenExpander, mbe::TokenMap)>> { 141fn 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 });