aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_expand/src/builtin_macro.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_expand/src/builtin_macro.rs')
-rw-r--r--crates/ra_hir_expand/src/builtin_macro.rs52
1 files changed, 46 insertions, 6 deletions
diff --git a/crates/ra_hir_expand/src/builtin_macro.rs b/crates/ra_hir_expand/src/builtin_macro.rs
index b2c8a911f..9fc33e4b1 100644
--- a/crates/ra_hir_expand/src/builtin_macro.rs
+++ b/crates/ra_hir_expand/src/builtin_macro.rs
@@ -5,8 +5,9 @@ use crate::{
5 name, AstId, CrateId, MacroDefId, MacroDefKind, TextUnit, 5 name, AstId, CrateId, MacroDefId, MacroDefKind, TextUnit,
6}; 6};
7 7
8use crate::{quote, LazyMacroId}; 8use crate::{quote, EagerMacroId, LazyMacroId, MacroCallId};
9use either::Either; 9use either::Either;
10use ra_db::{FileId, RelativePath};
10use ra_parser::FragmentKind; 11use ra_parser::FragmentKind;
11 12
12macro_rules! register_builtin { 13macro_rules! register_builtin {
@@ -38,12 +39,14 @@ macro_rules! register_builtin {
38 impl EagerExpander { 39 impl EagerExpander {
39 pub fn expand( 40 pub fn expand(
40 &self, 41 &self,
42 db: &dyn AstDatabase,
43 arg_id: EagerMacroId,
41 tt: &tt::Subtree, 44 tt: &tt::Subtree,
42 ) -> Result<(tt::Subtree, FragmentKind), mbe::ExpandError> { 45 ) -> Result<(tt::Subtree, FragmentKind), mbe::ExpandError> {
43 let expander = match *self { 46 let expander = match *self {
44 $( EagerExpander::$e_kind => $e_expand, )* 47 $( EagerExpander::$e_kind => $e_expand, )*
45 }; 48 };
46 expander(tt) 49 expander(db,arg_id,tt)
47 } 50 }
48 } 51 }
49 52
@@ -80,7 +83,6 @@ pub fn find_builtin_macro(
80 83
81register_builtin! { 84register_builtin! {
82 LAZY: 85 LAZY:
83
84 (column, Column) => column_expand, 86 (column, Column) => column_expand,
85 (compile_error, CompileError) => compile_error_expand, 87 (compile_error, CompileError) => compile_error_expand,
86 (file, File) => file_expand, 88 (file, File) => file_expand,
@@ -94,8 +96,8 @@ register_builtin! {
94 (format_args_nl, FormatArgsNl) => format_args_expand, 96 (format_args_nl, FormatArgsNl) => format_args_expand,
95 97
96 EAGER: 98 EAGER:
97 // eagers 99 (concat, Concat) => concat_expand,
98 (concat, Concat) => concat_expand 100 (include, Include) => include_expand
99} 101}
100 102
101fn line_expand( 103fn line_expand(
@@ -251,7 +253,11 @@ fn unquote_str(lit: &tt::Literal) -> Option<String> {
251 token.value() 253 token.value()
252} 254}
253 255
254fn concat_expand(tt: &tt::Subtree) -> Result<(tt::Subtree, FragmentKind), mbe::ExpandError> { 256fn concat_expand(
257 _db: &dyn AstDatabase,
258 _arg_id: EagerMacroId,
259 tt: &tt::Subtree,
260) -> Result<(tt::Subtree, FragmentKind), mbe::ExpandError> {
255 let mut text = String::new(); 261 let mut text = String::new();
256 for (i, t) in tt.token_trees.iter().enumerate() { 262 for (i, t) in tt.token_trees.iter().enumerate() {
257 match t { 263 match t {
@@ -266,6 +272,40 @@ fn concat_expand(tt: &tt::Subtree) -> Result<(tt::Subtree, FragmentKind), mbe::E
266 Ok((quote!(#text), FragmentKind::Expr)) 272 Ok((quote!(#text), FragmentKind::Expr))
267} 273}
268 274
275fn relative_file(db: &dyn AstDatabase, call_id: MacroCallId, path: &str) -> Option<FileId> {
276 let call_site = call_id.as_file().original_file(db);
277 let path = RelativePath::new(&path);
278
279 db.resolve_relative_path(call_site, &path)
280}
281
282fn include_expand(
283 db: &dyn AstDatabase,
284 arg_id: EagerMacroId,
285 tt: &tt::Subtree,
286) -> Result<(tt::Subtree, FragmentKind), mbe::ExpandError> {
287 let path = tt
288 .token_trees
289 .get(0)
290 .and_then(|tt| match tt {
291 tt::TokenTree::Leaf(tt::Leaf::Literal(it)) => unquote_str(&it),
292 _ => None,
293 })
294 .ok_or_else(|| mbe::ExpandError::ConversionError)?;
295
296 let file_id =
297 relative_file(db, arg_id.into(), &path).ok_or_else(|| mbe::ExpandError::ConversionError)?;
298
299 // FIXME:
300 // Handle include as expression
301 let node =
302 db.parse_or_expand(file_id.into()).ok_or_else(|| mbe::ExpandError::ConversionError)?;
303 let res =
304 mbe::syntax_node_to_token_tree(&node).ok_or_else(|| mbe::ExpandError::ConversionError)?.0;
305
306 Ok((res, FragmentKind::Items))
307}
308
269#[cfg(test)] 309#[cfg(test)]
270mod tests { 310mod tests {
271 use super::*; 311 use super::*;