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
|
/// span, e.g. a string literal `"//"`, but we know that this isn't the case for empty
|
||||||
/// match arms.
|
/// match arms.
|
||||||
fn empty_arm_has_comment(cx: &LateContext<'_>, span: Span) -> bool {
|
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()
|
&& let Some(text) = ff.as_str()
|
||||||
{
|
{
|
||||||
text.as_bytes().windows(2).any(|w| w == b"//" || w == b"/*")
|
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)
|
if let Some(expr_span) = walk_span_to_context(expr.span, span.ctxt)
|
||||||
&& let expr_lo = expr_span.lo()
|
&& let expr_lo = expr_span.lo()
|
||||||
&& expr_lo >= 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()
|
&& let Some(src) = src.as_str()
|
||||||
{
|
{
|
||||||
use rustc_lexer::TokenKind::{BlockComment, LineComment, OpenBrace, Semi, Whitespace};
|
use rustc_lexer::TokenKind::{BlockComment, LineComment, OpenBrace, Semi, Whitespace};
|
||||||
|
@ -1191,9 +1191,9 @@ fn eq_span_tokens(
|
|||||||
pred: impl Fn(TokenKind) -> bool,
|
pred: impl Fn(TokenKind) -> bool,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
fn f(cx: &LateContext<'_>, left: Range<BytePos>, right: Range<BytePos>, 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(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 Some(rsrc) = rsrc.as_str()
|
||||||
{
|
{
|
||||||
let pred = |t: &(_, _)| pred(t.0);
|
let pred = |t: &(_, _)| pred(t.0);
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
};
|
};
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::ops::Range;
|
use std::ops::{Deref, Range};
|
||||||
|
|
||||||
pub trait HasSession {
|
pub trait HasSession {
|
||||||
fn sess(&self) -> &Session;
|
fn sess(&self) -> &Session;
|
||||||
@ -94,10 +94,16 @@ fn with_ctxt(self, ctxt: SyntaxContext) -> Span {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub trait SpanRangeExt: SpanRange {
|
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
|
/// 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.
|
/// extends through multiple files, or is malformed.
|
||||||
fn get_source_text(self, cx: &impl HasSession) -> Option<SourceFileRange> {
|
fn get_source_range(self, cx: &impl HasSession) -> Option<SourceFileRange> {
|
||||||
get_source_text(cx.sess().source_map(), self.into_range())
|
get_source_range(cx.sess().source_map(), self.into_range())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Calls the given function with the source text referenced and returns the value. Returns
|
/// 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> {
|
fn trim_start(self, cx: &impl HasSession) -> Range<BytePos> {
|
||||||
trim_start(cx.sess().source_map(), self.into_range())
|
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 {}
|
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 start = sm.lookup_byte_offset(sp.start);
|
||||||
let end = sm.lookup_byte_offset(sp.end);
|
let end = sm.lookup_byte_offset(sp.end);
|
||||||
if !Lrc::ptr_eq(&start.sf, &end.sf) || start.pos > end.pos {
|
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> {
|
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()
|
&& let Some(src) = src.as_str()
|
||||||
{
|
{
|
||||||
Some(f(src))
|
Some(f(src))
|
||||||
@ -183,7 +217,7 @@ fn with_source_text_and_range<T>(
|
|||||||
sp: Range<BytePos>,
|
sp: Range<BytePos>,
|
||||||
f: impl for<'a> FnOnce(&'a str, Range<usize>) -> T,
|
f: impl for<'a> FnOnce(&'a str, Range<usize>) -> T,
|
||||||
) -> Option<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
|
&& let Some(text) = &src.sf.src
|
||||||
{
|
{
|
||||||
Some(f(text, src.range))
|
Some(f(text, src.range))
|
||||||
@ -198,7 +232,7 @@ fn map_range(
|
|||||||
sp: Range<BytePos>,
|
sp: Range<BytePos>,
|
||||||
f: impl for<'a> FnOnce(&'a str, Range<usize>) -> Option<Range<usize>>,
|
f: impl for<'a> FnOnce(&'a str, Range<usize>) -> Option<Range<usize>>,
|
||||||
) -> Option<Range<BytePos>> {
|
) -> 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(text) = &src.sf.src
|
||||||
&& let Some(range) = f(text, src.range.clone())
|
&& 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)
|
.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 struct SourceFileRange {
|
||||||
pub sf: Lrc<SourceFile>,
|
pub sf: Lrc<SourceFile>,
|
||||||
pub range: Range<usize>,
|
pub range: Range<usize>,
|
||||||
|
Loading…
Reference in New Issue
Block a user