@@ -16,7 +16,7 @@ use rustc_span::{
1616} ;
1717use std:: borrow:: Cow ;
1818use std:: fmt;
19- use std:: ops:: Range ;
19+ use std:: ops:: { Deref , Range } ;
2020
2121pub trait HasSession {
2222 fn sess ( & self ) -> & Session ;
@@ -94,10 +94,16 @@ impl IntoSpan for Range<BytePos> {
9494}
9595
9696pub trait SpanRangeExt : SpanRange {
97+ /// Attempts to get a handle to the source text. Returns `None` if either the span is malformed,
98+ /// or the source text is not accessible.
99+ fn get_source_text ( self , cx : & impl HasSession ) -> Option < SourceText > {
100+ get_source_range ( cx. sess ( ) . source_map ( ) , self . into_range ( ) ) . and_then ( SourceText :: new)
101+ }
102+
97103 /// Gets the source file, and range in the file, of the given span. Returns `None` if the span
98104 /// extends through multiple files, or is malformed.
99- fn get_source_text ( self , cx : & impl HasSession ) -> Option < SourceFileRange > {
100- get_source_text ( cx. sess ( ) . source_map ( ) , self . into_range ( ) )
105+ fn get_source_range ( self , cx : & impl HasSession ) -> Option < SourceFileRange > {
106+ get_source_range ( cx. sess ( ) . source_map ( ) , self . into_range ( ) )
101107 }
102108
103109 /// Calls the given function with the source text referenced and returns the value. Returns
@@ -144,21 +150,49 @@ pub trait SpanRangeExt: SpanRange {
144150 fn trim_start ( self , cx : & impl HasSession ) -> Range < BytePos > {
145151 trim_start ( cx. sess ( ) . source_map ( ) , self . into_range ( ) )
146152 }
153+ }
154+ impl < T : SpanRange > SpanRangeExt for T { }
147155
148- /// Writes the referenced source text to the given writer. Will return `Err` if the source text
149- /// could not be retrieved.
150- fn write_source_text_to ( self , cx : & impl HasSession , dst : & mut impl fmt:: Write ) -> fmt:: Result {
151- write_source_text_to ( cx. sess ( ) . source_map ( ) , self . into_range ( ) , dst)
156+ /// Handle to a range of text in a source file.
157+ pub struct SourceText ( SourceFileRange ) ;
158+ impl SourceText {
159+ /// Takes ownership of the source file handle if the source text is accessible.
160+ pub fn new ( text : SourceFileRange ) -> Option < Self > {
161+ if text. as_str ( ) . is_some ( ) {
162+ Some ( Self ( text) )
163+ } else {
164+ None
165+ }
166+ }
167+
168+ /// Gets the source text.
169+ pub fn as_str ( & self ) -> & str {
170+ self . 0 . as_str ( ) . unwrap ( )
152171 }
153172
154- /// Extracts the referenced source text as an owned string.
155- fn source_text_to_string ( self , cx : & impl HasSession ) -> Option < String > {
156- self . with_source_text ( cx, ToOwned :: to_owned)
173+ /// Converts this into an owned string.
174+ pub fn to_owned ( & self ) -> String {
175+ self . as_str ( ) . to_owned ( )
176+ }
177+ }
178+ impl Deref for SourceText {
179+ type Target = str ;
180+ fn deref ( & self ) -> & Self :: Target {
181+ self . as_str ( )
182+ }
183+ }
184+ impl AsRef < str > for SourceText {
185+ fn as_ref ( & self ) -> & str {
186+ self . as_str ( )
187+ }
188+ }
189+ impl fmt:: Display for SourceText {
190+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
191+ self . as_str ( ) . fmt ( f)
157192 }
158193}
159- impl < T : SpanRange > SpanRangeExt for T { }
160194
161- fn get_source_text ( sm : & SourceMap , sp : Range < BytePos > ) -> Option < SourceFileRange > {
195+ fn get_source_range ( sm : & SourceMap , sp : Range < BytePos > ) -> Option < SourceFileRange > {
162196 let start = sm. lookup_byte_offset ( sp. start ) ;
163197 let end = sm. lookup_byte_offset ( sp. end ) ;
164198 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
169203}
170204
171205fn with_source_text < T > ( sm : & SourceMap , sp : Range < BytePos > , f : impl for < ' a > FnOnce ( & ' a str ) -> T ) -> Option < T > {
172- if let Some ( src) = get_source_text ( sm, sp)
206+ if let Some ( src) = get_source_range ( sm, sp)
173207 && let Some ( src) = src. as_str ( )
174208 {
175209 Some ( f ( src) )
@@ -183,7 +217,7 @@ fn with_source_text_and_range<T>(
183217 sp : Range < BytePos > ,
184218 f : impl for < ' a > FnOnce ( & ' a str , Range < usize > ) -> T ,
185219) -> Option < T > {
186- if let Some ( src) = get_source_text ( sm, sp)
220+ if let Some ( src) = get_source_range ( sm, sp)
187221 && let Some ( text) = & src. sf . src
188222 {
189223 Some ( f ( text, src. range ) )
@@ -198,7 +232,7 @@ fn map_range(
198232 sp : Range < BytePos > ,
199233 f : impl for < ' a > FnOnce ( & ' a str , Range < usize > ) -> Option < Range < usize > > ,
200234) -> Option < Range < BytePos > > {
201- if let Some ( src) = get_source_text ( sm, sp. clone ( ) )
235+ if let Some ( src) = get_source_range ( sm, sp. clone ( ) )
202236 && let Some ( text) = & src. sf . src
203237 && let Some ( range) = f ( text, src. range . clone ( ) )
204238 {
@@ -232,13 +266,6 @@ fn trim_start(sm: &SourceMap, sp: Range<BytePos>) -> Range<BytePos> {
232266 . unwrap_or ( sp)
233267}
234268
235- fn write_source_text_to ( sm : & SourceMap , sp : Range < BytePos > , dst : & mut impl fmt:: Write ) -> fmt:: Result {
236- match with_source_text ( sm, sp, |src| dst. write_str ( src) ) {
237- Some ( x) => x,
238- None => Err ( fmt:: Error ) ,
239- }
240- }
241-
242269pub struct SourceFileRange {
243270 pub sf : Lrc < SourceFile > ,
244271 pub range : Range < usize > ,
0 commit comments