Make path::resolve a method on ExtCtxt

This commit is contained in:
Jonas Schievink 2019-06-22 21:51:51 +02:00
parent 8ccf52c1c6
commit edb21873cc
5 changed files with 30 additions and 36 deletions

View File

@ -1,6 +1,6 @@
use crate::ast::{self, Attribute, Name, PatKind};
use crate::attr::{HasAttrs, Stability, Deprecation};
use crate::source_map::{SourceMap, Spanned, respan};
use crate::source_map::{SourceMap, Spanned, FileName, respan};
use crate::edition::Edition;
use crate::ext::expand::{self, AstFragment, Invocation};
use crate::ext::hygiene::{ExpnId, SyntaxContext, Transparency};
@ -889,6 +889,31 @@ impl<'a> ExtCtxt<'a> {
pub fn check_unused_macros(&self) {
self.resolver.check_unused_macros();
}
/// 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(&self, path: impl Into<PathBuf>, span: Span) -> 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 self.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),
};
result.pop();
result.push(path);
result
} else {
path
}
}
}
/// Extracts a string literal from the macro expanded version of `expr`,

View File

@ -17,7 +17,6 @@ use crate::symbol::{sym, Symbol};
use crate::tokenstream::{TokenStream, TokenTree};
use crate::visit::{self, Visitor};
use crate::util::map_in_place::MapInPlace;
use crate::util::path;
use errors::{Applicability, FatalError};
use smallvec::{smallvec, SmallVec};
@ -1254,7 +1253,7 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
return noop_visit_attribute(at, self);
}
let filename = path::resolve(&*file.as_str(), it.span(), self.cx.source_map());
let filename = self.cx.resolve_path(&*file.as_str(), it.span());
match fs::read_to_string(&filename) {
Ok(src) => {
let src_interned = Symbol::intern(&src);

View File

@ -6,7 +6,6 @@ use crate::print::pprust;
use crate::ptr::P;
use crate::symbol::Symbol;
use crate::tokenstream;
use crate::util::path;
use smallvec::SmallVec;
use syntax_pos::{self, Pos, Span};
@ -78,7 +77,7 @@ pub fn expand_include<'cx>(cx: &'cx mut ExtCtxt<'_>, sp: Span, tts: &[tokenstrea
None => return DummyResult::any(sp),
};
// The file will be added to the code map by the parser
let file = path::resolve(file, sp, cx.source_map());
let file = cx.resolve_path(file, sp);
let directory_ownership = DirectoryOwnership::Owned { relative: None };
let p = parse::new_sub_parser_from_file(cx.parse_sess(), &file, directory_ownership, None, sp);
@ -115,7 +114,7 @@ pub fn expand_include_str(cx: &mut ExtCtxt<'_>, sp: Span, tts: &[tokenstream::To
Some(f) => f,
None => return DummyResult::expr(sp)
};
let file = path::resolve(file, sp, cx.source_map());
let file = cx.resolve_path(file, sp);
match fs::read_to_string(&file) {
Ok(src) => {
let interned_src = Symbol::intern(&src);
@ -143,7 +142,7 @@ pub fn expand_include_bytes(cx: &mut ExtCtxt<'_>, sp: Span, tts: &[tokenstream::
Some(f) => f,
None => return DummyResult::expr(sp)
};
let file = path::resolve(file, sp, cx.source_map());
let file = cx.resolve_path(file, sp);
match fs::read(&file) {
Ok(bytes) => {
// Add the contents to the source map if it contains UTF-8.

View File

@ -135,7 +135,6 @@ pub mod util {
#[cfg(test)]
pub mod parser_testing;
pub mod map_in_place;
pub mod path;
}
pub mod json;

View File

@ -1,28 +0,0 @@
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
}
}