From b4420626fbcc5f7b58e19f735fdbec1b0c48f045 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lauren=C8=9Biu=20Nicola?= Date: Sat, 27 Jun 2020 15:31:19 +0300 Subject: Add support for include_str --- crates/ra_hir_expand/src/builtin_macro.rs | 38 +++++++++++++++++++++++++++---- crates/ra_hir_expand/src/name.rs | 1 + 2 files changed, 35 insertions(+), 4 deletions(-) (limited to 'crates/ra_hir_expand/src') diff --git a/crates/ra_hir_expand/src/builtin_macro.rs b/crates/ra_hir_expand/src/builtin_macro.rs index b50eb347c..631358f41 100644 --- a/crates/ra_hir_expand/src/builtin_macro.rs +++ b/crates/ra_hir_expand/src/builtin_macro.rs @@ -99,6 +99,7 @@ register_builtin! { EAGER: (concat, Concat) => concat_expand, (include, Include) => include_expand, + (include_str, IncludeStr) => include_str_expand, (env, Env) => env_expand, (option_env, OptionEnv) => option_env_expand } @@ -292,11 +293,16 @@ fn concat_expand( Ok((quote!(#text), FragmentKind::Expr)) } -fn relative_file(db: &dyn AstDatabase, call_id: MacroCallId, path: &str) -> Option { +fn relative_file( + db: &dyn AstDatabase, + call_id: MacroCallId, + path: &str, + allow_recursion: bool, +) -> Option { let call_site = call_id.as_file().original_file(db); let res = db.resolve_path(call_site, path)?; // Prevent include itself - if res == call_site { + if res == call_site && !allow_recursion { None } else { Some(res) @@ -319,8 +325,8 @@ fn include_expand( tt: &tt::Subtree, ) -> Result<(tt::Subtree, FragmentKind), mbe::ExpandError> { let path = parse_string(tt)?; - let file_id = - relative_file(db, arg_id.into(), &path).ok_or_else(|| mbe::ExpandError::ConversionError)?; + let file_id = relative_file(db, arg_id.into(), &path, false) + .ok_or_else(|| mbe::ExpandError::ConversionError)?; // FIXME: // Handle include as expression @@ -331,6 +337,30 @@ fn include_expand( Ok((res, FragmentKind::Items)) } +fn include_str_expand( + db: &dyn AstDatabase, + arg_id: EagerMacroId, + tt: &tt::Subtree, +) -> Result<(tt::Subtree, FragmentKind), mbe::ExpandError> { + let path = parse_string(tt)?; + + // FIXME: we're not able to read excluded files (which is most of them because + // it's unusual to `include_str!` a Rust file), but we can return an empty string. + // Ideally, we'd be able to offer a precise expansion if the user asks for macro + // expansion. + let file_id = match relative_file(db, arg_id.into(), &path, true) { + Some(file_id) => file_id, + None => { + return Ok((quote!(""), FragmentKind::Expr)); + } + }; + + let text = db.file_text(file_id); + let text = &*text; + + Ok((quote!(#text), FragmentKind::Expr)) +} + fn get_env_inner(db: &dyn AstDatabase, arg_id: EagerMacroId, key: &str) -> Option { let krate = db.lookup_intern_eager_expansion(arg_id).krate; db.crate_graph()[krate].env.get(key) diff --git a/crates/ra_hir_expand/src/name.rs b/crates/ra_hir_expand/src/name.rs index 660bdfe33..b475c8cc7 100644 --- a/crates/ra_hir_expand/src/name.rs +++ b/crates/ra_hir_expand/src/name.rs @@ -191,6 +191,7 @@ pub mod known { stringify, concat, include, + include_str, format_args, format_args_nl, env, -- cgit v1.2.3