From 759bcea96de448a7758276a9ce5696a56b44b465 Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Wed, 11 Mar 2020 23:08:12 +0800 Subject: Implement dummy assert macro --- crates/ra_hir_expand/src/builtin_macro.rs | 56 +++++++++++++++++++++++++++++++ crates/ra_hir_expand/src/name.rs | 1 + crates/ra_hir_expand/src/quote.rs | 1 + 3 files changed, 58 insertions(+) (limited to 'crates/ra_hir_expand') diff --git a/crates/ra_hir_expand/src/builtin_macro.rs b/crates/ra_hir_expand/src/builtin_macro.rs index a90007f26..01f78fc77 100644 --- a/crates/ra_hir_expand/src/builtin_macro.rs +++ b/crates/ra_hir_expand/src/builtin_macro.rs @@ -88,6 +88,7 @@ register_builtin! { (compile_error, CompileError) => compile_error_expand, (file, File) => file_expand, (line, Line) => line_expand, + (assert, Assert) => assert_expand, (stringify, Stringify) => stringify_expand, (format_args, FormatArgs) => format_args_expand, // format_args_nl only differs in that it adds a newline in the end, @@ -151,6 +152,45 @@ fn column_expand( Ok(expanded) } +fn assert_expand( + _db: &dyn AstDatabase, + _id: LazyMacroId, + tt: &tt::Subtree, +) -> Result { + // A hacky implementation for goto def and hover + // We expand `assert!("", arg1, arg2)` to + // ``` + // {(&(arg1), &(arg2));} + // ```, + // which is wrong but useful. + + let mut args = Vec::new(); + let mut current = Vec::new(); + for tt in tt.token_trees.iter().cloned() { + match tt { + tt::TokenTree::Leaf(tt::Leaf::Punct(p)) if p.char == ',' => { + args.push(current); + current = Vec::new(); + } + _ => { + current.push(tt); + } + } + } + if !current.is_empty() { + args.push(current); + } + + let arg_tts = args.into_iter().flat_map(|arg| { + quote! { &(##arg), } + }.token_trees).collect::>(); + + let expanded = quote! { + { { (##arg_tts); } } + }; + Ok(expanded) +} + fn file_expand( _db: &dyn AstDatabase, _id: LazyMacroId, @@ -493,6 +533,22 @@ mod tests { assert_eq!(expanded, "\"\""); } + #[test] + fn test_assert_expand() { + let expanded = expand_builtin_macro( + r#" + #[rustc_builtin_macro] + macro_rules! assert { + ($fmt:expr) => ({ /* compiler built-in */ }); + ($fmt:expr, $($args:tt)*) => ({ /* compiler built-in */ }) + } + assert!(true, "{} {:?}", arg1(a, b, c), arg2); + "#, + ); + + assert_eq!(expanded, "{{(&(true), &(\"{} {:?}\"), &(arg1(a,b,c)), &(arg2),);}}"); + } + #[test] fn test_compile_error_expand() { let expanded = expand_builtin_macro( diff --git a/crates/ra_hir_expand/src/name.rs b/crates/ra_hir_expand/src/name.rs index 6d201256f..25cc1e9fc 100644 --- a/crates/ra_hir_expand/src/name.rs +++ b/crates/ra_hir_expand/src/name.rs @@ -172,6 +172,7 @@ pub mod known { column, compile_error, line, + assert, stringify, concat, include, diff --git a/crates/ra_hir_expand/src/quote.rs b/crates/ra_hir_expand/src/quote.rs index 57e7eebf9..3fd4233da 100644 --- a/crates/ra_hir_expand/src/quote.rs +++ b/crates/ra_hir_expand/src/quote.rs @@ -99,6 +99,7 @@ macro_rules! __quote { ( & ) => {$crate::__quote!(@PUNCT '&')}; ( , ) => {$crate::__quote!(@PUNCT ',')}; ( : ) => {$crate::__quote!(@PUNCT ':')}; + ( ; ) => {$crate::__quote!(@PUNCT ';')}; ( :: ) => {$crate::__quote!(@PUNCT ':', ':')}; ( . ) => {$crate::__quote!(@PUNCT '.')}; ( < ) => {$crate::__quote!(@PUNCT '<')}; -- cgit v1.2.3