Rename get_source_text
to get_source_range
. Add new get_source_text
which returns a displayable string-like type.
This commit is contained in:
parent
cb806113e0
commit
9afab36ca9
@ -22,7 +22,7 @@
|
||||
/// span, e.g. a string literal `"//"`, but we know that this isn't the case for empty
|
||||
/// match arms.
|
||||
fn empty_arm_has_comment(cx: &LateContext<'_>, span: Span) -> bool {
|
||||
if let Some(ff) = span.get_source_text(cx)
|
||||
if let Some(ff) = span.get_source_range(cx)
|
||||
&& let Some(text) = ff.as_str()
|
||||
{
|
||||
text.as_bytes().windows(2).any(|w| w == b"//" || w == b"/*")
|
||||
|
@ -687,7 +687,7 @@ fn block(&self, block: &Block<'_>) -> Option<Constant<'tcx>> {
|
||||
if let Some(expr_span) = walk_span_to_context(expr.span, span.ctxt)
|
||||
&& let expr_lo = expr_span.lo()
|
||||
&& expr_lo >= span.lo
|
||||
&& let Some(src) = (span.lo..expr_lo).get_source_text(&self.tcx)
|
||||
&& let Some(src) = (span.lo..expr_lo).get_source_range(&self.tcx)
|
||||
&& let Some(src) = src.as_str()
|
||||
{
|
||||
use rustc_lexer::TokenKind::{BlockComment, LineComment, OpenBrace, Semi, Whitespace};
|
||||
|
@ -1191,9 +1191,9 @@ fn eq_span_tokens(
|
||||
pred: impl Fn(TokenKind) -> bool,
|
||||
) -> bool {
|
||||
fn f(cx: &LateContext<'_>, left: Range<BytePos>, right: Range<BytePos>, pred: impl Fn(TokenKind) -> bool) -> bool {
|
||||
if let Some(lsrc) = left.get_source_text(cx)
|
||||
if let Some(lsrc) = left.get_source_range(cx)
|
||||
&& let Some(lsrc) = lsrc.as_str()
|
||||
&& let Some(rsrc) = right.get_source_text(cx)
|
||||
&& let Some(rsrc) = right.get_source_range(cx)
|
||||
&& let Some(rsrc) = rsrc.as_str()
|
||||
{
|
||||
let pred = |t: &(_, _)| pred(t.0);
|
||||
|
@ -16,7 +16,7 @@
|
||||
};
|
||||
use std::borrow::Cow;
|
||||
use std::fmt;
|
||||
use std::ops::Range;
|
||||
use std::ops::{Deref, Range};
|
||||
|
||||
pub trait HasSession {
|
||||
fn sess(&self) -> &Session;
|
||||
@ -94,10 +94,16 @@ fn with_ctxt(self, ctxt: SyntaxContext) -> Span {
|
||||
}
|
||||
|
||||
pub trait SpanRangeExt: SpanRange {
|
||||
/// Attempts to get a handle to the source text. Returns `None` if either the span is malformed,
|
||||
/// or the source text is not accessible.
|
||||
fn get_source_text(self, cx: &impl HasSession) -> Option<SourceText> {
|
||||
get_source_range(cx.sess().source_map(), self.into_range()).and_then(SourceText::new)
|
||||
}
|
||||
|
||||
/// Gets the source file, and range in the file, of the given span. Returns `None` if the span
|
||||
/// extends through multiple files, or is malformed.
|
||||
fn get_source_text(self, cx: &impl HasSession) -> Option<SourceFileRange> {
|
||||
get_source_text(cx.sess().source_map(), self.into_range())
|
||||
fn get_source_range(self, cx: &impl HasSession) -> Option<SourceFileRange> {
|
||||
get_source_range(cx.sess().source_map(), self.into_range())
|
||||
}
|
||||
|
||||
/// Calls the given function with the source text referenced and returns the value. Returns
|
||||
@ -144,21 +150,49 @@ fn with_leading_whitespace(self, cx: &impl HasSession) -> Range<BytePos> {
|
||||
fn trim_start(self, cx: &impl HasSession) -> Range<BytePos> {
|
||||
trim_start(cx.sess().source_map(), self.into_range())
|
||||
}
|
||||
|
||||
/// Writes the referenced source text to the given writer. Will return `Err` if the source text
|
||||
/// could not be retrieved.
|
||||
fn write_source_text_to(self, cx: &impl HasSession, dst: &mut impl fmt::Write) -> fmt::Result {
|
||||
write_source_text_to(cx.sess().source_map(), self.into_range(), dst)
|
||||
}
|
||||
|
||||
/// Extracts the referenced source text as an owned string.
|
||||
fn source_text_to_string(self, cx: &impl HasSession) -> Option<String> {
|
||||
self.with_source_text(cx, ToOwned::to_owned)
|
||||
}
|
||||
}
|
||||
impl<T: SpanRange> SpanRangeExt for T {}
|
||||
|
||||
fn get_source_text(sm: &SourceMap, sp: Range<BytePos>) -> Option<SourceFileRange> {
|
||||
/// Handle to a range of text in a source file.
|
||||
pub struct SourceText(SourceFileRange);
|
||||
impl SourceText {
|
||||
/// Takes ownership of the source file handle if the source text is accessible.
|
||||
pub fn new(text: SourceFileRange) -> Option<Self> {
|
||||
if text.as_str().is_some() {
|
||||
Some(Self(text))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// Gets the source text.
|
||||
pub fn as_str(&self) -> &str {
|
||||
self.0.as_str().unwrap()
|
||||
}
|
||||
|
||||
/// Converts this into an owned string.
|
||||
pub fn to_owned(&self) -> String {
|
||||
self.as_str().to_owned()
|
||||
}
|
||||
}
|
||||
impl Deref for SourceText {
|
||||
type Target = str;
|
||||
fn deref(&self) -> &Self::Target {
|
||||
self.as_str()
|
||||
}
|
||||
}
|
||||
impl AsRef<str> for SourceText {
|
||||
fn as_ref(&self) -> &str {
|
||||
self.as_str()
|
||||
}
|
||||
}
|
||||
impl fmt::Display for SourceText {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
self.as_str().fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
fn get_source_range(sm: &SourceMap, sp: Range<BytePos>) -> Option<SourceFileRange> {
|
||||
let start = sm.lookup_byte_offset(sp.start);
|
||||
let end = sm.lookup_byte_offset(sp.end);
|
||||
if !Lrc::ptr_eq(&start.sf, &end.sf) || start.pos > end.pos {
|
||||
@ -169,7 +203,7 @@ fn get_source_text(sm: &SourceMap, sp: Range<BytePos>) -> Option<SourceFileRange
|
||||
}
|
||||
|
||||
fn with_source_text<T>(sm: &SourceMap, sp: Range<BytePos>, f: impl for<'a> FnOnce(&'a str) -> T) -> Option<T> {
|
||||
if let Some(src) = get_source_text(sm, sp)
|
||||
if let Some(src) = get_source_range(sm, sp)
|
||||
&& let Some(src) = src.as_str()
|
||||
{
|
||||
Some(f(src))
|
||||
@ -183,7 +217,7 @@ fn with_source_text_and_range<T>(
|
||||
sp: Range<BytePos>,
|
||||
f: impl for<'a> FnOnce(&'a str, Range<usize>) -> T,
|
||||
) -> Option<T> {
|
||||
if let Some(src) = get_source_text(sm, sp)
|
||||
if let Some(src) = get_source_range(sm, sp)
|
||||
&& let Some(text) = &src.sf.src
|
||||
{
|
||||
Some(f(text, src.range))
|
||||
@ -198,7 +232,7 @@ fn map_range(
|
||||
sp: Range<BytePos>,
|
||||
f: impl for<'a> FnOnce(&'a str, Range<usize>) -> Option<Range<usize>>,
|
||||
) -> Option<Range<BytePos>> {
|
||||
if let Some(src) = get_source_text(sm, sp.clone())
|
||||
if let Some(src) = get_source_range(sm, sp.clone())
|
||||
&& let Some(text) = &src.sf.src
|
||||
&& let Some(range) = f(text, src.range.clone())
|
||||
{
|
||||
@ -232,13 +266,6 @@ fn trim_start(sm: &SourceMap, sp: Range<BytePos>) -> Range<BytePos> {
|
||||
.unwrap_or(sp)
|
||||
}
|
||||
|
||||
fn write_source_text_to(sm: &SourceMap, sp: Range<BytePos>, dst: &mut impl fmt::Write) -> fmt::Result {
|
||||
match with_source_text(sm, sp, |src| dst.write_str(src)) {
|
||||
Some(x) => x,
|
||||
None => Err(fmt::Error),
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SourceFileRange {
|
||||
pub sf: Lrc<SourceFile>,
|
||||
pub range: Range<usize>,
|
||||
|
Loading…
Reference in New Issue
Block a user