@@ -412,4 +412,58 @@ MacroBuiltin::cfg (Location invoc_locus, AST::MacroInvocData &invoc)
412
412
return AST::ASTFragment ({literal_exp});
413
413
}
414
414
415
+ /* Expand builtin macro include!(), which includes a source file at the current
416
+ scope compile time. */
417
+
418
+ AST::ASTFragment
419
+ MacroBuiltin::include (Location invoc_locus, AST::MacroInvocData &invoc)
420
+ {
421
+ /* Get target filename from the macro invocation, which is treated as a path
422
+ relative to the include!-ing file (currently being compiled). */
423
+ auto lit_expr
424
+ = parse_single_string_literal (invoc.get_delim_tok_tree (), invoc_locus);
425
+ if (lit_expr == nullptr )
426
+ return AST::ASTFragment::create_error ();
427
+
428
+ std::string target_filename
429
+ = source_relative_path (lit_expr->as_string (), invoc_locus);
430
+
431
+ RAIIFile target_file (target_filename.c_str ());
432
+ Linemap *linemap = Session::get_instance ().linemap ;
433
+
434
+ if (target_file.get_raw () == nullptr )
435
+ {
436
+ rust_error_at (lit_expr->get_locus (), " cannot open included file %s: %m" ,
437
+ target_filename.c_str ());
438
+ return AST::ASTFragment::create_error ();
439
+ }
440
+
441
+ rust_debug (" Attempting to parse included file %s" , target_filename.c_str ());
442
+
443
+ Lexer lex (target_filename.c_str (), std::move (target_file), linemap);
444
+ Parser<Lexer> parser (std::move (lex));
445
+
446
+ auto parsed_items = parser.parse_items ();
447
+ bool has_error = !parser.get_errors ().empty ();
448
+
449
+ for (const auto &error : parser.get_errors ())
450
+ error.emit_error ();
451
+
452
+ if (has_error)
453
+ {
454
+ // inform the user that the errors above are from a included file
455
+ rust_inform (invoc_locus, " included from here" );
456
+ return AST::ASTFragment::create_error ();
457
+ }
458
+
459
+ std::vector<AST::SingleASTNode> nodes{};
460
+ for (auto &item : parsed_items)
461
+ {
462
+ AST::SingleASTNode node (std::move (item));
463
+ nodes.push_back (node);
464
+ }
465
+
466
+ return AST::ASTFragment (nodes);
467
+ }
468
+
415
469
} // namespace Rust
0 commit comments