diff options
author | Laurențiu Nicola <[email protected]> | 2020-06-27 13:31:19 +0100 |
---|---|---|
committer | Laurențiu Nicola <[email protected]> | 2020-06-27 17:34:48 +0100 |
commit | b4420626fbcc5f7b58e19f735fdbec1b0c48f045 (patch) | |
tree | d7373e0339c114703184921c2477c994181c0088 /crates/ra_hir_expand | |
parent | 6a067ce947980d887a254d71d7183c3d306d8978 (diff) |
Add support for include_str
Diffstat (limited to 'crates/ra_hir_expand')
-rw-r--r-- | crates/ra_hir_expand/src/builtin_macro.rs | 38 | ||||
-rw-r--r-- | crates/ra_hir_expand/src/name.rs | 1 |
2 files changed, 35 insertions, 4 deletions
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! { | |||
99 | EAGER: | 99 | EAGER: |
100 | (concat, Concat) => concat_expand, | 100 | (concat, Concat) => concat_expand, |
101 | (include, Include) => include_expand, | 101 | (include, Include) => include_expand, |
102 | (include_str, IncludeStr) => include_str_expand, | ||
102 | (env, Env) => env_expand, | 103 | (env, Env) => env_expand, |
103 | (option_env, OptionEnv) => option_env_expand | 104 | (option_env, OptionEnv) => option_env_expand |
104 | } | 105 | } |
@@ -292,11 +293,16 @@ fn concat_expand( | |||
292 | Ok((quote!(#text), FragmentKind::Expr)) | 293 | Ok((quote!(#text), FragmentKind::Expr)) |
293 | } | 294 | } |
294 | 295 | ||
295 | fn relative_file(db: &dyn AstDatabase, call_id: MacroCallId, path: &str) -> Option<FileId> { | 296 | fn relative_file( |
297 | db: &dyn AstDatabase, | ||
298 | call_id: MacroCallId, | ||
299 | path: &str, | ||
300 | allow_recursion: bool, | ||
301 | ) -> Option<FileId> { | ||
296 | let call_site = call_id.as_file().original_file(db); | 302 | let call_site = call_id.as_file().original_file(db); |
297 | let res = db.resolve_path(call_site, path)?; | 303 | let res = db.resolve_path(call_site, path)?; |
298 | // Prevent include itself | 304 | // Prevent include itself |
299 | if res == call_site { | 305 | if res == call_site && !allow_recursion { |
300 | None | 306 | None |
301 | } else { | 307 | } else { |
302 | Some(res) | 308 | Some(res) |
@@ -319,8 +325,8 @@ fn include_expand( | |||
319 | tt: &tt::Subtree, | 325 | tt: &tt::Subtree, |
320 | ) -> Result<(tt::Subtree, FragmentKind), mbe::ExpandError> { | 326 | ) -> Result<(tt::Subtree, FragmentKind), mbe::ExpandError> { |
321 | let path = parse_string(tt)?; | 327 | let path = parse_string(tt)?; |
322 | let file_id = | 328 | let file_id = relative_file(db, arg_id.into(), &path, false) |
323 | relative_file(db, arg_id.into(), &path).ok_or_else(|| mbe::ExpandError::ConversionError)?; | 329 | .ok_or_else(|| mbe::ExpandError::ConversionError)?; |
324 | 330 | ||
325 | // FIXME: | 331 | // FIXME: |
326 | // Handle include as expression | 332 | // Handle include as expression |
@@ -331,6 +337,30 @@ fn include_expand( | |||
331 | Ok((res, FragmentKind::Items)) | 337 | Ok((res, FragmentKind::Items)) |
332 | } | 338 | } |
333 | 339 | ||
340 | fn include_str_expand( | ||
341 | db: &dyn AstDatabase, | ||
342 | arg_id: EagerMacroId, | ||
343 | tt: &tt::Subtree, | ||
344 | ) -> Result<(tt::Subtree, FragmentKind), mbe::ExpandError> { | ||
345 | let path = parse_string(tt)?; | ||
346 | |||
347 | // FIXME: we're not able to read excluded files (which is most of them because | ||
348 | // it's unusual to `include_str!` a Rust file), but we can return an empty string. | ||
349 | // Ideally, we'd be able to offer a precise expansion if the user asks for macro | ||
350 | // expansion. | ||
351 | let file_id = match relative_file(db, arg_id.into(), &path, true) { | ||
352 | Some(file_id) => file_id, | ||
353 | None => { | ||
354 | return Ok((quote!(""), FragmentKind::Expr)); | ||
355 | } | ||
356 | }; | ||
357 | |||
358 | let text = db.file_text(file_id); | ||
359 | let text = &*text; | ||
360 | |||
361 | Ok((quote!(#text), FragmentKind::Expr)) | ||
362 | } | ||
363 | |||
334 | fn get_env_inner(db: &dyn AstDatabase, arg_id: EagerMacroId, key: &str) -> Option<String> { | 364 | fn get_env_inner(db: &dyn AstDatabase, arg_id: EagerMacroId, key: &str) -> Option<String> { |
335 | let krate = db.lookup_intern_eager_expansion(arg_id).krate; | 365 | let krate = db.lookup_intern_eager_expansion(arg_id).krate; |
336 | db.crate_graph()[krate].env.get(key) | 366 | 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 { | |||
191 | stringify, | 191 | stringify, |
192 | concat, | 192 | concat, |
193 | include, | 193 | include, |
194 | include_str, | ||
194 | format_args, | 195 | format_args, |
195 | format_args_nl, | 196 | format_args_nl, |
196 | env, | 197 | env, |