diff options
Diffstat (limited to 'crates/ra_hir_expand/src/builtin_macro.rs')
-rw-r--r-- | crates/ra_hir_expand/src/builtin_macro.rs | 52 |
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 | ||
8 | use crate::{quote, LazyMacroId}; | 8 | use crate::{quote, EagerMacroId, LazyMacroId, MacroCallId}; |
9 | use either::Either; | 9 | use either::Either; |
10 | use ra_db::{FileId, RelativePath}; | ||
10 | use ra_parser::FragmentKind; | 11 | use ra_parser::FragmentKind; |
11 | 12 | ||
12 | macro_rules! register_builtin { | 13 | macro_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 | ||
81 | register_builtin! { | 84 | register_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 | ||
101 | fn line_expand( | 103 | fn line_expand( |
@@ -251,7 +253,11 @@ fn unquote_str(lit: &tt::Literal) -> Option<String> { | |||
251 | token.value() | 253 | token.value() |
252 | } | 254 | } |
253 | 255 | ||
254 | fn concat_expand(tt: &tt::Subtree) -> Result<(tt::Subtree, FragmentKind), mbe::ExpandError> { | 256 | fn 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 | ||
275 | fn 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 | |||
282 | fn 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)] |
270 | mod tests { | 310 | mod tests { |
271 | use super::*; | 311 | use super::*; |