Skip to content

Commit b442062

Browse files
committed
Add support for include_str
1 parent 6a067ce commit b442062

File tree

3 files changed

+60
-19
lines changed

3 files changed

+60
-19
lines changed

crates/ra_hir_expand/src/builtin_macro.rs

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ register_builtin! {
9999
EAGER:
100100
(concat, Concat) => concat_expand,
101101
(include, Include) => include_expand,
102+
(include_str, IncludeStr) => include_str_expand,
102103
(env, Env) => env_expand,
103104
(option_env, OptionEnv) => option_env_expand
104105
}
@@ -292,11 +293,16 @@ fn concat_expand(
292293
Ok((quote!(#text), FragmentKind::Expr))
293294
}
294295

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> {
296302
let call_site = call_id.as_file().original_file(db);
297303
let res = db.resolve_path(call_site, path)?;
298304
// Prevent include itself
299-
if res == call_site {
305+
if res == call_site && !allow_recursion {
300306
None
301307
} else {
302308
Some(res)
@@ -319,8 +325,8 @@ fn include_expand(
319325
tt: &tt::Subtree,
320326
) -> Result<(tt::Subtree, FragmentKind), mbe::ExpandError> {
321327
let path = parse_string(tt)?;
322-
let file_id =
323-
relative_file(db, arg_id.into(), &path).ok_or_else(|| mbe::ExpandError::ConversionError)?;
328+
let file_id = relative_file(db, arg_id.into(), &path, false)
329+
.ok_or_else(|| mbe::ExpandError::ConversionError)?;
324330

325331
// FIXME:
326332
// Handle include as expression
@@ -331,6 +337,30 @@ fn include_expand(
331337
Ok((res, FragmentKind::Items))
332338
}
333339

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+
334364
fn get_env_inner(db: &dyn AstDatabase, arg_id: EagerMacroId, key: &str) -> Option<String> {
335365
let krate = db.lookup_intern_eager_expansion(arg_id).krate;
336366
db.crate_graph()[krate].env.get(key)

crates/ra_hir_expand/src/name.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,7 @@ pub mod known {
191191
stringify,
192192
concat,
193193
include,
194+
include_str,
194195
format_args,
195196
format_args_nl,
196197
env,

crates/rust-analyzer/tests/heavy_tests/main.rs

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -494,6 +494,7 @@ fn main() {
494494
}
495495
//- /src/main.rs
496496
#[rustc_builtin_macro] macro_rules! include {}
497+
#[rustc_builtin_macro] macro_rules! include_str {}
497498
#[rustc_builtin_macro] macro_rules! concat {}
498499
#[rustc_builtin_macro] macro_rules! env {}
499500
@@ -512,6 +513,7 @@ fn main() {
512513
let va = A;
513514
let vb = B;
514515
let should_be_str = message();
516+
let another_str = include_str!("main.rs");
515517
}
516518
"###,
517519
)
@@ -523,7 +525,15 @@ fn main() {
523525
let res = server.send_request::<HoverRequest>(HoverParams {
524526
text_document_position_params: TextDocumentPositionParams::new(
525527
server.doc_id("src/main.rs"),
526-
Position::new(18, 10),
528+
Position::new(19, 10),
529+
),
530+
work_done_progress_params: Default::default(),
531+
});
532+
assert!(res.to_string().contains("&str"));
533+
let res = server.send_request::<HoverRequest>(HoverParams {
534+
text_document_position_params: TextDocumentPositionParams::new(
535+
server.doc_id("src/main.rs"),
536+
Position::new(20, 10),
527537
),
528538
work_done_progress_params: Default::default(),
529539
});
@@ -532,23 +542,23 @@ fn main() {
532542
GotoDefinitionParams {
533543
text_document_position_params: TextDocumentPositionParams::new(
534544
server.doc_id("src/main.rs"),
535-
Position::new(16, 9),
545+
Position::new(17, 9),
536546
),
537547
work_done_progress_params: Default::default(),
538548
partial_result_params: Default::default(),
539549
},
540550
json!([{
541551
"originSelectionRange": {
542-
"end": { "character": 10, "line": 16 },
543-
"start": { "character": 8, "line": 16 }
552+
"end": { "character": 10, "line": 17 },
553+
"start": { "character": 8, "line": 17 }
544554
},
545555
"targetRange": {
546-
"end": { "character": 9, "line": 7 },
547-
"start": { "character": 0, "line": 6 }
556+
"end": { "character": 9, "line": 8 },
557+
"start": { "character": 0, "line": 7 }
548558
},
549559
"targetSelectionRange": {
550-
"end": { "character": 8, "line": 7 },
551-
"start": { "character": 7, "line": 7 }
560+
"end": { "character": 8, "line": 8 },
561+
"start": { "character": 7, "line": 8 }
552562
},
553563
"targetUri": "file:///[..]src/main.rs"
554564
}]),
@@ -557,23 +567,23 @@ fn main() {
557567
GotoDefinitionParams {
558568
text_document_position_params: TextDocumentPositionParams::new(
559569
server.doc_id("src/main.rs"),
560-
Position::new(17, 9),
570+
Position::new(18, 9),
561571
),
562572
work_done_progress_params: Default::default(),
563573
partial_result_params: Default::default(),
564574
},
565575
json!([{
566576
"originSelectionRange": {
567-
"end": { "character": 10, "line": 17 },
568-
"start": { "character": 8, "line": 17 }
577+
"end": { "character": 10, "line": 18 },
578+
"start": { "character": 8, "line": 18 }
569579
},
570580
"targetRange": {
571-
"end": { "character": 9, "line": 11 },
572-
"start": { "character": 0, "line":10 }
581+
"end": { "character": 9, "line": 12 },
582+
"start": { "character": 0, "line":11 }
573583
},
574584
"targetSelectionRange": {
575-
"end": { "character": 8, "line": 11 },
576-
"start": { "character": 7, "line": 11 }
585+
"end": { "character": 8, "line": 12 },
586+
"start": { "character": 7, "line": 12 }
577587
},
578588
"targetUri": "file:///[..]src/main.rs"
579589
}]),

0 commit comments

Comments
 (0)