use crate::ptr::P;
use crate::symbol::Symbol;
use crate::tokenstream;
+use crate::util::path;
use smallvec::SmallVec;
-use syntax_pos::{self, Pos, Span, FileName};
+use syntax_pos::{self, Pos, Span};
use std::fs;
use std::io::ErrorKind;
-use std::path::PathBuf;
use rustc_data_structures::sync::Lrc;
// These macros all relate to the file system; they either return
None => return DummyResult::any(sp),
};
// The file will be added to the code map by the parser
- let path = res_rel_file(cx, sp, file);
+ let file = path::resolve(file, sp, cx.source_map());
let directory_ownership = DirectoryOwnership::Owned { relative: None };
- let p = parse::new_sub_parser_from_file(cx.parse_sess(), &path, directory_ownership, None, sp);
+ let p = parse::new_sub_parser_from_file(cx.parse_sess(), &file, directory_ownership, None, sp);
struct ExpandResult<'a> {
p: parse::parser::Parser<'a>,
Some(f) => f,
None => return DummyResult::expr(sp)
};
- let file = res_rel_file(cx, sp, file);
+ let file = path::resolve(file, sp, cx.source_map());
match fs::read_to_string(&file) {
Ok(src) => {
let interned_src = Symbol::intern(&src);
Some(f) => f,
None => return DummyResult::expr(sp)
};
- let file = res_rel_file(cx, sp, file);
+ let file = path::resolve(file, sp, cx.source_map());
match fs::read(&file) {
Ok(bytes) => {
// Add the contents to the source map if it contains UTF-8.
}
}
}
-
-// resolve a file-system path to an absolute file-system path (if it
-// isn't already)
-fn res_rel_file(cx: &mut ExtCtxt<'_>, sp: syntax_pos::Span, arg: String) -> PathBuf {
- let arg = PathBuf::from(arg);
- // Relative paths are resolved relative to the file in which they are found
- // after macro expansion (that is, they are unhygienic).
- if !arg.is_absolute() {
- let callsite = sp.source_callsite();
- let mut path = match cx.source_map().span_to_unmapped_path(callsite) {
- FileName::Real(path) => path,
- FileName::DocTest(path, _) => path,
- other => panic!("cannot resolve relative path in non-file source `{}`", other),
- };
- path.pop();
- path.push(arg);
- path
- } else {
- arg
- }
-}
--- /dev/null
+use crate::source_map::SourceMap;
+use std::path::PathBuf;
+use syntax_pos::{Span, FileName};
+
+/// Resolve a path mentioned inside Rust code.
+///
+/// This unifies the logic used for resolving `include_X!`, and `#[doc(include)]` file paths.
+///
+/// Returns an absolute path to the file that `path` refers to.
+pub fn resolve(path: impl Into<PathBuf>, span: Span, map: &SourceMap) -> PathBuf {
+ let path = path.into();
+
+ // Relative paths are resolved relative to the file in which they are found
+ // after macro expansion (that is, they are unhygienic).
+ if !path.is_absolute() {
+ let callsite = span.source_callsite();
+ let mut result = match map.span_to_unmapped_path(callsite) {
+ FileName::Real(path) => path,
+ FileName::DocTest(path, _) => path,
+ other => panic!("cannot resolve relative path in non-file source `{}`", other),
+ };
+ result.pop();
+ result.push(path);
+ result
+ } else {
+ path
+ }
+}