Skip to content

Commit

Permalink
Expose proc_macro's source_text() on Span
Browse files Browse the repository at this point in the history
  • Loading branch information
dtolnay committed Mar 22, 2023
1 parent ab25487 commit f27abfc
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 0 deletions.
4 changes: 4 additions & 0 deletions build.rs
Expand Up @@ -100,6 +100,10 @@ fn main() {
println!("cargo:rustc-cfg=no_is_available");
}

if version.minor < 66 {
println!("cargo:rustc-cfg=no_source_text");
}

let target = env::var("TARGET").unwrap();
if !enable_use_proc_macro(&target) {
return;
Expand Down
19 changes: 19 additions & 0 deletions src/fallback.rs
Expand Up @@ -342,6 +342,7 @@ thread_local! {
files: vec![FileInfo {
#[cfg(procmacro2_semver_exempt)]
name: "<unspecified>".to_owned(),
source_text: String::new(),
span: Span { lo: 0, hi: 0 },
lines: vec![0],
}],
Expand All @@ -352,6 +353,7 @@ thread_local! {
struct FileInfo {
#[cfg(procmacro2_semver_exempt)]
name: String,
source_text: String,
span: Span,
lines: Vec<usize>,
}
Expand Down Expand Up @@ -379,6 +381,12 @@ impl FileInfo {
fn span_within(&self, span: Span) -> bool {
span.lo >= self.span.lo && span.hi <= self.span.hi
}

fn source_text(&self, span: Span) -> String {
let lo = (span.lo - self.span.lo) as usize;
let hi = (span.hi - self.span.hi) as usize;
self.source_text[lo..hi].to_owned()
}
}

/// Computes the offsets of each line in the given source string
Expand Down Expand Up @@ -425,6 +433,7 @@ impl SourceMap {
self.files.push(FileInfo {
#[cfg(procmacro2_semver_exempt)]
name: name.to_owned(),
source_text: src.to_owned(),
span,
lines,
});
Expand Down Expand Up @@ -554,6 +563,16 @@ impl Span {
})
}

#[cfg(not(span_locations))]
pub fn source_text(&self) -> Option<String> {
None
}

#[cfg(span_locations)]
pub fn source_text(&self) -> Option<String> {
SOURCE_MAP.with(|cm| Some(cm.borrow().fileinfo(*self).source_text(*self)))
}

#[cfg(not(span_locations))]
pub(crate) fn first_byte(self) -> Self {
self
Expand Down
11 changes: 11 additions & 0 deletions src/lib.rs
Expand Up @@ -528,6 +528,17 @@ impl Span {
pub fn eq(&self, other: &Span) -> bool {
self.inner.eq(&other.inner)
}

/// Returns the source text behind a span. This preserves the original
/// source code, including spaces and comments. It only returns a result if
/// the span corresponds to real source code.
///
/// Note: The observable result of a macro should only rely on the tokens
/// and not on this source text. The result of this function is a best
/// effort to be used for diagnostics only.
pub fn source_text(&self) -> Option<String> {
self.inner.source_text()
}
}

/// Prints a span in a form convenient for debugging.
Expand Down
10 changes: 10 additions & 0 deletions src/wrapper.rs
Expand Up @@ -530,6 +530,16 @@ impl Span {
}
}

pub fn source_text(&self) -> Option<String> {
match self {
#[cfg(not(no_source_text))]
Span::Compiler(s) => s.source_text(),
#[cfg(no_source_text)]
Span::Compiler(_) => None,
Span::Fallback(s) => s.source_text(),
}
}

fn unwrap_nightly(self) -> proc_macro::Span {
match self {
Span::Compiler(s) => s,
Expand Down

0 comments on commit f27abfc

Please sign in to comment.