1 use crate::source_map::SourceMap;
2 use crate::{BytePos, SourceFile};
3 use rustc_data_structures::sync::Lrc;
11 file: Lrc<SourceFile>,
16 pub struct CachingSourceMapView<'sm> {
17 source_map: &'sm SourceMap,
18 line_cache: [CacheEntry; 3],
22 impl<'sm> CachingSourceMapView<'sm> {
23 pub fn new(source_map: &'sm SourceMap) -> CachingSourceMapView<'sm> {
24 let files = source_map.files();
25 let first_file = files[0].clone();
26 let entry = CacheEntry {
29 line_start: BytePos(0),
35 CachingSourceMapView {
37 line_cache: [entry.clone(), entry.clone(), entry],
42 pub fn byte_pos_to_line_and_col(
45 ) -> Option<(Lrc<SourceFile>, usize, BytePos)> {
48 // Check if the position is in one of the cached lines
49 for cache_entry in self.line_cache.iter_mut() {
50 if pos >= cache_entry.line_start && pos < cache_entry.line_end {
51 cache_entry.time_stamp = self.time_stamp;
54 cache_entry.file.clone(),
55 cache_entry.line_number,
56 pos - cache_entry.line_start,
63 for index in 1..self.line_cache.len() {
64 if self.line_cache[index].time_stamp < self.line_cache[oldest].time_stamp {
69 let cache_entry = &mut self.line_cache[oldest];
71 // If the entry doesn't point to the correct file, fix it up
72 if pos < cache_entry.file.start_pos || pos >= cache_entry.file.end_pos {
74 if self.source_map.files().len() > 0 {
75 let file_index = self.source_map.lookup_source_file_idx(pos);
76 let file = self.source_map.files()[file_index].clone();
78 if pos >= file.start_pos && pos < file.end_pos {
79 cache_entry.file = file;
80 cache_entry.file_index = file_index;
94 let line_index = cache_entry.file.lookup_line(pos).unwrap();
95 let line_bounds = cache_entry.file.line_bounds(line_index);
97 cache_entry.line_number = line_index + 1;
98 cache_entry.line_start = line_bounds.0;
99 cache_entry.line_end = line_bounds.1;
100 cache_entry.time_stamp = self.time_stamp;
102 Some((cache_entry.file.clone(), cache_entry.line_number, pos - cache_entry.line_start))